From: Willy Tarreau Date: Sun, 2 Sep 2012 20:19:18 +0000 (+0200) Subject: CLEANUP: fdtab: flatten the struct and merge the spec struct with the rest X-Git-Tag: v1.5-dev12~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=45dab73788967ce459b40e5a158cd7af038a45e2;p=thirdparty%2Fhaproxy.git CLEANUP: fdtab: flatten the struct and merge the spec struct with the rest The "spec" sub-struct was using 8 bytes for only 5 needed. There is no reason to keep it as a struct, it doesn't bring any value. By flattening it, we can merge the single byte with the next single byte, resulting in an immediate saving of 4 bytes (20%). Interestingly, tests have shown a steady performance gain of 0.6% after this change, which can possibly be attributed to a more cache-line friendly struct. --- diff --git a/include/types/fd.h b/include/types/fd.h index f45b04603f..1ccb0ebede 100644 --- a/include/types/fd.h +++ b/include/types/fd.h @@ -55,10 +55,8 @@ enum { struct fdtab { int (*iocb)(int fd); /* I/O handler, returns FD_WAIT_* */ void *owner; /* the connection or listener associated with this fd, NULL if closed */ - struct { /* used by pollers which support speculative polling */ - unsigned char e; /* read and write events status. 4 bits, may be merged into flags' lower bits */ - unsigned int s1; /* Position in spec list+1. 0=not in list. */ - } spec; + unsigned int spec_p; /* speculative polling: position in spec list+1. 0=not in list. */ + unsigned char spec_e; /* speculative polling: read and write events status. 4 bits */ unsigned char ev; /* event seen in return of poll() : FD_POLL_* */ }; diff --git a/src/ev_sepoll.c b/src/ev_sepoll.c index 7c1cf4c535..bb2e47e37d 100644 --- a/src/ev_sepoll.c +++ b/src/ev_sepoll.c @@ -105,7 +105,7 @@ * The FD array has to hold a back reference to the speculative list. This * reference is only valid if at least one of the directions is marked SPEC. * - * We store the FD state in the 4 lower bits of fdtab[fd].spec.e, and save the + * We store the FD state in the 4 lower bits of fdtab[fd].spec_e, and save the * previous state upon changes in the 4 higher bits, so that changes are easy * to spot. */ @@ -160,10 +160,10 @@ static struct epoll_event ev; REGPRM1 static inline void alloc_spec_entry(const int fd) { - if (fdtab[fd].spec.s1) + if (fdtab[fd].spec_p) /* sometimes the entry already exists for the other direction */ return; - fdtab[fd].spec.s1 = nbspec + 1; + fdtab[fd].spec_p = nbspec + 1; spec_list[nbspec] = fd; nbspec++; } @@ -176,11 +176,11 @@ REGPRM1 static void release_spec_entry(int fd) { unsigned int pos; - pos = fdtab[fd].spec.s1; + pos = fdtab[fd].spec_p; if (!pos) return; - fdtab[fd].spec.s1 = 0; + fdtab[fd].spec_p = 0; pos--; /* we have spec_list[pos]==fd */ @@ -191,7 +191,7 @@ REGPRM1 static void release_spec_entry(int fd) /* we replace current FD by the highest one, which may sometimes be the same */ fd = spec_list[nbspec]; spec_list[pos] = fd; - fdtab[fd].spec.s1 = pos + 1; + fdtab[fd].spec_p = pos + 1; } /* @@ -207,7 +207,7 @@ REGPRM2 static int __fd_is_set(const int fd, int dir) ABORT_NOW(); } #endif - ret = ((unsigned)fdtab[fd].spec.e >> dir) & FD_EV_MASK_DIR; + ret = ((unsigned)fdtab[fd].spec_e >> dir) & FD_EV_MASK_DIR; return (ret == FD_EV_SPEC || ret == FD_EV_WAIT); } @@ -225,14 +225,14 @@ REGPRM2 static void __fd_wai(const int fd, int dir) ABORT_NOW(); } #endif - i = ((unsigned)fdtab[fd].spec.e >> dir) & FD_EV_MASK_DIR; + i = ((unsigned)fdtab[fd].spec_e >> dir) & FD_EV_MASK_DIR; if (!(i & FD_EV_IN_SL)) { if (i == FD_EV_WAIT) return; /* already in desired state */ alloc_spec_entry(fd); /* need a spec entry */ } - fdtab[fd].spec.e ^= (i ^ (unsigned int)FD_EV_IN_PL) << dir; + fdtab[fd].spec_e ^= (i ^ (unsigned int)FD_EV_IN_PL) << dir; } REGPRM2 static void __fd_set(const int fd, int dir) @@ -245,7 +245,7 @@ REGPRM2 static void __fd_set(const int fd, int dir) ABORT_NOW(); } #endif - i = ((unsigned)fdtab[fd].spec.e >> dir) & FD_EV_MASK_DIR; + i = ((unsigned)fdtab[fd].spec_e >> dir) & FD_EV_MASK_DIR; if (i != FD_EV_STOP) { if (unlikely(i != FD_EV_IDLE)) @@ -253,7 +253,7 @@ REGPRM2 static void __fd_set(const int fd, int dir) // switch to SPEC state and allocate a SPEC entry. alloc_spec_entry(fd); } - fdtab[fd].spec.e ^= (unsigned int)(FD_EV_IN_SL << dir); + fdtab[fd].spec_e ^= (unsigned int)(FD_EV_IN_SL << dir); } REGPRM2 static void __fd_clr(const int fd, int dir) @@ -266,7 +266,7 @@ REGPRM2 static void __fd_clr(const int fd, int dir) ABORT_NOW(); } #endif - i = ((unsigned)fdtab[fd].spec.e >> dir) & FD_EV_MASK_DIR; + i = ((unsigned)fdtab[fd].spec_e >> dir) & FD_EV_MASK_DIR; if (i != FD_EV_SPEC) { if (unlikely(i != FD_EV_WAIT)) @@ -278,7 +278,7 @@ REGPRM2 static void __fd_clr(const int fd, int dir) */ alloc_spec_entry(fd); } - fdtab[fd].spec.e ^= (unsigned int)(FD_EV_IN_SL << dir); + fdtab[fd].spec_e ^= (unsigned int)(FD_EV_IN_SL << dir); } /* normally unused */ @@ -295,7 +295,7 @@ REGPRM1 static void __fd_rem(int fd) REGPRM1 static void __fd_clo(int fd) { release_spec_entry(fd); - fdtab[fd].spec.e &= ~(FD_EV_MASK | FD_EV_MASK_OLD); + fdtab[fd].spec_e &= ~(FD_EV_MASK | FD_EV_MASK_OLD); } /* @@ -314,8 +314,8 @@ REGPRM2 static void _do_poll(struct poller *p, int exp) while (likely(spec_idx > 0)) { spec_idx--; fd = spec_list[spec_idx]; - en = fdtab[fd].spec.e & 15; /* new events */ - eo = fdtab[fd].spec.e >> 4; /* previous events */ + en = fdtab[fd].spec_e & 15; /* new events */ + eo = fdtab[fd].spec_e >> 4; /* previous events */ /* If an fd with a poll bit is present here, it means that it * has last requested a poll, or is leaving from a poll. Given @@ -372,9 +372,9 @@ REGPRM2 static void _do_poll(struct poller *p, int exp) epoll_ctl(epoll_fd, opcode, fd, &ev); } - fdtab[fd].spec.e = (en << 4) + en; /* save new events */ + fdtab[fd].spec_e = (en << 4) + en; /* save new events */ - if (!(fdtab[fd].spec.e & FD_EV_RW_SL)) { + if (!(fdtab[fd].spec_e & FD_EV_RW_SL)) { /* This fd switched to combinations of either WAIT or * IDLE. It must be removed from the spec list. */ @@ -447,7 +447,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp) while (likely(spec_idx > 0)) { spec_idx--; fd = spec_list[spec_idx]; - eo = fdtab[fd].spec.e; /* save old events */ + eo = fdtab[fd].spec_e; /* save old events */ /* * Process the speculative events. @@ -473,7 +473,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp) if (!fdtab[fd].owner) continue; - if (!(fdtab[fd].spec.e & (FD_EV_RW_SL|FD_EV_RW_PL))) { + if (!(fdtab[fd].spec_e & (FD_EV_RW_SL|FD_EV_RW_PL))) { /* This fd switched to IDLE, it can be removed from the spec list. */ release_spec_entry(fd); continue;