Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
setting result help to propogate it
[simgrid.git] / src / simix / smx_io.c
1 /* Copyright (c) 2007, 2008, 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 #include "smx_private.h"
8 #include "surf/storage_private.h"
9 #include "xbt/sysdep.h"
10 #include "xbt/log.h"
11 #include "xbt/dict.h"
12 #include "mc/mc.h"
13
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_io, simix,
15                                 "Logging specific to SIMIX (io)");
16
17
18 //SIMIX FILE READ
19 void SIMIX_pre_file_read(smx_simcall_t simcall, void *ptr, size_t size,
20                          size_t nmemb, smx_file_t stream)
21 {
22   smx_action_t action = SIMIX_file_read(simcall->issuer, ptr, size, nmemb, stream);
23   xbt_fifo_push(action->simcalls, simcall);
24   simcall->issuer->waiting_action = action;
25 }
26
27 smx_action_t SIMIX_file_read(smx_process_t process, void* ptr, size_t size, size_t nmemb, smx_file_t stream)
28 {
29   smx_action_t action;
30   smx_host_t host = process->smx_host;
31
32   /* check if the host is active */
33   if (surf_workstation_model->extension.
34       workstation.get_state(host) != SURF_RESOURCE_ON) {
35     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
36            sg_host_name(host));
37   }
38
39   action = xbt_mallocator_get(simix_global->action_mallocator);
40   action->type = SIMIX_ACTION_IO;
41   action->name = NULL;
42 #ifdef HAVE_TRACING
43   action->category = NULL;
44 #endif
45
46   action->io.host = host;
47   action->io.surf_io = surf_workstation_model->extension.workstation.read(host, ptr, size, nmemb, stream->surf_file);
48
49   surf_workstation_model->action_data_set(action->io.surf_io, action);
50   XBT_DEBUG("Create io action %p", action);
51
52   return action;
53 }
54
55 //SIMIX FILE WRITE
56 void SIMIX_pre_file_write(smx_simcall_t simcall, const void *ptr, size_t size,
57                           size_t nmemb, smx_file_t stream)
58 {
59   smx_action_t action = SIMIX_file_write(simcall->issuer, ptr, size, nmemb, stream);
60   xbt_fifo_push(action->simcalls, simcall);
61   simcall->issuer->waiting_action = action;
62 }
63
64 smx_action_t SIMIX_file_write(smx_process_t process, const void* ptr, size_t size, size_t nmemb, smx_file_t stream)
65 {
66   smx_action_t action;
67   smx_host_t host = process->smx_host;
68
69   /* check if the host is active */
70   if (surf_workstation_model->extension.
71       workstation.get_state(host) != SURF_RESOURCE_ON) {
72     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
73            sg_host_name(host));
74   }
75
76   action = xbt_mallocator_get(simix_global->action_mallocator);
77   action->type = SIMIX_ACTION_IO;
78   action->name = NULL;
79 #ifdef HAVE_TRACING
80   action->category = NULL;
81 #endif
82
83   action->io.host = host;
84   action->io.surf_io = surf_workstation_model->extension.workstation.write(host, ptr, size, nmemb, stream->surf_file);
85
86   surf_workstation_model->action_data_set(action->io.surf_io, action);
87   XBT_DEBUG("Create io action %p", action);
88
89   return action;
90 }
91
92 //SIMIX FILE OPEN
93 void SIMIX_pre_file_open(smx_simcall_t simcall, const char* mount,
94                          const char* path, const char* mode)
95 {
96   smx_action_t action = SIMIX_file_open(simcall->issuer, mount, path, mode);
97   xbt_fifo_push(action->simcalls, simcall);
98   simcall->issuer->waiting_action = action;
99 }
100
101 smx_action_t SIMIX_file_open(smx_process_t process ,const char* mount, const char* path, const char* mode)
102 {
103   smx_action_t action;
104   smx_host_t host = process->smx_host;
105
106   /* check if the host is active */
107   if (surf_workstation_model->extension.
108       workstation.get_state(host) != SURF_RESOURCE_ON) {
109     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
110            sg_host_name(host));
111   }
112
113   action = xbt_mallocator_get(simix_global->action_mallocator);
114   action->type = SIMIX_ACTION_IO;
115   action->name = NULL;
116 #ifdef HAVE_TRACING
117   action->category = NULL;
118 #endif
119
120   action->io.host = host;
121   action->io.surf_io = surf_workstation_model->extension.workstation.open(host, mount, path, mode);
122
123   surf_workstation_model->action_data_set(action->io.surf_io, action);
124   XBT_DEBUG("Create io action %p", action);
125
126   return action;
127 }
128
129 //SIMIX FILE CLOSE
130 void SIMIX_pre_file_close(smx_simcall_t simcall, smx_file_t fd)
131 {
132   smx_action_t action = SIMIX_file_close(simcall->issuer, fd);
133   xbt_fifo_push(action->simcalls, simcall);
134   simcall->issuer->waiting_action = action;
135 }
136
137 smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fd)
138 {
139   smx_action_t action;
140   smx_host_t host = process->smx_host;
141
142   /* check if the host is active */
143   if (surf_workstation_model->extension.
144       workstation.get_state(host) != SURF_RESOURCE_ON) {
145     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
146            sg_host_name(host));
147   }
148
149   action = xbt_mallocator_get(simix_global->action_mallocator);
150   action->type = SIMIX_ACTION_IO;
151   action->name = NULL;
152 #ifdef HAVE_TRACING
153   action->category = NULL;
154 #endif
155
156   action->io.host = host;
157   action->io.surf_io = surf_workstation_model->extension.workstation.close(host, fd->surf_file);
158
159   surf_workstation_model->action_data_set(action->io.surf_io, action);
160   XBT_DEBUG("Create io action %p", action);
161
162   return action;
163 }
164
165
166 //SIMIX FILE UNLINK
167 void SIMIX_pre_file_unlink(smx_simcall_t simcall, smx_file_t fd)
168 {
169   smx_action_t action = SIMIX_file_unlink(simcall->issuer, fd);
170   xbt_fifo_push(action->simcalls, simcall);
171   simcall->issuer->waiting_action = action;
172 }
173
174 smx_action_t SIMIX_file_unlink(smx_process_t process, smx_file_t fd)
175 {
176   smx_action_t action;
177   smx_host_t host = process->smx_host;
178   /* check if the host is active */
179   if (surf_workstation_model->extension.
180       workstation.get_state(host) != SURF_RESOURCE_ON) {
181     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
182            sg_host_name(host));
183   }
184
185   action = xbt_mallocator_get(simix_global->action_mallocator);
186   action->type = SIMIX_ACTION_IO;
187   action->name = NULL;
188 #ifdef HAVE_TRACING
189   action->category = NULL;
190 #endif
191
192   action->io.host = host;
193   action->io.surf_io = surf_workstation_model->extension.workstation.unlink(host, fd->surf_file);
194
195   surf_workstation_model->action_data_set(action->io.surf_io, action);
196   XBT_DEBUG("Create io action %p", action);
197
198   return action;
199 }
200
201 //SIMIX FILE LS
202 void SIMIX_pre_file_ls(smx_simcall_t simcall,
203                        const char* mount, const char* path)
204 {
205   smx_action_t action = SIMIX_file_ls(simcall->issuer, mount, path);
206   xbt_fifo_push(action->simcalls, simcall);
207   simcall->issuer->waiting_action = action;
208 }
209 smx_action_t SIMIX_file_ls(smx_process_t process, const char* mount, const char *path)
210 {
211   smx_action_t action;
212   smx_host_t host = process->smx_host;
213   /* check if the host is active */
214   if (surf_workstation_model->extension.workstation.get_state(host) != SURF_RESOURCE_ON) {
215     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
216            sg_host_name(host));
217   }
218
219   action = xbt_mallocator_get(simix_global->action_mallocator);
220   action->type = SIMIX_ACTION_IO;
221   action->name = NULL;
222 #ifdef HAVE_TRACING
223   action->category = NULL;
224 #endif
225
226   action->io.host = host;
227   action->io.surf_io = surf_workstation_model->extension.workstation.ls(host,mount,path);
228
229   surf_workstation_model->action_data_set(action->io.surf_io, action);
230   XBT_DEBUG("Create io action %p", action);
231   return action;
232 }
233
234 void SIMIX_pre_file_get_size(smx_simcall_t simcall, smx_file_t fd)
235 {
236   smx_action_t action = SIMIX_file_get_size(simcall->issuer, fd);
237   xbt_fifo_push(action->simcalls, simcall);
238   simcall->issuer->waiting_action = action;
239 }
240
241 smx_action_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
242 {
243   smx_action_t action;
244   smx_host_t host = process->smx_host;
245
246   /* check if the host is active */
247   if (surf_workstation_model->extension.
248       workstation.get_state(host) != SURF_RESOURCE_ON) {
249     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
250            sg_host_name(host));
251   }
252
253   action = xbt_mallocator_get(simix_global->action_mallocator);
254   action->type = SIMIX_ACTION_IO;
255   action->name = NULL;
256 #ifdef HAVE_TRACING
257   action->category = NULL;
258 #endif
259
260   action->io.host = host;
261   action->io.surf_io = surf_workstation_model->extension.workstation.get_size(host, fd->surf_file);
262
263   surf_workstation_model->action_data_set(action->io.surf_io, action);
264   XBT_DEBUG("Create io action %p", action);
265
266   return action;
267 }
268
269
270 void SIMIX_post_io(smx_action_t action)
271 {
272   xbt_fifo_item_t i;
273   smx_simcall_t simcall;
274 //  char* key;
275 //  xbt_dict_cursor_t cursor = NULL;
276 //  s_file_stat_t *dst = NULL;
277 //  s_file_stat_t *src = NULL;
278
279   xbt_fifo_foreach(action->simcalls,i,simcall,smx_simcall_t) {
280     switch (simcall->call) {
281     case SIMCALL_FILE_OPEN:;
282       smx_file_t tmp = xbt_new(s_smx_file_t,1);
283       tmp->surf_file = (action->io.surf_io)->file;
284       simcall_file_open__set__result(simcall, tmp);
285       break;
286
287     case SIMCALL_FILE_CLOSE:
288       xbt_free(simcall_file_close__get__fd(simcall));
289       simcall_file_close__set__result(simcall, 0);
290       break;
291
292     case SIMCALL_FILE_WRITE:
293       simcall_file_write__set__result(simcall, (action->io.surf_io)->cost);
294       break;
295
296     case SIMCALL_FILE_READ:
297       simcall_file_read__set__result(simcall, (action->io.surf_io)->cost);
298       break;
299
300     case SIMCALL_FILE_UNLINK:
301       xbt_free(simcall_file_unlink__get__fd(simcall));
302       simcall_file_unlink__set__result(simcall, 0);
303       break;
304
305     case SIMCALL_FILE_LS:
306 //      xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){
307 //        // if there is a stat we have to duplicate it
308 //        if(src){
309 //          dst = xbt_new0(s_file_stat_t,1);
310 //          file_stat_copy(src, dst);
311 //          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,xbt_free);
312 //        }
313 //      }
314       simcall_file_ls__set__result(simcall, (action->io.surf_io)->ls_dict);
315       break;
316     case SIMCALL_FILE_GET_SIZE:
317       simcall_file_get_size__set__result(simcall,
318           ((action->io.surf_io)->file->size));
319       break;
320
321     default:
322       break;
323     }
324   }
325
326   switch (surf_workstation_model->action_state_get(action->io.surf_io)) {
327
328     case SURF_ACTION_FAILED:
329       action->state = SIMIX_FAILED;
330       break;
331
332     case SURF_ACTION_DONE:
333       action->state = SIMIX_DONE;
334       break;
335
336     default:
337       THROW_IMPOSSIBLE;
338       break;
339   }
340
341   SIMIX_io_finish(action);
342 }
343
344 void SIMIX_io_destroy(smx_action_t action)
345 {
346   XBT_DEBUG("Destroy action %p", action);
347   if (action->io.surf_io)
348     action->io.surf_io->model_type->action_unref(action->io.surf_io);
349   xbt_mallocator_release(simix_global->action_mallocator, action);
350 }
351
352 void SIMIX_io_finish(smx_action_t action)
353 {
354   xbt_fifo_item_t item;
355   smx_simcall_t simcall;
356
357   xbt_fifo_foreach(action->simcalls, item, simcall, smx_simcall_t) {
358
359     switch (action->state) {
360
361       case SIMIX_DONE:
362         /* do nothing, action done */
363         break;
364
365       case SIMIX_FAILED:
366         SMX_EXCEPTION(simcall->issuer, io_error, 0, "IO failed");
367         break;
368
369       case SIMIX_CANCELED:
370         SMX_EXCEPTION(simcall->issuer, cancel_error, 0, "Canceled");
371         break;
372
373       default:
374         xbt_die("Internal error in SIMIX_io_finish: unexpected action state %d",
375             (int)action->state);
376     }
377
378     if (surf_workstation_model->extension.
379         workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
380       simcall->issuer->context->iwannadie = 1;
381     }
382
383     simcall->issuer->waiting_action = NULL;
384     SIMIX_simcall_answer(simcall);
385   }
386
387   /* We no longer need it */
388   SIMIX_io_destroy(action);
389 }