From 0c8449a2d985770bba06e089fcbcce0910023f66 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Wed, 25 Oct 2023 19:57:00 +0200 Subject: [PATCH] sthread: implement recursive mutexes (test broken so far) The interception is here, but the S4U mutexes cannot be recursive yet. --- examples/sthread/CMakeLists.txt | 2 +- src/sthread/sthread.c | 40 ++++++++++++++++++++++- src/sthread/sthread.h | 14 ++++++++- src/sthread/sthread_impl.cpp | 56 ++++++++++++++++++++++++++++++++- 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/examples/sthread/CMakeLists.txt b/examples/sthread/CMakeLists.txt index 98811c23ad..7d9d7b5bca 100644 --- a/examples/sthread/CMakeLists.txt +++ b/examples/sthread/CMakeLists.txt @@ -5,7 +5,7 @@ find_package(Threads REQUIRED) ######################################################################### foreach(x - mutex-simple + mutex-simple mutex-recursive producer-consumer) if("${CMAKE_SYSTEM}" MATCHES "Linux") diff --git a/src/sthread/sthread.c b/src/sthread/sthread.c index ee9e0847ea..2005f297ad 100644 --- a/src/sthread/sthread.c +++ b/src/sthread/sthread.c @@ -28,6 +28,12 @@ static int (*raw_mutex_trylock)(pthread_mutex_t*); static int (*raw_mutex_unlock)(pthread_mutex_t*); static int (*raw_mutex_destroy)(pthread_mutex_t*); +static int (*raw_pthread_mutexattr_init)(pthread_mutexattr_t*); +static int (*raw_pthread_mutexattr_settype)(pthread_mutexattr_t*, int); +static int (*raw_pthread_mutexattr_gettype)(const pthread_mutexattr_t* restrict, int* restrict); +static int (*raw_pthread_mutexattr_getrobust)(const pthread_mutexattr_t*, int*); +static int (*raw_pthread_mutexattr_setrobust)(pthread_mutexattr_t*, int); + static unsigned int (*raw_sleep)(unsigned int); static int (*raw_usleep)(useconds_t); static int (*raw_gettimeofday)(struct timeval*, void*); @@ -50,6 +56,12 @@ static void intercepter_init() raw_mutex_unlock = dlsym(RTLD_NEXT, "pthread_mutex_unlock"); raw_mutex_destroy = dlsym(RTLD_NEXT, "pthread_mutex_destroy"); + raw_pthread_mutexattr_init = dlsym(RTLD_NEXT, "pthread_mutexattr_init"); + raw_pthread_mutexattr_settype = dlsym(RTLD_NEXT, "pthread_mutexattr_settype"); + raw_pthread_mutexattr_gettype = dlsym(RTLD_NEXT, "pthread_mutexattr_gettype"); + raw_pthread_mutexattr_getrobust = dlsym(RTLD_NEXT, "pthread_mutexattr_getrobust"); + raw_pthread_mutexattr_setrobust = dlsym(RTLD_NEXT, "pthread_mutexattr_setrobust"); + raw_sleep = dlsym(RTLD_NEXT, "sleep"); raw_usleep = dlsym(RTLD_NEXT, "usleep"); raw_gettimeofday = dlsym(RTLD_NEXT, "gettimeofday"); @@ -85,6 +97,32 @@ int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_ sthread_enable(); return res; } + +#define _STHREAD_CONCAT(a, b) a##b +#define intercepted_call(name, raw_params, call_params, sim_params) \ + int _STHREAD_CONCAT(pthread_, name) raw_params \ + { \ + if (_STHREAD_CONCAT(raw_pthread_, name) == NULL) \ + intercepter_init(); \ + if (sthread_inside_simgrid) \ + return _STHREAD_CONCAT(raw_pthread_, name) call_params; \ + \ + sthread_disable(); \ + int res = _STHREAD_CONCAT(sthread_, name) sim_params; \ + sthread_enable(); \ + return res; \ + } + +intercepted_call(mutexattr_init, (pthread_mutexattr_t * attr), (attr), ((sthread_mutexattr_t*)attr)); +intercepted_call(mutexattr_settype, (pthread_mutexattr_t * attr, int type), (attr, type), + ((sthread_mutexattr_t*)attr, type)); +intercepted_call(mutexattr_gettype, (const pthread_mutexattr_t* restrict attr, int* type), (attr, type), + ((sthread_mutexattr_t*)attr, type)); +intercepted_call(mutexattr_setrobust, (pthread_mutexattr_t* restrict attr, int robustness), (attr, robustness), + ((sthread_mutexattr_t*)attr, robustness)); +intercepted_call(mutexattr_getrobust, (const pthread_mutexattr_t* restrict attr, int* restrict robustness), + (attr, robustness), ((sthread_mutexattr_t*)attr, robustness)); + int pthread_join(pthread_t thread, void** retval) { if (raw_pthread_join == NULL) @@ -107,7 +145,7 @@ int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr) return raw_mutex_init(mutex, attr); sthread_disable(); - int res = sthread_mutex_init((sthread_mutex_t*)mutex, attr); + int res = sthread_mutex_init((sthread_mutex_t*)mutex, (sthread_mutexattr_t*)attr); sthread_enable(); return res; } diff --git a/src/sthread/sthread.h b/src/sthread/sthread.h index ba4252e2d0..f0a9117db1 100644 --- a/src/sthread/sthread.h +++ b/src/sthread/sthread.h @@ -31,10 +31,22 @@ typedef unsigned long int sthread_t; int sthread_create(sthread_t* thread, const /*pthread_attr_t*/ void* attr, void* (*start_routine)(void*), void* arg); int sthread_join(sthread_t thread, void** retval); +typedef struct { + unsigned recursive : 1; + unsigned errorcheck : 1; + unsigned robust : 1; +} sthread_mutexattr_t; + +int sthread_mutexattr_init(sthread_mutexattr_t* attr); +int sthread_mutexattr_settype(sthread_mutexattr_t* attr, int type); +int sthread_mutexattr_gettype(const sthread_mutexattr_t* attr, int* type); +int sthread_mutexattr_getrobust(const sthread_mutexattr_t* attr, int* robustness); +int sthread_mutexattr_setrobust(sthread_mutexattr_t* attr, int robustness); + typedef struct { void* mutex; } sthread_mutex_t; -int sthread_mutex_init(sthread_mutex_t* mutex, const /*pthread_mutexattr_t*/ void* attr); +int sthread_mutex_init(sthread_mutex_t* mutex, const sthread_mutexattr_t* attr); int sthread_mutex_lock(sthread_mutex_t* mutex); int sthread_mutex_trylock(sthread_mutex_t* mutex); int sthread_mutex_unlock(sthread_mutex_t* mutex); diff --git a/src/sthread/sthread_impl.cpp b/src/sthread/sthread_impl.cpp index 7a606d8089..885c8b6bd2 100644 --- a/src/sthread/sthread_impl.cpp +++ b/src/sthread/sthread_impl.cpp @@ -6,6 +6,7 @@ /* SimGrid's pthread interposer. Actual implementation of the symbols (see the comment in sthread.h) */ #include "smpi/smpi.h" +#include "xbt/ex.h" #include "xbt/string.hpp" #include #include @@ -115,7 +116,57 @@ int sthread_join(sthread_t thread, void** /*retval*/) return 0; } -int sthread_mutex_init(sthread_mutex_t* mutex, const void* /*pthread_mutexattr_t* attr*/) +int sthread_mutexattr_init(sthread_mutexattr_t* attr) +{ + memset(attr, 0, sizeof(*attr)); + return 0; +} +int sthread_mutexattr_settype(sthread_mutexattr_t* attr, int type) +{ + // reset + attr->recursive = 0; + attr->errorcheck = 0; + + switch (type) { + case PTHREAD_MUTEX_NORMAL: + attr->recursive = 0; + break; + case PTHREAD_MUTEX_RECURSIVE: + attr->recursive = 1; + break; + case PTHREAD_MUTEX_ERRORCHECK: + attr->errorcheck = 1; + THROW_UNIMPLEMENTED; + break; + default: + THROW_IMPOSSIBLE; + } + return 0; +} +int sthread_mutexattr_gettype(const sthread_mutexattr_t* attr, int* type) +{ + if (attr->recursive) + *type = PTHREAD_MUTEX_RECURSIVE; + else if (attr->errorcheck) + *type = PTHREAD_MUTEX_ERRORCHECK; + else + *type = PTHREAD_MUTEX_NORMAL; + return 0; +} +int sthread_mutexattr_getrobust(const sthread_mutexattr_t* attr, int* robustness) +{ + *robustness = attr->robust; + return 0; +} +int sthread_mutexattr_setrobust(sthread_mutexattr_t* attr, int robustness) +{ + attr->robust = robustness; + if (robustness) + THROW_UNIMPLEMENTED; + return 0; +} + +int sthread_mutex_init(sthread_mutex_t* mutex, const sthread_mutexattr_t* attr) { auto m = sg4::Mutex::create(); intrusive_ptr_add_ref(m.get()); @@ -130,6 +181,7 @@ int sthread_mutex_lock(sthread_mutex_t* mutex) if (mutex->mutex == nullptr) sthread_mutex_init(mutex, nullptr); + XBT_DEBUG("%s(%p)", __FUNCTION__, mutex); static_cast(mutex->mutex)->lock(); return 0; } @@ -152,6 +204,7 @@ int sthread_mutex_unlock(sthread_mutex_t* mutex) if (mutex->mutex == nullptr) sthread_mutex_init(mutex, nullptr); + XBT_DEBUG("%s(%p)", __FUNCTION__, mutex); static_cast(mutex->mutex)->unlock(); return 0; } @@ -161,6 +214,7 @@ int sthread_mutex_destroy(sthread_mutex_t* mutex) if (mutex->mutex == nullptr) sthread_mutex_init(mutex, nullptr); + XBT_DEBUG("%s(%p)", __FUNCTION__, mutex); intrusive_ptr_release(static_cast(mutex->mutex)); return 0; } -- 2.20.1