Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Added round trip time contraint to the SDP program, this parameter
[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   int cursor,found;
49   s_gras_timer_t timer;
50
51   found = FALSE;
52   xbt_dynar_foreach(pd->timers,cursor,timer){
53      if (timer.repeat == FALSE    &&
54          timer.period == interval &&
55          timer.action == action) {
56         
57         found = TRUE;
58         xbt_dynar_cursor_rm(pd->timers, &cursor);
59      }
60   }
61   
62   if (!found)
63      THROW2(mismatch_error,0,"Cannot remove the action %p delayed of %f second: not found",
64             action,interval);
65    
66 }
67
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);
71   int cursor,found;
72   s_gras_timer_t timer;
73
74   found = FALSE;
75   xbt_dynar_foreach(pd->timers,cursor,timer){
76      if (timer.repeat == TRUE     &&
77          timer.period == interval &&
78          timer.action == action) {
79         
80         found = TRUE;
81         xbt_dynar_cursor_rm(pd->timers, &cursor);
82      }
83   }
84   
85   if (!found)
86      THROW2(mismatch_error,0,"Cannot remove the action %p delayed of %f second: not found",
87             action,interval);
88 }
89
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);
93   int cursor, found;
94   s_gras_timer_t timer;
95
96   found = FALSE;
97   xbt_dynar_foreach(pd->timers,cursor,timer){
98      if (timer.repeat   == FALSE) {
99         
100         found = TRUE;
101         xbt_dynar_cursor_rm(pd->timers, &cursor);
102      }
103   }
104   
105   if (!found)
106      THROW0(mismatch_error,0,"No delayed action to remove");
107    
108 }
109
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);
113   int cursor, found;
114   s_gras_timer_t timer;
115
116   found = FALSE;
117   xbt_dynar_foreach(pd->timers,cursor,timer){
118     if (timer.repeat   == FALSE) {
119       
120       found = TRUE;
121       xbt_dynar_cursor_rm(pd->timers, &cursor);
122     }
123   }
124   
125   if (!found)
126     THROW0(mismatch_error,0,"No repetitive action to remove");
127 }
128
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 );
133 }
134
135    
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);
139   int cursor;
140   gras_timer_t timer;
141   double now=gras_os_time();
142   double untilnext = -1.0;
143   
144   for (cursor=0; cursor < xbt_dynar_length(pd->timers); cursor++) {
145      double untilthis;
146      
147      timer = xbt_dynar_get_ptr (pd->timers, cursor);
148      untilthis = timer->expiry - now;
149      
150      DEBUG2("Action %p expires in %f", timer->action, untilthis);
151      
152      if (untilthis <= 0.0) {
153        void_f_void_t *action = timer->action;
154         
155        DEBUG5("[%.0f] Serve %s action %p (%f<%f)",gras_os_time(),
156               timer->repeat ? "repetitive" : "delayed", timer->action,
157               timer->expiry, now);
158         
159        if (timer->repeat) {     
160          timer->expiry = now + timer->period;
161          DEBUG4("[%.0f] Re-arm repetitive action %p for %f (period=%f)",
162                 gras_os_time(),
163                 timer->action, timer->expiry, timer->period);
164        } else {
165          DEBUG2("[%.0f] Remove %p now that it's done", gras_os_time(), timer->action);
166          xbt_dynar_cursor_rm(pd->timers, &cursor);
167        }
168        action();
169        return 0.0;
170      } else if (untilthis < untilnext || untilnext == -1) {
171         untilnext = untilthis;
172      }
173   }
174   return untilnext;
175 }