1 /* Copyright (c) 2007-2010, 2012-2015. The SimGrid Team.
2 * All rights reserved. */
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. */
7 #include "smx_private.h"
8 #include "xbt/sysdep.h"
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_io, simix,
14 "Logging specific to SIMIX (io)");
18 * \brief Internal function to create a SIMIX storage.
19 * \param name name of the storage to create
20 * \param storage the SURF storage to encapsulate
21 * \param data some user data (may be NULL)
23 smx_storage_t SIMIX_storage_create(const char *name, void *storage, void *data)
25 smx_storage_priv_t smx_storage = xbt_new0(s_smx_storage_priv_t, 1);
27 smx_storage->data = data;
29 /* Update global variables */
30 xbt_lib_set(storage_lib,name,SIMIX_STORAGE_LEVEL,smx_storage);
31 return xbt_lib_get_elm_or_null(storage_lib, name);
35 * \brief Internal function to destroy a SIMIX storage.
37 * \param s the host to destroy (a smx_storage_t)
39 void SIMIX_storage_destroy(void *s)
41 smx_storage_priv_t storage = (smx_storage_priv_t) s;
43 xbt_assert((storage != NULL), "Invalid parameters");
47 /* Clean storage structure */
52 void simcall_HANDLER_file_read(smx_simcall_t simcall, smx_file_t fd, sg_size_t size, sg_host_t host)
54 smx_synchro_t synchro = SIMIX_file_read(fd, size, host);
55 xbt_fifo_push(synchro->simcalls, simcall);
56 simcall->issuer->waiting_synchro = synchro;
59 smx_synchro_t SIMIX_file_read(smx_file_t fd, sg_size_t size, sg_host_t host)
61 smx_synchro_t synchro;
63 /* check if the host is active */
64 if (surf_host_get_state(surf_host_resource_priv(host)) != SURF_RESOURCE_ON) {
65 THROWF(host_error, 0, "Host %s failed, you cannot call this function",
66 sg_host_get_name(host));
69 synchro = (smx_synchro_t) xbt_mallocator_get(simix_global->synchro_mallocator);
70 synchro->type = SIMIX_SYNC_IO;
72 synchro->category = NULL;
74 synchro->io.host = host;
75 synchro->io.surf_io = surf_host_read(host, fd->surf_file, size);
77 surf_action_set_data(synchro->io.surf_io, synchro);
78 XBT_DEBUG("Create io synchro %p", synchro);
84 void simcall_HANDLER_file_write(smx_simcall_t simcall, smx_file_t fd, sg_size_t size, sg_host_t host)
86 smx_synchro_t synchro = SIMIX_file_write(fd, size, host);
87 xbt_fifo_push(synchro->simcalls, simcall);
88 simcall->issuer->waiting_synchro = synchro;
91 smx_synchro_t SIMIX_file_write(smx_file_t fd, sg_size_t size, sg_host_t host)
93 smx_synchro_t synchro;
95 /* check if the host is active */
96 if (surf_host_get_state(surf_host_resource_priv(host)) != SURF_RESOURCE_ON) {
97 THROWF(host_error, 0, "Host %s failed, you cannot call this function",
98 sg_host_get_name(host));
101 synchro = (smx_synchro_t) xbt_mallocator_get(simix_global->synchro_mallocator);
102 synchro->type = SIMIX_SYNC_IO;
103 synchro->name = NULL;
104 synchro->category = NULL;
106 synchro->io.host = host;
107 synchro->io.surf_io = surf_host_write(host, fd->surf_file, size);
109 surf_action_set_data(synchro->io.surf_io, synchro);
110 XBT_DEBUG("Create io synchro %p", synchro);
116 void simcall_HANDLER_file_open(smx_simcall_t simcall, const char* fullpath, sg_host_t host)
118 smx_synchro_t synchro = SIMIX_file_open(fullpath, host);
119 xbt_fifo_push(synchro->simcalls, simcall);
120 simcall->issuer->waiting_synchro = synchro;
123 smx_synchro_t SIMIX_file_open(const char* fullpath, sg_host_t host)
125 smx_synchro_t synchro;
127 /* check if the host is active */
128 if (surf_host_get_state(surf_host_resource_priv(host)) != SURF_RESOURCE_ON) {
129 THROWF(host_error, 0, "Host %s failed, you cannot call this function",
130 sg_host_get_name(host));
133 synchro = (smx_synchro_t) xbt_mallocator_get(simix_global->synchro_mallocator);
134 synchro->type = SIMIX_SYNC_IO;
135 synchro->name = NULL;
136 synchro->category = NULL;
138 synchro->io.host = host;
139 synchro->io.surf_io = surf_host_open(host, fullpath);
141 surf_action_set_data(synchro->io.surf_io, synchro);
142 XBT_DEBUG("Create io synchro %p", synchro);
148 void simcall_HANDLER_file_close(smx_simcall_t simcall, smx_file_t fd, sg_host_t host)
150 smx_synchro_t synchro = SIMIX_file_close(fd, host);
151 xbt_fifo_push(synchro->simcalls, simcall);
152 simcall->issuer->waiting_synchro = synchro;
155 smx_synchro_t SIMIX_file_close(smx_file_t fd, sg_host_t host)
157 smx_synchro_t synchro;
159 /* check if the host is active */
160 if (surf_host_get_state(surf_host_resource_priv(host)) != SURF_RESOURCE_ON) {
161 THROWF(host_error, 0, "Host %s failed, you cannot call this function",
162 sg_host_get_name(host));
165 synchro = (smx_synchro_t) xbt_mallocator_get(simix_global->synchro_mallocator);
166 synchro->type = SIMIX_SYNC_IO;
167 synchro->name = NULL;
168 synchro->category = NULL;
170 synchro->io.host = host;
171 synchro->io.surf_io = surf_host_close(host, fd->surf_file);
173 surf_action_set_data(synchro->io.surf_io, synchro);
174 XBT_DEBUG("Create io synchro %p", synchro);
181 int SIMIX_file_unlink(smx_file_t fd, sg_host_t host)
183 /* check if the host is active */
184 if (surf_host_get_state(surf_host_resource_priv(host)) != SURF_RESOURCE_ON) {
185 THROWF(host_error, 0, "Host %s failed, you cannot call this function",
186 sg_host_get_name(host));
189 int res = surf_host_unlink(host, fd->surf_file);
194 sg_size_t simcall_HANDLER_file_get_size(smx_simcall_t simcall, smx_file_t fd)
196 return SIMIX_file_get_size(simcall->issuer, fd);
199 sg_size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
201 sg_host_t host = process->host;
202 return surf_host_get_size(host, fd->surf_file);
205 sg_size_t simcall_HANDLER_file_tell(smx_simcall_t simcall, smx_file_t fd)
207 return SIMIX_file_tell(simcall->issuer, fd);
210 sg_size_t SIMIX_file_tell(smx_process_t process, smx_file_t fd)
212 sg_host_t host = process->host;
213 return surf_host_file_tell(host, fd->surf_file);
217 xbt_dynar_t simcall_HANDLER_file_get_info(smx_simcall_t simcall, smx_file_t fd)
219 return SIMIX_file_get_info(simcall->issuer, fd);
222 xbt_dynar_t SIMIX_file_get_info(smx_process_t process, smx_file_t fd)
224 sg_host_t host = process->host;
225 return surf_host_get_info(host, fd->surf_file);
228 int simcall_HANDLER_file_seek(smx_simcall_t simcall, smx_file_t fd, sg_offset_t offset, int origin)
230 return SIMIX_file_seek(simcall->issuer, fd, offset, origin);
233 int SIMIX_file_seek(smx_process_t process, smx_file_t fd, sg_offset_t offset, int origin)
235 sg_host_t host = process->host;
236 return surf_host_file_seek(host, fd->surf_file, offset, origin);
239 int simcall_HANDLER_file_move(smx_simcall_t simcall, smx_file_t file, const char* fullpath)
241 return SIMIX_file_move(simcall->issuer, file, fullpath);
244 int SIMIX_file_move(smx_process_t process, smx_file_t file, const char* fullpath)
246 sg_host_t host = process->host;
247 return surf_host_file_move(host, file->surf_file, fullpath);
250 sg_size_t SIMIX_storage_get_size(smx_storage_t storage){
251 xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
252 return surf_storage_get_size(storage);
255 sg_size_t simcall_HANDLER_storage_get_free_size(smx_simcall_t simcall, smx_storage_t storage)
257 return SIMIX_storage_get_free_size(simcall->issuer, storage);
260 sg_size_t SIMIX_storage_get_free_size(smx_process_t process, smx_storage_t storage)
262 return surf_storage_get_free_size(storage);
265 sg_size_t simcall_HANDLER_storage_get_used_size(smx_simcall_t simcall, smx_storage_t storage)
267 return SIMIX_storage_get_used_size(simcall->issuer, storage);
270 sg_size_t SIMIX_storage_get_used_size(smx_process_t process, smx_storage_t storage)
272 return surf_storage_get_used_size(storage);
275 xbt_dict_t SIMIX_storage_get_properties(smx_storage_t storage){
276 xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
277 return (xbt_dict_t) surf_resource_get_properties((surf_cpp_resource_t)
278 surf_storage_resource_priv(storage));
281 const char* SIMIX_storage_get_name(smx_storage_t storage){
282 xbt_assert((storage != NULL), "Invalid parameters");
283 return sg_storage_name(storage);
286 xbt_dict_t SIMIX_storage_get_content(smx_storage_t storage){
287 xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
288 return surf_storage_get_content(storage);
291 const char* SIMIX_storage_get_host(smx_storage_t storage){
292 xbt_assert((storage != NULL), "Invalid parameters");
293 return surf_storage_get_host(storage);
296 void SIMIX_post_io(smx_synchro_t synchro)
299 smx_simcall_t simcall;
301 xbt_fifo_foreach(synchro->simcalls,i,simcall,smx_simcall_t) {
302 switch (simcall->call) {
303 case SIMCALL_FILE_OPEN: {
304 smx_file_t tmp = xbt_new(s_smx_file_t,1);
305 tmp->surf_file = surf_storage_action_get_file(synchro->io.surf_io);
306 simcall_file_open__set__result(simcall, tmp);
309 case SIMCALL_FILE_CLOSE:
310 xbt_free(simcall_file_close__get__fd(simcall));
311 simcall_file_close__set__result(simcall, 0);
313 case SIMCALL_FILE_WRITE:
314 simcall_file_write__set__result(simcall, surf_action_get_cost(synchro->io.surf_io));
317 case SIMCALL_FILE_READ:
318 simcall_file_read__set__result(simcall, surf_action_get_cost(synchro->io.surf_io));
326 switch (surf_action_get_state(synchro->io.surf_io)) {
328 case SURF_ACTION_FAILED:
329 synchro->state = SIMIX_FAILED;
332 case SURF_ACTION_DONE:
333 synchro->state = SIMIX_DONE;
341 SIMIX_io_finish(synchro);
344 void SIMIX_io_destroy(smx_synchro_t synchro)
346 XBT_DEBUG("Destroy synchro %p", synchro);
347 if (synchro->io.surf_io)
348 surf_action_unref(synchro->io.surf_io);
349 xbt_mallocator_release(simix_global->synchro_mallocator, synchro);
352 void SIMIX_io_finish(smx_synchro_t synchro)
354 xbt_fifo_item_t item;
355 smx_simcall_t simcall;
357 xbt_fifo_foreach(synchro->simcalls, item, simcall, smx_simcall_t) {
359 switch (synchro->state) {
362 /* do nothing, synchro done */
366 SMX_EXCEPTION(simcall->issuer, io_error, 0, "IO failed");
370 SMX_EXCEPTION(simcall->issuer, cancel_error, 0, "Canceled");
374 xbt_die("Internal error in SIMIX_io_finish: unexpected synchro state %d",
375 (int)synchro->state);
378 if (surf_host_get_state(surf_host_resource_priv(simcall->issuer->host)) != SURF_RESOURCE_ON) {
379 simcall->issuer->context->iwannadie = 1;
382 simcall->issuer->waiting_synchro = NULL;
383 SIMIX_simcall_answer(simcall);
386 /* We no longer need it */
387 SIMIX_io_destroy(synchro);