X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2ddd4202532d54d217533b97ffde98f1ab078a11..dc061ae1d3507d0e3b7d3569553b31cb6709702e:/src/simix/private.h diff --git a/src/simix/private.h b/src/simix/private.h index 5a635c3c34..d58d6e5b62 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -9,7 +9,6 @@ #ifndef SIMIX_PRIVATE_H #define SIMIX_PRIVATE_H -#include #include "simix/simix.h" #include "surf/surf.h" #include "xbt/fifo.h" @@ -17,6 +16,7 @@ #include "xbt/dict.h" #include "xbt/config.h" #include "xbt/function_types.h" +#include "xbt/ex_interface.h" /******************************** Datatypes ***********************************/ @@ -54,30 +54,27 @@ extern SIMIX_Global_t simix_global; /******************************** Process *************************************/ -typedef struct s_smx_context *smx_context_t; - -/** @brief Process datatype +/** @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 synchro_hookup; /* process_to_run or mutex->sleeping and co */ 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 */ + ex_ctx_t *exception; 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 */ + smx_sem_t sem; /* semaphore on which the process is blocked */ + smx_action_t waiting_action; 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; /** @} */ @@ -93,9 +90,11 @@ typedef struct s_smx_process_arg { xbt_dict_t properties; } s_smx_process_arg_t, *smx_process_arg_t; +void SIMIX_create_maestro_process(void); void SIMIX_process_empty_trash(void); -void __SIMIX_process_schedule(smx_process_t process); -void __SIMIX_process_yield(void); +void SIMIX_process_schedule(smx_process_t process); +ex_ctx_t *SIMIX_process_get_exception(void); +void SIMIX_process_exception_terminate(xbt_ex_t * e); /*************************** Mutex and Conditional ****************************/ @@ -118,13 +117,68 @@ typedef struct s_smx_cond { } s_smx_cond_t; +typedef struct s_smx_sem { + /* KEEP IT IN SYNC WITH src/xbt_sg_thread.c::struct s_xbt_sem */ + xbt_swag_t sleeping; /* list of sleeping process */ + int capacity; + xbt_fifo_t actions; /* list of actions */ + /* KEEP IT IN SYNC WITH src/xbt_sg_thread.c::struct s_xbt_sem */ + +} s_smx_sem_t; + +/******************************* Networking ***********************************/ + +/** @brief Rendez-vous point datatype */ +typedef struct s_smx_rvpoint { + char *name; + smx_mutex_t read; + smx_mutex_t write; + xbt_fifo_t comm_fifo; + void *data; +} s_smx_rvpoint_t; + +typedef struct s_smx_comm { + + + smx_comm_type_t type; /* Type of the communication (comm_send,comm_recv) */ + smx_rdv_t rdv; /* Rendez-vous where the comm is queued */ + smx_sem_t sem; /* Semaphore associated to the surf simulation */ + int refcount; /* Number of processes involved in the cond */ + + /* Surf action data */ + smx_process_t src_proc; + smx_process_t dst_proc; + smx_action_t src_timeout; + smx_action_t dst_timeout; + smx_action_t act; + double rate; + double task_size; + + /* Data to be transfered */ + void *src_buff; + void *dst_buff; + size_t src_buff_size; + size_t *dst_buff_size; + void *data; /* User data associated to communication */ +} s_smx_comm_t; + +void SIMIX_network_copy_data(smx_comm_t comm); +smx_comm_t SIMIX_communication_new(smx_comm_type_t type); +static inline void SIMIX_communication_use(smx_comm_t comm); +static inline void SIMIX_communication_wait_for_completion(smx_comm_t comm, double timeout); +static inline void SIMIX_rdv_push(smx_rdv_t rdv, smx_comm_t comm); +static inline void SIMIX_rdv_remove(smx_rdv_t rdv, smx_comm_t comm); + /********************************* Action *************************************/ +typedef enum {ready, ongoing, done, failed} smx_action_state_t; + /** @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. */ + xbt_fifo_t sem_list; /*< semaphores 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 */ @@ -146,7 +200,6 @@ 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 *************************************/ @@ -163,8 +216,11 @@ void SIMIX_context_mod_exit(void); /* 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; \ + int argc; \ + char **argv; \ + void_f_pvoid_t cleanup_func; \ + void *cleanup_arg; \ /* all other context types derive from this structure */ typedef struct s_smx_context { @@ -189,10 +245,8 @@ typedef struct s_smx_context { */ /* 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); +typedef smx_context_t (*smx_pfn_context_factory_create_context_t) + (xbt_main_func_t, int, char**, void_f_pvoid_t, void*); /* this function finalize the specified context factory */ typedef int (*smx_pfn_context_factory_finalize_t) (smx_context_factory_t*); @@ -204,22 +258,19 @@ typedef void (*smx_pfn_context_free_t) (smx_context_t); 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); +typedef void (*smx_pfn_context_stop_t) (smx_context_t); /* 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); +typedef void (*smx_pfn_context_resume_t) (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; @@ -240,79 +291,82 @@ void SIMIX_context_init_factory_by_name(smx_context_factory_t * factory, const c 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_lua_factory_init(smx_context_factory_t * factory); +void SIMIX_ctx_lua_factory_set_state(void *state); + void SIMIX_ctx_java_factory_init(smx_context_factory_t * factory); -/* ******************************* */ -/* contexts manipulation functions */ -/* ******************************* */ +/* ****************************** */ +/* context manipulation functions */ +/* ****************************** */ -/** - * \param smx_process the simix maestro process that contains this context +/* Scenario for the end of a context: + * + * CASE 1: death after end of the main function + * the context_wrapper, called internally by the context module, calls + * SIMIX_context_stop after user code stops, smx_context_stop calls user + * cleanup_func if any (in context settings), add current process to trashbin + * and yields back to maestro. + * From time to time, maestro calls SIMIX_context_empty_trash, which destroy + * all the process and context data structures, and frees the memory + * + * CASE 2: brutal death + * SIMIX_process_kill (from any process) set process->iwannadie = 1 and then + * schedules the process. Then the process is awaken in the middle of the + * SIMIX_process_yield function, and at the end of it, it checks that + * iwannadie == 1, and call SIMIX_context_stop(same than first case afterward) */ -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 + * \brief creates a new context for a user level process * \param code a main function + * \param argc the number of arguments of the main function + * \param argv the vector of arguments of the main function + * \param cleanup_func the function to call when the context stops + * \param cleanup_arg the argument of the cleanup_func function */ -static inline smx_context_t SIMIX_context_new(xbt_main_func_t code) -{ - return (*(simix_global->context_factory->create_context)) (code); +static inline smx_context_t SIMIX_context_new(xbt_main_func_t code, int argc, + char** argv, + void_f_pvoid_t cleanup_func, + void* cleanup_arg) { + + return (*(simix_global->context_factory->create_context)) + (code, argc, argv, cleanup_func, cleanup_arg); } -/* 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) +/** + * \brief destroy a context + * \param context the context to destroy + * Argument must be stopped first -- runs in maestro context */ - -/* Argument must be stopped first -- runs in maestro context */ -static inline void SIMIX_context_free(smx_context_t 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 + * \brief stops the execution of a context + * \param context to stop */ -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_stop(smx_context_t context) { + (*(simix_global->context_factory->stop)) (context); } -static inline void SIMIX_context_resume(smx_context_t old_context, - smx_context_t new_context) +/** + \brief resumes the execution of a context + \param old_context the actual context from which is resuming + \param new_context the context to resume + */ +static inline void SIMIX_context_resume(smx_context_t new_context) { - (*(simix_global->context_factory->resume)) (old_context, new_context); + (*(simix_global->context_factory->resume)) (new_context); } +/** + \brief suspends a context and return the control back to the one which + scheduled it + \param context the context to be suspended (it must be the running one) + */ static inline void SIMIX_context_suspend(smx_context_t context) { (*(simix_global->context_factory->suspend)) (context);