41 #include <sys/param.h> 64 tv->tv_usec = 1e6 * (t - tv->tv_sec);
65 while (tv->tv_usec >= 1000000)
67 tv->tv_usec -= 1000000;
79 return dt < 0 ? -1 : (dt > 0 ? +1 : 0);
88 #define TIMER_SIGNAL SIGALRM 115 ASSERT (now >= 0 && finite (now));
124 _vec_len (timers) -= 1;
130 struct itimerval itv;
131 memset (&itv, 0,
sizeof (itv));
133 if (setitimer (ITIMER_REAL, &itv, 0) < 0)
143 sigset_t block_timer;
145 memset (&block_timer, 0,
sizeof (block_timer));
147 sigprocmask (SIG_BLOCK, &block_timer, save);
153 sigprocmask (SIG_SETMASK, save, 0);
165 static word signal_installed = 0;
167 if (!signal_installed)
174 memset (&sa, 0,
sizeof (sa));
180 signal_installed = 1;
195 if (_vec_len (timers) > 1)
197 reset_timer += t->
time < (t - 1)->time;
216 static f64 ave_delay = 0;
217 static word ave_delay_count = 0;
223 ave_delay_count += 1;
228 f64 time_requested, time_called;
231 static f64 foo_base_time = 0;
232 static foo_t *foos = 0;
250 bar_t *b = (bar_t *) arg;
252 fformat (stdout,
"bar %d delay %g\n", b->count++, delay);
255 if (b->count < b->limit)
260 main (
int argc,
char *argv[])
262 word i, n = atoi (argv[1]);
263 word run_foo = argc > 2;
264 bar_t b = { limit:10 };
270 time_limit = atof (argv[2]);
273 for (i = 0; i < n; i++)
275 foos[
i].time_requested = time_limit *
random_f64 ();
276 foos[
i].time_called = 1e100;
280 for (i = 0; i < n; i++)
291 f64 min = 1e100, max = -min;
292 f64 ave = 0, rms = 0;
294 for (i = 0; i < n; i++)
296 f64 dt = foos[
i].time_requested - foos[
i].time_called;
305 rms =
sqrt (rms / n - ave * ave);
306 fformat (stdout,
"error min %g max %g ave %g +- %g\n", min, max, ave,
310 fformat (stdout,
"%d function calls, ave. timer delay %g secs\n",
311 ave_delay_count, ave_delay / ave_delay_count);
static void os_sched_yield(void)
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.
#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)