diff options
author | Chris Hall <chris.hall@highwayman.com> | 2011-03-29 00:29:35 +0100 |
---|---|---|
committer | Chris Hall <chris.hall@highwayman.com> | 2011-03-29 00:29:35 +0100 |
commit | e20f7ccd9e110fcd5deb945f8d23922efd8b0822 (patch) | |
tree | 89b61ee61ac306817dc19b9313806bf2562b1c1b /lib | |
parent | 6481583be322b0ba223a0140500a0a6d50546dd9 (diff) | |
download | quagga-ex14.tar.bz2 quagga-ex14.tar.xz |
Bring "ex" version up to date with 0.99.18ex14
Release: 0.99.18ex14
Also fixes issue with unknown attributes -- does not release them prematurely.
Contains the "bgpd: New show commands for improved view and address family support", which is post 0.99.18. (But not RFC 5082 GTSM.)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/command.c | 9 | ||||
-rw-r--r-- | lib/distribute.c | 13 | ||||
-rw-r--r-- | lib/hash.c | 11 | ||||
-rw-r--r-- | lib/hash.h | 2 | ||||
-rw-r--r-- | lib/if.c | 18 | ||||
-rw-r--r-- | lib/if.h | 1 | ||||
-rw-r--r-- | lib/if_rmap.c | 9 | ||||
-rw-r--r-- | lib/keystroke.h | 2 | ||||
-rw-r--r-- | lib/log.c | 3 | ||||
-rw-r--r-- | lib/memory.c | 27 | ||||
-rw-r--r-- | lib/prefix.c | 13 | ||||
-rw-r--r-- | lib/prefix.h | 4 | ||||
-rw-r--r-- | lib/qtime.c | 11 | ||||
-rw-r--r-- | lib/qtime.h | 30 | ||||
-rw-r--r-- | lib/table.c | 14 | ||||
-rw-r--r-- | lib/thread.c | 165 | ||||
-rw-r--r-- | lib/thread.h | 3 | ||||
-rw-r--r-- | lib/vector.c | 9 | ||||
-rw-r--r-- | lib/vector.h | 5 | ||||
-rw-r--r-- | lib/workqueue.c | 31 | ||||
-rw-r--r-- | lib/workqueue.h | 2 | ||||
-rw-r--r-- | lib/zclient.c | 6 | ||||
-rw-r--r-- | lib/zclient.h | 9 |
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) { @@ -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. */ @@ -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 */ @@ -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; +} @@ -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 ; @@ -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 */ |