From: donassbr Date: Fri, 9 Mar 2007 14:29:13 +0000 (+0000) Subject: Modified some functions and datatypes. Simix API changed too. X-Git-Tag: v3.3~2135 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/5979fe52092423ac8915b118cff1e161e57d1ecb Modified some functions and datatypes. Simix API changed too. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3224 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/include/simix/simix.h b/src/include/simix/simix.h index ccafb75060..0ccb914ff9 100644 --- a/src/include/simix/simix.h +++ b/src/include/simix/simix.h @@ -10,6 +10,7 @@ #define _SIMIX_SIMIX_H #include "xbt/misc.h" +#include "xbt/fifo.h" #include "simix/datatypes.h" SG_BEGIN_DECL() @@ -19,31 +20,39 @@ SG_BEGIN_DECL() XBT_PUBLIC(void) SIMIX_config(const char *name, ...); XBT_PUBLIC(void) SIMIX_global_init(int *argc, char **argv); XBT_PUBLIC(void) SIMIX_global_init_args(int *argc, char **argv); -XBT_PUBLIC(void) SIMIX_main(void); XBT_PUBLIC(void) SIMIX_clean(void); XBT_PUBLIC(void) SIMIX_function_register(const char *name, smx_process_code_t code); XBT_PUBLIC(smx_process_code_t) SIMIX_get_registered_function(const char *name); -// SIMIX_deploy_application??? + XBT_PUBLIC(void) SIMIX_launch_application(const char *file); XBT_PUBLIC(double) SIMIX_get_clock(void); +XBT_PUBLIC(double) SIMIX_solve(xbt_fifo_t actions_done, xbt_fifo_t actions_failed); + +/* Timer functions */ +XBT_PUBLIC(void) SIMIX_timer_set (double date, void *function, void *arg); +XBT_PUBLIC(int) SIMIX_timer_get(void **function, void **arg); +/* only for tests */ +XBT_PUBLIC(void) __SIMIX_main(void); /************************** Host handling ***********************************/ -//pointer to above layer + XBT_PUBLIC(void) SIMIX_host_set_data(smx_host_t host, void *data); XBT_PUBLIC(void*) SIMIX_host_get_data(smx_host_t host); XBT_PUBLIC(const char *) SIMIX_host_get_name(smx_host_t host); XBT_PUBLIC(smx_host_t) SIMIX_host_self(void); -/* int SIMIX_get_msgload(void); This function lacks specification; discard it */ -XBT_PUBLIC(double) SIMIX_get_host_speed(smx_host_t h); -XBT_PUBLIC(int) SIMIX_host_is_avail (smx_host_t h); +XBT_PUBLIC(double) SIMIX_host_get_speed(smx_host_t host); +XBT_PUBLIC(double) SIMIX_host_get_available_speed(smx_host_t host); + +XBT_PUBLIC(int) SIMIX_host_get_number(void); +XBT_PUBLIC(smx_host_t *)SIMIX_host_get_table(void); XBT_PUBLIC(void) SIMIX_create_environment(const char *file); +XBT_PUBLIC(smx_host_t) SIMIX_host_get_by_name(const char *name); -XBT_PUBLIC(smx_host_t) SIMIX_get_host_by_name(const char *name); -XBT_PUBLIC(int) SIMIX_get_host_number(void); -XBT_PUBLIC(smx_host_t *)SIMIX_get_host_table(void); +/* Two possible states, 1 - CPU ON and 0 CPU OFF */ +XBT_PUBLIC(int) SIMIX_host_get_state(smx_host_t host); /************************** Process handling *********************************/ XBT_PUBLIC(smx_process_t) SIMIX_process_create(const char *name, @@ -55,7 +64,6 @@ XBT_PUBLIC(smx_process_t) SIMIX_process_create_with_arguments(const char *name, XBT_PUBLIC(void) SIMIX_process_kill(smx_process_t process); XBT_PUBLIC(void) SIMIX_process_killall(void); -XBT_PUBLIC(void) SIMIX_process_change_host(smx_process_t process, smx_host_t host); //above layer XBT_PUBLIC(void*) SIMIX_process_get_data(smx_process_t process); XBT_PUBLIC(void) SIMIX_process_set_data(smx_process_t process, void *data); @@ -68,9 +76,6 @@ XBT_PUBLIC(void) SIMIX_process_suspend(smx_process_t process); XBT_PUBLIC(void) SIMIX_process_resume(smx_process_t process); XBT_PUBLIC(int) SIMIX_process_is_suspended(smx_process_t process); -XBT_PUBLIC(void) SIMIX_process_sleep(double nb_sec); -//XBT_PUBLIC(void) SIMIX_get_errno(void); - /************************** Synchro handling **********************************/ @@ -88,18 +93,28 @@ XBT_PUBLIC(void) SIMIX_cond_wait(smx_cond_t cond,smx_mutex_t mutex); XBT_PUBLIC(void) SIMIX_cond_wait_timeout(smx_cond_t cond,smx_mutex_t mutex, double max_duration); XBT_PUBLIC(void) SIMIX_cond_broadcast(smx_cond_t cond); XBT_PUBLIC(void) SIMIX_cond_destroy(smx_cond_t cond); +XBT_PUBLIC(void) SIMIX_register_condition_to_action(smx_action_t action, smx_cond_t cond); /************************** Action handling ************************************/ -XBT_PUBLIC(smx_action_t) SIMIX_communicate(smx_host_t sender,smx_host_t receiver, char *name, double size, double rate); -XBT_PUBLIC(smx_action_t) SIMIX_execute(smx_host_t host,char *name, double amount); +XBT_PUBLIC(smx_action_t) SIMIX_action_communicate(smx_host_t sender,smx_host_t receiver, char *name, + double size, double rate); +XBT_PUBLIC(smx_action_t) SIMIX_action_execute(smx_host_t host,char *name, double amount); +XBT_PUBLIC(smx_action_t) SIMIX_action_sleep(smx_host_t host, double amount); XBT_PUBLIC(void) SIMIX_action_cancel(smx_action_t action); XBT_PUBLIC(void) SIMIX_action_set_priority(smx_action_t action, double priority); XBT_PUBLIC(void) SIMIX_action_destroy(smx_action_t action); XBT_PUBLIC(void) SIMIX_register_action_to_condition(smx_action_t action, smx_cond_t cond); -XBT_PUBLIC(void) SIMIX_register_condition_to_action(smx_action_t action, smx_cond_t cond); -//SIMIX_action_wait_for_computation(smx_process_t process, smx_action_t action); +/*Not implemented yet */ +XBT_PUBLIC(smx_action_t) SIMIX_action_parallel_execute(int workstation_nb, + void **workstation_list, + double *computation_amount, + double *communication_amount, + double amount, + double rate); + SG_END_DECL() + #endif /* _SIMIX_SIMIX_H */ diff --git a/src/simix/private.h b/src/simix/private.h index 293b0a0700..630a5b0045 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -33,12 +33,9 @@ typedef struct SIMIX_Global { xbt_fifo_t host; xbt_swag_t process_to_run; xbt_swag_t process_list; - /* xbt_swag_t process_sleeping; */ smx_process_t current_process; xbt_dict_t registered_functions; -/* FILE *paje_output; - int session; */ } s_SIMIX_Global_t, *SIMIX_Global_t; extern SIMIX_Global_t simix_global; @@ -52,12 +49,8 @@ typedef struct s_simdata_process { 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 */ -// int paje_state; /* the number of states stacked with Paje */ } s_simdata_process_t; typedef struct process_arg { @@ -93,11 +86,6 @@ typedef struct s_simdata_action { xbt_fifo_t cond_list; /* conditional variables that must be signaled when the action finish. */ smx_host_t source; -/* control needed when the action blocks a process(__SIMIX_process_block). For each process that is blocked a new action is created, the process is stocked in cond_process variable and the "boolean" action_block is marked to 1 */ - int action_block; /* simix control variable, system action or not */ - smx_process_t cond_process; /* system process will wake up */ - smx_cond_t timeout_cond; /* useful to remove the process from the sleeping list when a timeout occurs */ - } s_simdata_action_t; @@ -112,15 +100,6 @@ extern int _simix_init_status; /* 0: beginning of time; extern xbt_cfg_t _simix_cfg_set; - - - - -//#define PROCESS_SET_ERRNO(val) (SIMIX_process_self()->simdata->last_errno=val) -//#define PROCESS_GET_ERRNO() (SIMIX_process_self()->simdata->last_errno) -//#define SIMIX_RETURN(val) do {PROCESS_SET_ERRNO(val);return(val);} while(0) -/* #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(SIMIX_host_self()->simdata->host)==SURF_CPU_ON,\ "Host failed, you cannot call this function.") @@ -128,19 +107,9 @@ extern xbt_cfg_t _simix_cfg_set; smx_host_t __SIMIX_host_create(const char *name, void *workstation, void *data); void __SIMIX_host_destroy(smx_host_t host); -int __SIMIX_process_block(double max_duration); -void __SIMIX_process_unblock(smx_process_t process); -int __SIMIX_process_isBlocked(smx_process_t process); +void __SIMIX_cond_wait(smx_cond_t cond); void __SIMIX_display_process_status(void); -void __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_task_wait_event(smx_process_t process, m_task_t task); -*/ - #endif diff --git a/src/simix/smx_action.c b/src/simix/smx_action.c index dbde45337c..ac4560010b 100644 --- a/src/simix/smx_action.c +++ b/src/simix/smx_action.c @@ -14,8 +14,15 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_action, simix, /************************************* Actions *********************************/ -smx_action_t SIMIX_communicate(smx_host_t sender,smx_host_t receiver,char * name, double size, double rate) +smx_action_t SIMIX_action_communicate(smx_host_t sender,smx_host_t receiver,char * name, double size, double rate) { + /* check if the host is active */ + if ( surf_workstation_resource->extension_public->get_state(sender->simdata->host)!=SURF_CPU_ON) { + THROW1(1,1,"Host %s failed, you cannot call this function",sender->name); + } + if ( surf_workstation_resource->extension_public->get_state(receiver->simdata->host)!=SURF_CPU_ON) { + THROW1(1,1,"Host %s failed, you cannot call this function",receiver->name); + } /* alloc structures */ smx_action_t act = xbt_new0(s_smx_action_t,1); @@ -25,9 +32,6 @@ smx_action_t SIMIX_communicate(smx_host_t sender,smx_host_t receiver,char * name /* initialize them */ act->name = xbt_strdup(name); - simdata->action_block=0; - simdata->cond_process=NULL; - simdata->timeout_cond = NULL; simdata->surf_action = surf_workstation_resource->extension_public-> @@ -38,9 +42,13 @@ smx_action_t SIMIX_communicate(smx_host_t sender,smx_host_t receiver,char * name return act; } -smx_action_t SIMIX_execute(smx_host_t host, char * name, double amount) +smx_action_t SIMIX_action_execute(smx_host_t host, char * name, double amount) { - CHECK_HOST(); + /* check if the host is active */ + if ( surf_workstation_resource->extension_public->get_state(host->simdata->host)!=SURF_CPU_ON) { + THROW1(1,1,"Host %s failed, you cannot call this function",host->name); + } + /* alloc structures */ smx_action_t act = xbt_new0(s_smx_action_t,1); act->simdata = xbt_new0(s_simdata_action_t,1); @@ -50,9 +58,6 @@ smx_action_t SIMIX_execute(smx_host_t host, char * name, double amount) /* initialize them */ simdata->source = host; act-> name = xbt_strdup(name); - simdata->action_block=0; - simdata->cond_process=NULL; - simdata->timeout_cond = NULL; /* set communication */ simdata->surf_action = surf_workstation_resource->extension_public-> @@ -63,6 +68,29 @@ smx_action_t SIMIX_execute(smx_host_t host, char * name, double amount) return act; } + +smx_action_t SIMIX_action_sleep(smx_host_t host, double duration) +{ + char name[] = "sleep"; + /* alloc structures */ + smx_action_t act = xbt_new0(s_smx_action_t,1); + act->simdata = xbt_new0(s_simdata_action_t,1); + simdata_action_t simdata = act->simdata; + simdata->cond_list = xbt_fifo_new(); + + /* initialize them */ + simdata->source = host; + act->name = xbt_strdup(name); + + simdata->surf_action = surf_workstation_resource->extension_public-> + sleep(host->simdata->host, duration); + + surf_workstation_resource->common_public->action_set_data(simdata->surf_action,act); + + return act; +} + + void SIMIX_action_cancel(smx_action_t action) { xbt_assert0((action != NULL), "Invalid parameter"); @@ -107,33 +135,3 @@ void SIMIX_register_action_to_condition(smx_action_t action, smx_cond_t cond) xbt_fifo_push(cond->actions,action); } -void __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; - } 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; - } else { - if(surf_workstation_resource->common_public->action_free(simdata->surf_action)) - simdata->surf_action = NULL; - } - return; - -} diff --git a/src/simix/smx_deployment.c b/src/simix/smx_deployment.c index dd0680734b..e5a9f119d9 100644 --- a/src/simix/smx_deployment.c +++ b/src/simix/smx_deployment.c @@ -23,7 +23,7 @@ static double kill_time = -1.0; static void parse_process_init(void) { - parse_host = SIMIX_get_host_by_name(A_surfxml_process_host); + parse_host = SIMIX_host_get_by_name(A_surfxml_process_host); xbt_assert1(parse_host, "Unknown host %s",A_surfxml_process_host); parse_code = SIMIX_get_registered_function(A_surfxml_process_function); xbt_assert1(parse_code, "Unknown function %s",A_surfxml_process_function); diff --git a/src/simix/smx_environment.c b/src/simix/smx_environment.c index 56047924b0..f346e642b5 100644 --- a/src/simix/smx_environment.c +++ b/src/simix/smx_environment.c @@ -21,26 +21,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_environment, simix, /********************************* SIMIX **************************************/ -/** \ingroup msg_easier_life - * \brief A name directory service... - * - * Finds a m_host_t using its name. - * \param name the name of an host. - * \return the corresponding host - */ -smx_host_t SIMIX_get_host_by_name(const char *name) -{ - xbt_fifo_item_t i = NULL; - smx_host_t host = NULL; - xbt_assert0(((simix_global != NULL) - && (simix_global->host != NULL)), "Environment not set yet"); - - xbt_fifo_foreach(simix_global->host,i,host,smx_host_t) { - if(strcmp(host->name, name) == 0) return host; - } - return NULL; -} /** \ingroup msg_easier_life * \brief A platform constructor. diff --git a/src/simix/smx_global.c b/src/simix/smx_global.c index c35edaf7c3..7335b59e23 100644 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@ -13,7 +13,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix, "Logging specific to SIMIX (kernel)"); -int __stop_time = -1.0 ; SIMIX_Global_t simix_global = NULL; @@ -43,7 +42,7 @@ void SIMIX_global_init(int *argc, char **argv) s_smx_process_t proc; if (!simix_global) { - surf_init(argc, argv); /* Initialize some common structures. Warning, it sets msg_global=NULL */ + surf_init(argc, argv); /* Initialize some common structures. Warning, it sets simix_global=NULL */ simix_global = xbt_new0(s_SIMIX_Global_t,1); @@ -60,8 +59,8 @@ void SIMIX_global_init(int *argc, char **argv) void __SIMIX_display_process_status(void) { smx_process_t process = NULL; - //xbt_fifo_item_t item = NULL; - //int i; + xbt_fifo_item_t item = NULL; + smx_action_t act; int nbprocess=xbt_swag_size(simix_global->process_list); INFO1("SIMIX: %d processes are still running, waiting for something.", @@ -76,9 +75,19 @@ void __SIMIX_display_process_status(void) asprintf(&who,"SIMIX: %s on %s: %s", process->name, p_simdata->host->name, - (process->simdata->blocked)?"[blocked] " - :((process->simdata->suspended)?"[suspended] ":"")); - + (process->simdata->blocked)?"[BLOCKED] " + :((process->simdata->suspended)?"[SUSPENDED] ":"")); + if (p_simdata->mutex) { + DEBUG1("Block on a mutex: %s", who); + } + else if (p_simdata->cond) { + DEBUG1("Block on a condition: %s", who); + DEBUG0("Waiting actions:"); + xbt_fifo_foreach(p_simdata->cond->actions,item, act, smx_action_t) { + DEBUG1("\t %s", act->name); + } + } + else DEBUG1("Unknown block status: %s", who); free(who); } } @@ -96,13 +105,13 @@ static void _XBT_CALL inthandler(int ignored) /** \ingroup msg_simulation * \brief Launch the SIMIX simulation */ -void SIMIX_main(void) +void __SIMIX_main(void) { smx_process_t process = NULL; smx_cond_t cond = NULL; - int i; - double elapsed_time = 0.0; - int state_modifications = 1; + smx_action_t smx_action; + xbt_fifo_t actions_done = xbt_fifo_new(); + xbt_fifo_t actions_failed = xbt_fifo_new(); /* Prepare to display some more info when dying on Ctrl-C pressing */ signal(SIGINT,inthandler); @@ -111,173 +120,43 @@ void SIMIX_main(void) fflush(stdout); fflush(stderr); - surf_solve(); /* Takes traces into account. Returns 0.0 */ + //surf_solve(); /* Takes traces into account. Returns 0.0 */ /* xbt_fifo_size(msg_global->process_to_run) */ - while (1) { - xbt_context_empty_trash(); - if(xbt_swag_size(simix_global->process_to_run) && (elapsed_time>0)) { - DEBUG0("**************************************************"); - } - - if((__stop_time>0) && (SIMIX_get_clock() >= __stop_time)) { - DEBUG0("Let's stop here!"); - } - while ((process = xbt_swag_extract(simix_global->process_to_run))) { - DEBUG2("Scheduling %s on %s", - process->name, - process->simdata->host->name); - simix_global->current_process = process; - xbt_context_schedule(process->simdata->context); - /* fflush(NULL); */ - simix_global->current_process = NULL; - } + while (SIMIX_solve(actions_done, actions_failed) != -1.0) { - { - surf_action_t action = NULL; - surf_resource_t resource = NULL; - smx_action_t smx_action = NULL; + while ( (smx_action = xbt_fifo_pop(actions_failed)) ) { - void *fun = NULL; - void *arg = NULL; + xbt_fifo_item_t _cursor; - xbt_dynar_foreach(resource_list, i, resource) { - if(xbt_swag_size(resource->common_public->states.failed_action_set) || - xbt_swag_size(resource->common_public->states.done_action_set)) - state_modifications = 1; - } - - if(!state_modifications) { - DEBUG1("%f : Calling surf_solve",SIMIX_get_clock()); - elapsed_time = surf_solve(); - DEBUG1("Elapsed_time %f",elapsed_time); - - if (elapsed_time<0.0) { - /* fprintf(stderr, "We're done %g\n",elapsed_time); */ - break; + DEBUG1("** %s failed **",smx_action->name); + xbt_fifo_foreach(smx_action->simdata->cond_list,_cursor,cond,smx_cond_t) { + xbt_swag_foreach(process,cond->sleeping) { + DEBUG2("\t preparing to wake up %s on %s", + process->name, process->simdata->host->name); } + SIMIX_cond_broadcast(cond); + /* remove conditional from action */ + xbt_fifo_remove(smx_action->simdata->cond_list,cond); } + } - while (surf_timer_resource->extension_public->get(&fun,(void*)&arg)) { - DEBUG2("got %p %p", fun, arg); - if(fun==SIMIX_process_create_with_arguments) { - process_arg_t args = arg; - DEBUG2("Launching %s on %s", args->name, args->host->name); - process = SIMIX_process_create_with_arguments(args->name, args->code, - args->data, args->host, - args->argc,args->argv); - if(args->kill_time > SIMIX_get_clock()) { - surf_timer_resource->extension_public->set(args->kill_time, - (void*) &SIMIX_process_kill, - (void*) process); - } - xbt_free(args); - } - if(fun==SIMIX_process_kill) { - process = arg; - DEBUG2("Killing %s on %s", process->name, - process->simdata->host->name); - SIMIX_process_kill(process); - } - } - - /* Wake up all process waiting for the action finish */ - xbt_dynar_foreach(resource_list, i, resource) { - while ((action = - xbt_swag_extract(resource->common_public->states. - failed_action_set))) { - smx_action = action->data; - if (smx_action) { - xbt_fifo_item_t _cursor; - - DEBUG1("** %s failed **",smx_action->name); - /* put all the process that are waiting in a conditional (dummy action) on the process_to_run list */ - if ( smx_action->simdata->action_block) { - xbt_swag_insert(smx_action->simdata->cond_process,simix_global->process_to_run); - } - /* else, do the dummy action finish, call the signal broadcast */ - else { - xbt_fifo_foreach(smx_action->simdata->cond_list,_cursor,cond,smx_cond_t) { - xbt_swag_foreach(process,cond->sleeping) { - DEBUG2("\t preparing to wake up %s on %s", - process->name, process->simdata->host->name); - } - SIMIX_cond_broadcast(cond); - /* remove conditional from action */ - xbt_fifo_remove(smx_action->simdata->cond_list,cond); - } - } - process=NULL; - } - } - while ((action = - xbt_swag_extract(resource->common_public->states. - done_action_set))) { - smx_action = action->data; - if (smx_action) { - xbt_fifo_item_t _cursor; - - DEBUG1("** %s done **",smx_action->name); - /* put all the process that are waiting in a conditional (dummy action) on the process_to_run list */ - if ( smx_action->simdata->action_block) { - if (smx_action->simdata->timeout_cond) { - xbt_swag_remove(smx_action->simdata->cond_process,smx_action->simdata->timeout_cond->sleeping); - } - process = smx_action->simdata->cond_process; - xbt_swag_insert(smx_action->simdata->cond_process,simix_global->process_to_run); - DEBUG2("\t preparing to wake up %s on %s", - process->name, process->simdata->host->name); - } - /* else, do the dummy action finish, call the signal broadcast */ - else { - xbt_fifo_foreach(smx_action->simdata->cond_list,_cursor,cond,smx_cond_t) { - xbt_swag_foreach(process,cond->sleeping) { - DEBUG2("\t preparing to wake up %s on %s", - process->name, process->simdata->host->name); - } - SIMIX_cond_broadcast(cond); - /* remove conditional from action */ - xbt_fifo_remove(smx_action->simdata->cond_list,cond); - } - } - process=NULL; - } -/* - if (smx_action) { - xbt_fifo_item_t _cursor; - - DEBUG1("** %s done **",smx_action->name); - xbt_fifo_foreach(smx_action->simdata->cond_list,_cursor,cond,smx_cond_t) { - SIMIX_cond_broadcast(cond); - xbt_swag_foreach(process,cond->sleeping) { - DEBUG2("\t preparing to wake up %s on %s", - process->name, process->simdata->host->name); - } - } - process=NULL; - }*/ + while ( (smx_action = xbt_fifo_pop(actions_done)) ) { + xbt_fifo_item_t _cursor; + DEBUG1("** %s done **",smx_action->name); + xbt_fifo_foreach(smx_action->simdata->cond_list,_cursor,cond,smx_cond_t) { + xbt_swag_foreach(process,cond->sleeping) { + DEBUG2("\t preparing to wake up %s on %s", + process->name, process->simdata->host->name); } + SIMIX_cond_broadcast(cond); + /* remove conditional from action */ + xbt_fifo_remove(smx_action->simdata->cond_list,cond); } } - state_modifications = 0; - } - - if (xbt_swag_size(simix_global->process_list) == 0) { - INFO0("Congratulations ! Simulation terminated : all processes are over"); - return; - } else { - INFO0("Oops ! Deadlock or code not perfectly clean."); - __SIMIX_display_process_status(); - if(XBT_LOG_ISENABLED(simix, xbt_log_priority_debug) || - XBT_LOG_ISENABLED(simix_kernel, xbt_log_priority_debug)) { - DEBUG0("Aborting!"); - xbt_abort(); - } - - INFO0("Return a Warning."); - return; } + return; } /** \ingroup msg_simulation @@ -338,6 +217,121 @@ void SIMIX_clean(void) /** \ingroup msg_easier_life * \brief A clock (in second). */ -double SIMIX_get_clock(void) { +double SIMIX_get_clock(void) +{ return surf_get_clock(); } + +double SIMIX_solve(xbt_fifo_t actions_done, xbt_fifo_t actions_failed) +{ + + smx_process_t process = NULL; + int i; + double elapsed_time = 0.0; + int state_modifications = 0; + + + //surf_solve(); /* Takes traces into account. Returns 0.0 I don't know what to do with this*/ + + xbt_context_empty_trash(); + if(xbt_swag_size(simix_global->process_to_run) && (elapsed_time>0)) { + DEBUG0("**************************************************"); + } + + while ((process = xbt_swag_extract(simix_global->process_to_run))) { + DEBUG2("Scheduling %s on %s", + process->name, + process->simdata->host->name); + simix_global->current_process = process; + xbt_context_schedule(process->simdata->context); + /* fflush(NULL); */ + simix_global->current_process = NULL; + } + + { + surf_action_t action = NULL; + surf_resource_t resource = NULL; + smx_action_t smx_action = NULL; + + void *fun = NULL; + void *arg = NULL; + + xbt_dynar_foreach(resource_list, i, resource) { + if(xbt_swag_size(resource->common_public->states.failed_action_set) || + xbt_swag_size(resource->common_public->states.done_action_set)) + state_modifications = 1; + } + + if(!state_modifications) { + DEBUG1("%f : Calling surf_solve",SIMIX_get_clock()); + elapsed_time = surf_solve(); + DEBUG1("Elapsed_time %f",elapsed_time); + } + + while (surf_timer_resource->extension_public->get(&fun,(void*)&arg)) { + DEBUG2("got %p %p", fun, arg); + if(fun==SIMIX_process_create_with_arguments) { + process_arg_t args = arg; + DEBUG2("Launching %s on %s", args->name, args->host->name); + process = SIMIX_process_create_with_arguments(args->name, args->code, + args->data, args->host, + args->argc,args->argv); + if(args->kill_time > SIMIX_get_clock()) { + surf_timer_resource->extension_public->set(args->kill_time, + (void*) &SIMIX_process_kill, + (void*) process); + } + xbt_free(args); + } + if(fun==SIMIX_process_kill) { + process = arg; + DEBUG2("Killing %s on %s", process->name, + process->simdata->host->name); + SIMIX_process_kill(process); + } + } + + /* Wake up all process waiting for the action finish */ + xbt_dynar_foreach(resource_list, i, resource) { + while ((action = xbt_swag_extract(resource->common_public->states.failed_action_set))) { + smx_action = action->data; + if (smx_action) { + xbt_fifo_unshift(actions_failed,smx_action); + } + } + while ((action =xbt_swag_extract(resource->common_public->states.done_action_set))) { + smx_action = action->data; + if (smx_action) { + xbt_fifo_unshift(actions_done,smx_action); + } + } + } + } + + if (elapsed_time == -1) { + if (xbt_swag_size(simix_global->process_list) == 0) { + INFO0("Congratulations ! Simulation terminated : all processes are over"); + } else { + INFO0("Oops ! Deadlock or code not perfectly clean."); + __SIMIX_display_process_status(); + if(XBT_LOG_ISENABLED(simix, xbt_log_priority_debug) || + XBT_LOG_ISENABLED(simix_kernel, xbt_log_priority_debug)) { + DEBUG0("Aborting!"); + xbt_abort(); + } + INFO0("Return a Warning."); + } + } + return elapsed_time; +} + + +void SIMIX_timer_set (double date, void *function, void *arg) +{ + surf_timer_resource->extension_public->set(date, function, arg); +} + +int SIMIX_timer_get(void **function, void **arg) +{ + return surf_timer_resource->extension_public->get(function, arg); +} diff --git a/src/simix/smx_host.c b/src/simix/smx_host.c index d700fef4b2..650162799d 100644 --- a/src/simix/smx_host.c +++ b/src/simix/smx_host.c @@ -139,7 +139,7 @@ void __SIMIX_host_destroy(smx_host_t host) /** \ingroup m_host_management * \brief Return the current number of #m_host_t. */ -int SIMIX_get_host_number(void) +int SIMIX_host_get_number(void) { return (xbt_fifo_size(simix_global->host)); } @@ -147,7 +147,7 @@ int SIMIX_get_host_number(void) /** \ingroup m_host_management * \brief Return a array of all the #m_host_t. */ -smx_host_t *SIMIX_get_host_table(void) +smx_host_t *SIMIX_host_get_table(void) { return ((smx_host_t *)xbt_fifo_to_array(simix_global->host)); } @@ -157,12 +157,20 @@ smx_host_t *SIMIX_get_host_table(void) * \brief Return the speed of the processor (in Mflop/s), regardless of the current load on the machine. */ -double SIMIX_get_host_speed(smx_host_t h) +double SIMIX_host_get_speed(smx_host_t host) { - xbt_assert0((h!= NULL), "Invalid parameters"); + xbt_assert0((host!= NULL), "Invalid parameters"); return(surf_workstation_resource-> - extension_public->get_speed(h->simdata->host,1.0)); + extension_public->get_speed(host->simdata->host,1.0)); +} + +double SIMIX_host_get_available_speed(smx_host_t host) +{ + xbt_assert0((host!= NULL), "Invalid parameters"); + + return(surf_workstation_resource-> + extension_public->get_available_speed(host->simdata->host)); } /** \ingroup msg_gos_functions @@ -170,16 +178,36 @@ double SIMIX_get_host_speed(smx_host_t h) * * \param h host to test */ -int SIMIX_host_is_avail (smx_host_t h) + +/** \ingroup msg_easier_life + * \brief A name directory service... + * + * Finds a m_host_t using its name. + * \param name the name of an host. + * \return the corresponding host + */ + +smx_host_t SIMIX_host_get_by_name(const char *name) { - e_surf_cpu_state_t cpustate; - xbt_assert0((h!= NULL), "Invalid parameters"); + xbt_fifo_item_t i = NULL; + smx_host_t host = NULL; + + xbt_assert0(((simix_global != NULL) + && (simix_global->host != NULL)), "Environment not set yet"); + + xbt_fifo_foreach(simix_global->host,i,host,smx_host_t) { + if(strcmp(host->name, name) == 0) return host; + } + return NULL; +} - cpustate = - surf_workstation_resource->extension_public->get_state(h->simdata->host); +int SIMIX_host_get_state(smx_host_t host) +{ + xbt_assert0((host!= NULL), "Invalid parameters"); - xbt_assert0((cpustate == SURF_CPU_ON || cpustate == SURF_CPU_OFF), - "Invalid cpu state"); + return(surf_workstation_resource-> + extension_public->get_state(host->simdata->host)); - return (cpustate==SURF_CPU_ON); } + + diff --git a/src/simix/smx_process.c b/src/simix/smx_process.c index 08f6c8ce22..9c65d07a75 100644 --- a/src/simix/smx_process.c +++ b/src/simix/smx_process.c @@ -164,29 +164,6 @@ void SIMIX_process_kill(smx_process_t process) } } -/** \ingroup m_process_management - * \brief Migrates an agent to another location. - * - * This functions checks whether \a process and \a host are valid pointers - and change the value of the #m_host_t on which \a process is running. - */ -void SIMIX_process_change_host(smx_process_t process, smx_host_t host) -{ - simdata_process_t simdata = NULL; - - /* Sanity check */ - - xbt_assert0(((process) && (process->simdata) - && (host)), "Invalid parameters"); - simdata = process->simdata; - - xbt_swag_remove(process,simdata->host->simdata->process_list); - simdata->host = host; - xbt_swag_insert(process,host->simdata->process_list); - - return ; -} - /** \ingroup m_process_management * \brief Return the user data of a #m_process_t. * @@ -286,18 +263,25 @@ void SIMIX_process_suspend(smx_process_t process) surf_workstation_resource->common_public->suspend(act->simdata->surf_action); } } - else if (simdata->block_action) { + else { simdata->suspended = 1; } - else xbt_assert0(0, "Unknown process status"); - } else { /* process executing, I can create an action and suspend it */ process->simdata->suspended = 1; - __SIMIX_process_block(-1); - process->simdata->suspended = 0; - + smx_action_t dummy; + smx_cond_t cond; + char name[] = "dummy"; + + cond = SIMIX_cond_init(); + dummy = SIMIX_action_execute(SIMIX_process_get_host(process), name, 0); + surf_workstation_resource->common_public->set_priority(dummy->simdata->surf_action,0.0); + SIMIX_register_condition_to_action(dummy,cond); + SIMIX_register_action_to_condition(dummy,cond); + __SIMIX_cond_wait(cond); + //SIMIX_action_destroy(dummy); + //SIMIX_cond_destroy(cond); } return ; } @@ -338,12 +322,10 @@ void SIMIX_process_resume(smx_process_t process) } return; } - else if (simdata->block_action){ + else { simdata->suspended = 0; - surf_workstation_resource->common_public->resume(simdata->block_action->simdata->surf_action); - return; + xbt_swag_insert(process,simix_global->process_to_run); } - else xbt_assert0(0, "Unknown status"); } @@ -360,90 +342,5 @@ int SIMIX_process_is_suspended(smx_process_t process) return (process->simdata->suspended); } -int __SIMIX_process_block(double max_duration) -{ - - smx_process_t process = SIMIX_process_self(); - smx_action_t dummy = NULL; - char name[] = "dummy"; - - dummy = SIMIX_execute(SIMIX_process_get_host(process), name, 0); - dummy->simdata->action_block=1; - - /* process which will wake up when this system action finish */ - dummy->simdata->cond_process = process; - - 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); - dummy->simdata->timeout_cond = process->simdata->cond; - } - __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"); - } - - return 1; -} - -void __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"); - simdata = process->simdata; - if(!(simdata->block_action)) { - xbt_assert0(0,"Process is not blocked !"); - return; - } - - simdata_action = simdata->block_action->simdata; - xbt_assert0(simdata->blocked,"Process not blocked"); - surf_workstation_resource->common_public->resume(simdata_action->surf_action); - return ; - -/* - simdata_process_t simdata = NULL; - simdata_task_t simdata_task = NULL; - - xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters"); - CHECK_HOST(); - - XBT_IN2(": %s unblocking %s", SIMIX_process_self()->name,process->name); - - simdata = process->simdata; - 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; - - xbt_assert0(simdata->blocked,"Process not blocked"); - - surf_workstation_resource->common_public->resume(simdata_task->compute); - - XBT_OUT; -*/ -} - -int __SIMIX_process_isBlocked(smx_process_t process) -{ - xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters"); - - return (process->simdata->blocked); -} diff --git a/src/simix/smx_synchro.c b/src/simix/smx_synchro.c index 9e067c7a71..c14e550ab2 100644 --- a/src/simix/smx_synchro.c +++ b/src/simix/smx_synchro.c @@ -37,7 +37,13 @@ void SIMIX_mutex_lock(smx_mutex_t mutex) /* somebody using the mutex, block */ xbt_swag_insert(self, mutex->sleeping); self->simdata->mutex = mutex; - __SIMIX_process_block(-1); + /* wait for some process make the unlock and wake up me from mutex->sleeping */ + xbt_context_yield(); + /* verify if the process was suspended */ + while (self->simdata->suspended) { + xbt_context_yield(); + } + self->simdata->mutex = NULL; mutex->using = 1; } @@ -47,6 +53,7 @@ void SIMIX_mutex_lock(smx_mutex_t mutex) } return; } + /* return 1 if the process got the mutex, else 0. */ int SIMIX_mutex_trylock(smx_mutex_t mutex) { @@ -69,10 +76,10 @@ void SIMIX_mutex_unlock(smx_mutex_t mutex) if (xbt_swag_size(mutex->sleeping) > 0) { p = xbt_swag_extract(mutex->sleeping); mutex->using = 0; - __SIMIX_process_unblock(p); + xbt_swag_insert(p, simix_global->process_to_run); } else { - /* nobody to wape up */ + /* nobody to wake up */ mutex->using = 0; } return; @@ -108,7 +115,7 @@ void SIMIX_cond_signal(smx_cond_t cond) if (xbt_swag_size(cond->sleeping) >= 1) { proc = xbt_swag_extract(cond->sleeping); - __SIMIX_process_unblock(proc); + xbt_swag_insert(proc, simix_global->process_to_run); } return; @@ -116,41 +123,62 @@ void SIMIX_cond_signal(smx_cond_t cond) void SIMIX_cond_wait(smx_cond_t cond,smx_mutex_t mutex) { - /* call the function with timeout, with max_duration > 0 - * the process is blocked forever */ - SIMIX_cond_wait_timeout(cond, mutex, -1); + smx_process_t self = SIMIX_process_self(); + xbt_assert0((mutex != NULL), "Invalid parameters"); + + cond->mutex = mutex; + + SIMIX_mutex_unlock(mutex); + __SIMIX_cond_wait(cond); + /* get the mutex again */ + self->simdata->mutex = cond->mutex; + SIMIX_mutex_lock(cond->mutex); + return; } -void SIMIX_cond_wait_timeout(smx_cond_t cond,smx_mutex_t mutex, double max_duration) +void __SIMIX_cond_wait(smx_cond_t cond) { smx_process_t self = SIMIX_process_self(); - - xbt_assert0((mutex != NULL), "Invalid parameters"); + xbt_assert0((cond != NULL), "Invalid parameters"); /* process status */ self->simdata->cond = cond; + xbt_swag_insert(self, cond->sleeping); + + xbt_context_yield(); + self->simdata->cond = NULL; + while (self->simdata->suspended) { + xbt_context_yield(); + } + return; + +} + +void SIMIX_cond_wait_timeout(smx_cond_t cond,smx_mutex_t mutex, double max_duration) +{ + smx_process_t self = SIMIX_process_self(); + xbt_assert0((mutex != NULL), "Invalid parameters"); + smx_action_t act_sleep; + cond->mutex = mutex; SIMIX_mutex_unlock(mutex); - xbt_swag_insert(self, cond->sleeping); - /* creates a new action to be the timeout */ if (max_duration >=0) { - __SIMIX_process_block(max_duration); - self->simdata->cond = NULL; - } - else { - __SIMIX_process_block(-1); - self->simdata->cond = NULL; + act_sleep = SIMIX_action_sleep(SIMIX_host_self(), max_duration); + SIMIX_register_action_to_condition(act_sleep,cond); + SIMIX_register_condition_to_action(act_sleep,cond); } + __SIMIX_cond_wait(cond); + /* get the mutex again */ + self->simdata->mutex = cond->mutex; SIMIX_mutex_lock(cond->mutex); return; } - void SIMIX_cond_broadcast(smx_cond_t cond) { xbt_assert0((cond != NULL), "Invalid parameters"); @@ -158,8 +186,8 @@ void SIMIX_cond_broadcast(smx_cond_t cond) smx_process_t proc_next = NULL; xbt_swag_foreach_safe(proc,proc_next,cond->sleeping) { - __SIMIX_process_unblock(proc); xbt_swag_remove(proc,cond->sleeping); + xbt_swag_insert(proc, simix_global->process_to_run); } return;