1 /* timer - Delayed and repetitive actions */
3 /* Copyright (c) 2005, 2006, 2007, 2009, 2010. The SimGrid Team.
4 * All rights reserved. */
6 /* This program is free software; you can redistribute it and/or modify it
7 * under the terms of the license (GNU LGPL) which comes with this package. */
10 #include "gras/Msg/msg_private.h"
11 #include "gras/timer.h"
12 #include "gras/Virtu/virtu_interface.h"
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_timer, gras,
16 "Delayed and repetitive actions");
18 /** @brief Request \a action to be called once in \a delay seconds */
19 void gras_timer_delay(double delay, void_f_void_t action)
21 gras_msg_procdata_t pd =
22 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
24 gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
26 XBT_VERB("Register delayed action %p", action);
27 timer->period = delay;
28 timer->expiry = delay + gras_os_time();
29 timer->action = action;
30 timer->repeat = FALSE;
33 /** @brief Request \a action to be called every \a interval seconds */
34 void gras_timer_repeat(double interval, void_f_void_t action)
36 gras_msg_procdata_t pd =
37 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
39 gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
41 XBT_VERB("Register repetitive action %p", action);
42 timer->period = interval;
43 timer->expiry = interval + gras_os_time();
44 timer->action = action;
48 /** @brief Cancel a delayed task */
49 void gras_timer_cancel_delay(double interval, void_f_void_t action)
51 gras_msg_procdata_t pd =
52 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
58 xbt_dynar_foreach(pd->timers, cursor, timer) {
59 if (timer.repeat == FALSE &&
60 timer.period == interval && timer.action == action) {
63 xbt_dynar_cursor_rm(pd->timers, &cursor);
68 THROWF(mismatch_error, 0,
69 "Cannot remove the action %p delayed of %f second: not found",
74 /** @brief Cancel a repetitive task */
75 void gras_timer_cancel_repeat(double interval, void_f_void_t action)
77 gras_msg_procdata_t pd =
78 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
84 xbt_dynar_foreach(pd->timers, cursor, timer) {
85 if (timer.repeat == TRUE &&
86 timer.period == interval && timer.action == action) {
89 xbt_dynar_cursor_rm(pd->timers, &cursor);
94 THROWF(mismatch_error, 0,
95 "Cannot remove the action %p delayed of %f second: not found",
99 /** @brief Cancel all delayed tasks */
100 void gras_timer_cancel_delay_all(void)
102 gras_msg_procdata_t pd =
103 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
106 s_gras_timer_t timer;
109 xbt_dynar_foreach(pd->timers, cursor, timer) {
110 if (timer.repeat == FALSE) {
113 xbt_dynar_cursor_rm(pd->timers, &cursor);
118 THROWF(mismatch_error, 0, "No delayed action to remove");
122 /** @brief Cancel all repetitive tasks */
123 void gras_timer_cancel_repeat_all(void)
125 gras_msg_procdata_t pd =
126 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
129 s_gras_timer_t timer;
132 xbt_dynar_foreach(pd->timers, cursor, timer) {
133 if (timer.repeat == FALSE) {
136 xbt_dynar_cursor_rm(pd->timers, &cursor);
141 THROWF(mismatch_error, 0, "No repetitive action to remove");
144 /** @brief Cancel all delayed and repetitive tasks */
145 void gras_timer_cancel_all(void)
147 gras_msg_procdata_t pd =
148 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
149 xbt_dynar_reset(pd->timers);
153 /* returns 0 if it handled a timer, or the delay until next timer, or -1 if no armed timer */
154 double gras_msg_timer_handle(void)
156 gras_msg_procdata_t pd =
157 (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
160 double now = gras_os_time();
161 double untilnext = -1.0;
163 for (cursor = 0; cursor < xbt_dynar_length(pd->timers); cursor++) {
166 timer = xbt_dynar_get_ptr(pd->timers, cursor);
167 untilthis = timer->expiry - now;
169 XBT_DEBUG("Action %p expires in %f", timer->action, untilthis);
171 if (untilthis <= 0.0) {
172 void_f_void_t action = timer->action;
174 XBT_DEBUG("[%.0f] Serve %s action %p (%f<%f)", gras_os_time(),
175 timer->repeat ? "repetitive" : "delayed", timer->action,
179 timer->expiry = now + timer->period;
180 XBT_DEBUG("[%.0f] Re-arm repetitive action %p for %f (period=%f)",
181 gras_os_time(), timer->action, timer->expiry,
184 XBT_DEBUG("[%.0f] Remove %p now that it's done", gras_os_time(),
186 xbt_dynar_cursor_rm(pd->timers, &cursor);
190 } else if (untilthis < untilnext || untilnext == -1) {
191 untilnext = untilthis;