Logo AND Algorithmique Numérique Distribuée

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