Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
46a9e4bdb7607d174a8eaf038a3bd228abc99d72
[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, "Workload characterisation mecanisms");
19
20
21 xbt_workload_elm_t xbt_workload_elm_parse(char *line) {
22   xbt_workload_elm_t res = xbt_new(s_xbt_workload_elm_t,1);
23   res->date=-1;
24   res->comment=NULL; /* it's not enough to memset for valgrind, apparently */
25   res->who=NULL;
26   res->str_arg=NULL;
27
28   xbt_dynar_t w = xbt_str_split(line," ");
29
30   if (xbt_dynar_length(w) == 0) {
31     free(res);
32     xbt_dynar_free(&w);
33     return NULL;
34   }
35
36   char **words = xbt_dynar_get_ptr(w,0);
37   int i=0;
38   if (words[i][0] == '[') {
39     sscanf(words[i]+1,"%lg",&(res->date));
40     i++;
41   }
42   res->who = xbt_strdup(words[i++]);
43   if (!strcmp(words[i],"recv")) {
44     res->action = XBT_WORKLOAD_RECV;
45     res->str_arg = xbt_strdup(words[++i]);
46     sscanf(words[++i],"%lg",&(res->d_arg));
47
48   } else if (!strcmp(words[i],"send")) {
49     res->action = XBT_WORKLOAD_SEND;
50     res->str_arg = xbt_strdup(words[++i]);
51     sscanf(words[++i],"%lg",&(res->d_arg));
52
53   } else if (!strcmp(words[i],"compute")) {
54     res->action = XBT_WORKLOAD_COMPUTE;
55     sscanf(words[++i],"%lg",&(res->d_arg));
56   } else {
57     xbt_die(bprintf("Unparsable command: %s (in %s)",words[i],line));
58   }
59   i++;
60   if (words[i] && words[i][0] == '#') {
61     res->comment = xbt_strdup(strchr(line,'#')+1);
62   }
63
64   xbt_dynar_free(&w);
65   return res;
66 }
67 void xbt_workload_elm_free(xbt_workload_elm_t cmd) {
68   if (!cmd)
69     return;
70   if (cmd->who)
71     free(cmd->who);
72   if (cmd->comment)
73     free(cmd->comment);
74   if (cmd->str_arg)
75     free(cmd->str_arg);
76   free(cmd);
77 }
78 void xbt_workload_elm_free_voidp(void*cmd) {
79   xbt_workload_elm_free(*(xbt_workload_elm_t*)cmd);
80 }
81
82 char *xbt_workload_elm_to_string(xbt_workload_elm_t cmd) {
83   char res[2048];
84   char *addon;
85   res[0]='\0';
86   if (cmd==NULL)
87     return xbt_strdup("(null command)");
88   if (cmd->date != -1) {
89     addon=bprintf("[%f] ",cmd->date);
90     strcat(res,addon);
91     free(addon);
92   }
93   addon= bprintf("'%s' ",cmd->who);
94   strcat(res,addon);free(addon);
95
96   switch (cmd->action) {
97   case XBT_WORKLOAD_COMPUTE:
98     addon=bprintf("computed %f flops",cmd->d_arg);
99     strcat(res,addon);free(addon);
100     break;
101   case XBT_WORKLOAD_SEND:
102     addon=bprintf("sent %f bytes to '%s'",cmd->d_arg,cmd->str_arg);
103     strcat(res,addon);free(addon);
104     break;
105   case XBT_WORKLOAD_RECV:
106     addon=bprintf("received %f bytes from '%s'",cmd->d_arg,cmd->str_arg);
107     strcat(res,addon);free(addon);
108     break;
109   default:
110     xbt_die(bprintf("Unknown command %d in '%s...'",cmd->action,res));
111   }
112   if (cmd->comment) {
113     addon=bprintf(" (comment: %s)",cmd->comment);
114     strcat(res,addon);free(addon);
115   }
116   return xbt_strdup(res);
117 }
118
119 int xbt_workload_elm_cmp_who_date(const void* _c1, const void* _c2) {
120   xbt_workload_elm_t c1=*(xbt_workload_elm_t*)_c1;
121   xbt_workload_elm_t c2=*(xbt_workload_elm_t*)_c2;
122   if (!c1 || !c1->who)
123     return -1;
124   if (!c2 || !c2->who)
125     return 1;
126   int r = strcmp(c1->who,c2->who);
127   if (r)
128     return r;
129   if (c1->date == c2->date)
130     return 0;
131   if (c1->date < c2->date)
132     return -1;
133   return 1;
134 }
135 void xbt_workload_sort_who_date(xbt_dynar_t c) {
136   qsort(xbt_dynar_get_ptr(c,0),xbt_dynar_length(c),sizeof(xbt_workload_elm_t),xbt_workload_elm_cmp_who_date);
137 }
138 xbt_dynar_t xbt_workload_parse_file(char *filename) {
139   FILE *file_in;
140   file_in = fopen(filename,"r");
141   xbt_assert1(file_in, "cannot open tracefile '%s'",filename);
142   char *str_in = xbt_str_from_file(file_in);
143   fclose(file_in);
144   xbt_dynar_t in = xbt_str_split(str_in,"\n");
145   free(str_in);
146   xbt_dynar_t cmds=xbt_dynar_new(sizeof(xbt_workload_elm_t),xbt_workload_elm_free_voidp);
147
148   unsigned int cursor;
149   char *line;
150   xbt_dynar_foreach(in,cursor,line) {
151     xbt_workload_elm_t cmd = xbt_workload_elm_parse(line);
152     if (cmd)
153       xbt_dynar_push(cmds,&cmd);
154   }
155   xbt_dynar_shrink(cmds,0);
156   xbt_dynar_free(&in);
157   return cmds;
158 }
159
160
161 void xbt_workload_declare_datadesc(void) {
162   gras_datadesc_type_t ddt;
163
164   ddt = gras_datadesc_struct("s_xbt_workload_elm_t");
165   gras_datadesc_struct_append(ddt,"who",gras_datadesc_by_name("string"));
166   gras_datadesc_struct_append(ddt,"comment",gras_datadesc_by_name("string"));
167   gras_datadesc_struct_append(ddt,"action",gras_datadesc_by_name("int"));
168   gras_datadesc_struct_append(ddt,"date",gras_datadesc_by_name("double"));
169   gras_datadesc_struct_append(ddt,"d_arg",gras_datadesc_by_name("double"));
170   gras_datadesc_struct_append(ddt,"str_arg",gras_datadesc_by_name("string"));
171   gras_datadesc_struct_close(ddt);
172
173   gras_datadesc_ref("xbt_workload_elm_t",ddt);
174
175   ddt = gras_datadesc_struct("s_xbt_workload_data_chunk_t");
176   gras_datadesc_struct_append(ddt,"size",gras_datadesc_by_name("int"));
177   gras_datadesc_cb_field_push(ddt, "size");
178   gras_datadesc_struct_append(ddt,"chunk",gras_datadesc_ref_pop_arr(gras_datadesc_by_name("char")));
179   gras_datadesc_struct_close(ddt);
180
181   gras_datadesc_ref("xbt_workload_data_chunk_t",ddt);
182 }
183
184
185
186 xbt_workload_data_chunk_t xbt_workload_data_chunk_new(int size) {
187   xbt_workload_data_chunk_t res = xbt_new0(s_xbt_workload_data_chunk_t,1);
188   res->size = size-sizeof(res)-sizeof(int);
189   res->chunk = xbt_new(char,res->size);
190   return res;
191 }
192 void xbt_workload_data_chunk_free(xbt_workload_data_chunk_t c) {
193   free(c->chunk);
194   free(c);
195 }