Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : MUTEX_UNLOCK is invisible for MC
[simgrid.git] / src / instr / instr_trace.c
1 /* Copyright (c) 2010-2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "instr/instr_private.h"
8 #include "xbt/virtu.h" /* sg_cmdline */
9
10 #ifdef HAVE_TRACING
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_trace, instr, "tracing event system");
13
14
15 FILE *tracing_file = NULL;
16
17 void print_NULL(paje_event_t event){}
18
19 /* The active set of functions for the selected trace format
20  * By default, they all do nothing, hence the print_NULL to avoid segfaults */
21
22 s_instr_trace_writer_t active_writer = {
23     print_NULL, print_NULL, print_NULL, print_NULL,
24     print_NULL, print_NULL, print_NULL, print_NULL,
25     print_NULL, print_NULL, print_NULL, print_NULL,
26     print_NULL, print_NULL, print_NULL, print_NULL,
27     print_NULL, print_NULL
28 };
29
30 xbt_dynar_t buffer = NULL;
31
32 void dump_comment (const char *comment)
33 {
34   if (!strlen(comment)) return;
35   fprintf (tracing_file, "# %s\n", comment);
36 }
37
38 void dump_comment_file (const char *filename)
39 {
40   if (!strlen(filename)) return;
41   FILE *file = fopen (filename, "r");
42   if (!file){
43     THROWF (system_error, 1, "Comment file %s could not be opened for reading.", filename);
44   }
45   while (!feof(file)){
46     char c;
47     c = fgetc(file);
48     if (feof(file)) break;
49     fprintf (tracing_file, "# ");
50     while (c != '\n'){
51       fprintf (tracing_file, "%c", c);
52       c = fgetc(file);
53       if (feof(file)) break;
54     }
55     fprintf (tracing_file, "\n");
56   }
57   fclose(file);
58 }
59
60 void TRACE_init()
61 {
62   buffer = xbt_dynar_new(sizeof(paje_event_t), NULL);
63 }
64
65 void TRACE_finalize()
66 {
67   xbt_dynar_free(&buffer);
68 }
69
70 double TRACE_last_timestamp_to_dump = 0;
71 //dumps the trace file until the timestamp TRACE_last_timestamp_to_dump
72 void TRACE_paje_dump_buffer (int force)
73 {
74   if (!TRACE_is_enabled()) return;
75   XBT_DEBUG("%s: dump until %f. starts", __FUNCTION__, TRACE_last_timestamp_to_dump);
76   if (force){
77     paje_event_t event;
78     unsigned int i;
79     xbt_dynar_foreach(buffer, i, event){
80       event->print (event);
81       event->free (event);
82     }
83     xbt_dynar_free (&buffer);
84     buffer = xbt_dynar_new (sizeof(paje_event_t), NULL);
85   }else{
86     paje_event_t event;
87     unsigned int cursor;
88     xbt_dynar_foreach(buffer, cursor, event) {
89       double head_timestamp = event->timestamp;
90       if (head_timestamp > TRACE_last_timestamp_to_dump){
91         break;
92       }
93       event->print (event);
94       event->free (event);
95     }
96     xbt_dynar_remove_n_at(buffer, cursor, 0);
97   }
98   XBT_DEBUG("%s: ends", __FUNCTION__);
99 }
100
101 /* internal do the instrumentation module */
102 static void insert_into_buffer (paje_event_t tbi)
103 {
104   if (TRACE_buffer() == 0){
105     tbi->print (tbi);
106     tbi->free (tbi);
107     return;
108   }
109
110   XBT_DEBUG("%s: insert event_type=%d, timestamp=%f, buffersize=%lu)",
111       __FUNCTION__, (int)tbi->event_type, tbi->timestamp, xbt_dynar_length(buffer));
112
113   unsigned int i;
114   for (i = xbt_dynar_length(buffer); i > 0; i--) {
115     paje_event_t e1 = *(paje_event_t*)xbt_dynar_get_ptr(buffer, i - 1);
116     if (e1->timestamp <= tbi->timestamp)
117       break;
118   }
119   xbt_dynar_insert_at(buffer, i, &tbi);
120   if (i == 0)
121     XBT_DEBUG("%s: inserted at beginning", __FUNCTION__);
122   else
123     XBT_DEBUG("%s: inserted at%s %u", __FUNCTION__,
124               (i == xbt_dynar_length(buffer) - 1 ? " end, pos =" : ""), i);
125 }
126
127
128 static void free_paje_event (paje_event_t event)
129 {
130   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
131   switch (event->event_type){
132   case PAJE_StartLink:
133     xbt_free (((startLink_t)(event->data))->value);
134     xbt_free (((startLink_t)(event->data))->key);
135     break;
136   case PAJE_EndLink:
137     xbt_free (((endLink_t)(event->data))->value);
138     xbt_free (((endLink_t)(event->data))->key);
139     break;
140   default:
141     break;
142   }
143   xbt_free (event->data);
144   xbt_free (event);
145 }
146
147 void new_pajeDefineContainerType(type_t type)
148 {
149   paje_event_t event = xbt_new0(s_paje_event_t, 1);
150   event->event_type = PAJE_DefineContainerType;
151   event->timestamp = 0;
152   event->print = active_writer.print_DefineContainerType;
153   event->free = free_paje_event;
154   event->data = xbt_new0(s_defineContainerType_t, 1);
155   ((defineContainerType_t)(event->data))->type = type;
156
157   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event->event_type);
158
159   //print it
160   event->print (event);
161   event->free (event);
162 }
163
164 void new_pajeDefineVariableType(type_t type)
165 {
166   paje_event_t event = xbt_new0(s_paje_event_t, 1);
167   event->event_type = PAJE_DefineVariableType;
168   event->timestamp = 0;
169   event->print = active_writer.print_DefineVariableType;
170   event->free = free_paje_event;
171   event->data = xbt_new0(s_defineVariableType_t, 1);
172   ((defineVariableType_t)(event->data))->type = type;
173
174   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event->event_type);
175
176   //print it
177   event->print (event);
178   event->free (event);
179 }
180
181 void new_pajeDefineStateType(type_t type)
182 {
183   paje_event_t event = xbt_new0(s_paje_event_t, 1);
184   event->event_type = PAJE_DefineStateType;
185   event->timestamp = 0;
186   event->print = active_writer.print_DefineStateType;
187   event->free = free_paje_event;
188   event->data = xbt_new0(s_defineStateType_t, 1);
189   ((defineStateType_t)(event->data))->type = type;
190
191   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event->event_type);
192
193   //print it
194   event->print (event);
195   event->free (event);
196 }
197
198 void new_pajeDefineEventType(type_t type)
199 {
200   paje_event_t event = xbt_new0(s_paje_event_t, 1);
201   event->event_type = PAJE_DefineEventType;
202   event->timestamp = 0;
203   event->print = active_writer.print_DefineEventType;
204   event->free = free_paje_event;
205   event->data = xbt_new0(s_defineEventType_t, 1);
206   ((defineEventType_t)(event->data))->type = type;
207
208   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event->event_type);
209
210   //print it
211   event->print (event);
212   event->free (event);
213 }
214
215 void new_pajeDefineLinkType(type_t type, type_t source, type_t dest)
216 {
217   paje_event_t event = xbt_new0(s_paje_event_t, 1);
218   event->event_type = PAJE_DefineLinkType;
219   event->timestamp = 0;
220   event->print = active_writer.print_DefineLinkType;
221   event->free = free_paje_event;
222   event->data = xbt_new0(s_defineLinkType_t, 1);
223   ((defineLinkType_t)(event->data))->type = type;
224   ((defineLinkType_t)(event->data))->source = source;
225   ((defineLinkType_t)(event->data))->dest = dest;
226
227   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event->event_type);
228
229   //print it
230   event->print (event);
231   event->free (event);
232 }
233
234 void new_pajeDefineEntityValue (val_t value)
235 {
236   paje_event_t event = xbt_new0(s_paje_event_t, 1);
237   event->event_type = PAJE_DefineEntityValue;
238   event->timestamp = 0;
239   event->print = active_writer.print_DefineEntityValue;
240   event->free = free_paje_event;
241   event->data = xbt_new0(s_defineEntityValue_t, 1);
242   ((defineEntityValue_t)(event->data))->value = value;
243
244   XBT_DEBUG("%s: event_type=%d", __FUNCTION__, (int)event->event_type);
245
246   //print it
247   event->print (event);
248   event->free (event);
249 }
250
251 void new_pajeCreateContainer (container_t container)
252 {
253   paje_event_t event = xbt_new0(s_paje_event_t, 1);
254   event->event_type = PAJE_CreateContainer;
255   event->timestamp = SIMIX_get_clock();
256   event->print = active_writer.print_CreateContainer;
257   event->free = free_paje_event;
258   event->data = xbt_new0(s_createContainer_t, 1);
259   ((createContainer_t)(event->data))->container = container;
260
261   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
262
263   //print it
264   event->print (event);
265   event->free (event);
266 }
267
268 void new_pajeDestroyContainer (container_t container)
269 {
270   paje_event_t event = xbt_new0(s_paje_event_t, 1);
271   event->event_type = PAJE_DestroyContainer;
272   event->timestamp = SIMIX_get_clock();
273   event->print = active_writer.print_DestroyContainer;
274   event->free = free_paje_event;
275   event->data = xbt_new0(s_destroyContainer_t, 1);
276   ((destroyContainer_t)(event->data))->container = container;
277
278   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
279
280   //print it
281   event->print (event);
282   event->free (event);
283 }
284
285 void new_pajeSetVariable (double timestamp, container_t container, type_t type, double value)
286 {
287   paje_event_t event = xbt_new0(s_paje_event_t, 1);
288   event->event_type = PAJE_SetVariable;
289   event->timestamp = timestamp;
290   event->print = active_writer.print_SetVariable;
291   event->free = free_paje_event;
292   event->data = xbt_new0(s_setVariable_t, 1);
293   ((setVariable_t)(event->data))->type = type;
294   ((setVariable_t)(event->data))->container = container;
295   ((setVariable_t)(event->data))->value = value;
296
297   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
298
299   insert_into_buffer (event);
300 }
301
302
303 void new_pajeAddVariable (double timestamp, container_t container, type_t type, double value)
304 {
305   paje_event_t event = xbt_new0(s_paje_event_t, 1);
306   event->event_type = PAJE_AddVariable;
307   event->timestamp = timestamp;
308   event->print = active_writer.print_AddVariable;
309   event->free = free_paje_event;
310   event->data = xbt_new0(s_addVariable_t, 1);
311   ((addVariable_t)(event->data))->type = type;
312   ((addVariable_t)(event->data))->container = container;
313   ((addVariable_t)(event->data))->value = value;
314
315   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
316
317   insert_into_buffer (event);
318 }
319
320 void new_pajeSubVariable (double timestamp, container_t container, type_t type, double value)
321 {
322   paje_event_t event = xbt_new0(s_paje_event_t, 1);
323   event->event_type = PAJE_SubVariable;
324   event->timestamp = timestamp;
325   event->print = active_writer.print_SubVariable;
326   event->free = free_paje_event;
327   event->data = xbt_new0(s_subVariable_t, 1);
328   ((subVariable_t)(event->data))->type = type;
329   ((subVariable_t)(event->data))->container = container;
330   ((subVariable_t)(event->data))->value = value;
331
332   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
333
334   insert_into_buffer (event);
335 }
336
337 void new_pajeSetState (double timestamp, container_t container, type_t type, val_t value)
338 {
339   paje_event_t event = xbt_new0(s_paje_event_t, 1);
340   event->event_type = PAJE_SetState;
341   event->timestamp = timestamp;
342   event->print = active_writer.print_SetState;
343   event->free = free_paje_event;
344   event->data = xbt_new0(s_setState_t, 1);
345   ((setState_t)(event->data))->type = type;
346   ((setState_t)(event->data))->container = container;
347   ((setState_t)(event->data))->value = value;
348
349   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
350
351   insert_into_buffer (event);
352 }
353
354
355 void new_pajePushStateWithExtra (double timestamp, container_t container, type_t type, val_t value, void* extra)
356 {
357   paje_event_t event = xbt_new0(s_paje_event_t, 1);
358   event->event_type = PAJE_PushState;
359   event->timestamp = timestamp;
360   event->print = active_writer.print_PushState;
361   event->free = free_paje_event;
362   event->data = xbt_new0(s_pushState_t, 1);
363   ((pushState_t)(event->data))->type = type;
364   ((pushState_t)(event->data))->container = container;
365   ((pushState_t)(event->data))->value = value;
366   ((pushState_t)(event->data))->extra = extra;
367
368   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
369
370   insert_into_buffer (event);
371 }
372
373
374 void new_pajePushState (double timestamp, container_t container, type_t type, val_t value)
375 {
376   paje_event_t event = xbt_new0(s_paje_event_t, 1);
377   event->event_type = PAJE_PushState;
378   event->timestamp = timestamp;
379   event->print = active_writer.print_PushState;
380   event->free = free_paje_event;
381   event->data = xbt_new0(s_pushState_t, 1);
382   ((pushState_t)(event->data))->type = type;
383   ((pushState_t)(event->data))->container = container;
384   ((pushState_t)(event->data))->value = value;
385   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
386
387   insert_into_buffer (event);
388 }
389
390 void new_pajePopState (double timestamp, container_t container, type_t type)
391 {
392   paje_event_t event = xbt_new0(s_paje_event_t, 1);
393   event->event_type = PAJE_PopState;
394   event->timestamp = timestamp;
395   event->print = active_writer.print_PopState;
396   event->free = free_paje_event;
397   event->data = xbt_new0(s_popState_t, 1);
398   ((popState_t)(event->data))->type = type;
399   ((popState_t)(event->data))->container = container;
400
401   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
402
403   insert_into_buffer (event);
404 }
405
406
407 void new_pajeResetState (double timestamp, container_t container, type_t type)
408 {
409   paje_event_t event = xbt_new0(s_paje_event_t, 1);
410   event->event_type = PAJE_ResetState;
411   event->timestamp = timestamp;
412   event->print = active_writer.print_ResetState;
413   event->free = free_paje_event;
414   event->data = xbt_new0(s_resetState_t, 1);
415   ((resetState_t)(event->data))->type = type;
416   ((resetState_t)(event->data))->container = container;
417
418   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
419
420   insert_into_buffer (event);
421 }
422
423 void new_pajeStartLink (double timestamp, container_t container, type_t type, container_t sourceContainer, const char *value, const char *key)
424 {
425   paje_event_t event = xbt_new0(s_paje_event_t, 1);
426   event->event_type = PAJE_StartLink;
427   event->timestamp = timestamp;
428   event->print = active_writer.print_StartLink;
429   event->free = free_paje_event;
430   event->data = xbt_new0(s_startLink_t, 1);
431   ((startLink_t)(event->data))->type = type;
432   ((startLink_t)(event->data))->container = container;
433   ((startLink_t)(event->data))->sourceContainer = sourceContainer;
434   ((startLink_t)(event->data))->value = xbt_strdup(value);
435   ((startLink_t)(event->data))->key = xbt_strdup(key);
436   ((startLink_t)(event->data))->size = -1;
437   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
438
439   insert_into_buffer (event);
440 }
441
442 void new_pajeStartLinkWithSize (double timestamp, container_t container, type_t type, container_t sourceContainer, const char *value, const char *key, int size)
443 {
444   paje_event_t event = xbt_new0(s_paje_event_t, 1);
445   event->event_type = PAJE_StartLink;
446   event->timestamp = timestamp;
447   event->print = active_writer.print_StartLink;
448   event->free = free_paje_event;
449   event->data = xbt_new0(s_startLink_t, 1);
450   ((startLink_t)(event->data))->type = type;
451   ((startLink_t)(event->data))->container = container;
452   ((startLink_t)(event->data))->sourceContainer = sourceContainer;
453   ((startLink_t)(event->data))->value = xbt_strdup(value);
454   ((startLink_t)(event->data))->key = xbt_strdup(key);
455   ((startLink_t)(event->data))->size = size;
456
457   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
458
459   insert_into_buffer (event);
460 }
461
462 void new_pajeEndLink (double timestamp, container_t container, type_t type, container_t destContainer, const char *value, const char *key)
463 {
464   paje_event_t event = xbt_new0(s_paje_event_t, 1);
465   event->event_type = PAJE_EndLink;
466   event->timestamp = timestamp;
467   event->print = active_writer.print_EndLink;
468   event->free = free_paje_event;
469   event->data = xbt_new0(s_endLink_t, 1);
470   ((endLink_t)(event->data))->type = type;
471   ((endLink_t)(event->data))->container = container;
472   ((endLink_t)(event->data))->destContainer = destContainer;
473   ((endLink_t)(event->data))->value = xbt_strdup(value);
474   ((endLink_t)(event->data))->key = xbt_strdup(key);
475
476   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
477
478   insert_into_buffer (event);
479 }
480
481 void new_pajeNewEvent (double timestamp, container_t container, type_t type, val_t value)
482 {
483   paje_event_t event = xbt_new0(s_paje_event_t, 1);
484   event->event_type = PAJE_NewEvent;
485   event->timestamp = timestamp;
486   event->print = active_writer.print_NewEvent;
487   event->free = free_paje_event;
488   event->data = xbt_new0(s_newEvent_t, 1);
489   ((newEvent_t)(event->data))->type = type;
490   ((newEvent_t)(event->data))->container = container;
491   ((newEvent_t)(event->data))->value = value;
492
493   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
494
495   insert_into_buffer (event);
496 }
497
498 #endif /* HAVE_TRACING */