Logo AND Algorithmique Numérique Distribuée

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