diff --git a/bin/tests/task_test.c b/bin/tests/task_test.c index 6ba24b085f..5691c8b875 100644 --- a/bin/tests/task_test.c +++ b/bin/tests/task_test.c @@ -20,7 +20,7 @@ my_callback(task_t task, task_event_t event) char *name = event->arg; j = 0; - for (i = 0; i < 100000000; i++) + for (i = 0; i < 1000000; i++) j += 100; printf("task %s: %d\n", name, j); @@ -75,7 +75,7 @@ main(int argc, char *argv[]) { ti1 = NULL; absolute.seconds = 0; absolute.nanoseconds = 0; - interval.seconds = 2; + interval.seconds = 1; interval.nanoseconds = 0; INSIST(timer_create(timgr, timer_type_ticker, absolute, interval, t1, my_tick, "foo", &ti1) == ISC_R_SUCCESS); @@ -139,6 +139,7 @@ main(int argc, char *argv[]) { task_detach(&t3); task_detach(&t4); + sleep(10); printf("destroy\n"); timer_detach(&ti1); timer_detach(&ti2); diff --git a/bin/tests/timer_test.c b/bin/tests/timer_test.c new file mode 100644 index 0000000000..023b7b9efc --- /dev/null +++ b/bin/tests/timer_test.c @@ -0,0 +1,140 @@ + +#include "attribute.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +mem_context_t mctx = NULL; +task_t t1, t2, t3; +timer_t ti1, ti2, ti3; +int tick_count = 0; + +static boolean_t +shutdown_task(task_t task, task_event_t event) { + char *name = event->arg; + + printf("shutdown %s\n", name); + return (TRUE); +} + +static boolean_t +tick(task_t task, task_event_t event) +{ + char *name = event->arg; + + INSIST(event->type == TIMER_EVENT_TICK); + + printf("task %s (%p) tick\n", name, task); + + tick_count++; + if (tick_count % 3 == 0) + timer_touch(ti3); + + if (tick_count == 7) { + os_time_t expires, interval, now; + + (void)os_time_get(&now); + expires.seconds = 5; + expires.nanoseconds = 0; + os_time_add(&now, &expires, &expires); + interval.seconds = 4; + interval.nanoseconds = 0; + printf("*** resetting ti3 ***\n"); + INSIST(timer_reset(ti3, timer_type_idle, expires, interval) + == ISC_R_SUCCESS); + } + + return (FALSE); +} + +static boolean_t +timeout(task_t task, task_event_t event) +{ + char *name = event->arg; + char *type; + + INSIST(event->type == TIMER_EVENT_IDLE || + event->type == TIMER_EVENT_LIFE); + + if (event->type == TIMER_EVENT_IDLE) + type = "idle"; + else + type = "life"; + printf("task %s (%p) %s timeout\n", name, task, type); + + if (strcmp(name, "3") == 0) { + printf("*** saving task 3 ***\n"); + return (FALSE); + } + return (TRUE); +} + +void +main(int argc, char *argv[]) { + task_manager_t manager = NULL; + timer_manager_t timgr = NULL; + unsigned int workers; + os_time_t expires, interval, now; + + if (argc > 1) + workers = atoi(argv[1]); + else + workers = 2; + printf("%d workers\n", workers); + + INSIST(mem_context_create(0, 0, &mctx) == 0); + INSIST(task_manager_create(mctx, workers, 0, &manager) == workers); + INSIST(task_create(manager, shutdown_task, "1", 0, &t1)); + INSIST(task_create(manager, shutdown_task, "2", 0, &t2)); + INSIST(task_create(manager, shutdown_task, "3", 0, &t3)); + INSIST(timer_manager_create(mctx, &timgr) == ISC_R_SUCCESS); + + printf("task 1: %p\n", t1); + printf("task 2: %p\n", t2); + printf("task 3: %p\n", t3); + + (void)os_time_get(&now); + + expires.seconds = 0; + expires.nanoseconds = 0; + interval.seconds = 2; + interval.nanoseconds = 0; + INSIST(timer_create(timgr, timer_type_idle, expires, interval, + t2, timeout, "2", &ti2) == ISC_R_SUCCESS); + expires.seconds = 0; + expires.nanoseconds = 0; + interval.seconds = 1; + interval.nanoseconds = 0; + INSIST(timer_create(timgr, timer_type_ticker, expires, interval, + t1, tick, "1", &ti1) == ISC_R_SUCCESS); + expires.seconds = 10; + expires.nanoseconds = 0; + os_time_add(&now, &expires, &expires); + interval.seconds = 2; + interval.nanoseconds = 0; + INSIST(timer_create(timgr, timer_type_idle, expires, interval, + t3, timeout, "3", &ti3) == ISC_R_SUCCESS); + + task_detach(&t1); + task_detach(&t2); + task_detach(&t3); + + sleep(15); + printf("destroy\n"); + timer_detach(&ti1); + timer_detach(&ti2); + timer_detach(&ti3); + sleep(2); + timer_manager_destroy(&timgr); + task_manager_destroy(&manager); + printf("destroyed\n"); + + mem_stats(mctx, stdout); +} diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h index 3fefbd5fa2..aadb8bb4ef 100644 --- a/lib/isc/include/isc/timer.h +++ b/lib/isc/include/isc/timer.h @@ -11,16 +11,14 @@ * * Provides timers which are event sources in the task system. * - * Three kinds of timer are supported. + * Two kinds of timer are supported. * - * 'ticker' timers generate a tick event at specified regular times. + * 'ticker' timers generate a periodic tick event. * * 'idle' timers generate an idle timeout event if they are idle for too * long, and generate a life timeout event if their lifetime expires. * They are used to implement both expiring idle timers and 'one-shot' * timers. - * - * 'inactive' timers generate no events. * * Note: unlike in eventlib, a timer's resources are never reclaimed merely * because it generated an event. A timer reference will remain valid until @@ -92,7 +90,7 @@ typedef struct timer_event { isc_result timer_create(timer_manager_t manager, timer_type_t type, - os_time_t absolute, + os_time_t expires, os_time_t interval, task_t task, task_action_t action, @@ -100,19 +98,17 @@ timer_create(timer_manager_t manager, timer_t *timerp); /* * Create a new 'type' timer managed by 'manager'. The timers parameters - * are specified by 'absolute' and 'interval'. Events will be posted to + * are specified by 'expires' and 'interval'. Events will be posted to * 'task' and when dispatched 'action' will be called with 'arg' as the * arg value. The new timer is returned in 'timerp'. * * Notes: * - * For ticker timers, 'absolute' specifies when the timer should first - * generate a tick event. If 'absolute' is 0, then the timer will first - * tick at Now + 'interval'. The timer will tick every 'interval' - * seconds after the first tick. + * For ticker timers, the timer will generate a 'tick' event every + * 'interval' seconds. The value of 'expires' is ignored. * - * For idle timers, 'absolute' specifies the time when a life timeout - * event should be generated. If 'absolute' is 0, then no life + * For idle timers, 'expires' specifies the time when a life timeout + * event should be generated. If 'expires' is 0, then no life * timeout will be generated. 'interval' specifies how long the timer * can be idle before it generates an idle timeout. If 0, then no * idle timeout will be generated. @@ -125,7 +121,7 @@ timer_create(timer_manager_t manager, * * 'action' is a valid action * - * 'absolute' and 'idle' may not both be 0 + * 'expires' and 'interval' may not both be 0 * * 'timerp' is a valid pointer, and *timerp == NULL * @@ -148,10 +144,10 @@ timer_create(timer_manager_t manager, isc_result timer_reset(timer_t timer, timer_type_t type, - os_time_t absolute, + os_time_t expires, os_time_t interval); /* - * Change the timer's type, absolute, and interval values to the given + * Change the timer's type, expires, and interval values to the given * values. * * Requires: @@ -159,7 +155,7 @@ timer_reset(timer_t timer, * 'timer' is a valid timer * * The same requirements that timer_create() imposes on 'type', - * 'absolute' and 'interval' apply. + * 'expires' and 'interval' apply. * * Ensures: *