diff options
Diffstat (limited to 'sysdep/unix/io.c')
-rw-r--r-- | sysdep/unix/io.c | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 25121d74..3e56a32d 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -103,289 +103,6 @@ tracked_fopen(pool *p, char *name, char *mode) return f; } -/** - * DOC: Timers - * - * Timers are resources which represent a wish of a module to call - * a function at the specified time. The platform dependent code - * doesn't guarantee exact timing, only that a timer function - * won't be called before the requested time. - * - * In BIRD, time is represented by values of the &bird_clock_t type - * which are integral numbers interpreted as a relative number of seconds since - * some fixed time point in past. The current time can be read - * from variable @now with reasonable accuracy and is monotonic. There is also - * a current 'absolute' time in variable @now_real reported by OS. - * - * Each timer is described by a &timer structure containing a pointer - * to the handler function (@hook), data private to this function (@data), - * time the function should be called at (@expires, 0 for inactive timers), - * for the other fields see |timer.h|. - */ - -#if 0 -#define NEAR_TIMER_LIMIT 4 - -static list near_timers, far_timers; -static bird_clock_t first_far_timer = TIME_INFINITY; - - -/* now must be different from 0, because 0 is a special value in timer->expires */ -bird_clock_t now = 1, now_real, boot_time; - -static void -update_times_plain(void) -{ - bird_clock_t new_time = time(NULL); - int delta = new_time - now_real; - - if ((delta >= 0) && (delta < 60)) - now += delta; - else if (now_real != 0) - log(L_WARN "Time jump, delta %d s", delta); - - now_real = new_time; -} - -static void -update_times_gettime(void) -{ - struct timespec ts; - int rv; - - rv = clock_gettime(CLOCK_MONOTONIC, &ts); - if (rv != 0) - die("clock_gettime: %m"); - - if (ts.tv_sec != now) { - if (ts.tv_sec < now) - log(L_ERR "Monotonic timer is broken"); - - now = ts.tv_sec; - now_real = time(NULL); - } -} - -static int clock_monotonic_available; - -static inline void -update_times(void) -{ - if (clock_monotonic_available) - update_times_gettime(); - else - update_times_plain(); -} - -static inline void -init_times(void) -{ - struct timespec ts; - clock_monotonic_available = (clock_gettime(CLOCK_MONOTONIC, &ts) == 0); - if (!clock_monotonic_available) - log(L_WARN "Monotonic timer is missing"); -} - -static void -tm_free(resource *r) -{ - timer *t = (timer *) r; - - tm_stop(t); -} - -static void -tm_dump(resource *r) -{ - timer *t = (timer *) r; - - debug("(code %p, data %p, ", t->hook, t->data); - if (t->randomize) - debug("rand %d, ", t->randomize); - if (t->recurrent) - debug("recur %d, ", t->recurrent); - if (t->expires) - debug("expires in %d sec)\n", t->expires - now); - else - debug("inactive)\n"); -} - -static struct resclass tm_class = { - "Timer", - sizeof(timer), - tm_free, - tm_dump, - NULL, - NULL -}; - -/** - * tm_new - create a timer - * @p: pool - * - * This function creates a new timer resource and returns - * a pointer to it. To use the timer, you need to fill in - * the structure fields and call tm_start() to start timing. - */ -timer * -tm_new(pool *p) -{ - timer *t = ralloc(p, &tm_class); - return t; -} - -static inline void -tm_insert_near(timer *t) -{ - node *n = HEAD(near_timers); - - while (n->next && (SKIP_BACK(timer, n, n)->expires < t->expires)) - n = n->next; - insert_node(&t->n, n->prev); -} - -/** - * tm_start - start a timer - * @t: timer - * @after: number of seconds the timer should be run after - * - * This function schedules the hook function of the timer to - * be called after @after seconds. If the timer has been already - * started, it's @expire time is replaced by the new value. - * - * You can have set the @randomize field of @t, the timeout - * will be increased by a random number of seconds chosen - * uniformly from range 0 .. @randomize. - * - * You can call tm_start() from the handler function of the timer - * to request another run of the timer. Also, you can set the @recurrent - * field to have the timer re-added automatically with the same timeout. - */ -void -tm_start(timer *t, unsigned after) -{ - bird_clock_t when; - - if (t->randomize) - after += random() % (t->randomize + 1); - when = now + after; - if (t->expires == when) - return; - if (t->expires) - rem_node(&t->n); - t->expires = when; - if (after <= NEAR_TIMER_LIMIT) - tm_insert_near(t); - else - { - if (!first_far_timer || first_far_timer > when) - first_far_timer = when; - add_tail(&far_timers, &t->n); - } -} - -/** - * tm_stop - stop a timer - * @t: timer - * - * This function stops a timer. If the timer is already stopped, - * nothing happens. - */ -void -tm_stop(timer *t) -{ - if (t->expires) - { - rem_node(&t->n); - t->expires = 0; - } -} - -static void -tm_dump_them(char *name, list *l) -{ - node *n; - timer *t; - - debug("%s timers:\n", name); - WALK_LIST(n, *l) - { - t = SKIP_BACK(timer, n, n); - debug("%p ", t); - tm_dump(&t->r); - } - debug("\n"); -} - -void -tm_dump_all(void) -{ - tm_dump_them("Near", &near_timers); - tm_dump_them("Far", &far_timers); -} - -static inline time_t -tm_first_shot(void) -{ - time_t x = first_far_timer; - - if (!EMPTY_LIST(near_timers)) - { - timer *t = SKIP_BACK(timer, n, HEAD(near_timers)); - if (t->expires < x) - x = t->expires; - } - return x; -} - -void io_log_event(void *hook, void *data); - -static void -tm_shot(void) -{ - timer *t; - node *n, *m; - - if (first_far_timer <= now) - { - bird_clock_t limit = now + NEAR_TIMER_LIMIT; - first_far_timer = TIME_INFINITY; - n = HEAD(far_timers); - while (m = n->next) - { - t = SKIP_BACK(timer, n, n); - if (t->expires <= limit) - { - rem_node(n); - tm_insert_near(t); - } - else if (t->expires < first_far_timer) - first_far_timer = t->expires; - n = m; - } - } - while ((n = HEAD(near_timers)) -> next) - { - int delay; - t = SKIP_BACK(timer, n, n); - if (t->expires > now) - break; - rem_node(n); - delay = t->expires - now; - t->expires = 0; - if (t->recurrent) - { - int i = t->recurrent - delay; - if (i < 0) - i = 0; - tm_start(t, i); - } - io_log_event(t->hook, t->data); - t->hook(t); - } -} -#endif - /* * Time clock |