Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Ongoing work to port GRAS to smx_network. Not working yet
[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   smx_action_t act;
23   smx_cond_t cond;
24   smx_mutex_t mutex;
25
26   if (flops>0) {
27     cond = SIMIX_cond_init();
28     mutex = SIMIX_mutex_init();
29
30     SIMIX_mutex_lock(mutex);
31     act =
32         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 /*** Timing macros ***/
46 static xbt_os_timer_t timer;
47 static int benchmarking = 0;
48 static xbt_dict_t benchmark_set = NULL;
49 static double reference = .00000000523066250047108838;  /* FIXME: we should benchmark host machine to set this; unit=s/flop */
50 static double duration = 0.0;
51
52 static char *locbuf = NULL;
53 static unsigned int locbufsize;
54
55 void gras_emul_init(void)
56 {
57   if (!benchmark_set) {
58     benchmark_set = xbt_dict_new();
59     timer = xbt_os_timer_new();
60   }
61 }
62
63 void gras_emul_exit(void)
64 {
65   if (locbuf)
66     free(locbuf);
67   xbt_dict_free(&benchmark_set);
68   xbt_os_timer_free(timer);
69 }
70
71
72 static void store_in_dict(xbt_dict_t dict, const char *key, double value)
73 {
74   double *ir;
75
76   ir = xbt_dict_get_or_null(dict, key);
77   if (!ir) {
78     ir = xbt_new0(double, 1);
79     xbt_dict_set(dict, key, ir, xbt_free_f);
80   }
81   *ir = value;
82 }
83
84 static double get_from_dict(xbt_dict_t dict, const char *key)
85 {
86   double *ir = xbt_dict_get(dict, key);
87
88   return *ir;
89 }
90
91 int gras_bench_always_begin(const char *location, int line)
92 {
93   xbt_assert0(!benchmarking, "Already benchmarking");
94   benchmarking = 1;
95
96   if (!timer)
97     xbt_os_timer_start(timer);
98   return 0;
99 }
100
101 int gras_bench_always_end(void) {
102   xbt_assert0(benchmarking, "Not benchmarking yet");
103   benchmarking = 0;
104   xbt_os_timer_stop(timer);
105   duration = xbt_os_timer_elapsed(timer);
106
107   gras_cpu_burn(duration/reference);
108
109   return 0;
110 }
111
112 int gras_bench_once_begin(const char *location, int line)
113 {
114   double *ir = NULL;
115   xbt_assert0(!benchmarking, "Already benchmarking");
116   benchmarking = 1;
117
118   if (!locbuf || locbufsize < strlen(location) + 64) {
119     locbufsize = strlen(location) + 64;
120     locbuf = xbt_realloc(locbuf, locbufsize);
121   }
122   sprintf(locbuf, "%s:%d", location, line);
123
124   ir = xbt_dict_get_or_null(benchmark_set, locbuf);
125   if (!ir) {
126     DEBUG1("%s", locbuf);
127     duration = 1;
128     xbt_os_timer_start(timer);
129     return 1;
130   } else {
131     duration = -1.0;
132     return 0;
133   }
134 }
135
136 int gras_bench_once_end(void) {
137   xbt_assert0(benchmarking, "Not benchmarking yet");
138   benchmarking = 0;
139   if (duration > 0) {
140     xbt_os_timer_stop(timer);
141     duration = xbt_os_timer_elapsed(timer);
142     store_in_dict(benchmark_set, locbuf, duration);
143   } else {
144     duration = get_from_dict(benchmark_set, locbuf);
145   }
146   DEBUG2("Simulate the run of a task of %f sec for %s", duration, locbuf);
147   gras_cpu_burn(duration/reference);
148   return 0;
149 }
150
151
152 /*** Conditional execution support ***/
153
154 int gras_if_RL(void)
155 {
156   return 0;
157 }
158
159 int gras_if_SG(void)
160 {
161   return 1;
162 }