Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
a657e1b4fca99bb05361855305dedfb9b0a30672
[simgrid.git] / src / simix / smx_io.c
1 /* Copyright (c) 2007-2010, 2012-2013. 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 /**
19  * \brief Internal function to create a SIMIX storage.
20  * \param name name of the storage to create
21  * \param storage the SURF storage to encapsulate
22  * \param data some user data (may be NULL)
23  */
24 smx_storage_t SIMIX_storage_create(const char *name, void *storage, void *data)
25 {
26   smx_storage_priv_t smx_storage = xbt_new0(s_smx_storage_priv_t, 1);
27
28   smx_storage->data = data;
29
30   /* Update global variables */
31   xbt_lib_set(storage_lib,name,SIMIX_STORAGE_LEVEL,smx_storage);
32
33   return xbt_lib_get_or_null(storage_lib, name, SIMIX_STORAGE_LEVEL);
34 }
35
36
37 void* SIMIX_pre_file_get_data(smx_simcall_t simcall,smx_file_t fd){
38   return SIMIX_file_get_data(fd);
39 }
40
41 void* SIMIX_file_get_data(smx_file_t fd){
42   xbt_assert((fd != NULL), "Invalid parameters (simix file is NULL)");
43
44   return fd->data;
45 }
46
47 void SIMIX_pre_file_set_data(smx_simcall_t simcall, smx_file_t fd, void *data) {
48   SIMIX_file_set_data(fd, data);
49 }
50
51 void SIMIX_file_set_data(smx_file_t fd, void *data){
52   xbt_assert((fd != NULL), "Invalid parameter");
53
54   fd->data = data;
55 }
56
57 //SIMIX FILE READ
58 void SIMIX_pre_file_read(smx_simcall_t simcall, sg_storage_size_t size,
59                         smx_file_t fd)
60 {
61   smx_action_t action = SIMIX_file_read(simcall->issuer, size, fd);
62   xbt_fifo_push(action->simcalls, simcall);
63   simcall->issuer->waiting_action = action;
64 }
65
66 smx_action_t SIMIX_file_read(smx_process_t process, sg_storage_size_t size,
67                              smx_file_t fd)
68 {
69   smx_action_t action;
70   smx_host_t host = process->smx_host;
71
72   /* check if the host is active */
73   if (surf_workstation_model->extension.
74       workstation.get_state(host) != SURF_RESOURCE_ON) {
75     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
76            sg_host_name(host));
77   }
78
79   action = xbt_mallocator_get(simix_global->action_mallocator);
80   action->type = SIMIX_ACTION_IO;
81   action->name = NULL;
82 #ifdef HAVE_TRACING
83   action->category = NULL;
84 #endif
85
86   action->io.host = host;
87   action->io.surf_io =
88       surf_workstation_model->extension.workstation.read(host, size,
89                                                          fd->surf_file);
90
91   surf_workstation_model->action_data_set(action->io.surf_io, action);
92   XBT_DEBUG("Create io action %p", action);
93
94   return action;
95 }
96
97 //SIMIX FILE WRITE
98 void SIMIX_pre_file_write(smx_simcall_t simcall, sg_storage_size_t size,
99                           smx_file_t fd)
100 {
101   smx_action_t action = SIMIX_file_write(simcall->issuer, size, fd);
102   xbt_fifo_push(action->simcalls, simcall);
103   simcall->issuer->waiting_action = action;
104 }
105
106 smx_action_t SIMIX_file_write(smx_process_t process,
107                 sg_storage_size_t size, smx_file_t fd)
108 {
109   smx_action_t action;
110   smx_host_t host = process->smx_host;
111
112   /* check if the host is active */
113   if (surf_workstation_model->extension.
114       workstation.get_state(host) != SURF_RESOURCE_ON) {
115     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
116            sg_host_name(host));
117   }
118
119   action = xbt_mallocator_get(simix_global->action_mallocator);
120   action->type = SIMIX_ACTION_IO;
121   action->name = NULL;
122 #ifdef HAVE_TRACING
123   action->category = NULL;
124 #endif
125
126   action->io.host = host;
127   action->io.surf_io =
128       surf_workstation_model->extension.workstation.write(host, size,
129                                                           fd->surf_file);
130
131   surf_workstation_model->action_data_set(action->io.surf_io, action);
132   XBT_DEBUG("Create io action %p", action);
133
134   return action;
135 }
136
137 //SIMIX FILE OPEN
138 void SIMIX_pre_file_open(smx_simcall_t simcall, const char* mount,
139                          const char* path)
140 {
141   smx_action_t action = SIMIX_file_open(simcall->issuer, mount, path);
142   xbt_fifo_push(action->simcalls, simcall);
143   simcall->issuer->waiting_action = action;
144 }
145
146 smx_action_t SIMIX_file_open(smx_process_t process ,const char* mount,
147                              const char* path)
148 {
149   smx_action_t action;
150   smx_host_t host = process->smx_host;
151
152   /* check if the host is active */
153   if (surf_workstation_model->extension.
154       workstation.get_state(host) != SURF_RESOURCE_ON) {
155     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
156            sg_host_name(host));
157   }
158
159   action = xbt_mallocator_get(simix_global->action_mallocator);
160   action->type = SIMIX_ACTION_IO;
161   action->name = NULL;
162 #ifdef HAVE_TRACING
163   action->category = NULL;
164 #endif
165
166   action->io.host = host;
167   action->io.surf_io =
168       surf_workstation_model->extension.workstation.open(host, mount, path);
169
170   surf_workstation_model->action_data_set(action->io.surf_io, action);
171   XBT_DEBUG("Create io action %p", action);
172
173   return action;
174 }
175
176 //SIMIX FILE CLOSE
177 void SIMIX_pre_file_close(smx_simcall_t simcall, smx_file_t fd)
178 {
179   smx_action_t action = SIMIX_file_close(simcall->issuer, fd);
180   xbt_fifo_push(action->simcalls, simcall);
181   simcall->issuer->waiting_action = action;
182 }
183
184 smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fd)
185 {
186   smx_action_t action;
187   smx_host_t host = process->smx_host;
188
189   /* check if the host is active */
190   if (surf_workstation_model->extension.
191       workstation.get_state(host) != SURF_RESOURCE_ON) {
192     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
193            sg_host_name(host));
194   }
195
196   action = xbt_mallocator_get(simix_global->action_mallocator);
197   action->type = SIMIX_ACTION_IO;
198   action->name = NULL;
199 #ifdef HAVE_TRACING
200   action->category = NULL;
201 #endif
202
203   action->io.host = host;
204   action->io.surf_io = surf_workstation_model->extension.workstation.close(host, fd->surf_file);
205
206   surf_workstation_model->action_data_set(action->io.surf_io, action);
207   XBT_DEBUG("Create io action %p", action);
208
209   return action;
210 }
211
212
213 //SIMIX FILE UNLINK
214 int SIMIX_pre_file_unlink(smx_simcall_t simcall, smx_file_t fd)
215 {
216   return SIMIX_file_unlink(simcall->issuer, fd);
217 }
218
219 int SIMIX_file_unlink(smx_process_t process, smx_file_t fd)
220 {
221   smx_host_t host = process->smx_host;
222   /* check if the host is active */
223   if (surf_workstation_model->extension.
224       workstation.get_state(host) != SURF_RESOURCE_ON) {
225     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
226            sg_host_name(host));
227   }
228
229   if (surf_workstation_model->extension.workstation.unlink(host, fd->surf_file)){
230     fd->surf_file = NULL;
231     return 1;
232   } else
233     return 0;
234 }
235
236 //SIMIX FILE LS
237 void SIMIX_pre_file_ls(smx_simcall_t simcall,
238                        const char* mount, const char* path)
239 {
240   smx_action_t action = SIMIX_file_ls(simcall->issuer, mount, path);
241   xbt_fifo_push(action->simcalls, simcall);
242   simcall->issuer->waiting_action = action;
243 }
244 smx_action_t SIMIX_file_ls(smx_process_t process, const char* mount, const char *path)
245 {
246   smx_action_t action;
247   smx_host_t host = process->smx_host;
248   /* check if the host is active */
249   if (surf_workstation_model->extension.workstation.get_state(host) != SURF_RESOURCE_ON) {
250     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
251            sg_host_name(host));
252   }
253
254   action = xbt_mallocator_get(simix_global->action_mallocator);
255   action->type = SIMIX_ACTION_IO;
256   action->name = NULL;
257 #ifdef HAVE_TRACING
258   action->category = NULL;
259 #endif
260
261   action->io.host = host;
262   action->io.surf_io = surf_workstation_model->extension.workstation.ls(host,mount,path);
263
264   surf_workstation_model->action_data_set(action->io.surf_io, action);
265   XBT_DEBUG("Create io action %p", action);
266   return action;
267 }
268
269 sg_storage_size_t SIMIX_pre_file_get_size(smx_simcall_t simcall, smx_file_t fd)
270 {
271   return SIMIX_file_get_size(simcall->issuer, fd);
272 }
273
274 sg_storage_size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
275 {
276   smx_host_t host = process->smx_host;
277   return  surf_workstation_model->extension.workstation.get_size(host,
278       fd->surf_file);
279 }
280
281 xbt_dynar_t SIMIX_pre_file_get_info(smx_simcall_t simcall, smx_file_t fd)
282 {
283   return SIMIX_file_get_info(simcall->issuer, fd);
284 }
285
286 xbt_dynar_t SIMIX_file_get_info(smx_process_t process, smx_file_t fd)
287 {
288   smx_host_t host = process->smx_host;
289   return  surf_workstation_model->extension.workstation.get_info(host,
290       fd->surf_file);
291 }
292
293 sg_storage_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall, const char* name)
294 {
295   return SIMIX_storage_get_free_size(simcall->issuer, name);
296 }
297
298 sg_storage_size_t SIMIX_storage_get_free_size(smx_process_t process, const char* name)
299 {
300   smx_host_t host = process->smx_host;
301   return  surf_workstation_model->extension.workstation.get_free_size(host,name);
302 }
303
304 sg_storage_size_t SIMIX_pre_storage_get_used_size(smx_simcall_t simcall, const char* name)
305 {
306   return SIMIX_storage_get_used_size(simcall->issuer, name);
307 }
308
309 sg_storage_size_t SIMIX_storage_get_used_size(smx_process_t process, const char* name)
310 {
311   smx_host_t host = process->smx_host;
312   return  surf_workstation_model->extension.workstation.get_used_size(host,name);
313 }
314
315 xbt_dict_t SIMIX_pre_storage_get_properties(smx_simcall_t simcall, smx_storage_t storage){
316   return SIMIX_storage_get_properties(storage);
317 }
318 xbt_dict_t SIMIX_storage_get_properties(smx_storage_t storage){
319   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
320   return surf_storage_model->extension.storage.get_properties(storage);
321 }
322
323 const char* SIMIX_pre_storage_get_name(smx_simcall_t simcall, smx_storage_t storage){
324    return SIMIX_storage_get_name(storage);
325 }
326
327 const char* SIMIX_storage_get_name(smx_storage_t storage){
328   xbt_assert((storage != NULL), "Invalid parameters");
329   return sg_storage_name(storage);
330 }
331
332 void SIMIX_pre_storage_set_data(smx_simcall_t simcall, smx_storage_t storage, void *data) {
333   SIMIX_storage_set_data(storage, data);
334 }
335 void SIMIX_storage_set_data(smx_storage_t storage, void *data){
336   xbt_assert((storage != NULL), "Invalid parameters");
337   xbt_assert((SIMIX_storage_priv(storage)->data == NULL), "Data already set");
338
339   SIMIX_storage_priv(storage)->data = data;
340 }
341
342 void* SIMIX_pre_storage_get_data(smx_simcall_t simcall,smx_storage_t storage){
343   return SIMIX_storage_get_data(storage);
344 }
345
346 void* SIMIX_storage_get_data(smx_storage_t storage){
347   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
348
349   return SIMIX_storage_priv(storage)->data;
350 }
351
352 xbt_dict_t SIMIX_pre_storage_get_content(smx_simcall_t simcall, smx_storage_t storage){
353   return SIMIX_storage_get_content(storage);
354 }
355
356 xbt_dict_t SIMIX_storage_get_content(smx_storage_t storage){
357   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
358   return surf_storage_model->extension.storage.get_content(storage);
359 }
360
361 void SIMIX_post_io(smx_action_t action)
362 {
363   xbt_fifo_item_t i;
364   smx_simcall_t simcall;
365 //  char* key;
366 //  xbt_dict_cursor_t cursor = NULL;
367 //  s_file_stat_t *dst = NULL;
368 //  s_file_stat_t *src = NULL;
369
370   xbt_fifo_foreach(action->simcalls,i,simcall,smx_simcall_t) {
371     switch (simcall->call) {
372     case SIMCALL_FILE_OPEN:;
373       smx_file_t tmp = xbt_new(s_smx_file_t,1);
374       tmp->surf_file = (action->io.surf_io)->file;
375       simcall_file_open__set__result(simcall, tmp);
376       break;
377
378     case SIMCALL_FILE_CLOSE:
379       xbt_free(simcall_file_close__get__fd(simcall));
380       simcall_file_close__set__result(simcall, 0);
381       break;
382
383     case SIMCALL_FILE_WRITE:
384       simcall_file_write__set__result(simcall, (action->io.surf_io)->cost);
385       break;
386
387     case SIMCALL_FILE_READ:
388       simcall_file_read__set__result(simcall, (action->io.surf_io)->cost);
389       break;
390
391     case SIMCALL_FILE_LS:
392 //      xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){
393 //        // if there is a stat we have to duplicate it
394 //        if(src){
395 //          dst = xbt_new0(s_file_stat_t,1);
396 //          file_stat_copy(src, dst);
397 //          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,xbt_free);
398 //        }
399 //      }
400       simcall_file_ls__set__result(simcall, (action->io.surf_io)->ls_dict);
401       break;
402     default:
403       break;
404     }
405   }
406
407   switch (surf_workstation_model->action_state_get(action->io.surf_io)) {
408
409     case SURF_ACTION_FAILED:
410       action->state = SIMIX_FAILED;
411       break;
412
413     case SURF_ACTION_DONE:
414       action->state = SIMIX_DONE;
415       break;
416
417     default:
418       THROW_IMPOSSIBLE;
419       break;
420   }
421
422   SIMIX_io_finish(action);
423 }
424
425 void SIMIX_io_destroy(smx_action_t action)
426 {
427   XBT_DEBUG("Destroy action %p", action);
428   if (action->io.surf_io)
429     action->io.surf_io->model_type->action_unref(action->io.surf_io);
430   xbt_mallocator_release(simix_global->action_mallocator, action);
431 }
432
433 void SIMIX_io_finish(smx_action_t action)
434 {
435   xbt_fifo_item_t item;
436   smx_simcall_t simcall;
437
438   xbt_fifo_foreach(action->simcalls, item, simcall, smx_simcall_t) {
439
440     switch (action->state) {
441
442       case SIMIX_DONE:
443         /* do nothing, action done */
444         break;
445
446       case SIMIX_FAILED:
447         SMX_EXCEPTION(simcall->issuer, io_error, 0, "IO failed");
448         break;
449
450       case SIMIX_CANCELED:
451         SMX_EXCEPTION(simcall->issuer, cancel_error, 0, "Canceled");
452         break;
453
454       default:
455         xbt_die("Internal error in SIMIX_io_finish: unexpected action state %d",
456             (int)action->state);
457     }
458
459     if (surf_workstation_model->extension.
460         workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
461       simcall->issuer->context->iwannadie = 1;
462     }
463
464     simcall->issuer->waiting_action = NULL;
465     SIMIX_simcall_answer(simcall);
466   }
467
468   /* We no longer need it */
469   SIMIX_io_destroy(action);
470 }