Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use proper timer; allow several timed sections per file (ie, use the 'line' argument...
[simgrid.git] / src / gras / Virtu / sg_chrono.c
1 /*      $Id$     */
2
3 /* sg_chrono.c - code benchmarking for emulation                            */
4
5 /* Copyright (c) 2005 Martin Quinson, Arnaud Legrand. All rights reserved.  */
6
7 /* This program is free software; you can redistribute it and/or modify it
8  * under the terms of the license (GNU LGPL) which comes with this package. */
9
10 #include "xbt/sysdep.h"
11 #include "xbt/dict.h"
12 #include "gras/chrono.h"
13 #include "msg/msg.h"
14 #include "xbt/xbt_portability.h"
15 #include "portable.h"
16 #include "gras_modinter.h"
17
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(chrono,gras,"Benchmarking used code");
19
20 static xbt_os_timer_t timer;
21 static int benchmarking = 0;
22 static xbt_dict_t benchmark_set = NULL;
23 static double reference = .00523066250047108838; /* FIXME: we should benchmark host machine to set this */
24 static double duration = 0.0;
25
26 static char* locbuf = NULL;
27 static int locbufsize;
28
29 static void store_in_dict(xbt_dict_t dict, const char *key, double value)
30 {
31   double *ir = NULL;
32
33   xbt_dict_get(dict, key, (void *) &ir);
34   if (!ir) {
35     ir = xbt_new0(double,1);
36     xbt_dict_set(dict, key, ir, free);
37   }
38   *ir = value;
39 }
40
41 static double get_from_dict(xbt_dict_t dict, const char *key)
42 {
43   double *ir = NULL;
44
45   xbt_dict_get(dict, key, (void *) &ir);
46
47   return *ir;
48 }
49
50 int gras_bench_always_begin(const char *location,int line)
51 {
52   xbt_assert0(!benchmarking,"Already benchmarking");
53   benchmarking = 1;
54
55   if (!timer)
56   xbt_os_timer_start(timer);
57   return 0;
58 }
59
60 int gras_bench_always_end(void)
61 {
62   m_task_t task = NULL;
63   
64   xbt_assert0(benchmarking,"Not benchmarking yet");
65   benchmarking = 0;
66   xbt_os_timer_stop(timer);
67   duration = xbt_os_timer_elapsed(timer);
68   task = MSG_task_create("task", (duration)/reference, 0 , NULL);
69   MSG_task_execute(task);
70   MSG_task_destroy(task);
71   return 0;
72 }
73
74 int gras_bench_once_begin(const char *location,int line)
75 {
76   double *ir = NULL;
77   xbt_assert0(!benchmarking,"Already benchmarking");
78   benchmarking = 1;
79
80   if (!locbuf || locbufsize < strlen(location) + 64) {
81      locbufsize = strlen(location) + 64;
82      locbuf = xbt_realloc(locbuf,locbufsize);
83   }
84   sprintf(locbuf,"%s:%d",location, line);
85    
86   xbt_dict_get(benchmark_set, locbuf, (void *) &ir);
87   if(!ir) {
88     DEBUG1("%s",locbuf); 
89     duration = 1;
90     xbt_os_timer_start(timer);
91     return 1;
92   } else {
93     duration = -1.0;
94     return 0;
95   }
96 }
97
98 int gras_bench_once_end(void)
99 {
100   m_task_t task = NULL;
101
102   xbt_assert0(benchmarking,"Not benchmarking yet");
103   benchmarking = 0;
104   if(duration>0) {
105     xbt_os_timer_stop(timer);
106     duration = xbt_os_timer_elapsed(timer);
107     store_in_dict(benchmark_set, locbuf, duration);
108   } else {
109     duration = get_from_dict(benchmark_set,locbuf);
110   }
111   DEBUG2("Simulate the run of a task of %f sec for %s",duration,locbuf);
112   task = MSG_task_create("task", (duration)/reference, 0 , NULL);
113   MSG_task_execute(task);
114   MSG_task_destroy(task);
115   return 0;
116 }
117
118 void gras_chrono_init(void)
119 {
120   if(!benchmark_set) {
121     benchmark_set = xbt_dict_new();
122     timer = xbt_os_timer_new();
123   }
124 }
125
126 void gras_chrono_exit(void) {
127   if (locbuf) free(locbuf);
128   xbt_dict_free(&benchmark_set);
129   xbt_os_timer_free(timer);
130 }