Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Allow users to attach arbitrary data to opened files
[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 void SIMIX_post_io(smx_action_t action)
297 {
298   xbt_fifo_item_t i;
299   smx_simcall_t simcall;
300 //  char* key;
301 //  xbt_dict_cursor_t cursor = NULL;
302 //  s_file_stat_t *dst = NULL;
303 //  s_file_stat_t *src = NULL;
304
305   xbt_fifo_foreach(action->simcalls,i,simcall,smx_simcall_t) {
306     switch (simcall->call) {
307     case SIMCALL_FILE_OPEN:;
308       smx_file_t tmp = xbt_new(s_smx_file_t,1);
309       tmp->surf_file = (action->io.surf_io)->file;
310       simcall_file_open__set__result(simcall, tmp);
311       break;
312
313     case SIMCALL_FILE_CLOSE:
314       xbt_free(simcall_file_close__get__fd(simcall));
315       simcall_file_close__set__result(simcall, 0);
316       break;
317
318     case SIMCALL_FILE_WRITE:
319       simcall_file_write__set__result(simcall, (action->io.surf_io)->cost);
320       break;
321
322     case SIMCALL_FILE_READ:
323       simcall_file_read__set__result(simcall, (action->io.surf_io)->cost);
324       break;
325
326     case SIMCALL_FILE_LS:
327 //      xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){
328 //        // if there is a stat we have to duplicate it
329 //        if(src){
330 //          dst = xbt_new0(s_file_stat_t,1);
331 //          file_stat_copy(src, dst);
332 //          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,xbt_free);
333 //        }
334 //      }
335       simcall_file_ls__set__result(simcall, (action->io.surf_io)->ls_dict);
336       break;
337     default:
338       break;
339     }
340   }
341
342   switch (surf_workstation_model->action_state_get(action->io.surf_io)) {
343
344     case SURF_ACTION_FAILED:
345       action->state = SIMIX_FAILED;
346       break;
347
348     case SURF_ACTION_DONE:
349       action->state = SIMIX_DONE;
350       break;
351
352     default:
353       THROW_IMPOSSIBLE;
354       break;
355   }
356
357   SIMIX_io_finish(action);
358 }
359
360 void SIMIX_io_destroy(smx_action_t action)
361 {
362   XBT_DEBUG("Destroy action %p", action);
363   if (action->io.surf_io)
364     action->io.surf_io->model_type->action_unref(action->io.surf_io);
365   xbt_mallocator_release(simix_global->action_mallocator, action);
366 }
367
368 void SIMIX_io_finish(smx_action_t action)
369 {
370   xbt_fifo_item_t item;
371   smx_simcall_t simcall;
372
373   xbt_fifo_foreach(action->simcalls, item, simcall, smx_simcall_t) {
374
375     switch (action->state) {
376
377       case SIMIX_DONE:
378         /* do nothing, action done */
379         break;
380
381       case SIMIX_FAILED:
382         SMX_EXCEPTION(simcall->issuer, io_error, 0, "IO failed");
383         break;
384
385       case SIMIX_CANCELED:
386         SMX_EXCEPTION(simcall->issuer, cancel_error, 0, "Canceled");
387         break;
388
389       default:
390         xbt_die("Internal error in SIMIX_io_finish: unexpected action state %d",
391             (int)action->state);
392     }
393
394     if (surf_workstation_model->extension.
395         workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
396       simcall->issuer->context->iwannadie = 1;
397     }
398
399     simcall->issuer->waiting_action = NULL;
400     SIMIX_simcall_answer(simcall);
401   }
402
403   /* We no longer need it */
404   SIMIX_io_destroy(action);
405 }