… | |
… | |
66 | } |
66 | } |
67 | |
67 | |
68 | #define array_needsize(base,cur,cnt,init) \ |
68 | #define array_needsize(base,cur,cnt,init) \ |
69 | if ((cnt) > cur) \ |
69 | if ((cnt) > cur) \ |
70 | { \ |
70 | { \ |
71 | int newcnt = cur; \ |
71 | int newcnt = cur ? cur << 1 : 16; \ |
72 | do \ |
|
|
73 | { \ |
|
|
74 | newcnt += (newcnt >> 1) + 16; \ |
|
|
75 | } \ |
|
|
76 | while ((cnt) > newcnt); \ |
|
|
77 | fprintf (stderr, "resize(" # base ") from %d to %d\n", cur, newcnt);\ |
72 | fprintf (stderr, "resize(" # base ") from %d to %d\n", cur, newcnt);\ |
78 | base = realloc (base, sizeof (*base) * (newcnt)); \ |
73 | base = realloc (base, sizeof (*base) * (newcnt)); \ |
79 | init (base + cur, newcnt - cur); \ |
74 | init (base + cur, newcnt - cur); \ |
80 | cur = newcnt; \ |
75 | cur = newcnt; \ |
81 | } |
76 | } |
… | |
… | |
159 | static void |
154 | static void |
160 | downheap (int k) |
155 | downheap (int k) |
161 | { |
156 | { |
162 | struct ev_timer *w = timers [k]; |
157 | struct ev_timer *w = timers [k]; |
163 | |
158 | |
164 | while (k <= (timercnt >> 1)) |
159 | while (k < (timercnt >> 1)) |
165 | { |
160 | { |
166 | int j = k << 1; |
161 | int j = k << 1; |
167 | |
162 | |
168 | if (j + 1 < timercnt && timers [j]->at > timers [j + 1]->at) |
163 | if (j + 1 < timercnt && timers [j]->at > timers [j + 1]->at) |
169 | ++j; |
164 | ++j; |
170 | |
165 | |
171 | if (w->at <= timers [j]->at) |
166 | if (w->at <= timers [j]->at) |
172 | break; |
167 | break; |
173 | |
168 | |
174 | timers [k] = timers [j]; |
169 | timers [k] = timers [j]; |
175 | timers [k]->active = k; |
170 | timers [k]->active = k + 1; |
176 | k = j; |
171 | k = j; |
177 | } |
172 | } |
178 | |
173 | |
179 | timers [k] = w; |
174 | timers [k] = w; |
180 | timers [k]->active = k + 1; |
175 | timers [k]->active = k + 1; |
… | |
… | |
264 | struct ev_timer *w = timers [0]; |
259 | struct ev_timer *w = timers [0]; |
265 | |
260 | |
266 | /* first reschedule timer */ |
261 | /* first reschedule timer */ |
267 | if (w->repeat) |
262 | if (w->repeat) |
268 | { |
263 | { |
269 | fprintf (stderr, "a %f now %f repeat %f, %f\n", w->at, ev_now, w->repeat, w->repeat *1e30);//D |
|
|
270 | if (w->is_abs) |
264 | if (w->is_abs) |
271 | w->at += floor ((ev_now - w->at) / w->repeat + 1.) * w->repeat; |
265 | w->at += ceil ((ev_now - w->at) / w->repeat + 1.) * w->repeat; |
272 | else |
266 | else |
273 | w->at = ev_now + w->repeat; |
267 | w->at = ev_now + w->repeat; |
274 | |
|
|
275 | fprintf (stderr, "b %f\n", w->at);//D |
|
|
276 | |
268 | |
277 | downheap (0); |
269 | downheap (0); |
278 | } |
270 | } |
279 | else |
271 | else |
280 | evtimer_stop (w); /* nonrepeating: stop timer */ |
272 | evtimer_stop (w); /* nonrepeating: stop timer */ |
… | |
… | |
307 | block = timers [0]->at - ev_now + method_fudge; |
299 | block = timers [0]->at - ev_now + method_fudge; |
308 | if (block < 0.) block = 0.; |
300 | if (block < 0.) block = 0.; |
309 | else if (block > MAX_BLOCKTIME) block = MAX_BLOCKTIME; |
301 | else if (block > MAX_BLOCKTIME) block = MAX_BLOCKTIME; |
310 | } |
302 | } |
311 | |
303 | |
312 | fprintf (stderr, "block %f\n", block);//D |
|
|
313 | method_poll (block); |
304 | method_poll (block); |
314 | |
305 | |
315 | /* put pending timers into pendign queue and reschedule them */ |
306 | /* put pending timers into pendign queue and reschedule them */ |
316 | timer_reify (); |
307 | timer_reify (); |
317 | |
308 | |
… | |
… | |
395 | evtimer_start (struct ev_timer *w) |
386 | evtimer_start (struct ev_timer *w) |
396 | { |
387 | { |
397 | if (ev_is_active (w)) |
388 | if (ev_is_active (w)) |
398 | return; |
389 | return; |
399 | |
390 | |
400 | fprintf (stderr, "t1 %f a %d\n", w->at, w->is_abs);//D |
|
|
401 | if (w->is_abs) |
391 | if (w->is_abs) |
402 | { |
392 | { |
|
|
393 | /* this formula differs from the one in timer_reify becuse we do not round up */ |
403 | if (w->repeat) |
394 | if (w->repeat) |
404 | w->at += ceil ((ev_now - w->at) / w->repeat) * w->repeat; |
395 | w->at += ceil ((ev_now - w->at) / w->repeat) * w->repeat; |
405 | } |
396 | } |
406 | else |
397 | else |
407 | w->at += ev_now; |
398 | w->at += ev_now; |
408 | fprintf (stderr, "t2 %f a %d\n", w->at, w->is_abs);//D |
|
|
409 | |
399 | |
410 | ev_start ((struct ev_watcher *)w, ++timercnt); |
400 | ev_start ((struct ev_watcher *)w, ++timercnt); |
411 | array_needsize (timers, timermax, timercnt, ); |
401 | array_needsize (timers, timermax, timercnt, ); |
412 | timers [timercnt - 1] = w; |
402 | timers [timercnt - 1] = w; |
413 | upheap (timercnt - 1); |
403 | upheap (timercnt - 1); |
… | |
… | |
417 | evtimer_stop (struct ev_timer *w) |
407 | evtimer_stop (struct ev_timer *w) |
418 | { |
408 | { |
419 | if (!ev_is_active (w)) |
409 | if (!ev_is_active (w)) |
420 | return; |
410 | return; |
421 | |
411 | |
|
|
412 | if (w->active < timercnt--) |
|
|
413 | { |
422 | timers [w->active - 1] = timers [--timercnt]; |
414 | timers [w->active - 1] = timers [timercnt]; |
423 | downheap (w->active - 1); |
415 | downheap (w->active - 1); |
|
|
416 | } |
|
|
417 | |
424 | ev_stop ((struct ev_watcher *)w); |
418 | ev_stop ((struct ev_watcher *)w); |
425 | } |
419 | } |
426 | |
420 | |
427 | void |
421 | void |
428 | evsignal_start (struct ev_signal *w) |
422 | evsignal_start (struct ev_signal *w) |
… | |
… | |
468 | |
462 | |
469 | evw_init (&sin, sin_cb, 55); |
463 | evw_init (&sin, sin_cb, 55); |
470 | evio_set (&sin, 0, EV_READ); |
464 | evio_set (&sin, 0, EV_READ); |
471 | evio_start (&sin); |
465 | evio_start (&sin); |
472 | |
466 | |
473 | struct ev_timer t1; |
467 | struct ev_timer t[1000]; |
|
|
468 | |
|
|
469 | int i; |
|
|
470 | for (i = 0; i < 1000; ++i) |
|
|
471 | { |
|
|
472 | struct ev_timer *w = t + i; |
474 | evw_init (&t1, ocb, 1); |
473 | evw_init (w, ocb, i); |
475 | evtimer_set_rel (&t1, 1, 0); |
474 | evtimer_set_rel (w, drand48 (), 0); |
476 | evtimer_start (&t1); |
475 | evtimer_start (w); |
477 | |
476 | if (drand48 () < 0.5) |
478 | struct ev_timer t2; |
477 | evtimer_stop (w); |
479 | evw_init (&t2, ocb, 2); |
478 | } |
480 | evtimer_set_abs (&t2, ev_time () + 2, 0); |
|
|
481 | evtimer_start (&t2); |
|
|
482 | |
479 | |
483 | ev_loop (0); |
480 | ev_loop (0); |
484 | |
481 | |
485 | return 0; |
482 | return 0; |
486 | } |
483 | } |