41 #include <sys/param.h> 61 tv->tv_usec = 1e6*(t - tv->tv_sec);
62 while (tv->tv_usec >= 1000000)
64 tv->tv_usec -= 1000000;
75 return dt < 0 ? -1 : (dt > 0 ? +1 : 0);
81 #define TIMER_SIGNAL SIGALRM 107 ASSERT (now >= 0 && finite (now));
116 _vec_len (timers) -= 1;
122 struct itimerval itv;
123 memset (&itv, 0,
sizeof (itv));
125 if (setitimer (ITIMER_REAL, &itv, 0) < 0)
134 sigset_t block_timer;
136 memset (&block_timer, 0,
sizeof (block_timer));
138 sigprocmask (SIG_BLOCK, &block_timer, save);
142 { sigprocmask (SIG_SETMASK, save, 0); }
152 static word signal_installed = 0;
154 if (! signal_installed)
167 signal_installed = 1;
182 if (_vec_len (timers) > 1)
184 reset_timer += t->
time < (t-1)->time;
203 static f64 ave_delay = 0;
204 static word ave_delay_count = 0;
209 ave_delay_count += 1;
213 f64 time_requested, time_called;
216 static f64 foo_base_time = 0;
217 static foo_t * foos = 0;
219 void foo (
any arg,
f64 delay)
230 void bar (
any arg,
f64 delay)
232 bar_t * b = (bar_t *) arg;
234 fformat (stdout,
"bar %d delay %g\n", b->count++, delay);
237 if (b->count < b->limit)
241 int main (
int argc,
char * argv[])
243 word i, n = atoi (argv[1]);
244 word run_foo = argc > 2;
245 bar_t b = {limit: 10};
251 time_limit = atof (argv[2]);
254 for (i = 0; i < n; i++)
256 foos[
i].time_requested = time_limit *
random_f64 ();
257 foos[
i].time_called = 1e100;
261 for (i = 0; i < n; i++)
272 f64 min = 1e100, max = -min;
273 f64 ave = 0, rms = 0;
275 for (i = 0; i < n; i++)
277 f64 dt = foos[
i].time_requested - foos[
i].time_called;
286 rms =
sqrt (rms / n - ave*ave);
287 fformat (stdout,
"error min %g max %g ave %g +- %g\n", min, max, ave, rms);
290 fformat (stdout,
"%d function calls, ave. timer delay %g secs\n",
291 ave_delay_count, ave_delay / ave_delay_count);
always_inline f64 unix_time_now(void)
sll srl srl sll sra u16x4 i
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.
static f64 time_resolution
always_inline f64 sqrt(f64 x)
static timer_callback_t * timers
#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.
always_inline f64 random_f64(u32 *seed)
Generate f64 random number in the interval [0,1].
always_inline void f64_to_tv(f64 t, struct timeval *tv)
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)
#define clib_unix_error(format, args...)
void( timer_func_t)(any arg, f64 delay)
void timer_block(sigset_t *save)
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)