Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add some peer traces.
[simgrid.git] / examples / gras / replay / xbt_workload.c
1 /* Copyright (c) 2009, 2010. 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 /* This datatype stores a a trace as produced by examples/simdag/dax, or other means
8  * It can be replayed in simulation with examples/msg/actions or on a real platform with
9  * examples/gras/replay.
10  */
11
12 #include "xbt/log.h"
13 #include "xbt/sysdep.h"
14 #include "xbt/str.h"
15 #include "workload.h"
16 #include "gras/datadesc.h"
17
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_workload, xbt,
19                                 "Workload characterisation mecanisms");
20
21
22 xbt_workload_elm_t xbt_workload_elm_parse(char *line)
23 {
24   xbt_workload_elm_t res = xbt_new(s_xbt_workload_elm_t, 1);
25   res->date = -1;
26   res->comment = NULL;          /* it's not enough to memset for valgrind, apparently */
27   res->who = NULL;
28   res->str_arg = NULL;
29
30   xbt_dynar_t w = xbt_str_split(line, " ");
31
32   if (xbt_dynar_length(w) == 0) {
33     free(res);
34     xbt_dynar_free(&w);
35     return NULL;
36   }
37
38   char **words = xbt_dynar_get_ptr(w, 0);
39   int i = 0;
40   if (words[i][0] == '[') {
41     sscanf(words[i] + 1, "%lg", &(res->date));
42     i++;
43   }
44   res->who = xbt_strdup(words[i++]);
45   if (!strcmp(words[i], "recv")) {
46     res->action = XBT_WORKLOAD_RECV;
47     res->str_arg = xbt_strdup(words[++i]);
48     sscanf(words[++i], "%lg", &(res->d_arg));
49
50   } else if (!strcmp(words[i], "send")) {
51     res->action = XBT_WORKLOAD_SEND;
52     res->str_arg = xbt_strdup(words[++i]);
53     sscanf(words[++i], "%lg", &(res->d_arg));
54
55   } else if (!strcmp(words[i], "compute")) {
56     res->action = XBT_WORKLOAD_COMPUTE;
57     sscanf(words[++i], "%lg", &(res->d_arg));
58   } else {
59     xbt_die("Unparsable command: %s (in %s)", words[i], line);
60   }
61   i++;
62   if (words[i] && words[i][0] == '#') {
63     res->comment = xbt_strdup(strchr(line, '#') + 1);
64   }
65
66   xbt_dynar_free(&w);
67   return res;
68 }
69
70 void xbt_workload_elm_free(xbt_workload_elm_t cmd)
71 {
72   if (!cmd)
73     return;
74   if (cmd->who)
75     free(cmd->who);
76   if (cmd->comment)
77     free(cmd->comment);
78   if (cmd->str_arg)
79     free(cmd->str_arg);
80   free(cmd);
81 }
82
83 void xbt_workload_elm_free_voidp(void *cmd)
84 {
85   xbt_workload_elm_free(*(xbt_workload_elm_t *) cmd);
86 }
87
88 char *xbt_workload_elm_to_string(xbt_workload_elm_t cmd)
89 {
90   char res[2048];
91   char *addon;
92   res[0] = '\0';
93   if (cmd == NULL)
94     return xbt_strdup("(null command)");
95   if (cmd->date != -1) {
96     addon = bprintf("[%f] ", cmd->date);
97     strcat(res, addon);
98     free(addon);
99   }
100   addon = bprintf("'%s' ", cmd->who);
101   strcat(res, addon);
102   free(addon);
103
104   switch (cmd->action) {
105   case XBT_WORKLOAD_COMPUTE:
106     addon = bprintf("computed %f flops", cmd->d_arg);
107     strcat(res, addon);
108     free(addon);
109     break;
110   case XBT_WORKLOAD_SEND:
111     addon = bprintf("sent %f bytes to '%s'", cmd->d_arg, cmd->str_arg);
112     strcat(res, addon);
113     free(addon);
114     break;
115   case XBT_WORKLOAD_RECV:
116     addon =
117         bprintf("received %f bytes from '%s'", cmd->d_arg, cmd->str_arg);
118     strcat(res, addon);
119     free(addon);
120     break;
121   default:
122     xbt_die("Unknown command %d in '%s...'", cmd->action, res);
123   }
124   if (cmd->comment) {
125     addon = bprintf(" (comment: %s)", cmd->comment);
126     strcat(res, addon);
127     free(addon);
128   }
129   return xbt_strdup(res);
130 }
131
132 int xbt_workload_elm_cmp_who_date(const void *_c1, const void *_c2)
133 {
134   xbt_workload_elm_t c1 = *(xbt_workload_elm_t *) _c1;
135   xbt_workload_elm_t c2 = *(xbt_workload_elm_t *) _c2;
136   if (!c1 || !c1->who)
137     return -1;
138   if (!c2 || !c2->who)
139     return 1;
140   int r = strcmp(c1->who, c2->who);
141   if (r)
142     return r;
143   if (c1->date == c2->date)
144     return 0;
145   if (c1->date < c2->date)
146     return -1;
147   return 1;
148 }
149
150 void xbt_workload_sort_who_date(xbt_dynar_t c)
151 {
152   qsort(xbt_dynar_get_ptr(c, 0), xbt_dynar_length(c),
153         sizeof(xbt_workload_elm_t), xbt_workload_elm_cmp_who_date);
154 }
155
156 xbt_dynar_t xbt_workload_parse_file(char *filename)
157 {
158   FILE *file_in;
159   file_in = fopen(filename, "r");
160   xbt_assert(file_in, "cannot open tracefile '%s'", filename);
161   char *str_in = xbt_str_from_file(file_in);
162   fclose(file_in);
163   xbt_dynar_t in = xbt_str_split(str_in, "\n");
164   free(str_in);
165   xbt_dynar_t cmds =
166       xbt_dynar_new(sizeof(xbt_workload_elm_t),
167                     xbt_workload_elm_free_voidp);
168
169   unsigned int cursor;
170   char *line;
171   xbt_dynar_foreach(in, cursor, line) {
172     xbt_workload_elm_t cmd = xbt_workload_elm_parse(line);
173     if (cmd)
174       xbt_dynar_push(cmds, &cmd);
175   }
176   xbt_dynar_shrink(cmds, 0);
177   xbt_dynar_free(&in);
178   return cmds;
179 }
180
181
182 void xbt_workload_declare_datadesc(void)
183 {
184   gras_datadesc_type_t ddt;
185
186   ddt = gras_datadesc_struct("s_xbt_workload_elm_t");
187   gras_datadesc_struct_append(ddt, "who", gras_datadesc_by_name("string"));
188   gras_datadesc_struct_append(ddt, "comment",
189                               gras_datadesc_by_name("string"));
190   gras_datadesc_struct_append(ddt, "action", gras_datadesc_by_name("int"));
191   gras_datadesc_struct_append(ddt, "date",
192                               gras_datadesc_by_name("double"));
193   gras_datadesc_struct_append(ddt, "d_arg",
194                               gras_datadesc_by_name("double"));
195   gras_datadesc_struct_append(ddt, "str_arg",
196                               gras_datadesc_by_name("string"));
197   gras_datadesc_struct_close(ddt);
198
199   gras_datadesc_ref("xbt_workload_elm_t", ddt);
200
201   ddt = gras_datadesc_struct("s_xbt_workload_data_chunk_t");
202   gras_datadesc_struct_append(ddt, "size", gras_datadesc_by_name("int"));
203   gras_datadesc_cb_field_push(ddt, "size");
204   gras_datadesc_struct_append(ddt, "chunk",
205                               gras_datadesc_ref_pop_arr
206                               (gras_datadesc_by_name("char")));
207   gras_datadesc_struct_close(ddt);
208
209   gras_datadesc_ref("xbt_workload_data_chunk_t", ddt);
210 }
211
212
213
214 xbt_workload_data_chunk_t xbt_workload_data_chunk_new(int size)
215 {
216   xbt_workload_data_chunk_t res = xbt_new0(s_xbt_workload_data_chunk_t, 1);
217   res->size = size - sizeof(res) - sizeof(int);
218   res->chunk = xbt_new(char, res->size);
219   return res;
220 }
221
222 void xbt_workload_data_chunk_free(xbt_workload_data_chunk_t c)
223 {
224   free(c->chunk);
225   free(c);
226 }