From b9d8ff0f5f0819d9103795c70ed49534d695f8ba Mon Sep 17 00:00:00 2001 From: navarro Date: Thu, 19 Jan 2012 16:31:41 +0100 Subject: [PATCH] Starting simix mecanism for io. --- buildtools/Cmake/DefinePackages.cmake | 2 + include/simix/simix.h | 2 + include/xbt/ex.h | 3 +- src/simix/io_private.h | 19 ++++ src/simix/private.h | 5 + src/simix/smurf_private.h | 7 +- src/simix/smx_io.c | 127 ++++++++++++++++++++++++++ src/simix/smx_process.c | 4 +- src/simix/smx_smurf.c | 4 + src/simix/smx_user.c | 11 +++ 10 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 src/simix/io_private.h create mode 100644 src/simix/smx_io.c diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index c30f7ef5a2..b15345e2b1 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -84,6 +84,7 @@ set(EXTRA_DIST src/simix/network_private.h src/simix/smurf_private.h src/simix/synchro_private.h + src/simix/io_private.h src/smpi/private.h src/smpi/smpi_mpi_dt_private.h @@ -249,6 +250,7 @@ set(SIMIX_SRC src/simix/smx_user.c src/simix/smx_smurf.c src/simix/smx_context_raw.c + src/simix/smx_io.c ) set(MSG_SRC diff --git a/include/simix/simix.h b/include/simix/simix.h index df128f61cb..5878388153 100644 --- a/include/simix/simix.h +++ b/include/simix/simix.h @@ -242,6 +242,8 @@ XBT_PUBLIC(void) SIMIX_req_sem_acquire_timeout(smx_sem_t sem, XBT_PUBLIC(unsigned int) SIMIX_req_sem_acquire_any(xbt_dynar_t sems); XBT_PUBLIC(int) SIMIX_req_sem_get_capacity(smx_sem_t sem); +XBT_PUBLIC(void) SIMIX_req_file_read(char* name); + const char *SIMIX_request_name(int kind); SG_END_DECL() diff --git a/include/xbt/ex.h b/include/xbt/ex.h index f1f3cc968c..f23bd37e1d 100644 --- a/include/xbt/ex.h +++ b/include/xbt/ex.h @@ -262,7 +262,8 @@ typedef enum { cancel_error, /**< an action was canceled */ thread_error, /**< error while [un]locking */ host_error, /**< host failed */ - tracing_error /**< error during the simulation tracing */ + tracing_error, /**< error during the simulation tracing */ + io_error /**< disk or file error */ } xbt_errcat_t; XBT_PUBLIC(const char *) xbt_ex_catname(xbt_errcat_t cat); diff --git a/src/simix/io_private.h b/src/simix/io_private.h new file mode 100644 index 0000000000..bccaf05bcb --- /dev/null +++ b/src/simix/io_private.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef _SIMIX_IO_PRIVATE_H +#define _SIMIX_IO_PRIVATE_H + +#include "simix/datatypes.h" +#include "smurf_private.h" + +void SIMIX_pre_file_read(smx_req_t req); +smx_action_t SIMIX_file_read(smx_process_t process, char* name); +void SIMIX_post_file_read(smx_action_t action); +void SIMIX_io_destroy(smx_action_t action); +void SIMIX_io_finish(smx_action_t action); + +#endif diff --git a/src/simix/private.h b/src/simix/private.h index 4032673aa3..6a9bb77808 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -19,6 +19,7 @@ #include "instr/instr_private.h" #include "process_private.h" #include "host_private.h" +#include "io_private.h" #include "network_private.h" #include "smurf_private.h" #include "synchro_private.h" @@ -125,6 +126,10 @@ typedef struct s_smx_action { surf_action_t sleep; } synchro; + struct { + smx_host_t host; /* The host that is sleeping */ + surf_action_t surf_io; + } io; }; #ifdef HAVE_LATENCY_BOUND_TRACKING diff --git a/src/simix/smurf_private.h b/src/simix/smurf_private.h index 6284d5be04..b8431a410b 100644 --- a/src/simix/smurf_private.h +++ b/src/simix/smurf_private.h @@ -83,7 +83,8 @@ SIMIX_REQ_ENUM_ELEMENT(REQ_SEM_RELEASE),\ SIMIX_REQ_ENUM_ELEMENT(REQ_SEM_WOULD_BLOCK),\ SIMIX_REQ_ENUM_ELEMENT(REQ_SEM_ACQUIRE),\ SIMIX_REQ_ENUM_ELEMENT(REQ_SEM_ACQUIRE_TIMEOUT),\ -SIMIX_REQ_ENUM_ELEMENT(REQ_SEM_GET_CAPACITY) +SIMIX_REQ_ENUM_ELEMENT(REQ_SEM_GET_CAPACITY),\ +SIMIX_REQ_ENUM_ELEMENT(REQ_FILE_READ) /* REQ_COMM_IS_LATENCY_BOUNDED and REQ_SET_CATEGORY make things complicated * because they are not always present */ @@ -500,6 +501,10 @@ typedef struct s_smx_req { smx_sem_t sem; int result; } sem_get_capacity; + + struct { + char* name;; + } file_read; }; } s_smx_req_t, *smx_req_t; diff --git a/src/simix/smx_io.c b/src/simix/smx_io.c new file mode 100644 index 0000000000..f535e9c067 --- /dev/null +++ b/src/simix/smx_io.c @@ -0,0 +1,127 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "private.h" +#include "xbt/sysdep.h" +#include "xbt/log.h" +#include "xbt/dict.h" +#include "mc/mc.h" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_io, simix, + "Logging specific to SIMIX (io)"); + +void SIMIX_pre_file_read(smx_req_t req) +{ + smx_action_t action = SIMIX_file_read(req->issuer, req->file_read.name); + xbt_fifo_push(action->request_list, req); + req->issuer->waiting_action = action; +} + +smx_action_t SIMIX_file_read(smx_process_t process, char* name) +{ + smx_action_t action; + smx_host_t host = process->smx_host; + + /* check if the host is active */ + if (surf_workstation_model->extension. + workstation.get_state(host->host) != SURF_RESOURCE_ON) { + THROWF(host_error, 0, "Host %s failed, you cannot call this function", + host->name); + } + + action = xbt_mallocator_get(simix_global->action_mallocator); + action->type = SIMIX_ACTION_IO; + action->name = NULL; +#ifdef HAVE_TRACING + action->category = NULL; +#endif + + action->io.host = host; + // TODO in surf model disk??? + // action->io.surf_io = surf_workstation_model->extension.disk.read(host->host, name), + action->io.surf_io = surf_workstation_model->extension.workstation.sleep(host->host, 1.0); + + surf_workstation_model->action_data_set(action->io.surf_io, action); + XBT_DEBUG("Create io action %p", action); + + return action; +} + +void SIMIX_post_file_read(smx_action_t action) +{ + smx_req_t req; + + while ((req = xbt_fifo_shift(action->request_list))) { + + switch(surf_workstation_model->action_state_get(action->io.surf_io)){ + case SURF_ACTION_FAILED: + action->state = SIMIX_FAILED; + break; + + case SURF_ACTION_DONE: + action->state = SIMIX_DONE; + break; + + default: + THROW_IMPOSSIBLE; + break; + } + } + /* If there are requests associated with the action, then answer them */ + if (xbt_fifo_size(action->request_list)) + SIMIX_io_finish(action); +} + +void SIMIX_io_destroy(smx_action_t action) +{ + XBT_DEBUG("Destroy action %p", action); + if (action->io.surf_io) + action->io.surf_io->model_type->action_unref(action->io.surf_io); + xbt_mallocator_release(simix_global->action_mallocator, action); +} + +void SIMIX_io_finish(smx_action_t action) +{ + volatile xbt_fifo_item_t item; + smx_req_t req; + + xbt_fifo_foreach(action->request_list, item, req, smx_req_t) { + + switch (action->state) { + + case SIMIX_DONE: + /* do nothing, action done */ + break; + + case SIMIX_FAILED: + TRY { + THROWF(io_error, 0, "IO failed"); + } + CATCH(req->issuer->running_ctx->exception) { + req->issuer->doexception = 1; + } + break; + + case SIMIX_CANCELED: + TRY { + THROWF(cancel_error, 0, "Canceled"); + } + CATCH(req->issuer->running_ctx->exception) { + req->issuer->doexception = 1; + } + break; + + default: + xbt_die("Internal error in SIMIX_io_finish: unexpected action state %d", + action->state); + } + req->issuer->waiting_action = NULL; + SIMIX_request_answer(req); + } + + /* We no longer need it */ + SIMIX_io_destroy(action); +} diff --git a/src/simix/smx_process.c b/src/simix/smx_process.c index 5af0e0b0db..bf04014bc7 100644 --- a/src/simix/smx_process.c +++ b/src/simix/smx_process.c @@ -284,8 +284,8 @@ void SIMIX_process_kill(smx_process_t process) { break; case SIMIX_ACTION_IO: - THROW_UNIMPLEMENTED; - break; + SIMIX_io_destroy(process->waiting_action); + break; } } diff --git a/src/simix/smx_smurf.c b/src/simix/smx_smurf.c index 1fb1585b25..2b77bb1f3a 100644 --- a/src/simix/smx_smurf.c +++ b/src/simix/smx_smurf.c @@ -481,6 +481,10 @@ void SIMIX_request_pre(smx_req_t req, int value) SIMIX_request_answer(req); break; + case REQ_FILE_READ: + SIMIX_pre_file_read(req); + break; + case REQ_NO_REQ: THROWF(arg_error,0,"Asked to do the noop syscall on %s@%s", SIMIX_process_get_name(req->issuer), diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index 09e26ea8e6..abc1d02ab6 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -1176,6 +1176,17 @@ int SIMIX_req_sem_get_capacity(smx_sem_t sem) SIMIX_request_push(req->issuer); return req->sem_get_capacity.result; } + +void SIMIX_req_file_read(char* name) +{ + smx_req_t req = SIMIX_req_mine(); + + req->call = REQ_FILE_READ; + req->file_read.name = name; + SIMIX_request_push(req->issuer); + +} + /* ************************************************************************** */ /** @brief returns a printable string representing the request kind */ -- 2.20.1