+* 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.
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;
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) \
ppentry = &(listhead); \
\
while (!(expr)) \
- if ((*ppentry)->nextlink != NULL) \
+ if ((*ppentry)->nextlink != NULL) { \
ppentry = &((*ppentry)->nextlink); \
- else { \
+ } else { \
ppentry = NULL; \
break; \
} \
(punlinked) = *ppentry; \
*ppentry = (punlinked)->nextlink; \
MAYBE_Z_LISTS((punlinked)->nextlink); \
- } else \
+ } else { \
(punlinked) = NULL; \
+ } \
} while (FALSE)
#define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \
#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); \
} \
} 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); \
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);
/*
* 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)
*/
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++;
/*
* Init buffer free list and stat counters
*/
- ISC_LIST_INIT(full_recv_list);
free_recvbufs = total_recvbufs = 0;
full_recvbufs = lowater_adds = 0;
{
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);
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();
}
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();
}
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;
}
/*
* 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;
{
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);
}
*/
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 */
/* 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,