Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
df420053d99b87a1a5c463db72084df63387963e
[simgrid.git] / src / surf / surf_model_timer.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2005 Arnaud Legrand. All rights reserved.                  */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "xbt/ex.h"
9 #include "surf_private.h"
10 #include "xbt/dict.h"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_timer, surf,
13                                 "Logging specific to SURF (timer)");
14
15 typedef struct command {
16   s_surf_resource_t generic_resource;   /* Must remain first, since we add this to a trace */
17   void *function;
18   void *args;
19   s_xbt_swag_hookup_t command_set_hookup;
20 } s_command_t, *command_t;
21
22
23 surf_model_t surf_timer_model = NULL;
24 static tmgr_trace_t empty_trace = NULL;
25 static xbt_swag_t command_pending = NULL;
26 static xbt_swag_t command_to_run = NULL;
27 static xbt_heap_t timer_heap = NULL;
28
29 static command_t command_new(void *fun, void *args)
30 {
31   command_t command = xbt_new0(s_command_t, 1);
32
33   command->generic_resource.model = surf_timer_model;
34   command->function = fun;
35   command->args = args;
36   xbt_swag_insert(command, command_pending);
37   return command;
38 }
39
40 static void command_free(command_t command)
41 {
42   if (xbt_swag_belongs(command, command_to_run)) {
43     xbt_swag_remove(command, command_to_run);
44   } else if (xbt_swag_belongs(command, command_pending)) {
45     xbt_swag_remove(command, command_pending);
46   }
47   surf_resource_free((surf_resource_t) command);
48   return;
49 }
50
51 static void parse_timer(void)
52 {
53 }
54
55 static void parse_file(const char *file)
56 {
57 }
58
59 static int resource_used(void *resource_id)
60 {
61   return 1;
62 }
63
64 static void timer_action_state_set(surf_action_t action,
65                                    e_surf_action_state_t state)
66 {
67   DIE_IMPOSSIBLE;
68   return;
69 }
70
71 static double share_resources(double now)
72 {
73   if (xbt_heap_size(timer_heap)) {
74     DEBUG1("Share resoure returning %lf", xbt_heap_maxkey(timer_heap));
75     return (xbt_heap_maxkey(timer_heap));
76   } else
77     return -1.0;
78 }
79
80 static void update_actions_state(double now, double delta)
81 {
82   while ((xbt_heap_size(timer_heap)) > 0
83          && (xbt_heap_maxkey(timer_heap) <= now + delta))
84     xbt_heap_pop(timer_heap);
85   return;
86 }
87
88 static void update_resource_state(void *id,
89                                   tmgr_trace_event_t event_type,
90                                   double value, double date)
91 {
92   command_t command = id;
93
94   /* Move this command to the list of commands to execute */
95   xbt_swag_remove(command, command_pending);
96   xbt_swag_insert(command, command_to_run);
97   tmgr_trace_event_free(event_type);
98
99   DEBUG1("Insert command on date %lf", date);
100
101   return;
102 }
103
104 static void set(double date, void *function, void *arg)
105 {
106   command_t command = NULL;
107
108   command = command_new(function, arg);
109
110   tmgr_history_add_trace(history, empty_trace, date, 0, command);
111   xbt_heap_push(timer_heap, NULL, date);
112
113   DEBUG1("Putting value %lf on heap", date);
114 }
115
116
117 static int get(void **function, void **arg)
118 {
119   command_t command = NULL;
120
121   command = xbt_swag_extract(command_to_run);
122   if (command) {
123     *function = command->function;
124     *arg = command->args;
125     xbt_free(command);
126     return 1;
127   } else {
128     return 0;
129   }
130 }
131
132 static void action_suspend(surf_action_t action)
133 {
134   DIE_IMPOSSIBLE;
135 }
136
137 static void action_resume(surf_action_t action)
138 {
139   DIE_IMPOSSIBLE;
140 }
141
142 static int action_is_suspended(surf_action_t action)
143 {
144   DIE_IMPOSSIBLE;
145   return 0;
146 }
147
148 static void finalize(void)
149 {
150   xbt_heap_free(timer_heap);
151   timer_heap = NULL;
152
153   tmgr_trace_free(empty_trace);
154   empty_trace = NULL;
155
156   xbt_swag_free(command_pending);
157   xbt_swag_free(command_to_run);
158
159   surf_model_exit(surf_timer_model);
160   surf_timer_model = NULL;
161 }
162
163 static void surf_timer_model_init_internal(void)
164 {
165   surf_timer_model = surf_model_init();
166
167   surf_timer_model->name = "TIMER";
168   surf_timer_model->action_state_set = timer_action_state_set;
169
170   surf_timer_model->model_private->resource_used = resource_used;
171   surf_timer_model->model_private->share_resources = share_resources;
172   surf_timer_model->model_private->update_actions_state =
173     update_actions_state;
174   surf_timer_model->model_private->update_resource_state =
175     update_resource_state;
176   surf_timer_model->model_private->finalize = finalize;
177
178   surf_timer_model->suspend = action_suspend;
179   surf_timer_model->resume = action_resume;
180   surf_timer_model->is_suspended = action_is_suspended;
181
182   surf_timer_model->extension.timer.set = set;
183   surf_timer_model->extension.timer.get = get;
184
185   {
186     s_command_t var;
187     command_pending = xbt_swag_new(xbt_swag_offset(var, command_set_hookup));
188     command_to_run = xbt_swag_new(xbt_swag_offset(var, command_set_hookup));
189   }
190
191   empty_trace = tmgr_empty_trace_new();
192   timer_heap = xbt_heap_new(8, NULL);
193 }
194
195 void surf_timer_model_init(const char *filename)
196 {
197   if (surf_timer_model)
198     return;
199   surf_timer_model_init_internal();
200   xbt_dynar_push(model_list, &surf_timer_model);
201 }