From 8267a61f91f5ed9e7368d3059e9d53b96cc8fcb7 Mon Sep 17 00:00:00 2001 From: mquinson Date: Fri, 9 Mar 2007 16:49:28 +0000 Subject: [PATCH 1/1] don't use either pthread or winthread to implement xbt_context, but use our compatibility layer xbt_thread instead (when ucontext are not available, of course) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3232 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- configure.ac | 7 +- src/xbt/context.c | 184 +++++++++++--------------------------- src/xbt/context_private.h | 31 +++---- 3 files changed, 68 insertions(+), 154 deletions(-) diff --git a/configure.ac b/configure.ac index 543696b938..9241aefe0b 100644 --- a/configure.ac +++ b/configure.ac @@ -131,7 +131,7 @@ esac if test "x$with_context" = "xucontext" ; then if test ".$mcsc" = .yes; then AC_MSG_RESULT(found working ucontext. Great!) - AC_DEFINE([USE_UCONTEXT],1,[Define if we use ucontext or not]) + AC_DEFINE([CONTEXT_UCONTEXT],1,[Define if xbt contexts are based on ucontext or not]) else if test ".$windows_context" = .yes ; then AC_MSG_RESULT(use windows context portability layer.) @@ -147,7 +147,7 @@ if test "x$with_context" = "xpthread"; then AC_CHECK_HEADERS([pthread.h]) AC_CHECK_LIB(pthread,pthread_create,, [AC_MSG_ERROR([[Cannot find pthreads (try --with-context=ucontext if you haven't already tried).]])]) - AC_DEFINE([USE_PTHREADS],1,[Define if we use pthreads or not]) + AC_DEFINE([CONTEXT_THREADS],1,[Define if xbt contexts are based on our threads implementation or not]) AC_MSG_RESULT(You have pthreads. Let's use them.) fi @@ -214,7 +214,8 @@ AC_CHECK_LIB(socket, connect, [GRAS_DEP="$GRAS_DEP -lsocket"]) AC_MSG_CHECKING(for extra dependencies of libgras) case $host_os in *mingw* ) GRAS_DEP="$GRAS_DEP -lws2_32" ; SIMGRID_DEP="$SIMGRID_DEP -lws2_32"; - AC_SUBST(AM_CFLAGS,-DDLL_EXPORT);; + AC_SUBST(AM_CFLAGS,-DDLL_EXPORT) + AC_DEFINE(CONTEXT_THREADS,1);; esac if test "x$GRAS_DEP" = x; then diff --git a/src/xbt/context.c b/src/xbt/context.c index aa49e3bc99..b2fb2ad1dd 100644 --- a/src/xbt/context.c +++ b/src/xbt/context.c @@ -13,6 +13,7 @@ #include "context_private.h" #include "xbt/log.h" #include "xbt/dynar.h" +#include "xbt/xbt_thread.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ctx, xbt, "Context"); @@ -23,55 +24,29 @@ static xbt_context_t init_context = NULL; static xbt_swag_t context_to_destroy = NULL; static xbt_swag_t context_living = NULL; -#if (!defined(USE_PTHREADS) && !defined(USE_WIN_THREADS)) /* USE_PTHREADS and USE_CONTEXT are exclusive */ -# ifndef USE_UCONTEXT -/* don't want to play with conditional compilation in automake tonight, sorry. - include directly the c file from here when needed. */ -# include "context_win32.c" -# define USE_WIN_CONTEXT -# endif -#endif - static void __xbt_context_yield(xbt_context_t context) { xbt_assert0(current_context,"You have to call context_init() first."); - + DEBUG2("--------- current_context (%p) is yielding to context(%p) ---------",current_context,context); - - #ifdef USE_PTHREADS + + #ifdef CONTEXT_THREADS if (context){ xbt_context_t self = current_context; DEBUG0("**** Locking ****"); - pthread_mutex_lock(&(context->mutex)); + xbt_mutex_lock(context->mutex); DEBUG0("**** Updating current_context ****"); current_context = context; DEBUG0("**** Releasing the prisonner ****"); - pthread_cond_signal(&(context->cond)); + xbt_thcond_signal(context->cond); DEBUG0("**** Going to jail ****"); - pthread_cond_wait(&(context->cond), &(context->mutex)); + xbt_thcond_wait(context->cond, context->mutex); DEBUG0("**** Unlocking ****"); - pthread_mutex_unlock(&(context->mutex)); + xbt_mutex_unlock(context->mutex); DEBUG0("**** Updating current_context ****"); current_context = self; } - #elif defined(USE_WIN_THREADS) - if (context){ - xbt_context_t self = current_context; - DEBUG0("**** Locking ****"); - win_thread_mutex_lock(&(context->mutex)); - DEBUG0("**** Updating current_context ****"); - current_context = context; - DEBUG0("**** Releasing the prisonner ****"); - win_thread_cond_signal(&(context->cond)); - DEBUG0("**** Going to jail ****"); - win_thread_cond_wait(&(context->cond), &(context->mutex)); - DEBUG0("**** Unlocking ****"); - win_thread_mutex_unlock(&(context->mutex)); - DEBUG0("**** Updating current_context ****"); - current_context = self; - - } - #else + #else /* use SUSv2 contexts */ if(current_context) VOIRP(current_context->save); @@ -115,31 +90,20 @@ static void __xbt_context_yield(xbt_context_t context) static void xbt_context_destroy(xbt_context_t context) { - #ifdef USE_PTHREADS + if (!context) return; +#ifdef CONTEXT_THREADS xbt_free(context->thread); - pthread_mutex_destroy(&(context->mutex)); - pthread_cond_destroy(&(context->cond)); - #elif defined(USE_WIN_THREADS) - /*xbt_free(context->thread);*/ - - if(context->mutex) - win_thread_mutex_destroy(&(context->mutex)); - - - if(context->cond) - win_thread_cond_destroy(&(context->cond)); - + xbt_mutex_destroy(context->mutex); + xbt_thcond_destroy(context->cond); - #endif + context->thread = NULL; + context->mutex = NULL; + context->cond = NULL; +#endif if(context->exception) free(context->exception); - - #ifdef USE_WIN_CONTEXT - if(context->uc.uc_stack.ss_sp) - free (context->uc.uc_stack.ss_sp); - #endif - + free(context); return; } @@ -166,69 +130,42 @@ static void __context_exit(xbt_context_t context ,int value) DEBUG0("Context put in the to_destroy set"); DEBUG0("Yielding"); - #ifdef USE_PTHREADS - DEBUG0("**** Locking ****"); - pthread_mutex_lock(&(context->mutex)); - DEBUG0("**** Updating current_context ****"); - current_context = context; - DEBUG0("**** Releasing the prisonner ****"); - pthread_cond_signal(&(context->cond)); - DEBUG0("**** Unlocking ****"); - pthread_mutex_unlock(&(context->mutex)); - DEBUG0("**** Exiting ****"); - pthread_exit(0); - #elif defined(USE_WIN_THREADS) + #ifdef CONTEXT_THREADS DEBUG0("**** Locking ****"); - win_thread_mutex_lock(&(context->mutex)); + xbt_mutex_lock(context->mutex); DEBUG0("**** Updating current_context ****"); current_context = context; DEBUG0("**** Releasing the prisonner ****"); - win_thread_cond_signal(&(context->cond)); + xbt_thcond_signal(context->cond); DEBUG0("**** Unlocking ****"); - win_thread_mutex_unlock(&(context->mutex)); + xbt_mutex_unlock(context->mutex); DEBUG0("**** Exiting ****"); - win_thread_exit(context->thread,0); + xbt_thread_exit(0); #else __xbt_context_yield(context); #endif xbt_assert0(0,"You can't be here!"); } -#ifdef USE_WIN_THREADS -static DWORD WINAPI /* special thread proc signature */ -#else static void * -#endif -__context_wrapper(void* c) -{ +__context_wrapper(void* c) { xbt_context_t context = (xbt_context_t)c; - #ifdef USE_PTHREADS - DEBUG2("**[%p:%p]** Lock ****",context,(void*)pthread_self()); - pthread_mutex_lock(&(context->mutex)); + #ifdef CONTEXT_THREADS + context->thread = xbt_thread_self(); + + DEBUG2("**[%p:%p]** Lock ****",context,(void*)xbt_thread_self()); + xbt_mutex_lock(context->mutex); - DEBUG2("**[%p:%p]** Releasing the prisonner ****",context,(void*)pthread_self()); - pthread_cond_signal(&(context->cond)); + DEBUG2("**[%p:%p]** Releasing the prisonner ****",context,(void*)xbt_thread_self()); + xbt_thcond_signal(context->cond); - DEBUG2("**[%p:%p]** Going to Jail ****",context,(void*)pthread_self()); - pthread_cond_wait(&(context->cond), &(context->mutex)); + DEBUG2("**[%p:%p]** Going to Jail ****",context,(void*)xbt_thread_self()); + xbt_thcond_wait(context->cond, context->mutex); - DEBUG2("**[%p:%p]** Unlocking ****",context,(void*)pthread_self()); - pthread_mutex_unlock(&(context->mutex)); + DEBUG2("**[%p:%p]** Unlocking ****",context,(void*)xbt_thread_self()); + xbt_mutex_unlock(context->mutex); - #elif defined(USE_WIN_THREADS) - DEBUG2("**[%p:%p]** Lock ****",context,(void*)win_thread_self()); - win_thread_mutex_lock(&(context->mutex)); - - DEBUG2("**[%p:%p]** Releasing the prisonner ****",context,(void*)win_thread_self()); - win_thread_cond_signal(&(context->cond)); - - DEBUG2("**[%p:%p]** Going to Jail ****",context,(void*)win_thread_self()); - win_thread_cond_wait(&(context->cond), &(context->mutex)); - - DEBUG2("**[%p:%p]** Unlocking ****",context,(void*)win_thread_self()); - win_thread_mutex_unlock(&(context->mutex)); - #endif if(context->startup_func) @@ -303,28 +240,19 @@ void xbt_context_empty_trash(void) */ void xbt_context_start(xbt_context_t context) { - #ifdef USE_PTHREADS + #ifdef CONTEXT_THREADS /* Launch the thread */ DEBUG1("**[%p]** Locking ****",context); - pthread_mutex_lock(&(context->mutex)); - DEBUG1("**[%p]** Pthread create ****",context); - xbt_assert0(!pthread_create(context->thread, NULL, __context_wrapper, context),"Unable to create a thread."); - DEBUG2("**[%p]** Pthread created : %p ****",context,(void*)(*(context->thread))); + xbt_mutex_lock(context->mutex); + + DEBUG1("**[%p]** Thread create ****",context); + context->thread = xbt_thread_create(__context_wrapper, context); + DEBUG2("**[%p]** Thread created : %p ****",context,context->thread); + DEBUG1("**[%p]** Going to jail ****",context); - pthread_cond_wait(&(context->cond), &(context->mutex)); + xbt_thcond_wait(context->cond, context->mutex); DEBUG1("**[%p]** Unlocking ****",context); - pthread_mutex_unlock(&(context->mutex)); - #elif defined(USE_WIN_THREADS) - /* Launch the thread */ - DEBUG1("**[%p]** Locking ****",context); - win_thread_mutex_lock(&(context->mutex)); - DEBUG1("**[%p]** Windows thread create ****",context); - xbt_assert0(!win_thread_create(&(context->thread), __context_wrapper, context),"Unable to create a thread."); - DEBUG2("**[%p]** Windows created : %p ****",context,(void*)(context->thread)); - DEBUG1("**[%p]** Going to jail ****",context); - win_thread_cond_wait(&(context->cond), &(context->mutex)); - DEBUG1("**[%p]** Unlocking ****",context); - win_thread_mutex_unlock(&(context->mutex)); + xbt_mutex_unlock(context->mutex); #else makecontext (&(context->uc), (void (*) (void)) __context_wrapper,1, context); #endif @@ -352,14 +280,9 @@ xbt_context_t xbt_context_new(xbt_context_function_t code, res = xbt_new0(s_xbt_context_t,1); res->code = code; - #ifdef USE_PTHREADS - res->thread = xbt_new0(pthread_t,1); - xbt_assert0(!pthread_mutex_init(&(res->mutex), NULL), "Mutex initialization error"); - xbt_assert0(!pthread_cond_init(&(res->cond), NULL), "Condition initialization error"); - #elif defined(USE_WIN_THREADS) - /*res->thread = xbt_new0(pthread_t,1);*/ - xbt_assert0(!win_thread_mutex_init(&(res->mutex)), "Mutex initialization error"); - xbt_assert0(!win_thread_cond_init(&(res->cond)), "Condition initialization error"); + #ifdef CONTEXT_THREADS + res->mutex = xbt_mutex_init(); + res->cond = xbt_thcond_init(); #else /* FIXME: strerror is not thread safe */ xbt_assert2(getcontext(&(res->uc))==0,"Error in context saving: %d (%s)", errno, strerror(errno)); @@ -368,14 +291,9 @@ xbt_context_t xbt_context_new(xbt_context_function_t code, /* WARNING : when this context is over, the current_context (i.e. the father), is awaken... Theorically, the wrapper should prevent using this feature. */ - # ifdef USE_WIN_CONTEXT - res->uc.uc_stack.ss_sp = xbt_malloc(STACK_SIZE); - res->uc.uc_stack.ss_size = STACK_SIZE ; - #else res->uc.uc_stack.ss_sp = pth_skaddr_makecontext(res->stack,STACK_SIZE); res->uc.uc_stack.ss_size = pth_sksize_makecontext(res->stack,STACK_SIZE); - # endif /* USE_WIN_CONTEXT */ - #endif /* USE_PTHREADS or not */ + #endif /* CONTEXT_THREADS or not */ res->argc = argc; res->argv = argv; @@ -422,13 +340,12 @@ void xbt_context_schedule(xbt_context_t context) void xbt_context_exit(void) { xbt_context_t context=NULL; - - xbt_context_empty_trash(); xbt_swag_free(context_to_destroy); - while((context=xbt_swag_extract(context_living))) + while((context=xbt_swag_extract(context_living))) { xbt_context_free(context); + } xbt_swag_free(context_living); @@ -444,6 +361,7 @@ void xbt_context_free(xbt_context_t context) { int i ; + xbt_swag_remove(context, context_living); for(i=0;iargc; i++) diff --git a/src/xbt/context_private.h b/src/xbt/context_private.h index f0450fda4e..386497863c 100644 --- a/src/xbt/context_private.h +++ b/src/xbt/context_private.h @@ -21,39 +21,34 @@ #include "xbt/context.h" #include "xbt/ex.h" -#ifdef USE_PTHREADS -# include -#elif defined(USE_WIN_THREADS) -# include "win_thread.h" +#ifdef CONTEXT_THREADS +# include "xbt/xbt_thread.h" #else +# include # define STACK_SIZE 128*1024 /* Lower this if you want to reduce the memory consumption */ -#endif /* USE_PTHREADS */ +#endif /* not CONTEXT_THREADS */ typedef struct s_xbt_context { s_xbt_swag_hookup_t hookup; - #ifdef USE_PTHREADS - pthread_cond_t cond; - pthread_mutex_t mutex; - pthread_t *thread; /* the thread that execute the code */ - #elif defined(USE_WIN_THREADS) - win_thread_cond_t cond; - win_thread_mutex_t mutex; - win_thread_t thread; /* the thread that execute the code */ - #else - ucontext_t uc; /* the thread that execute the code */ +#ifdef CONTEXT_THREADS + xbt_thcond_t cond; + xbt_mutex_t mutex; + xbt_thread_t thread; /* the thread that execute the code */ +#else + ucontext_t uc; /* the thread that execute the code */ char stack[STACK_SIZE]; struct s_xbt_context *save; - #endif /* USE_PTHREADS || USE_WIN_THREADS */ - xbt_context_function_t code; /* the scheduler fonction */ +#endif /* CONTEXT_THREADS */ + xbt_context_function_t code; /* the scheduler fonction */ int argc; char **argv; void_f_pvoid_t *startup_func; void *startup_arg; void_f_pvoid_t *cleanup_func; void *cleanup_arg; - ex_ctx_t *exception; /* exception */ + ex_ctx_t *exception; /* exception */ } s_xbt_context_t; -- 2.20.1