Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
4734db03c59e0ddb2d28d2d9d1f25f836ac1b4ac
[simgrid.git] / src / gras / Virtu / sg_emul.c
1 /* sg_emul - Emulation support (simulation)                                 */
2
3 /* Copyright (c) 2005, 2006, 2007, 2009, 2010. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7  * under the terms of the license (GNU LGPL) which comes with this package. */
8
9 #include <stdio.h>              /* sprintf */
10 #include "gras/emul.h"
11 #include "gras/Virtu/virtu_sg.h"
12 #include "gras_modinter.h"
13
14 #include "xbt/xbt_os_time.h"    /* timers */
15 #include "xbt/dict.h"
16 #include "xbt/ex.h"
17
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_virtu_emul, gras_virtu,
19                                 "Emulation support");
20 /*** CPU burning */
21 void gras_cpu_burn(double flops)
22 {
23   smx_action_t act;
24   smx_cond_t cond;
25   smx_mutex_t mutex;
26
27   if (flops > 0) {
28     cond = SIMIX_cond_init();
29     mutex = SIMIX_mutex_init();
30
31     SIMIX_mutex_lock(mutex);
32     act = SIMIX_action_execute(SIMIX_host_self(), "task", flops);
33
34     SIMIX_register_action_to_condition(act, cond);
35     SIMIX_cond_wait(cond, mutex);
36     SIMIX_unregister_action_to_condition(act, cond);
37
38     SIMIX_action_destroy(act);
39     SIMIX_mutex_unlock(mutex);
40
41     SIMIX_cond_destroy(cond);
42     SIMIX_mutex_destroy(mutex);
43   }
44 }
45
46 /*** Timing macros ***/
47 static xbt_os_timer_t timer;
48 static int benchmarking = 0;
49 static xbt_dict_t benchmark_set = NULL;
50 static double reference = .00000000523066250047108838;  /* FIXME: we should benchmark host machine to set this; unit=s/flop */
51 static double duration = 0.0;
52
53 static char *locbuf = NULL;
54 static unsigned int locbufsize;
55
56 void gras_emul_init(void)
57 {
58   if (!benchmark_set) {
59     benchmark_set = xbt_dict_new();
60     timer = xbt_os_timer_new();
61   }
62 }
63
64 void gras_emul_exit(void)
65 {
66   if (locbuf)
67     free(locbuf);
68   xbt_dict_free(&benchmark_set);
69   xbt_os_timer_free(timer);
70 }
71
72
73 static void store_in_dict(xbt_dict_t dict, const char *key, double value)
74 {
75   double *ir;
76
77   ir = xbt_dict_get_or_null(dict, key);
78   if (!ir) {
79     ir = xbt_new0(double, 1);
80     xbt_dict_set(dict, key, ir, xbt_free_f);
81   }
82   *ir = value;
83 }
84
85 static double get_from_dict(xbt_dict_t dict, const char *key)
86 {
87   double *ir = xbt_dict_get(dict, key);
88
89   return *ir;
90 }
91
92 int gras_bench_always_begin(const char *location, int line)
93 {
94   xbt_assert0(!benchmarking, "Already benchmarking");
95   benchmarking = 1;
96
97   if (!timer)
98     xbt_os_timer_start(timer);
99   return 0;
100 }
101
102 int gras_bench_always_end(void)
103 {
104   xbt_assert0(benchmarking, "Not benchmarking yet");
105   benchmarking = 0;
106   xbt_os_timer_stop(timer);
107   duration = xbt_os_timer_elapsed(timer);
108
109   gras_cpu_burn(duration / reference);
110
111   return 0;
112 }
113
114 int gras_bench_once_begin(const char *location, int line)
115 {
116   double *ir = NULL;
117   xbt_assert0(!benchmarking, "Already benchmarking");
118   benchmarking = 1;
119
120   if (!locbuf || locbufsize < strlen(location) + 64) {
121     locbufsize = strlen(location) + 64;
122     locbuf = xbt_realloc(locbuf, locbufsize);
123   }
124   sprintf(locbuf, "%s:%d", location, line);
125
126   ir = xbt_dict_get_or_null(benchmark_set, locbuf);
127   if (!ir) {
128     DEBUG1("%s", locbuf);
129     duration = 1;
130     xbt_os_timer_start(timer);
131     return 1;
132   } else {
133     duration = -1.0;
134     return 0;
135   }
136 }
137
138 int gras_bench_once_end(void)
139 {
140   xbt_assert0(benchmarking, "Not benchmarking yet");
141   benchmarking = 0;
142   if (duration > 0) {
143     xbt_os_timer_stop(timer);
144     duration = xbt_os_timer_elapsed(timer);
145     store_in_dict(benchmark_set, locbuf, duration);
146   } else {
147     duration = get_from_dict(benchmark_set, locbuf);
148   }
149   DEBUG2("Simulate the run of a task of %f sec for %s", duration, locbuf);
150   gras_cpu_burn(duration / reference);
151   return 0;
152 }
153
154
155 /*** Conditional execution support ***/
156
157 int gras_if_RL(void)
158 {
159   return 0;
160 }
161
162 int gras_if_SG(void)
163 {
164   return 1;
165 }