]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Convert receive buffer queue from doubly-linked list to FIFO.
authorDave Hart <hart@ntp.org>
Mon, 16 May 2011 05:18:56 +0000 (05:18 +0000)
committerDave Hart <hart@ntp.org>
Mon, 16 May 2011 05:18:56 +0000 (05:18 +0000)
bk: 4dd0b3c00AwjJ0oZCdLRMJEYzoOn1Q

ChangeLog
include/ntp_config.h
include/ntp_lists.h
include/recvbuff.h
libntp/recvbuff.c
ntpd/ntp_config.c

index 657839432a2a1565e083978403700863a249a937..ff72e534871bd1df6db1c0969e27f78dcfc253db 100644 (file)
--- 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 <stenn@ntp.org>
 * [Bug 1927] io_closeclock() should purge pending recvbufs.
 * [Bug 1931] cv always includes fudgetime1, never fudgetime2.
index efd7f9a03cac8212f2b8b5f903003adaa99995f8..f9101dc26ba2b8eaaf3cd27045597f17e1aec39d 100644 (file)
 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)          \
index df98fcb8e2c277fc1f067c0ad8eb9648fcf9fe61..43ebf680eb571106356c7f1de489e8fe5e8315cf 100644 (file)
@@ -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);                             \
index c73407db4ae28d4110409e6decd09a4d12c127e5..92188f5990cd2ef5931fb3fb82405eb5a81f3b99 100644 (file)
@@ -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);
index b7182252b527690dbdce9ce2502ea8cd6a8d7659..f78b2ba6a68884beb47b6a1a5a670090501deac6 100644 (file)
 /*
  * 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 */
index 9dfb623576aa0b83314b51c8602550b1979e65a6..2b1909ead560ad75356cdb52c1484773892a38d4 100644 (file)
@@ -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,