From: cristianrosa Date: Thu, 2 Dec 2010 16:55:05 +0000 (+0000) Subject: - Move simix_global->current_process to smx_current_context X-Git-Tag: v3.6_beta2~1007 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/9161dd12dbb9c069f5e100d30f56bf7b6f1362f5 - Move simix_global->current_process to smx_current_context - Add data field to smx_context_t (to be used by SIMIX to store the smx_process_t that owns the context) - Add a thread pool to ucontext factory Conflicts: src/simix/smx_process.c git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@8907 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/simix/private.h b/src/simix/private.h index 74a851ee63..53f20eb72b 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -34,7 +34,6 @@ typedef struct SIMIX_Global { xbt_swag_t process_to_run; xbt_swag_t process_list; xbt_swag_t process_to_destroy; - smx_process_t current_process; smx_process_t maestro_process; xbt_dict_t registered_functions; smx_creation_func_t create_process_function; @@ -156,7 +155,7 @@ static XBT_INLINE e_smx_state_t SIMIX_action_map_state(e_surf_action_state_t sta typedef smx_context_t(*smx_pfn_context_factory_create_context_t) - (xbt_main_func_t, int, char **, void_pfn_smxprocess_t, smx_process_t); + (xbt_main_func_t, int, char **, void_pfn_smxprocess_t, void* data); typedef int (*smx_pfn_context_factory_finalize_t) (smx_context_factory_t *); typedef void (*smx_pfn_context_free_t) (smx_context_t); @@ -164,10 +163,12 @@ typedef void (*smx_pfn_context_start_t) (smx_context_t); typedef void (*smx_pfn_context_stop_t) (smx_context_t); typedef void (*smx_pfn_context_suspend_t) (smx_context_t context); typedef void (*smx_pfn_context_runall_t) (xbt_swag_t processes); -typedef smx_process_t (*smx_pfn_context_self_t) (void); +typedef smx_context_t (*smx_pfn_context_self_t) (void); +typedef void* (*smx_pfn_context_get_data_t) (smx_context_t context); /* interface of the context factories */ typedef struct s_smx_context_factory { + const char *name; smx_pfn_context_factory_create_context_t create_context; smx_pfn_context_factory_finalize_t finalize; smx_pfn_context_free_t free; @@ -175,7 +176,7 @@ typedef struct s_smx_context_factory { smx_pfn_context_suspend_t suspend; smx_pfn_context_runall_t runall; smx_pfn_context_self_t self; - const char *name; + smx_pfn_context_get_data_t get_data; } s_smx_context_factory_t; @@ -266,9 +267,9 @@ static XBT_INLINE void SIMIX_context_runall(xbt_swag_t processes) } /** - \brief returns the current running process + \brief returns the current running context */ -static XBT_INLINE smx_process_t SIMIX_context_self(void) +static XBT_INLINE smx_context_t SIMIX_context_self(void) { if (simix_global->context_factory == NULL) { return NULL; @@ -277,5 +278,15 @@ static XBT_INLINE smx_process_t SIMIX_context_self(void) return (*(simix_global->context_factory->self))(); } +/** + \brief returns the data associated to a context + \param context The context + \return The data + */ +static XBT_INLINE void* SIMIX_context_get_data(smx_context_t context) +{ + return (*(simix_global->context_factory->get_data))(context); +} + #endif diff --git a/src/simix/smx_context_base.c b/src/simix/smx_context_base.c index 2c9a758993..bf79ab236b 100644 --- a/src/simix/smx_context_base.c +++ b/src/simix/smx_context_base.c @@ -24,6 +24,7 @@ void smx_ctx_base_factory_init(smx_context_factory_t * factory) (*factory)->suspend = NULL; (*factory)->runall = NULL; (*factory)->self = smx_ctx_base_self; + (*factory)->get_data = smx_ctx_base_get_data; (*factory)->name = "base context factory"; } @@ -40,19 +41,22 @@ smx_ctx_base_factory_create_context_sized(size_t size, xbt_main_func_t code, int argc, char **argv, void_pfn_smxprocess_t cleanup_func, - smx_process_t process) + void *data) { smx_context_t context = xbt_malloc0(size); /* If the user provided a function for the process then use it - otherwise is the context for maestro */ + otherwise is the context for maestro and we should set it as the + current context */ if (code) { context->cleanup_func = cleanup_func; - context->process = process; context->argc = argc; context->argv = argv; context->code = code; + }else{ + smx_current_context = context; } + context->data = data; return context; } @@ -79,13 +83,16 @@ void smx_ctx_base_free(smx_context_t context) void smx_ctx_base_stop(smx_context_t context) { - if (context->cleanup_func) - (*(context->cleanup_func)) (context->process); - + (*(context->cleanup_func)) (context->data); } -smx_process_t smx_ctx_base_self(void) +smx_context_t smx_ctx_base_self(void) { - return simix_global->current_process; + return smx_current_context; } + +void *smx_ctx_base_get_data(smx_context_t context) +{ + return context->data; +} \ No newline at end of file diff --git a/src/simix/smx_context_java.c b/src/simix/smx_context_java.c index daf5676d09..2c4d045d60 100644 --- a/src/simix/smx_context_java.c +++ b/src/simix/smx_context_java.c @@ -16,7 +16,7 @@ static smx_context_t smx_ctx_java_factory_create_context(xbt_main_func_t code, int argc, char **argv, void_pfn_smxprocess_t cleanup_func, - smx_process_t process); + void *data); static void smx_ctx_java_free(smx_context_t context); static void smx_ctx_java_start(smx_context_t context); @@ -43,7 +43,7 @@ static smx_context_t smx_ctx_java_factory_create_context(xbt_main_func_t code, int argc, char **argv, void_pfn_smxprocess_t cleanup_func, - smx_process_t process) + void* data) { smx_ctx_java_t context = xbt_new0(s_smx_ctx_java_t, 1); @@ -51,13 +51,15 @@ smx_ctx_java_factory_create_context(xbt_main_func_t code, int argc, otherwise is the context for maestro */ if (code) { context->super.cleanup_func = cleanup_func; - context->super.process = process; context->jprocess = (jobject) code; context->jenv = get_current_thread_env(); jprocess_start(((smx_ctx_java_t) context)->jprocess, get_current_thread_env()); + }else{ + smx_current_context = (smx_context_t)context; } - + context->super.data = data; + return (smx_context_t) context; } @@ -87,17 +89,17 @@ static void smx_ctx_java_stop(smx_context_t context) smx_ctx_java_t ctx_java; if (context->cleanup_func) - (*(context->cleanup_func)) (context->process); + (*(context->cleanup_func)) (context->data); ctx_java = (smx_ctx_java_t) context; /*FIXME: is this really necessary? */ - if (simix_global->current_process->iwannadie) { + if (((smx_process_t)smx_current_context->data)->iwannadie) { /* The maestro call xbt_context_stop() with an exit code set to one */ if (ctx_java->jprocess) { /* if the java process is alive schedule it */ if (jprocess_is_alive(ctx_java->jprocess, get_current_thread_env())) { - jprocess_schedule(simix_global->current_process->context); + jprocess_schedule(smx_current_context); jprocess = ctx_java->jprocess; ctx_java->jprocess = NULL; @@ -146,9 +148,12 @@ static void smx_ctx_java_resume(smx_context_t new_context) static void smx_ctx_java_runall(xbt_swag_t processes) { smx_process_t process; + smx_context_t old_context; + while((process = xbt_swag_extract(processes))){ - simix_global->current_process = process; - smx_ctx_java_resume(process->context); - simix_global->current_process = simix_global->maestro_process; + old_context = smx_current_context; + smx_current_context = process->context; + smx_ctx_java_resume(smx_current_context); + smx_current_context = old_context; } } diff --git a/src/simix/smx_context_private.h b/src/simix/smx_context_private.h index fc577dafdb..9e56c1abe1 100644 --- a/src/simix/smx_context_private.h +++ b/src/simix/smx_context_private.h @@ -18,6 +18,7 @@ typedef void (*SIMIX_ctx_factory_initializer_t)(smx_context_factory_t *); extern SIMIX_ctx_factory_initializer_t factory_initializer_to_use; extern int _surf_parallel_contexts; +smx_context_t smx_current_context; /* *********************** */ /* Context type definition */ @@ -32,7 +33,7 @@ typedef struct s_smx_context { int argc; char **argv; void_pfn_smxprocess_t cleanup_func; - smx_process_t process; + void *data; /* Here SIMIX stores the smx_process_t containing the context */ } s_smx_ctx_base_t; /* methods of this class */ void smx_ctx_base_factory_init(smx_context_factory_t * factory); @@ -43,10 +44,11 @@ smx_ctx_base_factory_create_context_sized(size_t size, xbt_main_func_t code, int argc, char **argv, void_pfn_smxprocess_t cleanup, - smx_process_t process); + void* data); void smx_ctx_base_free(smx_context_t context); void smx_ctx_base_stop(smx_context_t context); -smx_process_t smx_ctx_base_self(void); +smx_context_t smx_ctx_base_self(void); +void *smx_ctx_base_get_data(smx_context_t context); SG_END_DECL() #endif /* !_XBT_CONTEXT_PRIVATE_H */ diff --git a/src/simix/smx_context_sysv.c b/src/simix/smx_context_sysv.c index 9774fda2b9..9458a3b5ed 100644 --- a/src/simix/smx_context_sysv.c +++ b/src/simix/smx_context_sysv.c @@ -9,6 +9,7 @@ #include "smx_context_sysv_private.h" +#include "xbt/threadpool.h" #ifdef HAVE_VALGRIND_VALGRIND_H # include @@ -23,33 +24,47 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context); +static xbt_tpool_t tpool; + static smx_context_t smx_ctx_sysv_create_context(xbt_main_func_t code, int argc, char **argv, - void_pfn_smxprocess_t cleanup_func, - smx_process_t process); + void_pfn_smxprocess_t cleanup_func, void* data); static void smx_ctx_sysv_wrapper(smx_ctx_sysv_t context); void SIMIX_ctx_sysv_factory_init(smx_context_factory_t * factory) { - smx_ctx_base_factory_init(factory); + (*factory)->finalize = smx_ctx_sysv_factory_finalize; (*factory)->create_context = smx_ctx_sysv_create_context; /* Do not overload that method (*factory)->finalize */ (*factory)->free = smx_ctx_sysv_free; (*factory)->stop = smx_ctx_sysv_stop; (*factory)->suspend = smx_ctx_sysv_suspend; - (*factory)->runall = smx_ctx_sysv_runall; (*factory)->name = "smx_sysv_context_factory"; + + if(_surf_parallel_contexts){ + tpool = xbt_tpool_new(2, 10); + (*factory)->runall = smx_ctx_sysv_runall_parallel; + }else{ + (*factory)->runall = smx_ctx_sysv_runall; + } +} + +int smx_ctx_sysv_factory_finalize(smx_context_factory_t *factory) +{ + if(tpool) + xbt_tpool_destroy(tpool); + return smx_ctx_base_factory_finalize(factory); } smx_context_t smx_ctx_sysv_create_context_sized(size_t size, xbt_main_func_t code, int argc, char **argv, void_pfn_smxprocess_t cleanup_func, - smx_process_t process) + void *data) { smx_ctx_sysv_t context = @@ -58,7 +73,7 @@ smx_ctx_sysv_create_context_sized(size_t size, xbt_main_func_t code, argc, argv, cleanup_func, - process); + data); /* If the user provided a function for the process then use it otherwise is the context for maestro */ @@ -94,12 +109,12 @@ smx_ctx_sysv_create_context_sized(size_t size, xbt_main_func_t code, static smx_context_t smx_ctx_sysv_create_context(xbt_main_func_t code, int argc, char **argv, void_pfn_smxprocess_t cleanup_func, - smx_process_t process) + void *data) { return smx_ctx_sysv_create_context_sized(sizeof(s_smx_ctx_sysv_t), code, argc, argv, cleanup_func, - process); + data); } @@ -154,10 +169,21 @@ void smx_ctx_sysv_resume(smx_context_t new_context) void smx_ctx_sysv_runall(xbt_swag_t processes) { + smx_context_t old_context; smx_process_t process; + while((process = xbt_swag_extract(processes))){ - simix_global->current_process = process; - smx_ctx_sysv_resume(process->context); - simix_global->current_process = simix_global->maestro_process; + old_context = smx_current_context; + smx_current_context = process->context; + smx_ctx_sysv_resume(smx_current_context); + smx_current_context = old_context; } } + +void smx_ctx_sysv_runall_parallel(xbt_swag_t processes) +{ + smx_process_t process; + while((process = xbt_swag_extract(processes))){ + xbt_tpool_queue_job(tpool, (void_f_pvoid_t)smx_ctx_sysv_resume, process->context); + } +} \ No newline at end of file diff --git a/src/simix/smx_context_sysv_private.h b/src/simix/smx_context_sysv_private.h index ab7d4791c1..193f9c9a9a 100644 --- a/src/simix/smx_context_sysv_private.h +++ b/src/simix/smx_context_sysv_private.h @@ -35,17 +35,23 @@ typedef struct s_smx_ctx_sysv { #endif char stack[CONTEXT_STACK_SIZE]; /* the thread stack size */ } s_smx_ctx_sysv_t, *smx_ctx_sysv_t; + + +void SIMIX_ctx_sysv_factory_init(smx_context_factory_t *factory); +int smx_ctx_sysv_factory_finalize(smx_context_factory_t *factory); + smx_context_t smx_ctx_sysv_create_context_sized(size_t structure_size, xbt_main_func_t code, int argc, char **argv, void_pfn_smxprocess_t cleanup_func, - smx_process_t process); + void *data); void smx_ctx_sysv_free(smx_context_t context); void smx_ctx_sysv_stop(smx_context_t context); void smx_ctx_sysv_suspend(smx_context_t context); void smx_ctx_sysv_resume(smx_context_t new_context); void smx_ctx_sysv_runall(xbt_swag_t processes); +void smx_ctx_sysv_runall_parallel(xbt_swag_t processes); SG_END_DECL() #endif /* !_XBT_CONTEXT_SYSV_PRIVATE_H */ diff --git a/src/simix/smx_context_thread.c b/src/simix/smx_context_thread.c index 3d5ab923c8..fe51290de8 100644 --- a/src/simix/smx_context_thread.c +++ b/src/simix/smx_context_thread.c @@ -77,7 +77,6 @@ smx_ctx_thread_factory_create_context(xbt_main_func_t code, int argc, context->begin = xbt_os_sem_init(0); context->end = xbt_os_sem_init(0); - /* delay the thread creation until first run */ context->thread = NULL; diff --git a/src/simix/smx_global.c b/src/simix/smx_global.c index 2139013eca..d736082cc5 100644 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@ -73,7 +73,6 @@ void SIMIX_global_init(int *argc, char **argv) simix_global->process_to_destroy = xbt_swag_new(xbt_swag_offset(proc, destroy_hookup)); - simix_global->current_process = NULL; simix_global->maestro_process = NULL; simix_global->registered_functions = xbt_dict_new(); diff --git a/src/simix/smx_process.c b/src/simix/smx_process.c index 65788507ca..653998658c 100644 --- a/src/simix/smx_process.c +++ b/src/simix/smx_process.c @@ -82,7 +82,6 @@ void SIMIX_create_maestro_process() maestro->context = SIMIX_context_new(NULL, 0, NULL, NULL, maestro); simix_global->maestro_process = maestro; - simix_global->current_process = maestro; return; } @@ -492,6 +491,21 @@ void SIMIX_process_sleep_resume(smx_action_t action) surf_workstation_model->resume(action->sleep.surf_sleep); } +/** + * \brief Returns the current agent. + * + * This functions returns the currently running SIMIX process. + * + * \return The SIMIX process + */ +XBT_INLINE smx_process_t SIMIX_process_self(void) +{ + if(simix_global) + return SIMIX_context_get_data(SIMIX_context_self()); + + return NULL; +} + /** * Calling this function makes the process to yield. * Only the processes can call this function, giving back the control to maestro @@ -521,7 +535,7 @@ void SIMIX_process_yield(void) /* callback: context fetching */ xbt_running_ctx_t *SIMIX_process_get_running_context(void) { - return simix_global->current_process->running_ctx; + return SIMIX_process_self()->running_ctx; } /* callback: termination */