Logo AND Algorithmique Numérique Distribuée

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