X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/c2bf63103e5914cb2245c77d45adc47e9a302889..2ddd4202532d54d217533b97ffde98f1ab078a11:/src/simix/private.h diff --git a/src/simix/private.h b/src/simix/private.h index 293b0a0700..5a635c3c34 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -9,138 +9,313 @@ #ifndef SIMIX_PRIVATE_H #define SIMIX_PRIVATE_H +#include #include "simix/simix.h" #include "surf/surf.h" #include "xbt/fifo.h" #include "xbt/swag.h" #include "xbt/dict.h" -#include "xbt/context.h" #include "xbt/config.h" +#include "xbt/function_types.h" -/******************************* Datatypes **********************************/ +/******************************** Datatypes ***********************************/ -/********************************** Host ************************************/ +/*********************************** Host *************************************/ -typedef struct s_simdata_host { - void *host; /* SURF modeling */ +/** @brief Host datatype + @ingroup m_datatypes_management_details */ +typedef struct s_smx_host { + char *name; /**< @brief host name if any */ + void *host; /* SURF modeling */ xbt_swag_t process_list; -} s_simdata_host_t; + void *data; /**< @brief user data */ +} s_smx_host_t; -/********************************* Simix Global ******************************/ +/********************************** Simix Global ******************************/ + +typedef struct s_smx_context_factory *smx_context_factory_t; typedef struct SIMIX_Global { - xbt_fifo_t host; + smx_context_factory_t context_factory; + xbt_dict_t host; xbt_swag_t process_to_run; xbt_swag_t process_list; - /* xbt_swag_t process_sleeping; */ - + xbt_swag_t process_to_destroy; smx_process_t current_process; + smx_process_t maestro_process; xbt_dict_t registered_functions; -/* FILE *paje_output; - int session; */ + smx_creation_func_t create_process_function; + void_f_pvoid_t kill_process_function; + void_f_pvoid_t cleanup_process_function; } s_SIMIX_Global_t, *SIMIX_Global_t; extern SIMIX_Global_t simix_global; -/******************************* Process *************************************/ - -typedef struct s_simdata_process { - smx_host_t host; /* the host on which the process is running */ - 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 */ -// int paje_state; /* the number of states stacked with Paje */ -} s_simdata_process_t; - -typedef struct process_arg { +/******************************** Process *************************************/ + +typedef struct s_smx_context *smx_context_t; + +/** @brief Process datatype + @ingroup m_datatypes_management_details @{ */ + typedef struct s_smx_process { + s_xbt_swag_hookup_t process_hookup; + s_xbt_swag_hookup_t synchro_hookup; + s_xbt_swag_hookup_t host_proc_hookup; + s_xbt_swag_hookup_t destroy_hookup; + + char *name; /**< @brief process name if any */ + smx_host_t smx_host; /* the host on which the process is running */ + smx_context_t context; /* the context that executes the scheduler function */ + int argc; /* arguments number if any */ + char **argv; /* arguments table if any */ + int blocked : 1; + int suspended : 1; + int iwannadie : 1; + smx_mutex_t mutex; /* mutex on which the process is blocked */ + smx_cond_t cond; /* cond on which the process is blocked */ + xbt_dict_t properties; + void *data; /* kept for compatibility, it should be replaced with moddata */ + void_f_pvoid_t cleanup_func; + void *cleanup_arg; + + } s_smx_process_t; +/** @} */ + +typedef struct s_smx_process_arg { const char *name; - smx_process_code_t code; + xbt_main_func_t code; void *data; - smx_host_t host; + char *hostname; int argc; char **argv; double kill_time; -} s_process_arg_t, *process_arg_t; + xbt_dict_t properties; +} s_smx_process_arg_t, *smx_process_arg_t; + +void SIMIX_process_empty_trash(void); +void __SIMIX_process_schedule(smx_process_t process); +void __SIMIX_process_yield(void); -/********************************* Mutex and Conditional ****************************/ +/*************************** Mutex and Conditional ****************************/ typedef struct s_smx_mutex { - xbt_swag_t sleeping; /* list of sleeping process */ - int using; + + /* KEEP IT IN SYNC WITH src/xbt_sg_thread.c::struct s_xbt_mutex */ + xbt_swag_t sleeping; /* list of sleeping process */ + int refcount; + /* KEEP IT IN SYNC WITH src/xbt_sg_thread.c::struct s_xbt_mutex */ } s_smx_mutex_t; typedef struct s_smx_cond { - xbt_swag_t sleeping; /* list of sleeping process */ - smx_mutex_t mutex; - xbt_fifo_t actions; /* list of actions */ - -} s_smx_cond_t; - -/********************************* Action **************************************/ - -typedef struct s_simdata_action { - surf_action_t surf_action; /* SURF modeling of computation */ - - 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; - - - -/******************************* Configuration support **********************************/ - -void simix_config_init(void); /* create the config set, call this before use! */ -void simix_config_finalize(void); /* destroy the config set, call this at cleanup. */ -extern int _simix_init_status; /* 0: beginning of time; - 1: pre-inited (cfg_set created); - 2: inited (running) */ -extern xbt_cfg_t _simix_cfg_set; + /* KEEP IT IN SYNC WITH src/xbt_sg_thread.c::struct s_xbt_cond */ + xbt_swag_t sleeping; /* list of sleeping process */ + smx_mutex_t mutex; + xbt_fifo_t actions; /* list of actions */ + /* KEEP IT IN SYNC WITH src/xbt_sg_thread.c::struct s_xbt_cond */ +} s_smx_cond_t; +/********************************* Action *************************************/ +/** @brief Action datatype + @ingroup m_datatypes_management_details */ +typedef struct s_smx_action { + char *name; /**< @brief action name if any */ + xbt_fifo_t cond_list; /*< conditional variables that must be signaled when the action finish. */ + void *data; /**< @brief user data */ + int refcount; /**< @brief reference counter */ + surf_action_t surf_action; /* SURF modeling of computation */ + smx_host_t source; +} s_smx_action_t; +/************************** Configuration support *****************************/ -//#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.") */ +extern int _simix_init_status; /* 0: beginning of time; FIXME: KILLME ? + 1: pre-inited (cfg_set created); + 2: inited (running) */ -#define CHECK_HOST() xbt_assert0(surf_workstation_resource->extension_public-> \ - get_state(SIMIX_host_self()->simdata->host)==SURF_CPU_ON,\ +#define SIMIX_CHECK_HOST() xbt_assert0(surf_workstation_model->extension.workstation. \ + get_state(SIMIX_host_self()->host)==SURF_RESOURCE_ON,\ "Host failed, you cannot call this function.") 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_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); -*/ - +void __SIMIX_host_destroy(void *host); +void __SIMIX_cond_wait(smx_cond_t cond); +void __SIMIX_cond_display_actions(smx_cond_t cond); +void __SIMIX_action_display_conditions(smx_action_t action); +void __SIMIX_create_maestro_process(void); + +/******************************** Context *************************************/ + +void SIMIX_context_mod_init(void); + +void SIMIX_context_mod_exit(void); + +/* *********************** */ +/* Context type definition */ +/* *********************** */ +/* the following function pointers types describe the interface that all context + concepts must implement */ + +/* each context type must contain this macro at its begining -- OOP in C :/ */ +#define SMX_CTX_BASE_T \ + s_xbt_swag_hookup_t hookup; \ + ex_ctx_t *exception; \ + xbt_main_func_t code; \ + +/* all other context types derive from this structure */ +typedef struct s_smx_context { + SMX_CTX_BASE_T; +} s_smx_context_t; + +/* *********************** */ +/* factory type definition */ +/* *********************** */ + +/* Each context implementation define its own context factory + * A context factory is responsable of the creation and manipulation of the + * execution context of all the simulated processes (and maestro) using the + * selected implementation. + * + * For example, the context switch based on java thread use the + * java implementation of the context and the java factory to build and control + * the contexts depending on this implementation. + + * The following function pointer types describe the interface that any context + * factory should implement. + */ + +/* function used to create a new context */ +typedef smx_context_t (*smx_pfn_context_factory_create_context_t) (xbt_main_func_t); + +/* function used to create the context for the maestro process */ +typedef smx_context_t (*smx_pfn_context_factory_create_maestro_context_t) (void); + +/* this function finalize the specified context factory */ +typedef int (*smx_pfn_context_factory_finalize_t) (smx_context_factory_t*); + +/* function used to destroy the specified context */ +typedef void (*smx_pfn_context_free_t) (smx_context_t); + +/* function used to start the specified context */ +typedef void (*smx_pfn_context_start_t) (smx_context_t); + +/* function used to stop the current context */ +typedef void (*smx_pfn_context_stop_t) (int); + +/* function used to suspend the current context */ +typedef void (*smx_pfn_context_suspend_t) (smx_context_t context); + +/* function used to resume the current context */ +typedef void (*smx_pfn_context_resume_t) (smx_context_t old_context, + smx_context_t new_context); + +/* interface of the context factories */ +typedef struct s_smx_context_factory { + smx_pfn_context_factory_create_maestro_context_t create_maestro_context; + smx_pfn_context_factory_create_context_t create_context; + smx_pfn_context_factory_finalize_t finalize; + smx_pfn_context_free_t free; + smx_pfn_context_start_t start; + smx_pfn_context_stop_t stop; + smx_pfn_context_suspend_t suspend; + smx_pfn_context_resume_t resume; + const char *name; +} s_smx_context_factory_t; + +/* Selects a context factory associated with the name specified by the parameter name. + * If successful the function returns 0. Otherwise the function returns the error code. + */ +int SIMIX_context_select_factory(const char *name); + +/* Initializes a context factory from the name specified by the parameter name. + * If the factory cannot be found, an exception is raised. + */ +void SIMIX_context_init_factory_by_name(smx_context_factory_t * factory, const char *name); + +/* All factories init */ +void SIMIX_ctx_thread_factory_init(smx_context_factory_t * factory); + +void SIMIX_ctx_sysv_factory_init(smx_context_factory_t * factory); + +void SIMIX_ctx_java_factory_init(smx_context_factory_t * factory); + +/* ******************************* */ +/* contexts manipulation functions */ +/* ******************************* */ + +/** + * \param smx_process the simix maestro process that contains this context + */ +static inline smx_context_t SIMIX_context_create_maestro() +{ + return (*(simix_global->context_factory->create_maestro_context)) (); +} + +/** + * \param smx_process the simix process that contains this context + * \param code a main function + */ +static inline smx_context_t SIMIX_context_new(xbt_main_func_t code) +{ + return (*(simix_global->context_factory->create_context)) (code); +} + +/* Scenario for the end of a context: + * + * CASE 1: death after end of function + * __context_wrapper, called by os thread, calls smx_context_stop after user code stops + * smx_context_stop calls user cleanup_func if any (in context settings), + * add current to trashbin + * yields back to maestro (destroy os thread on need) + * From time to time, maestro calls smx_context_empty_trash, + * which maps smx_context_free on the content + * smx_context_free frees some more memory, + * joins os thread + * + * CASE 2: brutal death + * smx_context_kill (from any context) + * set context->wannadie to 1 + * yields to the context + * the context is awaken in the middle of __yield. + * At the end of it, it checks that wannadie == 1, and call smx_context_stop + * (same than first case afterward) + */ + +/* Argument must be stopped first -- runs in maestro context */ +static inline void SIMIX_context_free(smx_context_t context) +{ + (*(simix_global->context_factory->free)) (context); +} + +/** + * \param context the context to start + * + * Calling this function prepares \a process to be run. It will + however run effectively only when calling #SIMIX_context_schedule + */ +static inline void SIMIX_context_start(smx_context_t context) +{ + (*(simix_global->context_factory->start)) (context); +} + +static inline void SIMIX_context_stop(int exit_code) +{ + (*(simix_global->context_factory->stop)) (exit_code); +} + +static inline void SIMIX_context_resume(smx_context_t old_context, + smx_context_t new_context) +{ + (*(simix_global->context_factory->resume)) (old_context, new_context); +} + +static inline void SIMIX_context_suspend(smx_context_t context) +{ + (*(simix_global->context_factory->suspend)) (context); +} #endif