From df30ec204f03aef9ec97785dffe8835234488b10 Mon Sep 17 00:00:00 2001 From: donassbr Date: Fri, 2 Mar 2007 14:11:50 +0000 Subject: [PATCH] Added new functions and some modifications on the headers was made. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3192 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/include/simix/simix.h | 5 +- src/simix/private.h | 20 +++-- src/simix/smx_action.c | 38 +++++++++ src/simix/smx_process.c | 167 ++++++++++++++++++++++---------------- src/simix/smx_synchro.c | 59 ++++++++++++-- 5 files changed, 206 insertions(+), 83 deletions(-) diff --git a/src/include/simix/simix.h b/src/include/simix/simix.h index 1a892e5977..ed51809ceb 100644 --- a/src/include/simix/simix.h +++ b/src/include/simix/simix.h @@ -76,9 +76,9 @@ XBT_PUBLIC(SIMIX_error_t) SIMIX_get_errno(void); /******Mutex******/ XBT_PUBLIC(smx_mutex_t) SIMIX_mutex_init(void); XBT_PUBLIC(void) SIMIX_mutex_lock(smx_mutex_t mutex); -XBT_PUBLIC(void) SIMIX_mutex_trylock(smx_mutex_t mutex); +XBT_PUBLIC(int) SIMIX_mutex_trylock(smx_mutex_t mutex); XBT_PUBLIC(void) SIMIX_mutex_unlock(smx_mutex_t mutex); -XBT_PUBLIC(void) SIMIX_mutex_destroy(smx_mutex_t mutex); +XBT_PUBLIC(SIMIX_error_t) SIMIX_mutex_destroy(smx_mutex_t mutex); /*****Conditional*****/ XBT_PUBLIC(smx_cond_t) SIMIX_cond_init(void); @@ -95,6 +95,7 @@ XBT_PUBLIC(smx_action_t) SIMIX_execute(smx_host_t host,double amount); XBT_PUBLIC(SIMIX_error_t) SIMIX_action_cancel(smx_action_t action); XBT_PUBLIC(void) SIMIX_action_set_priority(smx_action_t action, double priority); XBT_PUBLIC(SIMIX_error_t) SIMIX_action_destroy(smx_action_t action); +XBT_PUBLIC(void) SIMIX_create_link(smx_action_t action, smx_cond_t cond); //SIMIX_action_wait_for_computation(smx_process_t process, smx_action_t action); diff --git a/src/simix/private.h b/src/simix/private.h index 41398698dd..710abc5278 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -18,7 +18,10 @@ #include "xbt/context.h" #include "xbt/config.h" -/**************** datatypes **********************************/ +/******************************* Datatypes **********************************/ + + +/********************************** Host ************************************/ typedef struct s_simdata_host { void *host; /* SURF modeling */ @@ -48,7 +51,10 @@ typedef struct s_simdata_process { xbt_context_t context; /* the context that executes the scheduler fonction */ int blocked; int suspended; + smx_mutex_t mutex; /* mutex on which the process is blocked */ + smx_cond_t cond; /* cond on which the process is blocked */ smx_host_t put_host; /* used for debugging purposes */ + smx_action_t block_action; /* action that block the process when it does a mutex_lock or cond_wait */ int argc; /* arguments number if any */ char **argv; /* arguments table if any */ SIMIX_error_t last_errno; /* the last value returned by a MSG_function */ @@ -68,14 +74,16 @@ typedef struct process_arg { /********************************* Mutex and Conditional ****************************/ typedef struct s_smx_mutex { - xbt_swag_t sleeping; + xbt_swag_t sleeping; /* list of sleeping process */ int using; } s_smx_mutex_t; typedef struct s_smx_cond { + xbt_swag_t sleeping; /* list of sleeping process */ s_smx_mutex_t * mutex; - xbt_swag_t sleeping; //process + xbt_fifo_t actions; /* list of actions */ + } s_smx_cond_t; /********************************* Action **************************************/ @@ -123,7 +131,7 @@ extern xbt_cfg_t _simix_cfg_set; /* #define CHECK_ERRNO() ASSERT((PROCESS_GET_ERRNO()!=MSG_HOST_FAILURE),"Host failed, you cannot call this function.") */ #define CHECK_HOST() xbt_assert0(surf_workstation_resource->extension_public-> \ - get_state(MSG_host_self()->simdata->host)==SURF_CPU_ON,\ + get_state(SIMIX_host_self()->simdata->host)==SURF_CPU_ON,\ "Host failed, you cannot call this function.") smx_host_t __SIMIX_host_create(const char *name, void *workstation, void *data); @@ -135,9 +143,11 @@ int __SIMIX_process_isBlocked(smx_process_t process); void __SIMIX_display_process_status(void); +SIMIX_error_t __SIMIX_wait_for_action(smx_process_t process, smx_action_t action); + + /* void __MSG_task_execute(smx_process_t process, m_task_t task); -MSG_error_t __MSG_wait_for_computation(smx_process_t process, m_task_t task); MSG_error_t __MSG_task_wait_event(smx_process_t process, m_task_t task); */ diff --git a/src/simix/smx_action.c b/src/simix/smx_action.c index 540c5f7bb6..8be954c18d 100644 --- a/src/simix/smx_action.c +++ b/src/simix/smx_action.c @@ -39,3 +39,41 @@ SIMIX_error_t SIMIX_action_destroy(smx_action_t action) { return SIMIX_OK; } + +void SIMIX_create_link(smx_action_t action, smx_cond_t cond) +{ + +} + +SIMIX_error_t __SIMIX_wait_for_action(smx_process_t process, smx_action_t action) +{ + e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM; + simdata_action_t simdata = action->simdata; + + xbt_assert0(((process != NULL) && (action != NULL) && (action->simdata != NULL)), "Invalid parameters"); + + /* change context while the action is running */ + do { + xbt_context_yield(); + state=surf_workstation_resource->common_public->action_get_state(simdata->surf_action); + } while (state==SURF_ACTION_RUNNING); + + /* action finished, we can continue */ + + if(state == SURF_ACTION_DONE) { + if(surf_workstation_resource->common_public->action_free(simdata->surf_action)) + simdata->surf_action = NULL; + SIMIX_RETURN(SIMIX_OK); + } else if(surf_workstation_resource->extension_public-> + get_state(SIMIX_process_get_host(process)->simdata->host) + == SURF_CPU_OFF) { + if(surf_workstation_resource->common_public->action_free(simdata->surf_action)) + simdata->surf_action = NULL; + SIMIX_RETURN(SIMIX_HOST_FAILURE); + } else { + if(surf_workstation_resource->common_public->action_free(simdata->surf_action)) + simdata->surf_action = NULL; + SIMIX_RETURN(SIMIX_ACTION_CANCELLED); + } + +} diff --git a/src/simix/smx_process.c b/src/simix/smx_process.c index cc8b6b1e0a..3f17ace9e3 100644 --- a/src/simix/smx_process.c +++ b/src/simix/smx_process.c @@ -261,52 +261,51 @@ smx_process_t SIMIX_process_self(void) */ SIMIX_error_t SIMIX_process_suspend(smx_process_t process) { -/* simdata_process_t simdata = NULL; - simdata_task_t simdata_task = NULL; - - XBT_IN2("(%p(%s))", process, process->name); - + smx_action_t dummy; + xbt_assert0(((process) && (process->simdata)), "Invalid parameters"); - PAJE_PROCESS_PUSH_STATE(process,"S",NULL); - if(process!=SIMIX_process_self()) { simdata = process->simdata; - xbt_assert0(simdata->waiting_task,"Process not waiting for anything else. Weird !"); - - simdata_task = simdata->waiting_task->simdata; - - simdata->suspended = 1; - if(simdata->blocked) { - XBT_OUT; - return SIMIX_OK; - } + if ( (simdata->mutex == NULL) && (simdata->cond == NULL) ) { + /* Ops, I don't know what to do yet. */ + + } + else if (simdata->mutex) { + /* process blocked on a mutex, only set suspend=1 */ + simdata->suspended = 1; + } + else if (simdata->cond){ + /* process blocked cond, suspend all actions */ + + /* temporaries variables */ + smx_cond_t c; + xbt_fifo_item_t i; + smx_action_t act; + + simdata->suspended = 1; + c = simdata->cond; + xbt_fifo_foreach(c->actions,i,act, smx_action_t) { + surf_workstation_resource->common_public->suspend(act->simdata->surf_action); + } + } + else xbt_assert0(0, "Unknown process status"); - xbt_assert0(((simdata_task->compute)||(simdata_task->comm))&& - !((simdata_task->compute)&&(simdata_task->comm)), - "Got a problem in deciding which action to choose !"); - simdata->suspended = 1; - if(simdata_task->compute) - surf_workstation_resource->common_public->suspend(simdata_task->compute); - else - surf_workstation_resource->common_public->suspend(simdata_task->comm); - } else { - m_task_t dummy = MSG_TASK_UNINITIALIZED; - dummy = MSG_task_create("suspended", 0.0, 0, NULL); - - simdata = process->simdata; - simdata->suspended = 1; - __MSG_task_execute(process,dummy); - surf_workstation_resource->common_public->suspend(dummy->simdata->compute); - __MSG_wait_for_computation(process,dummy); - simdata->suspended = 0; - - MSG_task_destroy(dummy); } - XBT_OUT; - */ + else { + /* process executing, I can create an action and suspend it */ + dummy = SIMIX_execute(SIMIX_process_get_host(process)->simdata->host, 0); + process->simdata->block_action = dummy; + + process->simdata->suspended = 1; + surf_workstation_resource->common_public->suspend(dummy->simdata->surf_action); + __SIMIX_wait_for_action(process,dummy); + SIMIX_action_destroy(dummy); + process->simdata->suspended = 0; + + } return SIMIX_OK; } @@ -318,50 +317,41 @@ SIMIX_error_t SIMIX_process_suspend(smx_process_t process) */ SIMIX_error_t SIMIX_process_resume(smx_process_t process) { -/* simdata_process_t simdata = NULL; - simdata_task_t simdata_task = NULL; xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters"); CHECK_HOST(); - XBT_IN2("(%p(%s))", process, process->name); - if(process == SIMIX_process_self()) { - XBT_OUT; SIMIX_RETURN(SIMIX_OK); } simdata = process->simdata; - if(simdata->blocked) { - PAJE_PROCESS_POP_STATE(process); - - simdata->suspended = 0; *//* He'll wake up by itself */ - /*XBT_OUT; + if(simdata->mutex) { + simdata->suspended = 0; /* He'll wake up by itself */ SIMIX_RETURN(SIMIX_OK); } + else if (simdata->cond) { + /* temporaries variables */ + smx_cond_t c; + xbt_fifo_item_t i; + smx_action_t act; + + simdata->suspended = 0; + c = simdata->cond; + xbt_fifo_foreach(c->actions,i,act, smx_action_t) { + surf_workstation_resource->common_public->resume(act->simdata->surf_action); + } + SIMIX_RETURN(SIMIX_OK); + } + else if (simdata->block_action){ + simdata->suspended = 0; + surf_workstation_resource->common_public->resume(simdata->block_action->simdata->surf_action); + SIMIX_RETURN(SIMIX_OK); + } + else xbt_assert0(0, "Unknown process status"); - if(!(simdata->waiting_task)) { - xbt_assert0(0,"Process not waiting for anything else. Weird !"); - XBT_OUT; - return SIMIX_WARNING; - } - simdata_task = simdata->waiting_task->simdata; - - - if(simdata_task->compute) { - surf_workstation_resource->common_public->resume(simdata_task->compute); - PAJE_PROCESS_POP_STATE(process); - } - else { - PAJE_PROCESS_POP_STATE(process); - surf_workstation_resource->common_public->resume(simdata_task->comm); - } - - XBT_OUT; - */ - SIMIX_RETURN(SIMIX_OK); } /** \ingroup m_process_management @@ -379,8 +369,30 @@ int SIMIX_process_is_suspended(smx_process_t process) int __SIMIX_process_block(double max_duration, const char *info) { -/* + smx_process_t process = SIMIX_process_self(); + smx_action_t dummy = NULL; + + dummy = SIMIX_execute(SIMIX_process_get_host(process)->simdata->host, 0); + process->simdata->block_action = dummy; + + process->simdata->blocked=1; + + surf_workstation_resource->common_public->suspend(dummy->simdata->surf_action); + if(max_duration>=0) + surf_workstation_resource->common_public->set_max_duration(dummy->simdata->surf_action, + max_duration); + __SIMIX_wait_for_action(process,dummy); + SIMIX_action_destroy(dummy); + process->simdata->blocked=0; + + if(process->simdata->suspended) { + DEBUG0("I've been suspended in the meantime"); + SIMIX_process_suspend(process); + DEBUG0("I've been resumed, let's keep going"); + } + +/* m_task_t dummy = SIMIX_TASK_UNINITIALIZED; char blocked_name[512]; snprintf(blocked_name,512,"blocked [%s] (%s:%s)", @@ -417,6 +429,22 @@ int __SIMIX_process_block(double max_duration, const char *info) SIMIX_error_t __SIMIX_process_unblock(smx_process_t process) { + simdata_process_t simdata = NULL; + simdata_action_t simdata_action = NULL; + + xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters"); + CHECK_HOST(); + + simdata = process->simdata; + if(!(simdata->block_action)) { + xbt_assert0(0,"Process is not blocked !"); + return SIMIX_WARNING; + } + simdata_action = simdata->block_action->simdata; + xbt_assert0(simdata->blocked,"Process not blocked"); + surf_workstation_resource->common_public->resume(simdata_action->surf_action); + SIMIX_RETURN(SIMIX_OK); + /* simdata_process_t simdata = NULL; simdata_task_t simdata_task = NULL; @@ -440,7 +468,6 @@ SIMIX_error_t __SIMIX_process_unblock(smx_process_t process) XBT_OUT; */ - SIMIX_RETURN(SIMIX_OK); } int __SIMIX_process_isBlocked(smx_process_t process) diff --git a/src/simix/smx_synchro.c b/src/simix/smx_synchro.c index 14a2e3afc6..a15d28c069 100644 --- a/src/simix/smx_synchro.c +++ b/src/simix/smx_synchro.c @@ -19,27 +19,74 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_synchro, simix, /*********************************** Mutex ************************************/ smx_mutex_t SIMIX_mutex_init() { - return xbt_new0(s_smx_mutex_t,1); + smx_mutex_t m = xbt_new0(s_smx_mutex_t,1); + s_smx_process_t p; /* useful to initialize sleeping swag */ + /* structures initialization */ + m->using = 0; + m->sleeping = xbt_swag_new(xbt_swag_offset(p, synchro_hookup)); + return m; } void SIMIX_mutex_lock(smx_mutex_t mutex) { + smx_process_t self = SIMIX_process_self(); + + xbt_assert0((mutex != NULL), "Invalid parameters"); + + if (mutex->using) { + /* somebody using the mutex, block */ + xbt_swag_insert(self, mutex->sleeping); + self->simdata->mutex = mutex; + __SIMIX_process_block(-1,""); + self->simdata->mutex = NULL; + mutex->using = 1; + } + else { + /* mutex free */ + mutex->using = 1; + } return; } - -void SIMIX_mutex_trylock(smx_mutex_t mutex) +/* return 1 if the process got the mutex, else 0. */ +int SIMIX_mutex_trylock(smx_mutex_t mutex) { - return; + xbt_assert0((mutex != NULL), "Invalid parameters"); + + if (mutex->using) + return 0; + else { + mutex->using = 1; + return 1; + } } void SIMIX_mutex_unlock(smx_mutex_t mutex) { + smx_process_t p; /*process to wake up */ + + xbt_assert0((mutex != NULL), "Invalid parameters"); + + if (xbt_swag_size(mutex->sleeping) > 0) { + p = xbt_swag_extract(mutex->sleeping); + mutex->using = 0; + __SIMIX_process_unblock(p); + } + else { + /* nobody to wape up */ + mutex->using = 0; + } return; } -void SIMIX_mutex_destroy(smx_mutex_t mutex) +SIMIX_error_t SIMIX_mutex_destroy(smx_mutex_t mutex) { - return; + if ( mutex == NULL ) + return SIMIX_WARNING; + else { + xbt_swag_free(mutex->sleeping); + xbt_free(mutex); + return SIMIX_OK; + } } /******************************** Conditional *********************************/ -- 2.20.1