Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Reindent some code, no real change (should do it for all my code once for good)
[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         gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
22
23         gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
24
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;
30 }
31
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);
35
36         gras_timer_t timer = xbt_dynar_push_ptr(pd->timers);
37
38         VERB1("Register repetitive action %p", action);
39         timer->period = interval;
40         timer->expiry = interval+gras_os_time();
41         timer->action = action;
42         timer->repeat = TRUE;
43 }
44
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);
48         unsigned int cursor;
49         int found;
50         s_gras_timer_t timer;
51
52         found = FALSE;
53         xbt_dynar_foreach(pd->timers,cursor,timer){
54                 if (timer.repeat == FALSE    &&
55                                 timer.period == interval &&
56                                 timer.action == action) {
57
58                         found = TRUE;
59                         xbt_dynar_cursor_rm(pd->timers, &cursor);
60                 }
61         }
62
63         if (!found)
64                 THROW2(mismatch_error,0,"Cannot remove the action %p delayed of %f second: not found",
65                                 action,interval);
66
67 }
68
69 /** @brief Cancel a repetitive task */
70 void gras_timer_cancel_repeat(double interval, void_f_void_t action) {
71         gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
72         unsigned int cursor;
73         int found;
74         s_gras_timer_t timer;
75
76         found = FALSE;
77         xbt_dynar_foreach(pd->timers,cursor,timer){
78                 if (timer.repeat == TRUE     &&
79                                 timer.period == interval &&
80                                 timer.action == action) {
81
82                         found = TRUE;
83                         xbt_dynar_cursor_rm(pd->timers, &cursor);
84                 }
85         }
86
87         if (!found)
88                 THROW2(mismatch_error,0,"Cannot remove the action %p delayed of %f second: not found",
89                                 action,interval);
90 }
91
92 /** @brief Cancel all delayed tasks */
93 void gras_timer_cancel_delay_all(void) {
94         gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
95         unsigned int cursor;
96         int found;
97         s_gras_timer_t timer;
98
99         found = FALSE;
100         xbt_dynar_foreach(pd->timers,cursor,timer){
101                 if (timer.repeat   == FALSE) {
102
103                         found = TRUE;
104                         xbt_dynar_cursor_rm(pd->timers, &cursor);
105                 }
106         }
107
108         if (!found)
109                 THROW0(mismatch_error,0,"No delayed action to remove");
110
111 }
112
113 /** @brief Cancel all repetitive tasks */
114 void gras_timer_cancel_repeat_all(void){
115         gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
116         unsigned int cursor;
117         int found;
118         s_gras_timer_t timer;
119
120         found = FALSE;
121         xbt_dynar_foreach(pd->timers,cursor,timer){
122                 if (timer.repeat   == FALSE) {
123
124                         found = TRUE;
125                         xbt_dynar_cursor_rm(pd->timers, &cursor);
126                 }
127         }
128
129         if (!found)
130                 THROW0(mismatch_error,0,"No repetitive action to remove");
131 }
132
133 /** @brief Cancel all delayed and repetitive tasks */
134 void gras_timer_cancel_all(void) {
135         gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
136         xbt_dynar_reset( pd->timers );
137 }
138
139
140 /* returns 0 if it handled a timer, or the delay until next timer, or -1 if no armed timer */
141 double gras_msg_timer_handle(void) {
142         gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_by_id(gras_msg_libdata_id);
143         unsigned int cursor;
144         gras_timer_t timer;
145         double now=gras_os_time();
146         double untilnext = -1.0;
147
148         for (cursor=0; cursor < xbt_dynar_length(pd->timers); cursor++) {
149                 double untilthis;
150
151                 timer = xbt_dynar_get_ptr (pd->timers, cursor);
152                 untilthis = timer->expiry - now;
153
154                 DEBUG2("Action %p expires in %f", timer->action, untilthis);
155
156                 if (untilthis <= 0.0) {
157                         void_f_void_t action = timer->action;
158
159                         DEBUG5("[%.0f] Serve %s action %p (%f<%f)",gras_os_time(),
160                                         timer->repeat ? "repetitive" : "delayed", timer->action,
161                                                         timer->expiry, now);
162
163                         if (timer->repeat) {
164                                 timer->expiry = now + timer->period;
165                                 DEBUG4("[%.0f] Re-arm repetitive action %p for %f (period=%f)",
166                                                 gras_os_time(),
167                                                 timer->action, timer->expiry, timer->period);
168                         } else {
169                                 DEBUG2("[%.0f] Remove %p now that it's done", gras_os_time(), timer->action);
170                                 xbt_dynar_cursor_rm(pd->timers, &cursor);
171                         }
172                         (*action)();
173                         return 0.0;
174                 } else if (untilthis < untilnext || untilnext == -1) {
175                         untilnext = untilthis;
176                 }
177         }
178         return untilnext;
179 }