41 #include <sys/param.h> 68 tv->tv_usec = 1e6 * (t - tv->tv_sec);
69 while (tv->tv_usec >= 1000000)
71 tv->tv_usec -= 1000000;
83 return dt < 0 ? -1 : (dt > 0 ? +1 : 0);
92 #define TIMER_SIGNAL SIGALRM 119 ASSERT (now >= 0 && isfinite (now));
128 _vec_len (timers) -= 1;
134 struct itimerval itv;
137 if (setitimer (ITIMER_REAL, &itv, 0) < 0)
147 sigset_t block_timer;
149 clib_memset (&block_timer, 0,
sizeof (block_timer));
151 sigprocmask (SIG_BLOCK, &block_timer, save);
157 sigprocmask (SIG_SETMASK, save, 0);
169 static word signal_installed = 0;
171 if (!signal_installed)
184 signal_installed = 1;
199 if (_vec_len (timers) > 1)
201 reset_timer += t->
time < (t - 1)->time;
220 static f64 ave_delay = 0;
221 static word ave_delay_count = 0;
227 ave_delay_count += 1;
232 f64 time_requested, time_called;
235 static f64 foo_base_time = 0;
236 static foo_t *foos = 0;
254 bar_t *b = (bar_t *) arg;
256 fformat (stdout,
"bar %d delay %g\n", b->count++, delay);
259 if (b->count < b->limit)
264 main (
int argc,
char *argv[])
266 word i, n = atoi (argv[1]);
267 word run_foo = argc > 2;
268 bar_t b = { limit:10 };
274 time_limit = atof (argv[2]);
277 for (i = 0; i < n; i++)
279 foos[
i].time_requested = time_limit *
random_f64 ();
280 foos[
i].time_called = 1e100;
284 for (i = 0; i < n; i++)
295 f64 min = 1e100, max = -min;
296 f64 ave = 0, rms = 0;
298 for (i = 0; i < n; i++)
300 f64 dt = foos[
i].time_requested - foos[
i].time_called;
309 rms =
sqrt (rms / n - ave * ave);
310 fformat (stdout,
"error min %g max %g ave %g +- %g\n", min, max, ave,
314 fformat (stdout,
"%d function calls, ave. timer delay %g secs\n",
315 ave_delay_count, ave_delay / ave_delay_count);
static void os_sched_yield(void)
Optimized string handling code, including c11-compliant "safe C library" variants.
void timer_unblock(sigset_t *save)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
#define clib_unix_error(format, args...)
static f64 time_resolution
static timer_callback_t * timers
static f64 unix_time_now(void)
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
#define vec_end(v)
End (last data address) of vector.
void timer_call(timer_func_t *func, any arg, f64 dt)
static int timer_compare(const void *_a, const void *_b)
static void timer_interrupt(int signum)
static void f64_to_tv(f64 t, struct timeval *tv)
static f64 random_f64(u32 *seed)
Generate f64 random number in the interval [0,1].
void( timer_func_t)(any arg, f64 delay)
void timer_block(sigset_t *save)
int main(int argc, char **argv)
void qsort(void *base, uword n, uword size, int(*compar)(const void *, const void *))
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Linear Congruential Random Number Generator.
#define clib_panic(format, args...)
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
static void sort_timers(timer_callback_t *timers)