3 /* Copyright (c) 2005 Arnaud Legrand. All rights reserved. */
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. */
9 #include "surf_private.h"
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_timer, surf,
13 "Logging specific to SURF (timer)");
15 typedef struct command {
16 s_surf_resource_t generic_resource; /* Must remain first, since we add this to a trace */
19 s_xbt_swag_hookup_t command_set_hookup;
20 } s_command_t, *command_t;
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;
29 static command_t command_new(void *fun, void *args)
31 command_t command = xbt_new0(s_command_t, 1);
33 command->generic_resource.model = surf_timer_model;
34 command->function = fun;
36 xbt_swag_insert(command, command_pending);
40 static void command_free(command_t command)
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);
47 surf_resource_free((surf_resource_t)command);
51 static void parse_timer(void)
55 static void parse_file(const char *file)
59 static int resource_used(void *resource_id)
64 static void timer_action_state_set(surf_action_t action,
65 e_surf_action_state_t state)
71 static double share_resources(double now)
73 if (xbt_heap_size(timer_heap))
74 return (xbt_heap_maxkey(timer_heap));
79 static void update_actions_state(double now, double delta)
81 if (xbt_heap_size(timer_heap)) {
82 if (xbt_heap_maxkey(timer_heap) <= now + delta) {
83 xbt_heap_pop(timer_heap);
89 static void update_resource_state(void *id,
90 tmgr_trace_event_t event_type,
91 double value, double date)
93 command_t command = id;
95 /* Move this command to the list of commands to execute */
96 xbt_swag_remove(command, command_pending);
97 xbt_swag_insert(command, command_to_run);
102 static void set(double date, void *function, void *arg)
104 command_t command = NULL;
106 command = command_new(function, arg);
108 tmgr_history_add_trace(history, empty_trace, date, 0, command);
109 xbt_heap_push(timer_heap, NULL, date);
113 static int get(void **function, void **arg)
115 command_t command = NULL;
117 command = xbt_swag_extract(command_to_run);
119 *function = command->function;
120 *arg = command->args;
127 static void action_suspend(surf_action_t action)
132 static void action_resume(surf_action_t action)
137 static int action_is_suspended(surf_action_t action)
143 static void finalize(void)
145 xbt_heap_free(timer_heap);
148 tmgr_trace_free(empty_trace);
151 xbt_swag_free(command_pending);
152 xbt_swag_free(command_to_run);
154 surf_model_exit(surf_timer_model);
155 surf_timer_model = NULL;
158 static void surf_timer_model_init_internal(void)
160 surf_timer_model = surf_model_init();
162 surf_timer_model->name = "TIMER";
163 surf_timer_model->action_state_set = timer_action_state_set;
165 surf_timer_model->model_private->resource_used = resource_used;
166 surf_timer_model->model_private->share_resources = share_resources;
167 surf_timer_model->model_private->update_actions_state =
168 update_actions_state;
169 surf_timer_model->model_private->update_resource_state =
170 update_resource_state;
171 surf_timer_model->model_private->finalize = finalize;
173 surf_timer_model->suspend = action_suspend;
174 surf_timer_model->resume = action_resume;
175 surf_timer_model->is_suspended = action_is_suspended;
177 surf_timer_model->extension.timer.set = set;
178 surf_timer_model->extension.timer.get = get;
182 command_pending = xbt_swag_new(xbt_swag_offset(var, command_set_hookup));
183 command_to_run = xbt_swag_new(xbt_swag_offset(var, command_set_hookup));
186 empty_trace = tmgr_empty_trace_new();
187 timer_heap = xbt_heap_new(8, NULL);
190 void surf_timer_model_init(const char *filename)
192 if (surf_timer_model)
194 surf_timer_model_init_internal();
195 xbt_dynar_push(model_list, &surf_timer_model);