Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
5106fcf2489b9e1cd78f30d0e6bde0d38d6b8788
[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)
95 {
96   smx_action_t action = SIMIX_file_open(simcall->issuer, mount, path);
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,
102                              const char* path)
103 {
104   smx_action_t action;
105   smx_host_t host = process->smx_host;
106
107   /* check if the host is active */
108   if (surf_workstation_model->extension.
109       workstation.get_state(host) != SURF_RESOURCE_ON) {
110     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
111            sg_host_name(host));
112   }
113
114   action = xbt_mallocator_get(simix_global->action_mallocator);
115   action->type = SIMIX_ACTION_IO;
116   action->name = NULL;
117 #ifdef HAVE_TRACING
118   action->category = NULL;
119 #endif
120
121   action->io.host = host;
122   action->io.surf_io =
123       surf_workstation_model->extension.workstation.open(host, mount, path);
124
125   surf_workstation_model->action_data_set(action->io.surf_io, action);
126   XBT_DEBUG("Create io action %p", action);
127
128   return action;
129 }
130
131 //SIMIX FILE CLOSE
132 void SIMIX_pre_file_close(smx_simcall_t simcall, smx_file_t fd)
133 {
134   smx_action_t action = SIMIX_file_close(simcall->issuer, fd);
135   xbt_fifo_push(action->simcalls, simcall);
136   simcall->issuer->waiting_action = action;
137 }
138
139 smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fd)
140 {
141   smx_action_t action;
142   smx_host_t host = process->smx_host;
143
144   /* check if the host is active */
145   if (surf_workstation_model->extension.
146       workstation.get_state(host) != SURF_RESOURCE_ON) {
147     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
148            sg_host_name(host));
149   }
150
151   action = xbt_mallocator_get(simix_global->action_mallocator);
152   action->type = SIMIX_ACTION_IO;
153   action->name = NULL;
154 #ifdef HAVE_TRACING
155   action->category = NULL;
156 #endif
157
158   action->io.host = host;
159   action->io.surf_io = surf_workstation_model->extension.workstation.close(host, fd->surf_file);
160
161   surf_workstation_model->action_data_set(action->io.surf_io, action);
162   XBT_DEBUG("Create io action %p", action);
163
164   return action;
165 }
166
167
168 //SIMIX FILE UNLINK
169 void SIMIX_pre_file_unlink(smx_simcall_t simcall, smx_file_t fd)
170 {
171   smx_action_t action = SIMIX_file_unlink(simcall->issuer, fd);
172   xbt_fifo_push(action->simcalls, simcall);
173   simcall->issuer->waiting_action = action;
174 }
175
176 smx_action_t SIMIX_file_unlink(smx_process_t process, smx_file_t fd)
177 {
178   smx_action_t action;
179   smx_host_t host = process->smx_host;
180   /* check if the host is active */
181   if (surf_workstation_model->extension.
182       workstation.get_state(host) != SURF_RESOURCE_ON) {
183     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
184            sg_host_name(host));
185   }
186
187   action = xbt_mallocator_get(simix_global->action_mallocator);
188   action->type = SIMIX_ACTION_IO;
189   action->name = NULL;
190 #ifdef HAVE_TRACING
191   action->category = NULL;
192 #endif
193
194   action->io.host = host;
195   action->io.surf_io = surf_workstation_model->extension.workstation.unlink(host, fd->surf_file);
196
197   surf_workstation_model->action_data_set(action->io.surf_io, action);
198   XBT_DEBUG("Create io action %p", action);
199
200   return action;
201 }
202
203 //SIMIX FILE LS
204 void SIMIX_pre_file_ls(smx_simcall_t simcall,
205                        const char* mount, const char* path)
206 {
207   smx_action_t action = SIMIX_file_ls(simcall->issuer, mount, path);
208   xbt_fifo_push(action->simcalls, simcall);
209   simcall->issuer->waiting_action = action;
210 }
211 smx_action_t SIMIX_file_ls(smx_process_t process, const char* mount, const char *path)
212 {
213   smx_action_t action;
214   smx_host_t host = process->smx_host;
215   /* check if the host is active */
216   if (surf_workstation_model->extension.workstation.get_state(host) != SURF_RESOURCE_ON) {
217     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
218            sg_host_name(host));
219   }
220
221   action = xbt_mallocator_get(simix_global->action_mallocator);
222   action->type = SIMIX_ACTION_IO;
223   action->name = NULL;
224 #ifdef HAVE_TRACING
225   action->category = NULL;
226 #endif
227
228   action->io.host = host;
229   action->io.surf_io = surf_workstation_model->extension.workstation.ls(host,mount,path);
230
231   surf_workstation_model->action_data_set(action->io.surf_io, action);
232   XBT_DEBUG("Create io action %p", action);
233   return action;
234 }
235
236 size_t SIMIX_pre_file_get_size(smx_simcall_t simcall, smx_file_t fd)
237 {
238   return SIMIX_file_get_size(simcall->issuer, fd);
239 }
240
241 size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
242 {
243   smx_host_t host = process->smx_host;
244   return  surf_workstation_model->extension.workstation.get_size(host,
245       fd->surf_file);
246 }
247
248
249 void SIMIX_post_io(smx_action_t action)
250 {
251   xbt_fifo_item_t i;
252   smx_simcall_t simcall;
253 //  char* key;
254 //  xbt_dict_cursor_t cursor = NULL;
255 //  s_file_stat_t *dst = NULL;
256 //  s_file_stat_t *src = NULL;
257
258   xbt_fifo_foreach(action->simcalls,i,simcall,smx_simcall_t) {
259     switch (simcall->call) {
260     case SIMCALL_FILE_OPEN:;
261       smx_file_t tmp = xbt_new(s_smx_file_t,1);
262       tmp->surf_file = (action->io.surf_io)->file;
263       simcall_file_open__set__result(simcall, tmp);
264       break;
265
266     case SIMCALL_FILE_CLOSE:
267       xbt_free(simcall_file_close__get__fd(simcall));
268       simcall_file_close__set__result(simcall, 0);
269       break;
270
271     case SIMCALL_FILE_WRITE:
272       simcall_file_write__set__result(simcall, (action->io.surf_io)->cost);
273       break;
274
275     case SIMCALL_FILE_READ:
276       simcall_file_read__set__result(simcall, (action->io.surf_io)->cost);
277       break;
278
279     case SIMCALL_FILE_UNLINK:
280       xbt_free(simcall_file_unlink__get__fd(simcall));
281       simcall_file_unlink__set__result(simcall, 0);
282       break;
283
284     case SIMCALL_FILE_LS:
285 //      xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){
286 //        // if there is a stat we have to duplicate it
287 //        if(src){
288 //          dst = xbt_new0(s_file_stat_t,1);
289 //          file_stat_copy(src, dst);
290 //          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,xbt_free);
291 //        }
292 //      }
293       simcall_file_ls__set__result(simcall, (action->io.surf_io)->ls_dict);
294       break;
295     default:
296       break;
297     }
298   }
299
300   switch (surf_workstation_model->action_state_get(action->io.surf_io)) {
301
302     case SURF_ACTION_FAILED:
303       action->state = SIMIX_FAILED;
304       break;
305
306     case SURF_ACTION_DONE:
307       action->state = SIMIX_DONE;
308       break;
309
310     default:
311       THROW_IMPOSSIBLE;
312       break;
313   }
314
315   SIMIX_io_finish(action);
316 }
317
318 void SIMIX_io_destroy(smx_action_t action)
319 {
320   XBT_DEBUG("Destroy action %p", action);
321   if (action->io.surf_io)
322     action->io.surf_io->model_type->action_unref(action->io.surf_io);
323   xbt_mallocator_release(simix_global->action_mallocator, action);
324 }
325
326 void SIMIX_io_finish(smx_action_t action)
327 {
328   xbt_fifo_item_t item;
329   smx_simcall_t simcall;
330
331   xbt_fifo_foreach(action->simcalls, item, simcall, smx_simcall_t) {
332
333     switch (action->state) {
334
335       case SIMIX_DONE:
336         /* do nothing, action done */
337         break;
338
339       case SIMIX_FAILED:
340         SMX_EXCEPTION(simcall->issuer, io_error, 0, "IO failed");
341         break;
342
343       case SIMIX_CANCELED:
344         SMX_EXCEPTION(simcall->issuer, cancel_error, 0, "Canceled");
345         break;
346
347       default:
348         xbt_die("Internal error in SIMIX_io_finish: unexpected action state %d",
349             (int)action->state);
350     }
351
352     if (surf_workstation_model->extension.
353         workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
354       simcall->issuer->context->iwannadie = 1;
355     }
356
357     simcall->issuer->waiting_action = NULL;
358     SIMIX_simcall_answer(simcall);
359   }
360
361   /* We no longer need it */
362   SIMIX_io_destroy(action);
363 }