Logo AND Algorithmique Numérique Distribuée

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