Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
remove gras from the main documentation
[simgrid.git] / src / gras / Msg / timer.c
1 /* timer - Delayed and repetitive actions                                   */
2
3 /* Copyright (c) 2005, 2006, 2007, 2009, 2010. The SimGrid Team.
4  * All rights reserved.                                                     */
5
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. */
8
9 #include "xbt/ex.h"
10 #include "gras/Msg/msg_private.h"
11 #include "gras/timer.h"
12 #include "gras/Virtu/virtu_interface.h"
13
14
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_timer, gras,
16                                 "Delayed and repetitive actions");
17
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)
20 {
21   gras_msg_procdata_t pd =
22       (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
23
24   gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
25
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;
31 }
32
33 /** @brief Request \a action to be called every \a interval seconds */
34 void gras_timer_repeat(double interval, void_f_void_t action)
35 {
36   gras_msg_procdata_t pd =
37       (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
38
39   gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
40
41   XBT_VERB("Register repetitive action %p", action);
42   timer->period = interval;
43   timer->expiry = interval + gras_os_time();
44   timer->action = action;
45   timer->repeat = TRUE;
46 }
47
48 /** @brief Cancel a delayed task */
49 void gras_timer_cancel_delay(double interval, void_f_void_t action)
50 {
51   gras_msg_procdata_t pd =
52       (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
53   unsigned int cursor;
54   int found;
55   s_gras_timer_t timer;
56
57   found = FALSE;
58   xbt_dynar_foreach(pd->timers, cursor, timer) {
59     if (timer.repeat == FALSE &&
60         timer.period == interval && timer.action == action) {
61
62       found = TRUE;
63       xbt_dynar_cursor_rm(pd->timers, &cursor);
64     }
65   }
66
67   if (!found)
68     THROWF(mismatch_error, 0,
69            "Cannot remove the action %p delayed of %f second: not found",
70            action, interval);
71
72 }
73
74 /** @brief Cancel a repetitive task */
75 void gras_timer_cancel_repeat(double interval, void_f_void_t action)
76 {
77   gras_msg_procdata_t pd =
78       (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
79   unsigned int cursor;
80   int found;
81   s_gras_timer_t timer;
82
83   found = FALSE;
84   xbt_dynar_foreach(pd->timers, cursor, timer) {
85     if (timer.repeat == TRUE &&
86         timer.period == interval && timer.action == action) {
87
88       found = TRUE;
89       xbt_dynar_cursor_rm(pd->timers, &cursor);
90     }
91   }
92
93   if (!found)
94     THROWF(mismatch_error, 0,
95            "Cannot remove the action %p delayed of %f second: not found",
96            action, interval);
97 }
98
99 /** @brief Cancel all delayed tasks */
100 void gras_timer_cancel_delay_all(void)
101 {
102   gras_msg_procdata_t pd =
103       (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
104   unsigned int cursor;
105   int found;
106   s_gras_timer_t timer;
107
108   found = FALSE;
109   xbt_dynar_foreach(pd->timers, cursor, timer) {
110     if (timer.repeat == FALSE) {
111
112       found = TRUE;
113       xbt_dynar_cursor_rm(pd->timers, &cursor);
114     }
115   }
116
117   if (!found)
118     THROWF(mismatch_error, 0, "No delayed action to remove");
119
120 }
121
122 /** @brief Cancel all repetitive tasks */
123 void gras_timer_cancel_repeat_all(void)
124 {
125   gras_msg_procdata_t pd =
126       (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
127   unsigned int cursor;
128   int found;
129   s_gras_timer_t timer;
130
131   found = FALSE;
132   xbt_dynar_foreach(pd->timers, cursor, timer) {
133     if (timer.repeat == FALSE) {
134
135       found = TRUE;
136       xbt_dynar_cursor_rm(pd->timers, &cursor);
137     }
138   }
139
140   if (!found)
141     THROWF(mismatch_error, 0, "No repetitive action to remove");
142 }
143
144 /** @brief Cancel all delayed and repetitive tasks */
145 void gras_timer_cancel_all(void)
146 {
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);
150 }
151
152
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)
155 {
156   gras_msg_procdata_t pd =
157       (gras_msg_procdata_t) gras_libdata_by_id(gras_msg_libdata_id);
158   unsigned int cursor;
159   gras_timer_t timer;
160   double now = gras_os_time();
161   double untilnext = -1.0;
162
163   for (cursor = 0; cursor < xbt_dynar_length(pd->timers); cursor++) {
164     double untilthis;
165
166     timer = xbt_dynar_get_ptr(pd->timers, cursor);
167     untilthis = timer->expiry - now;
168
169     XBT_DEBUG("Action %p expires in %f", timer->action, untilthis);
170
171     if (untilthis <= 0.0) {
172       void_f_void_t action = timer->action;
173
174       XBT_DEBUG("[%.0f] Serve %s action %p (%f<%f)", gras_os_time(),
175              timer->repeat ? "repetitive" : "delayed", timer->action,
176              timer->expiry, now);
177
178       if (timer->repeat) {
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,
182                timer->period);
183       } else {
184         XBT_DEBUG("[%.0f] Remove %p now that it's done", gras_os_time(),
185                timer->action);
186         xbt_dynar_cursor_rm(pd->timers, &cursor);
187       }
188       action();
189       return 0.0;
190     } else if (untilthis < untilnext || untilnext == -1) {
191       untilnext = untilthis;
192     }
193   }
194   return untilnext;
195 }