#include "xbt/context.h"
#include "xbt/config.h"
-/**************** datatypes **********************************/
+/******************************* Datatypes **********************************/
+
+
+/********************************** Host ************************************/
typedef struct s_simdata_host {
void *host; /* SURF modeling */
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 */
/********************************* 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 **************************************/
/* #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);
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);
*/
*/
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;
}
*/
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
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)",
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;
XBT_OUT;
*/
- SIMIX_RETURN(SIMIX_OK);
}
int __SIMIX_process_isBlocked(smx_process_t process)
/*********************************** 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 *********************************/