From: Dave Hart Date: Mon, 16 May 2011 05:18:56 +0000 (+0000) Subject: Convert receive buffer queue from doubly-linked list to FIFO. X-Git-Tag: NTP_4_2_7P168~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a4f7f2c849979f2a54b83d488da94eba6274b5c;p=thirdparty%2Fntp.git Convert receive buffer queue from doubly-linked list to FIFO. bk: 4dd0b3c00AwjJ0oZCdLRMJEYzoOn1Q --- diff --git a/ChangeLog b/ChangeLog index 657839432..ff72e5348 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* Convert receive buffer queue from doubly-linked list to FIFO. (4.2.7p167) 2011/05/14 Released by Harlan Stenn * [Bug 1927] io_closeclock() should purge pending recvbufs. * [Bug 1931] cv always includes fudgetime1, never fudgetime2. diff --git a/include/ntp_config.h b/include/ntp_config.h index efd7f9a03..f9101dc26 100644 --- a/include/ntp_config.h +++ b/include/ntp_config.h @@ -64,15 +64,6 @@ extern int cmdline_server_count; extern char ** cmdline_servers; -/* generic FIFO element */ -typedef struct gen_node_tag gen_node; -struct gen_node_tag { - gen_node * link; -}; - -/* generic FIFO */ -typedef DECL_FIFO_ANCHOR(gen_node) gen_fifo; - typedef struct int_range_tag { int first; int last; @@ -289,7 +280,6 @@ typedef struct settrap_parms_tag { const char * token_name(int token); /* generic fifo routines for structs linked by 1st member */ -void check_gen_fifo_consistency(void *fifo); void* append_gen_fifo(void *fifo, void *entry); void * concat_gen_fifos(void *first, void *second); #define APPEND_G_FIFO(pf, pe) \ diff --git a/include/ntp_lists.h b/include/ntp_lists.h index df98fcb8e..43ebf680e 100644 --- a/include/ntp_lists.h +++ b/include/ntp_lists.h @@ -187,9 +187,9 @@ do { \ ppentry = &(listhead); \ \ while (!(expr)) \ - if ((*ppentry)->nextlink != NULL) \ + if ((*ppentry)->nextlink != NULL) { \ ppentry = &((*ppentry)->nextlink); \ - else { \ + } else { \ ppentry = NULL; \ break; \ } \ @@ -198,8 +198,9 @@ do { \ (punlinked) = *ppentry; \ *ppentry = (punlinked)->nextlink; \ MAYBE_Z_LISTS((punlinked)->nextlink); \ - } else \ + } else { \ (punlinked) = NULL; \ + } \ } while (FALSE) #define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \ @@ -243,8 +244,22 @@ struct { \ #else #define CHECK_FIFO_CONSISTENCY(anchor) \ check_gen_fifo_consistency(&(anchor)) +void check_gen_fifo_consistency(void *fifo); #endif +/* + * generic FIFO element used to access any FIFO where each element + * begins with the link pointer + */ +typedef struct gen_node_tag gen_node; +struct gen_node_tag { + gen_node * link; +}; + +/* generic FIFO */ +typedef DECL_FIFO_ANCHOR(gen_node) gen_fifo; + + #define LINK_FIFO(anchor, pentry, nextlink) \ do { \ CHECK_FIFO_CONSISTENCY(anchor); \ @@ -279,6 +294,38 @@ do { \ } \ } while (FALSE) +#define UNLINK_MID_FIFO(punlinked, anchor, tounlink, nextlink, \ + entrytype) \ +do { \ + entrytype **ppentry; \ + \ + CHECK_FIFO_CONSISTENCY(anchor); \ + \ + ppentry = &(anchor).phead; \ + \ + while ((tounlink) != *ppentry) \ + if ((*ppentry)->nextlink != NULL) { \ + ppentry = &((*ppentry)->nextlink); \ + } else { \ + ppentry = NULL; \ + break; \ + } \ + \ + if (ppentry != NULL) { \ + (punlinked) = *ppentry; \ + *ppentry = (punlinked)->nextlink; \ + if (NULL == *ppentry) \ + (anchor).pptail = NULL; \ + else if ((anchor).pptail == \ + &(punlinked)->nextlink) \ + (anchor).pptail = &(anchor).phead; \ + MAYBE_Z_LISTS((punlinked)->nextlink); \ + CHECK_FIFO_CONSISTENCY(anchor); \ + } else { \ + (punlinked) = NULL; \ + } \ +} while (FALSE) + #define CONCAT_FIFO(f1, f2, nextlink) \ do { \ CHECK_FIFO_CONSISTENCY(f1); \ diff --git a/include/recvbuff.h b/include/recvbuff.h index c73407db4..92188f599 100644 --- a/include/recvbuff.h +++ b/include/recvbuff.h @@ -47,33 +47,33 @@ extern HANDLE get_recv_buff_event(void); typedef struct recvbuf recvbuf_t; struct recvbuf { - ISC_LINK(recvbuf_t) link; /* next in list */ + recvbuf_t * link; /* next in list */ union { - sockaddr_u X_recv_srcadr; - caddr_t X_recv_srcclock; - struct peer *X_recv_peer; + sockaddr_u X_recv_srcadr; + caddr_t X_recv_srcclock; + struct peer * X_recv_peer; } X_from_where; -#define recv_srcadr X_from_where.X_recv_srcadr -#define recv_srcclock X_from_where.X_recv_srcclock -#define recv_peer X_from_where.X_recv_peer +#define recv_srcadr X_from_where.X_recv_srcadr +#define recv_srcclock X_from_where.X_recv_srcclock +#define recv_peer X_from_where.X_recv_peer #ifndef HAVE_IO_COMPLETION_PORT - sockaddr_u srcadr; /* where packet came from */ + sockaddr_u srcadr; /* where packet came from */ #else - int recv_srcadr_len; /* filled in on completion */ + int recv_srcadr_len;/* filled in on completion */ #endif - endpt * dstadr; /* address pkt arrived on */ - SOCKET fd; /* fd on which it was received */ - int msg_flags; /* Flags received about the packet */ - l_fp recv_time; /* time of arrival */ - void (*receiver)(struct recvbuf *); /* routine to receive buffer */ - int recv_length; /* number of octets received */ + endpt * dstadr; /* address pkt arrived on */ + SOCKET fd; /* fd on which it was received */ + int msg_flags; /* Flags received about the packet */ + l_fp recv_time; /* time of arrival */ + void (*receiver)(struct recvbuf *); /* callback */ + int recv_length; /* number of octets received */ union { - struct pkt X_recv_pkt; - u_char X_recv_buffer[RX_BUFF_SIZE]; + struct pkt X_recv_pkt; + u_char X_recv_buffer[RX_BUFF_SIZE]; } recv_space; -#define recv_pkt recv_space.X_recv_pkt -#define recv_buffer recv_space.X_recv_buffer - int used; /* reference count */ +#define recv_pkt recv_space.X_recv_pkt +#define recv_buffer recv_space.X_recv_buffer + int used; /* reference count */ }; extern void init_recvbuff(int); diff --git a/libntp/recvbuff.c b/libntp/recvbuff.c index b7182252b..f78b2ba6a 100644 --- a/libntp/recvbuff.c +++ b/libntp/recvbuff.c @@ -15,15 +15,15 @@ /* * Memory allocation */ -static u_long volatile full_recvbufs; /* number of recvbufs on fulllist */ -static u_long volatile free_recvbufs; /* number of recvbufs on freelist */ +static u_long volatile full_recvbufs; /* recvbufs on full_recv_fifo */ +static u_long volatile free_recvbufs; /* recvbufs on free_recv_list */ static u_long volatile total_recvbufs; /* total recvbufs currently in use */ static u_long volatile lowater_adds; /* number of times we have added memory */ static u_long volatile buffer_shortfall;/* number of missed free receive buffers between replenishments */ -static ISC_LIST(recvbuf_t) full_recv_list; /* Currently used recv buffers */ -static recvbuf_t * free_recv_list; /* Currently unused buffers */ +static DECL_FIFO_ANCHOR(recvbuf_t) full_recv_fifo; +static recvbuf_t * free_recv_list; #if defined(SYS_WINNT) @@ -97,7 +97,7 @@ create_buffers(int nbufs) */ bufp = emalloc_zero(sizeof(*bufp)); #endif - LINK_SLIST(free_recv_list, bufp, link.next); + LINK_SLIST(free_recv_list, bufp, link); bufp++; free_recvbufs++; total_recvbufs++; @@ -112,7 +112,6 @@ init_recvbuff(int nbufs) /* * Init buffer free list and stat counters */ - ISC_LIST_INIT(full_recv_list); free_recvbufs = total_recvbufs = 0; full_recvbufs = lowater_adds = 0; @@ -134,13 +133,14 @@ uninit_recvbuff(void) { recvbuf_t *rbunlinked; - while ((rbunlinked = ISC_LIST_HEAD(full_recv_list)) != NULL) { - ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbunlinked, link, recvbuf_t); - free(rbunlinked); - } + do { + UNLINK_FIFO(rbunlinked, full_recv_fifo, link); + if (rbunlinked != NULL) + free(rbunlinked); + } while (rbunlinked != NULL); do { - UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link.next); + UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link); if (rbunlinked != NULL) free(rbunlinked); } while (rbunlinked != NULL); @@ -163,7 +163,7 @@ freerecvbuf(recvbuf_t *rb) rb->used--; if (rb->used != 0) msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used); - LINK_SLIST(free_recv_list, rb, link.next); + LINK_SLIST(free_recv_list, rb, link); free_recvbufs++; UNLOCK(); } @@ -177,8 +177,7 @@ add_full_recv_buffer(recvbuf_t *rb) return; } LOCK(); - ISC_LINK_INIT(rb, link); - ISC_LIST_APPEND(full_recv_list, rb, link); + LINK_FIFO(full_recv_fifo, rb, link); full_recvbufs++; UNLOCK(); } @@ -190,15 +189,17 @@ get_free_recv_buffer(void) recvbuf_t *buffer; LOCK(); - UNLINK_HEAD_SLIST(buffer, free_recv_list, link.next); + UNLINK_HEAD_SLIST(buffer, free_recv_list, link); if (buffer != NULL) { free_recvbufs--; initialise_buffer(buffer); - (buffer->used)++; - } else + buffer->used++; + } else { buffer_shortfall++; + } UNLOCK(); - return (buffer); + + return buffer; } @@ -246,18 +247,9 @@ get_full_recv_buffer(void) /* * try to grab a full buffer */ - rbuf = ISC_LIST_HEAD(full_recv_list); - if (rbuf != NULL) { - ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbuf, link, - recvbuf_t); + UNLINK_FIFO(rbuf, full_recv_fifo, link); + if (rbuf != NULL) full_recvbufs--; - } else { - /* - * Make sure we reset the full count to 0 - */ - full_recvbufs = 0; - } - UNLOCK(); return rbuf; @@ -275,16 +267,18 @@ purge_recv_buffers_for_fd( { recvbuf_t *rbufp; recvbuf_t *next; + recvbuf_t *punlinked; LOCK(); - for (rbufp = ISC_LIST_HEAD(full_recv_list); + for (rbufp = HEAD_FIFO(full_recv_fifo); rbufp != NULL; rbufp = next) { - next = ISC_LIST_NEXT(rbufp, link); + next = rbufp->link; if (rbufp->fd == fd) { - ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbufp, - link, recvbuf_t); + UNLINK_MID_FIFO(punlinked, full_recv_fifo, + rbufp, link, recvbuf_t); + INSIST(punlinked == rbufp); full_recvbufs--; freerecvbuf(rbufp); } @@ -299,8 +293,32 @@ purge_recv_buffers_for_fd( */ isc_boolean_t has_full_recv_buffer(void) { - if (ISC_LIST_HEAD(full_recv_list) != NULL) + if (HEAD_FIFO(full_recv_fifo) != NULL) return (ISC_TRUE); else return (ISC_FALSE); } + + +#ifdef NTP_DEBUG_LISTS_H +void +check_gen_fifo_consistency(void *fifo) +{ + gen_fifo *pf; + gen_node *pthis; + gen_node **pptail; + + pf = fifo; + REQUIRE((NULL == pf->phead && NULL == pf->pptail) || + (NULL != pf->phead && NULL != pf->pptail)); + + pptail = &pf->phead; + for (pthis = pf->phead; + pthis != NULL; + pthis = pthis->link) + if (NULL != pthis->link) + pptail = &pthis->link; + + REQUIRE(NULL == pf->pptail || pptail == pf->pptail); +} +#endif /* NTP_DEBUG_LISTS_H */ diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 9dfb62357..2b1909ead 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -954,30 +954,6 @@ dump_config_tree( /* generic fifo routines for structs linked by 1st member */ -#ifdef NTP_DEBUG_LISTS_H -void -check_gen_fifo_consistency(void *fifo) -{ - gen_fifo *pf; - gen_node *pthis; - gen_node **pptail; - - pf = fifo; - REQUIRE((NULL == pf->phead && NULL == pf->pptail) || - (NULL != pf->phead && NULL != pf->pptail)); - - pptail = &pf->phead; - for (pthis = pf->phead; - pthis != NULL; - pthis = pthis->link) - if (NULL != pthis->link) - pptail = &pthis->link; - - REQUIRE(NULL == pf->pptail || pptail == pf->pptail); -} -#endif /* NTP_DEBUG_LISTS_H */ - - void * append_gen_fifo( void *fifo,