3 /* timer - Delayed and repetitive actions */
5 /* Copyright (c) 2005 Martin Quinson. All rights reserved. */
7 /* This program is free software; you can redistribute it and/or modify it
8 * under the terms of the license (GNU LGPL) which comes with this package. */
11 #include "gras/Msg/msg_private.h"
12 #include "gras/timer.h"
13 #include "gras/Virtu/virtu_interface.h"
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_timer,gras,
17 "Delayed and repetitive actions");
19 /** @brief Request \a action to be called once in \a delay seconds */
20 void gras_timer_delay(double delay, void_f_void_t action) {
21 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
23 gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
25 VERB1("Register delayed action %p", action);
26 timer->period = delay;
27 timer->expiry = delay+gras_os_time();
28 timer->action = action;
29 timer->repeat = FALSE;
32 /** @brief Request \a action to be called every \a interval seconds */
33 void gras_timer_repeat(double interval, void_f_void_t action) {
34 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
36 gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
38 VERB1("Register repetitive action %p", action);
39 timer->period = interval;
40 timer->expiry = interval+gras_os_time();
41 timer->action = action;
45 /** @brief Cancel a delayed task */
46 void gras_timer_cancel_delay(double interval, void_f_void_t action) {
47 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
52 xbt_dynar_foreach(pd->timers,cursor,timer){
53 if (timer.repeat == FALSE &&
54 timer.period == interval &&
55 timer.action == action) {
58 xbt_dynar_cursor_rm(pd->timers, &cursor);
63 THROW2(mismatch_error,0,"Cannot remove the action %p delayed of %f second: not found",
68 /** @brief Cancel a repetitive task */
69 void gras_timer_cancel_repeat(double interval, void_f_void_t action) {
70 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
75 xbt_dynar_foreach(pd->timers,cursor,timer){
76 if (timer.repeat == TRUE &&
77 timer.period == interval &&
78 timer.action == action) {
81 xbt_dynar_cursor_rm(pd->timers, &cursor);
86 THROW2(mismatch_error,0,"Cannot remove the action %p delayed of %f second: not found",
90 /** @brief Cancel all delayed tasks */
91 void gras_timer_cancel_delay_all(void) {
92 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
97 xbt_dynar_foreach(pd->timers,cursor,timer){
98 if (timer.repeat == FALSE) {
101 xbt_dynar_cursor_rm(pd->timers, &cursor);
106 THROW0(mismatch_error,0,"No delayed action to remove");
110 /** @brief Cancel all repetitive tasks */
111 void gras_timer_cancel_repeat_all(void){
112 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
114 s_gras_timer_t timer;
117 xbt_dynar_foreach(pd->timers,cursor,timer){
118 if (timer.repeat == FALSE) {
121 xbt_dynar_cursor_rm(pd->timers, &cursor);
126 THROW0(mismatch_error,0,"No repetitive action to remove");
129 /** @brief Cancel all delayed and repetitive tasks */
130 void gras_timer_cancel_all(void) {
131 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
132 xbt_dynar_reset( pd->timers );
136 /* returns 0 if it handled a timer, or the delay until next timer, or -1 if no armed timer */
137 double gras_msg_timer_handle(void) {
138 gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
141 double now=gras_os_time();
142 double untilnext = -1.0;
144 for (cursor=0; cursor < xbt_dynar_length(pd->timers); cursor++) {
147 timer = xbt_dynar_get_ptr (pd->timers, cursor);
148 untilthis = timer->expiry - now;
150 DEBUG2("Action %p expires in %f", timer->action, untilthis);
152 if (untilthis <= 0.0) {
153 void_f_void_t *action = timer->action;
155 DEBUG5("[%.0f] Serve %s action %p (%f<%f)",gras_os_time(),
156 timer->repeat ? "repetitive" : "delayed", timer->action,
160 timer->expiry = now + timer->period;
161 DEBUG4("[%.0f] Re-arm repetitive action %p for %f (period=%f)",
163 timer->action, timer->expiry, timer->period);
165 DEBUG2("[%.0f] Remove %p now that it's done", gras_os_time(), timer->action);
166 xbt_dynar_cursor_rm(pd->timers, &cursor);
170 } else if (untilthis < untilnext || untilnext == -1) {
171 untilnext = untilthis;