Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Ansi C declaration of the variables (at the beginning of the blocks)
[simgrid.git] / src / surf / trace_mgr.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2004 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/sysdep.h"
9 #include "xbt/log.h"
10 #include "xbt/dict.h"
11 #include "trace_mgr_private.h"
12 #include "surf_private.h"
13
14 static xbt_dict_t trace_list = NULL;
15 static void _tmgr_trace_free(void *trace)
16 {
17   tmgr_trace_free(trace);
18 }
19
20 tmgr_history_t tmgr_history_new(void)
21 {
22   tmgr_history_t h;
23
24   h = xbt_new0(s_tmgr_history_t, 1);
25
26   h->heap = xbt_heap_new(8, xbt_free_f);        /* Why 8 ? Well, why not... */
27
28   return h;
29 }
30
31 void tmgr_history_free(tmgr_history_t h)
32 {
33   xbt_heap_free(h->heap);
34   free(h);
35 }
36
37 tmgr_trace_t tmgr_trace_new_from_string(const char* id, const char *input, double periodicity)
38 {
39   tmgr_trace_t trace = NULL;
40   int linecount = 0;
41   s_tmgr_event_t event;
42   tmgr_event_t last_event = NULL;
43   xbt_dynar_t list;
44   unsigned int cpt;
45   char * val;
46
47   if (trace_list) {
48     trace = xbt_dict_get_or_null(trace_list, id);
49     if (trace)
50       return trace;
51   }
52
53   if (periodicity <= 0) {
54     xbt_assert1(0, "Periodicity has to be positive. Your value %lg", periodicity);
55   }
56
57   trace = xbt_new0(s_tmgr_trace_t, 1);
58   trace->event_list = xbt_dynar_new(sizeof(s_tmgr_event_t), NULL);
59
60   list = xbt_str_split(input,"\n\r");
61   
62   
63   xbt_dynar_foreach(list, cpt, val) {
64      linecount++;
65      xbt_str_trim(val, " \t\n\r\x0B");
66      if (strlen(val) > 0) {
67        if (sscanf(val, "%lg" " " "%lg" "\n", &event.delta, &event.value) != 2) {
68           xbt_assert2(0, "%s\n%d: Syntax error", input, linecount);
69        }
70        if (last_event) {
71            if ((last_event->delta = event.delta - last_event->delta) <= 0) {
72                xbt_assert2(0, "%s\n%d: Invalid trace value, events have to be sorted", input, linecount);
73            }
74        }
75        xbt_dynar_push(trace->event_list, &event);
76        last_event = xbt_dynar_get_ptr(trace->event_list, xbt_dynar_length(trace->event_list) - 1);
77        if (periodicity > 0) {
78          if (last_event)
79            last_event->delta = periodicity;
80        }
81      }
82   }
83
84   if (!trace_list)
85     trace_list = xbt_dict_new();
86
87   xbt_dict_set(trace_list, id, (void *) trace, _tmgr_trace_free);
88
89   xbt_dynar_free(&list);
90   return trace;
91 }
92
93 tmgr_trace_t tmgr_trace_new(const char *filename)
94 {
95   tmgr_trace_t trace = NULL;
96   FILE *f = NULL;
97   int linecount = 0;
98   char line[256];
99   double periodicity = -1.0;    /* No periodicity by default */
100   s_tmgr_event_t event;
101   tmgr_event_t last_event = NULL;
102
103   if (trace_list) {
104     trace = xbt_dict_get_or_null(trace_list, filename);
105     if (trace)
106       return trace;
107   }
108
109   if ((f = surf_fopen(filename, "r")) == NULL) {
110     xbt_assert1(0, "Cannot open file '%s'", filename);
111   }
112
113   trace = xbt_new0(s_tmgr_trace_t, 1);
114   trace->event_list = xbt_dynar_new(sizeof(s_tmgr_event_t), NULL);
115
116   while (fgets(line, 256, f)) {
117     linecount++;
118     if ((line[0] == '#') || (line[0] == '\n') || (line[0] == '%'))
119       continue;
120
121     if (sscanf(line, "PERIODICITY " "%lg" "\n", &(periodicity))
122         == 1) {
123       if (periodicity <= 0) {
124         xbt_assert2(0,
125                     "%s,%d: Syntax error. Periodicity has to be positive",
126                     filename, linecount);
127       }
128       continue;
129     }
130
131     if (sscanf
132         (line, "%lg" " " "%lg" "\n", &event.delta, &event.value) != 2) {
133       xbt_assert2(0, "%s,%d: Syntax error", filename, linecount);
134     }
135
136     if (last_event) {
137       if ((last_event->delta = event.delta - last_event->delta) <= 0) {
138         xbt_assert2(0,
139                     "%s,%d: Invalid trace value, events have to be sorted",
140                     filename, linecount);
141       }
142     }
143     xbt_dynar_push(trace->event_list, &event);
144     last_event = xbt_dynar_get_ptr(trace->event_list,
145                                    xbt_dynar_length(trace->event_list) -
146                                    1);
147   }
148
149   if (periodicity > 0) {
150     if (last_event)
151       last_event->delta = periodicity;
152   }
153
154   if (!trace_list)
155     trace_list = xbt_dict_new();
156
157   xbt_dict_set(trace_list, filename, (void *) trace, _tmgr_trace_free);
158
159   fclose(f);
160
161   return trace;
162 }
163
164 tmgr_trace_t tmgr_empty_trace_new(void)
165 {
166   tmgr_trace_t trace = NULL;
167   /*double periodicity = -1.0;   No periodicity by default; unused variables
168      tmgr_event_t last_event = NULL; */
169   s_tmgr_event_t event;
170
171   trace = xbt_new0(s_tmgr_trace_t, 1);
172   trace->event_list = xbt_dynar_new(sizeof(s_tmgr_event_t), NULL);
173
174   event.delta = 0.0;
175   event.value = 0.0;
176   xbt_dynar_push(trace->event_list, &event);
177
178   return trace;
179 }
180
181 void tmgr_trace_free(tmgr_trace_t trace)
182 {
183   if (!trace)
184     return;
185   xbt_dynar_free(&(trace->event_list));
186   free(trace);
187 }
188
189 tmgr_trace_event_t tmgr_history_add_trace(tmgr_history_t h,
190                                           tmgr_trace_t trace,
191                                           double start_time, unsigned int offset,
192                                           void *model)
193 {
194   tmgr_trace_event_t trace_event = NULL;
195
196   trace_event = xbt_new0(s_tmgr_trace_event_t, 1);
197   trace_event->trace = trace;
198   trace_event->idx = offset;
199   trace_event->model = model;
200
201   xbt_assert0((trace_event->idx < xbt_dynar_length(trace->event_list)),
202               "You're refering to an event that does not exist!");
203
204   xbt_heap_push(h->heap, trace_event, start_time);
205
206   return trace_event;
207 }
208
209 double tmgr_history_next_date(tmgr_history_t h)
210 {
211   if (xbt_heap_size(h->heap))
212     return (xbt_heap_maxkey(h->heap));
213   else
214     return -1.0;
215 }
216
217 tmgr_trace_event_t tmgr_history_get_next_event_leq(tmgr_history_t h,
218                                                    double date,
219                                                    double *value,
220                                                    void **model)
221 {
222   double event_date = tmgr_history_next_date(h);
223   tmgr_trace_event_t trace_event = NULL;
224   tmgr_event_t event = NULL;
225   tmgr_trace_t trace = NULL;
226
227   if (event_date > date)
228     return NULL;
229
230   if (!(trace_event = xbt_heap_pop(h->heap)))
231     return NULL;
232
233   trace = trace_event->trace;
234   event = xbt_dynar_get_ptr(trace->event_list, trace_event->idx);
235
236   *value = event->value;
237   *model = trace_event->model;
238
239   if (trace_event->idx < xbt_dynar_length(trace->event_list) - 1) {
240     xbt_heap_push(h->heap, trace_event, event_date + event->delta);
241     trace_event->idx++;
242   } else if (event->delta > 0) {        /* Last element, checking for periodicity */
243     xbt_heap_push(h->heap, trace_event, event_date + event->delta);
244     trace_event->idx = 0;
245   } else {                      /* We don't need this trace_event anymore */
246     free(trace_event);
247         return NULL;
248   }
249
250   return trace_event;
251 }
252
253 void tmgr_finalize(void)
254 {
255   xbt_dict_free(&trace_list);
256 }