summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.c9
-rw-r--r--lib/distribute.c13
-rw-r--r--lib/hash.c11
-rw-r--r--lib/hash.h2
-rw-r--r--lib/if.c18
-rw-r--r--lib/if.h1
-rw-r--r--lib/if_rmap.c9
-rw-r--r--lib/keystroke.h2
-rw-r--r--lib/log.c3
-rw-r--r--lib/memory.c27
-rw-r--r--lib/prefix.c13
-rw-r--r--lib/prefix.h4
-rw-r--r--lib/qtime.c11
-rw-r--r--lib/qtime.h30
-rw-r--r--lib/table.c14
-rw-r--r--lib/thread.c165
-rw-r--r--lib/thread.h3
-rw-r--r--lib/vector.c9
-rw-r--r--lib/vector.h5
-rw-r--r--lib/workqueue.c31
-rw-r--r--lib/workqueue.h2
-rw-r--r--lib/zclient.c6
-rw-r--r--lib/zclient.h9
23 files changed, 312 insertions, 85 deletions
diff --git a/lib/command.c b/lib/command.c
index a78ac05c..67a9ab04 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -92,10 +92,11 @@ Hello, this is " QUAGGA_PROGNAME " (version " QUAGGA_VERSION ").\r\n\
" QUAGGA_COPYRIGHT "\r\n\
\r\n";
+
#ifdef QDEBUG
-const char *debug_banner =
- QUAGGA_PROGNAME " version " QUAGGA_VERSION " QDEBUG=" QDEBUG " "
- __DATE__ " " __TIME__;
+const char* debug_banner =
+ QUAGGA_PROGNAME " version " QUAGGA_VERSION " QDEBUG=" QDEBUG_NAME " "
+ __DATE__ " " __TIME__ ;
#endif
static const struct facility_map {
@@ -4172,6 +4173,8 @@ cmd_init (int terminal)
install_element (VIEW_NODE, &show_thread_cpu_cmd);
install_element (ENABLE_NODE, &show_thread_cpu_cmd);
install_element (RESTRICTED_NODE, &show_thread_cpu_cmd);
+
+ install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
install_element (VIEW_NODE, &show_work_queues_cmd);
install_element (ENABLE_NODE, &show_work_queues_cmd);
}
diff --git a/lib/distribute.c b/lib/distribute.c
index 0e1c9458..8c0f057e 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -115,16 +115,11 @@ distribute_get (const char *ifname)
}
static unsigned int
-distribute_hash_make (struct distribute *dist)
+distribute_hash_make (void *arg)
{
- unsigned int i, key;
+ const struct distribute *dist = arg;
- key = 0;
- if (dist->ifname)
- for (i = 0; i < strlen (dist->ifname); i++)
- key += dist->ifname[i];
-
- return key;
+ return dist->ifname ? string_hash_make (dist->ifname) : 0;
}
/* If two distribute-list have same value then return 1 else return
@@ -764,7 +759,7 @@ distribute_list_reset ()
void
distribute_list_init (int node)
{
- disthash = hash_create ((unsigned int (*) (void *)) distribute_hash_make,
+ disthash = hash_create (distribute_hash_make,
(int (*) (const void *, const void *)) distribute_cmp);
if(node==RIP_NODE) {
diff --git a/lib/hash.c b/lib/hash.c
index 672327ec..6db79ea7 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -101,6 +101,17 @@ hash_lookup (struct hash *hash, void *data)
return hash_get (hash, data, NULL);
}
+/* Simple Bernstein hash which is simple and fast for common case */
+unsigned int string_hash_make (const char *str)
+{
+ unsigned int hash = 0;
+
+ while (*str)
+ hash = (hash * 33) ^ (unsigned int) *str++;
+
+ return hash;
+}
+
/* This function release registered value from specified hash. When
release is successfully finished, return the data pointer in the
hash backet. */
diff --git a/lib/hash.h b/lib/hash.h
index f4b1c23e..4cb772e5 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -70,4 +70,6 @@ extern void hash_iterate (struct hash *,
extern void hash_clean (struct hash *, void (*) (void *));
extern void hash_free (struct hash *);
+extern unsigned int string_hash_make (const char *);
+
#endif /* _ZEBRA_HASH_H */
diff --git a/lib/if.c b/lib/if.c
index b1d0d49a..048ee1fb 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -878,3 +878,21 @@ if_init (void)
memset (&if_master, 0, sizeof if_master);
}
+
+void
+if_terminate (void)
+{
+ for (;;)
+ {
+ struct interface *ifp;
+
+ ifp = listnode_head (iflist);
+ if (ifp == NULL)
+ break;
+
+ if_delete (ifp);
+ }
+
+ list_delete (iflist);
+ iflist = NULL;
+}
diff --git a/lib/if.h b/lib/if.h
index c99ab81b..841ce51e 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -266,6 +266,7 @@ extern int if_is_pointopoint (struct interface *);
extern int if_is_multicast (struct interface *);
extern void if_add_hook (int, int (*)(struct interface *));
extern void if_init (void);
+extern void if_terminate (void);
extern void if_dump_all (void);
extern const char *if_flag_dump(unsigned long);
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index 9ef5ed94..e51f1fe5 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -110,14 +110,9 @@ if_rmap_get (const char *ifname)
static unsigned int
if_rmap_hash_make (void *data)
{
- struct if_rmap *if_rmap = data;
- unsigned int i, key;
+ const struct if_rmap *if_rmap = data;
- key = 0;
- for (i = 0; i < strlen (if_rmap->ifname); i++)
- key += if_rmap->ifname[i];
-
- return key;
+ return string_hash_make (if_rmap->ifname);
}
static int
diff --git a/lib/keystroke.h b/lib/keystroke.h
index 2b1d4d93..76fba15e 100644
--- a/lib/keystroke.h
+++ b/lib/keystroke.h
@@ -75,7 +75,7 @@ enum keystroke_flags
kf_type_mask = 0x0F, /* extraction of type */
} ;
-CONFIRM(ks_type_reserved == kf_type_mask) ;
+CONFIRM(ks_type_reserved == (enum keystroke_type)kf_type_mask) ;
typedef struct keystroke* keystroke ;
typedef struct keystroke_stream* keystroke_stream ;
diff --git a/lib/log.c b/lib/log.c
index 72f967f6..18878094 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -822,6 +822,9 @@ closezlog (struct zlog *zl)
if (zl->fp != NULL)
fclose (zl->fp);
+ if (zl->filename != NULL)
+ free (zl->filename);
+
XFREE (MTYPE_ZLOG, zl);
}
diff --git a/lib/memory.c b/lib/memory.c
index c13404d2..49b20c14 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -112,6 +112,12 @@ zerror (const char *fname, int type, size_t size)
/*------------------------------------------------------------------------------
* Memory allocation.
+ *
+ * Allocate memory of a given size, to be tracked by a given type.
+ *
+ * Returns: pointer to usable memory.
+ *
+ * NB: If memory cannot be allocated, aborts execution.
*/
void *
zmalloc (enum MTYPE mtype, size_t size MEMORY_TRACKER_NAME)
@@ -141,6 +147,8 @@ zmalloc (enum MTYPE mtype, size_t size MEMORY_TRACKER_NAME)
/*------------------------------------------------------------------------------
* Memory allocation zeroising the allocated area.
+ *
+ * As zmalloc, plus zeroises the allocated memory.
*/
void *
zcalloc (enum MTYPE mtype, size_t size MEMORY_TRACKER_NAME)
@@ -170,6 +178,16 @@ zcalloc (enum MTYPE mtype, size_t size MEMORY_TRACKER_NAME)
/*------------------------------------------------------------------------------
* Memory reallocation.
+ *
+ * Given a pointer returned by zmalloc()/zcalloc()/zrealloc(), extend or
+ * contract the allocation to the given size -- retaining current type.
+ * The type given MUST be the original type.
+ *
+ * Given a NULL, allocate memory as zmalloc().
+ *
+ * Returns: pointer to usable memory.
+ *
+ * NB: If memory cannot be allocated, aborts execution.
*/
void *
zrealloc (enum MTYPE mtype, void *ptr, size_t size MEMORY_TRACKER_NAME)
@@ -199,6 +217,11 @@ zrealloc (enum MTYPE mtype, void *ptr, size_t size MEMORY_TRACKER_NAME)
/*------------------------------------------------------------------------------
* Memory free.
+ *
+ * Free memory allocated by zmalloc()/zcalloc()/zrealloc()/zstrdup().
+ * The type given MUST be the original type.
+ *
+ * Does nothing if the given pointer is NULL.
*/
void
zfree (enum MTYPE mtype, void *ptr)
@@ -222,6 +245,10 @@ zfree (enum MTYPE mtype, void *ptr)
/*------------------------------------------------------------------------------
* String duplication.
+ *
+ * Memory is allocated as zmalloc() and must later be freed by zfree().
+ *
+ * NB: If memory cannot be allocated, aborts execution.
*/
char *
zstrdup (enum MTYPE mtype, const char *str MEMORY_TRACKER_NAME)
diff --git a/lib/prefix.c b/lib/prefix.c
index f13050e5..867c86a3 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -41,7 +41,7 @@ static const u_char maskbit[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0,
/* Address Famiy Identifier to Address Family converter. */
int
-afi2family (int afi)
+afi2family (afi_t afi)
{
if (afi == AFI_IP)
return AF_INET;
@@ -52,7 +52,7 @@ afi2family (int afi)
return 0;
}
-int
+afi_t
family2afi (int family)
{
if (family == AF_INET)
@@ -70,15 +70,16 @@ prefix_match (const struct prefix *n, const struct prefix *p)
{
int offset;
int shift;
-
- /* Set both prefix's head pointer. */
- const u_char *np = (const u_char *)&n->u.prefix;
- const u_char *pp = (const u_char *)&p->u.prefix;
+ const u_char *np, *pp;
/* If n's prefix is longer than p's one return 0. */
if (n->prefixlen > p->prefixlen)
return 0;
+ /* Set both prefix's head pointer. */
+ np = (const u_char *)&n->u.prefix;
+ pp = (const u_char *)&p->u.prefix;
+
offset = n->prefixlen / PNBBY;
shift = n->prefixlen % PNBBY;
diff --git a/lib/prefix.h b/lib/prefix.h
index 74f32e94..d4d6adb2 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -150,8 +150,8 @@ prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
}
/* Prototypes. */
-extern int afi2family (int);
-extern int family2afi (int);
+extern int afi2family (afi_t);
+extern afi_t family2afi (int);
extern struct prefix *prefix_new (void);
extern void prefix_free (struct prefix *);
diff --git a/lib/qtime.c b/lib/qtime.c
index 3ec34a72..42b903da 100644
--- a/lib/qtime.c
+++ b/lib/qtime.c
@@ -192,3 +192,14 @@ qt_craft_monotonic(void) {
return (monotonic * times_scale_q) +
((monotonic * times_scale_r) / times_clk_tcks) ;
} ;
+
+/*------------------------------------------------------------------------------
+ * Get crafted monotonic time -- in seconds
+ */
+extern time_t
+qt_craft_mono_secs(void)
+{
+ qt_craft_monotonic() ; /* update the monotonic counter */
+
+ return monotonic / times_clk_tcks ;
+} ;
diff --git a/lib/qtime.h b/lib/qtime.h
index 35e1a51b..df486dfd 100644
--- a/lib/qtime.h
+++ b/lib/qtime.h
@@ -108,6 +108,9 @@ qt_get_monotonic(void) ; /* clock_gettime(CLOCK_MONOTONIC, ...) */
/* OR equivalent using times() */
Inline qtime_mono_t
qt_add_monotonic(qtime_t interval) ; /* qt_get_monotonic() + interval */
+Inline time_t qt_get_mono_secs(void) ;
+ /* clock_gettime(CLOCK_MONOTONIC, ...) */
+ /* OR equivalent using times() */
Inline qtime_mono_t /* monotonic time from CLOCK_REALTIME */
qt_realtime2monotonic(qtime_real_t realtime) ;
@@ -115,8 +118,8 @@ Inline qtime_real_t /* CLOCK_REALTIME from monotonic time */
qt_monotonic2realtime(qtime_mono_t monotonic) ;
/* Function to manufacture a monotonic clock. */
-extern qtime_mono_t
-qt_craft_monotonic(void) ;
+extern qtime_mono_t qt_craft_monotonic(void) ;
+extern time_t qt_craft_mono_secs(void) ;
/* These are provided just in case gettimeofday() != CLOCK_REALTIME */
Inline qtime_tod_t
@@ -254,6 +257,29 @@ qt_add_monotonic(qtime_t interval)
return qt_get_monotonic() + interval;
} ;
+/* clock_gettime(CLOCK_MONOTONIC, ...) OR qt_craft_monotonic()
+ * -- returning time_t value
+ *
+ * Value returned is in seconds -- for coarser grain timings.
+ *
+ * While possibility of error is essentially theoretical, must treat it as a
+ * FATAL error -- cannot continue with broken time value !
+ */
+Inline time_t
+qt_get_mono_secs(void)
+{
+#ifdef HAVE_CLOCK_MONOTONIC
+ struct timespec ts ;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+ zabort_errno("clock_gettime failed") ;
+
+ return ts.tv_sec ;
+#else
+ return qt_craft_mono_secs() ;
+#endif
+} ;
+
/* gettimeofday(&tv, NULL) -- returning qtime_t value
*/
Inline qtime_tod_t
diff --git a/lib/table.c b/lib/table.c
index 04df3af5..e40e6707 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -209,6 +209,10 @@ route_node_match (const struct route_table *table, const struct prefix *p)
{
if (node->info)
matched = node;
+
+ if (node->p.prefixlen == p->prefixlen)
+ break;
+
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
@@ -260,8 +264,8 @@ route_node_lookup (struct route_table *table, struct prefix *p)
while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p))
{
- if (node->p.prefixlen == p->prefixlen && node->info)
- return route_lock_node (node);
+ if (node->p.prefixlen == p->prefixlen)
+ return node->info ? route_lock_node (node) : NULL;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
@@ -283,10 +287,8 @@ route_node_get (struct route_table *table, struct prefix *p)
prefix_match (&node->p, p))
{
if (node->p.prefixlen == p->prefixlen)
- {
- route_lock_node (node);
- return node;
- }
+ return route_lock_node (node);
+
match = node;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
diff --git a/lib/thread.c b/lib/thread.c
index 7a9a3a60..078a09d6 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -228,6 +228,9 @@ recent_relative_time (void)
return relative_time;
}
+/* Uses the address of the function (or at least ls part of same) as the hash
+ * key. (The function name is for display, only.)
+ */
static unsigned int
cpu_record_hash_key (struct cpu_thread_history *a)
{
@@ -288,15 +291,14 @@ static void
cpu_record_hash_free (void *a)
{
struct cpu_thread_history *hist = a;
- void* funcname = miyagi(hist->funcname) ;
- XFREE (MTYPE_THREAD_FUNCNAME, funcname);
+ XFREE (MTYPE_THREAD_FUNCNAME, hist->funcname);
XFREE (MTYPE_THREAD_STATS, hist);
}
static inline void
vty_out_cpu_thread_history(struct vty* vty,
- struct cpu_thread_history *a)
+ const struct cpu_thread_history *a)
{
#ifdef HAVE_RUSAGE
vty_out(vty, "%7ld.%03ld %9d %8ld %9ld %8ld %9ld",
@@ -349,7 +351,9 @@ cpu_record_print(struct vty *vty, thread_type filter)
void *args[3] = {&tmp, vty, &filter};
memset(&tmp, 0, sizeof tmp);
- tmp.funcname = "TOTAL";
+ tmp.funcname = miyagi("TOTAL"); /* NB: will not free tmp in the usual way,
+ in particular, will not attempt
+ to free this !! */
tmp.types = filter;
#ifdef HAVE_RUSAGE
@@ -433,6 +437,89 @@ DEFUN_CALL(show_thread_cpu,
return CMD_SUCCESS;
}
+static void
+cpu_record_hash_clear (struct hash_backet *bucket,
+ void *args)
+{
+ thread_type *filter = args;
+ struct cpu_thread_history *a = bucket->data;
+
+ a = bucket->data;
+ if ( !(a->types & *filter) )
+ return;
+
+ hash_release (cpu_record, bucket->data);
+}
+
+static void
+cpu_record_clear (thread_type filter)
+{
+ thread_type *tmp = &filter;
+ hash_iterate (cpu_record,
+ (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
+ tmp);
+}
+
+DEFUN(clear_thread_cpu,
+ clear_thread_cpu_cmd,
+ "clear thread cpu [FILTER]",
+ "Clear stored data\n"
+ "Thread information\n"
+ "Thread CPU usage\n"
+ "Display filter (rwtexb)\n")
+{
+ int i = 0;
+ thread_type filter = (thread_type) -1U;
+
+ if (argc > 0)
+ {
+ filter = 0;
+ while (argv[0][i] != '\0')
+ {
+ switch ( argv[0][i] )
+ {
+ case 'r':
+ case 'R':
+ filter |= (1 << THREAD_READ);
+ break;
+ case 'w':
+ case 'W':
+ filter |= (1 << THREAD_WRITE);
+ break;
+ case 't':
+ case 'T':
+ filter |= (1 << THREAD_TIMER);
+ break;
+ case 'e':
+ case 'E':
+ filter |= (1 << THREAD_EVENT);
+ break;
+ case 'x':
+ case 'X':
+ filter |= (1 << THREAD_EXECUTE);
+ break;
+ case 'b':
+ case 'B':
+ filter |= (1 << THREAD_BACKGROUND);
+ break;
+ default:
+ break;
+ }
+ ++i;
+ }
+ if (filter == 0)
+ {
+ vty_out(vty, "Invalid filter \"%s\" specified,"
+ " must contain at least one of 'RWTEXB'%s",
+ argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ cpu_record_clear (filter);
+ return CMD_SUCCESS;
+}
+
/* List allocation and head/tail print out. */
static void
thread_list_debug (struct thread_list *list)
@@ -630,9 +717,16 @@ thread_get_hist(struct thread* thread, const char* funcname)
struct cpu_thread_history* hist ;
tmp.func = thread->func ;
- tmp.funcname = funcname ;
-
+ tmp.funcname = miyagi(funcname); /* NB: will not free tmp in the usual way,
+ in particular, will not attempt
+ to free this !! */
LOCK
+
+ /* This looks up entry which matches the tmp just set up.
+ *
+ * If does not find one, allocates a new one -- taking a copy of the
+ * funcname.
+ */
hist = hash_get (cpu_record, &tmp,
(void * (*) (void *))cpu_record_hash_alloc);
UNLOCK
@@ -1121,6 +1215,26 @@ thread_timer_process (struct thread_list *list, struct timeval *timenow)
}
/*------------------------------------------------------------------------------
+ * Move the given list of threads to the back of the THREAD_READY queue.
+ */
+/* process a list en masse, e.g. for event thread lists */
+static unsigned int
+thread_process (struct thread_list *list)
+{
+ struct thread *thread;
+ unsigned int ready = 0;
+
+ for (thread = list->head; thread; thread = thread->next)
+ {
+ thread_list_delete (list, thread);
+ thread->type = THREAD_READY;
+ thread_list_add (&thread->master->ready, thread);
+ ready++;
+ }
+ return ready;
+}
+
+/*------------------------------------------------------------------------------
* Fetch next ready thread -- for standard thread handing.
*
* (This is not used when using qtimer_pile, or qnexus stuff.)
@@ -1141,32 +1255,45 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
{
int num = 0;
- /* Signals are highest priority */
+ /* Signals pre-empt everything */
quagga_sigevent_process ();
- /* Normal event are the next highest priority. */
- if ((thread = thread_trim_head (&m->event)) != NULL)
- return thread_run (m, thread, fetch);
-
- /* If there are any ready threads from previous scheduler runs,
- * process top of them.
+ /* Drain the ready queue of already scheduled jobs, before scheduling
+ * more.
*/
if ((thread = thread_trim_head (&m->ready)) != NULL)
return thread_run (m, thread, fetch);
+ /* To be fair to all kinds of threads, and avoid starvation, we
+ * need to be careful to consider all thread types for scheduling
+ * in each quanta. I.e. we should not return early from here on.
+ */
+
+ /* Normal event are the next highest priority. */
+ thread_process (&m->event);
+
/* Structure copy. */
readfd = m->readfd;
writefd = m->writefd;
exceptfd = m->exceptfd;
/* Calculate select wait timer if nothing else to do */
- quagga_get_relative (NULL);
- timer_wait = thread_timer_wait (&m->timer, &timer_val);
- timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
+ if (m->ready.count == 0)
+ {
+ quagga_get_relative (NULL);
+ timer_wait = thread_timer_wait (&m->timer, &timer_val);
+ timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
- if (timer_wait_bg &&
- (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
- timer_wait = timer_wait_bg;
+ if (timer_wait_bg &&
+ (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
+ timer_wait = timer_wait_bg;
+ }
+ else
+ {
+ timer_val.tv_sec = 0 ;
+ timer_val.tv_usec = 0 ;
+ timer_wait = &timer_val ;
+ } ;
num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
diff --git a/lib/thread.h b/lib/thread.h
index fa021486..a38fb19a 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -87,7 +87,7 @@ struct thread
struct cpu_thread_history
{
int (*func)(struct thread *);
- const char *funcname;
+ char *funcname;
unsigned int total_calls;
struct time_stats
{
@@ -207,6 +207,7 @@ extern int thread_should_yield (struct thread *);
/* Internal libzebra exports */
extern void thread_getrusage (RUSAGE_T *);
extern struct cmd_element show_thread_cpu_cmd;
+extern struct cmd_element clear_thread_cpu_cmd;
/* replacements for the system gettimeofday(), clock_gettime() and
* time() functions, providing support for non-decrementing clock on
diff --git a/lib/vector.c b/lib/vector.c
index 646f19a5..83f289fe 100644
--- a/lib/vector.c
+++ b/lib/vector.c
@@ -987,7 +987,8 @@ vector_bsearch(vector v, vector_bsearch_cmp* cmp, const void* p_val,
if (v->end <= 1)
{
- *result = (v->end == 0) ? -1 : cmp(&p_val, (const void**)&v->p_items[0]) ;
+ *result = (v->end == 0) ? -1 :
+ cmp(&p_val, (const void* const*)&v->p_items[0]) ;
return 0 ; /* Stop dead if 0 or 1 items */
} ;
@@ -996,12 +997,12 @@ vector_bsearch(vector v, vector_bsearch_cmp* cmp, const void* p_val,
ih = v->end - 1 ;
/* Pick off the edge cases: >= last and <= first. */
- if ((c = cmp(&p_val, (const void**)&v->p_items[ih])) >= 0)
+ if ((c = cmp(&p_val, (const void* const*)&v->p_items[ih])) >= 0)
{
*result = c ; /* 0 => found. +1 => val > last */
return ih ; /* return high index. */
} ;
- if ((c = cmp(&p_val, (const void**)&v->p_items[il])) <= 0)
+ if ((c = cmp(&p_val, (const void* const*)&v->p_items[il])) <= 0)
{
*result = c ; /* 0 => found. -1 => val < first */
return il ; /* return low index. */
@@ -1018,7 +1019,7 @@ vector_bsearch(vector v, vector_bsearch_cmp* cmp, const void* p_val,
return il ; /* return il: item[il] < val < item[il+1] */
} ;
/* We now know that il < iv < ih */
- c = cmp(&p_val, (const void**)&v->p_items[iv]) ;
+ c = cmp(&p_val, (const void* const*)&v->p_items[iv]) ;
if (c == 0)
{
*result = 0 ;
diff --git a/lib/vector.h b/lib/vector.h
index f098d78a..e69e628a 100644
--- a/lib/vector.h
+++ b/lib/vector.h
@@ -167,10 +167,11 @@ Inline p_vector_item vector_pop_item(vector v) ;
extern void vector_insert(vector v, vector_index i, unsigned int n) ;
extern void vector_delete(vector v, vector_index i, unsigned int n) ;
-typedef int vector_bsearch_cmp(const void** pp_val, const void** item) ;
+typedef int vector_bsearch_cmp(const void* const* pp_val,
+ const void* const* item) ;
vector_index vector_bsearch(vector v, vector_bsearch_cmp* cmp,
const void* p_val, int* result) ;
-typedef int vector_sort_cmp(const void** a, const void** b) ;
+typedef int vector_sort_cmp(const void* const* a, const void* const* b) ;
void vector_sort(vector v, vector_sort_cmp* cmp) ;
extern vector vector_copy_here(vector dst, vector src) ;
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 6f2cd531..56959db0 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -32,7 +32,10 @@
/* master list of work_queues */
static struct list work_queues;
-#define WORK_QUEUE_MIN_GRANULARITY 1
+enum {
+ WQ_MIN_GRANULARITY = 1,
+ WQ_HYSTERESIS_FACTOR = 4,
+} ;
static void
work_queue_item_free (struct work_queue *wq, struct work_queue_item *item)
@@ -62,7 +65,7 @@ work_queue_new (struct thread_master *m, const char *queue_name)
listnode_add (&work_queues, new);
- new->cycles.granularity = WORK_QUEUE_MIN_GRANULARITY;
+ new->cycles.granularity = WQ_MIN_GRANULARITY;
/* Default values, can be overriden by caller */
new->spec.hold = WORK_QUEUE_DEFAULT_HOLD;
@@ -335,7 +338,7 @@ work_queue_run (struct thread *thread)
*
* Best: starts low, can only increase
*
- * Granularity: starts at WORK_QUEUE_MIN_GRANULARITY, can be decreased
+ * Granularity: starts at WQ_MIN_GRANULARITY, can be decreased
* if we run to end of time slot, can increase otherwise
* by a small factor.
*
@@ -344,7 +347,7 @@ work_queue_run (struct thread *thread)
* daemon has been running a long time.
*/
if (wq->cycles.granularity == 0)
- wq->cycles.granularity = WORK_QUEUE_MIN_GRANULARITY;
+ wq->cycles.granularity = WQ_MIN_GRANULARITY;
next = wq->head ;
while (next != NULL)
@@ -420,27 +423,25 @@ work_queue_run (struct thread *thread)
stats:
-#define WQ_HYSTERIS_FACTOR 2
-
/* we yielded, check whether granularity should be reduced */
if (yielded && (cycles < wq->cycles.granularity))
{
wq->cycles.granularity = ((cycles > 0) ? cycles
- : WORK_QUEUE_MIN_GRANULARITY);
+ : WQ_MIN_GRANULARITY);
}
-
- if (cycles >= (wq->cycles.granularity))
+ /* otherwise, should granularity increase? */
+ else if (cycles >= (wq->cycles.granularity))
{
if (cycles > wq->cycles.best)
wq->cycles.best = cycles;
- /* along with yielded check, provides hysteris for granularity */
- if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR * 2))
- wq->cycles.granularity *= WQ_HYSTERIS_FACTOR; /* quick ramp-up */
- else if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR))
- wq->cycles.granularity += WQ_HYSTERIS_FACTOR;
+ /* along with yielded check, provides hysteresis for granularity */
+ if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR
+ * WQ_HYSTERESIS_FACTOR))
+ wq->cycles.granularity *= WQ_HYSTERESIS_FACTOR; /* quick ramp-up */
+ else if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR))
+ wq->cycles.granularity += WQ_HYSTERESIS_FACTOR;
}
-#undef WQ_HYSTERIS_FACTOR
wq->runs++;
wq->cycles.total += cycles;
diff --git a/lib/workqueue.h b/lib/workqueue.h
index 9ff7cdb5..369cd871 100644
--- a/lib/workqueue.h
+++ b/lib/workqueue.h
@@ -29,7 +29,7 @@
#endif
/* Hold time for the initial schedule of a queue run, in millisec */
-#define WORK_QUEUE_DEFAULT_HOLD 50
+enum { WORK_QUEUE_DEFAULT_HOLD = 50 } ;
/* action value, for use by item processor and item error handlers */
typedef enum
diff --git a/lib/zclient.c b/lib/zclient.c
index f365a1aa..6803aa4a 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -428,12 +428,12 @@ zclient_start (struct zclient *zclient)
/* Create read thread. */
zclient_event (ZCLIENT_READ, zclient);
- /* We need interface information. */
- zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
-
/* We need router-id information. */
zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
+ /* We need interface information. */
+ zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
+
/* Flush all redistribute request. */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != zclient->redist_default && zclient->redist[i])
diff --git a/lib/zclient.h b/lib/zclient.h
index 394407eb..17f4e317 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -7,12 +7,12 @@
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
@@ -25,6 +25,7 @@
/* For struct interface and struct connected. */
#include "if.h"
#include "qpnexus.h"
+#include "prefix.h"
/* For input/output buffer to zebra. */
#define ZEBRA_MAX_PACKET_SIZ 4096
@@ -161,7 +162,7 @@ extern struct interface *zebra_interface_state_read (struct stream *s);
extern struct connected *zebra_interface_address_read (int, struct stream *);
extern void zebra_interface_if_set_value (struct stream *, struct interface *);
extern void zebra_router_id_update_read (struct stream *s, struct prefix *rid);
-extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
+extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
struct zapi_ipv4 *);
#ifdef HAVE_IPV6
@@ -186,7 +187,7 @@ struct zapi_ipv6
u_int32_t metric;
};
-extern int zapi_ipv6_route (u_char cmd, struct zclient *zclient,
+extern int zapi_ipv6_route (u_char cmd, struct zclient *zclient,
struct prefix_ipv6 *p, struct zapi_ipv6 *api);
#endif /* HAVE_IPV6 */