X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/1e75aa05c1e1cc40dd97e136d2242be128d9c38a..12442080c860b7affd1b246f12895bda4f304330:/src/xbt/xbt_thread.c diff --git a/src/xbt/xbt_thread.c b/src/xbt/xbt_thread.c index adf3da7c44..0aef1c1549 100644 --- a/src/xbt/xbt_thread.c +++ b/src/xbt/xbt_thread.c @@ -22,6 +22,8 @@ typedef struct xbt_thread_ { pthread_t t; + void *param; + pvoid_f_pvoid_t *start_routine; } s_xbt_thread_t ; /* thread-specific data containing the xbt_thread_t structure */ @@ -35,33 +37,56 @@ static void xbt_thread_free_thread_data(void*d){ void xbt_thread_mod_init(void) { int errcode; - if ((errcode=pthread_key_create(&xbt_self_thread_key, &xbt_thread_free_thread_data))) + if ((errcode=pthread_key_create(&xbt_self_thread_key, NULL))) THROW0(system_error,errcode,"pthread_key_create failed for xbt_self_thread_key"); } void xbt_thread_mod_exit(void) { - int errcode; + /* FIXME: don't try to free our key on shutdown. Valgrind detects no leak if we don't, and whine if we try to */ +// int errcode; - if ((errcode=pthread_key_delete(xbt_self_thread_key))) - THROW0(system_error,errcode,"pthread_key_delete failed for xbt_self_thread_key"); +// if ((errcode=pthread_key_delete(xbt_self_thread_key))) +// THROW0(system_error,errcode,"pthread_key_delete failed for xbt_self_thread_key"); } +static void * wrapper_start_routine(void *s) { + xbt_thread_t t = s; + int errcode; + + if ((errcode=pthread_setspecific(xbt_self_thread_key,t))) + THROW0(system_error,errcode,"pthread_setspecific failed for xbt_self_thread_key"); + return t->start_routine(t->param); +} xbt_thread_t xbt_thread_create(pvoid_f_pvoid_t start_routine, void* param) { - xbt_thread_t res = xbt_new(s_xbt_thread_t,1); int errcode; - if ((errcode=pthread_setspecific(xbt_self_thread_key,res))) - THROW0(system_error,errcode,"pthread_setspecific failed for xbt_self_thread_key"); - - if ((errcode = pthread_create(&(res->t), NULL, start_routine, param))) - THROW0(system_error,errcode, "pthread_create failed"); + xbt_thread_t res_thread=xbt_new(s_xbt_thread_t,1); + res_thread->start_routine = start_routine; + res_thread->param = param; + - return res; + if ((errcode = pthread_create(&(res_thread->t), NULL, wrapper_start_routine, res_thread))) + THROW1(system_error,errcode, "pthread_create failed: %s",strerror(errcode)); + + return res_thread; +} + +void +xbt_thread_join(xbt_thread_t thread,void ** thread_return) { + + int errcode; + + if ((errcode = pthread_join(thread->t,thread_return))) + THROW1(system_error,errcode, "pthread_join failed: %s", + strerror(errcode)); + free(thread); } + void xbt_thread_exit(int *retval) { pthread_exit(retval); } + xbt_thread_t xbt_thread_self(void) { return pthread_getspecific(xbt_self_thread_key); } @@ -80,7 +105,8 @@ xbt_mutex_t xbt_mutex_init(void) { int errcode; if ((errcode = pthread_mutex_init(&(res->m),NULL))) - THROW0(system_error,errcode,"pthread_mutex_init() failed"); + THROW1(system_error,errcode,"pthread_mutex_init() failed: %s", + strerror(errcode)); return res; } @@ -89,21 +115,26 @@ void xbt_mutex_lock(xbt_mutex_t mutex) { int errcode; if ((errcode=pthread_mutex_lock(&(mutex->m)))) - THROW1(system_error,errcode,"pthread_mutex_lock(%p) failed",mutex); + THROW2(system_error,errcode,"pthread_mutex_lock(%p) failed: %s", + mutex, strerror(errcode)); } void xbt_mutex_unlock(xbt_mutex_t mutex) { int errcode; if ((errcode=pthread_mutex_unlock(&(mutex->m)))) - THROW1(system_error,errcode,"pthread_mutex_unlock(%p) failed",mutex); + THROW2(system_error,errcode,"pthread_mutex_unlock(%p) failed: %s", + mutex, strerror(errcode)); } void xbt_mutex_destroy(xbt_mutex_t mutex) { int errcode; + if (!mutex) return; + if ((errcode=pthread_mutex_destroy(&(mutex->m)))) - THROW1(system_error,errcode,"pthread_mutex_destroy(%p) failed",mutex); + THROW2(system_error,errcode,"pthread_mutex_destroy(%p) failed: %s", + mutex, strerror(errcode)); free(mutex); } @@ -116,7 +147,8 @@ xbt_thcond_t xbt_thcond_init(void) { xbt_thcond_t res = xbt_new(s_xbt_thcond_t,1); int errcode; if ((errcode=pthread_cond_init(&(res->c),NULL))) - THROW0(system_error,errcode,"pthread_cond_init() failed"); + THROW1(system_error,errcode,"pthread_cond_init() failed: %s", + strerror(errcode)); return res; } @@ -124,24 +156,31 @@ xbt_thcond_t xbt_thcond_init(void) { void xbt_thcond_wait(xbt_thcond_t cond, xbt_mutex_t mutex) { int errcode; if ((errcode=pthread_cond_wait(&(cond->c),&(mutex->m)))) - THROW2(system_error,errcode,"pthread_cond_wait(%p,%p) failed",cond,mutex); + THROW3(system_error,errcode,"pthread_cond_wait(%p,%p) failed: %s", + cond,mutex, strerror(errcode)); } void xbt_thcond_signal(xbt_thcond_t cond) { int errcode; if ((errcode=pthread_cond_signal(&(cond->c)))) - THROW1(system_error,errcode,"pthread_cond_signal(%p) failed",cond); + THROW2(system_error,errcode,"pthread_cond_signal(%p) failed: %s", + cond, strerror(errcode)); } void xbt_thcond_broadcast(xbt_thcond_t cond){ int errcode; if ((errcode=pthread_cond_broadcast(&(cond->c)))) - THROW1(system_error,errcode,"pthread_cond_broadcast(%p) failed",cond); + THROW2(system_error,errcode,"pthread_cond_broadcast(%p) failed: %s", + cond, strerror(errcode)); } void xbt_thcond_destroy(xbt_thcond_t cond){ int errcode; + + if (!cond) return; + if ((errcode=pthread_cond_destroy(&(cond->c)))) - THROW1(system_error,errcode,"pthread_cond_destroy(%p) failed",cond); + THROW2(system_error,errcode,"pthread_cond_destroy(%p) failed: %s", + cond, strerror(errcode)); free(cond); } @@ -150,8 +189,10 @@ void xbt_thcond_destroy(xbt_thcond_t cond){ #elif defined(WIN32) typedef struct xbt_thread_ { - HANDLE handle; /* the win thread handle */ - unsigned long id; /* the win thread id */ + HANDLE handle; /* the win thread handle */ + unsigned long id; /* the win thread id */ + pvoid_f_pvoid_t *start_routine; + void* param; } s_xbt_thread_t ; /* key to the TLS containing the xbt_thread_t structure */ @@ -161,38 +202,62 @@ void xbt_thread_mod_init(void) { xbt_self_thread_key = TlsAlloc(); } void xbt_thread_mod_exit(void) { - int errcode; - if (!(errcode = TlsFree(xbt_self_thread_key))) - THROW0(system_error,errcode,"TlsFree() failed to cleanup the thread submodule"); + + if (!TlsFree(xbt_self_thread_key)) + THROW0(system_error,(int)GetLastError(),"TlsFree() failed to cleanup the thread submodule"); } +static DWORD WINAPI wrapper_start_routine(void *s) { + xbt_thread_t t = (xbt_thread_t)s; + + if(!TlsSetValue(xbt_self_thread_key,t)) + THROW0(system_error,(int)GetLastError(),"TlsSetValue of data describing the created thread failed"); + + return (DWORD)t->start_routine(t->param); +} + + xbt_thread_t xbt_thread_create(pvoid_f_pvoid_t start_routine, void* param) { - xbt_thread_t res = xbt_new(s_xbt_thread_t,1); + xbt_thread_t t = xbt_new(s_xbt_thread_t,1); + + t->start_routine = start_routine ; + t->param = param; - res->handle = CreateThread(NULL,0, - (LPTHREAD_START_ROUTINE)start_routine, - param,0,& res->id); + t->handle = CreateThread(NULL,0, + (LPTHREAD_START_ROUTINE)wrapper_start_routine, + t,0,&(t->id)); - if(!res->handle) { - xbt_free(res); - THROW0(system_error,0,"CreateThread failed"); + if(!t->handle) { + xbt_free(t); + THROW0(system_error,(int)GetLastError(),"CreateThread failed"); } - if(!TlsSetValue(xbt_self_thread_key,res)) - THROW0(system_error,0,"TlsSetValue of data describing the created thread failed"); - - return res; + return t; +} + +void +xbt_thread_join(xbt_thread_t thread,void ** thread_return) { + + if(WAIT_OBJECT_0 != WaitForSingleObject(thread->handle,INFINITE)) + THROW0(system_error,(int)GetLastError(), "WaitForSingleObject failed"); + + if(thread_return){ + + if(!GetExitCodeThread(thread->handle,(DWORD*)(*thread_return))) + THROW0(system_error,(int)GetLastError(), "GetExitCodeThread failed"); + } + + CloseHandle(thread->handle); + free(thread); } void xbt_thread_exit(int *retval) { - xbt_thread_t self = xbt_thread_self(); - - CloseHandle(self->handle); - free(self); - - ExitThread(*retval); + if(retval) + ExitThread(*retval); + else + ExitThread(0); } xbt_thread_t xbt_thread_self(void) { @@ -230,8 +295,9 @@ void xbt_mutex_unlock(xbt_mutex_t mutex) { void xbt_mutex_destroy(xbt_mutex_t mutex) { - DeleteCriticalSection(& mutex->lock); - + if (!mutex) return; + + DeleteCriticalSection(& mutex->lock); free(mutex); } @@ -333,6 +399,8 @@ void xbt_thcond_signal(xbt_thcond_t cond) { if (have_waiters) if(!SetEvent(cond->events[SIGNAL])) THROW0(system_error,0,"SetEvent failed"); + + xbt_thread_yield(); } void xbt_thcond_broadcast(xbt_thcond_t cond){ @@ -349,6 +417,8 @@ void xbt_thcond_broadcast(xbt_thcond_t cond){ void xbt_thcond_destroy(xbt_thcond_t cond){ int error = 0; + if (!cond) return; + if(!CloseHandle(cond->events[SIGNAL])) error = 1;