Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Implement reentrant mutexes in xbt_os_thread
authorChristophe Thiéry <christopho128@gmail.com>
Thu, 21 Apr 2011 14:19:07 +0000 (16:19 +0200)
committerChristophe Thiéry <christopho128@gmail.com>
Thu, 21 Apr 2011 14:19:07 +0000 (16:19 +0200)
src/include/xbt/xbt_os_thread.h
src/xbt/xbt_main.c
src/xbt/xbt_os_thread.c

index e4e07fc..597815d 100644 (file)
@@ -64,6 +64,14 @@ XBT_PUBLIC(void) xbt_os_mutex_timedacquire(xbt_os_mutex_t mutex,
 XBT_PUBLIC(void) xbt_os_mutex_release(xbt_os_mutex_t mutex);
 XBT_PUBLIC(void) xbt_os_mutex_destroy(xbt_os_mutex_t mutex);
 
+/** \brief Thread reentrant mutex data type (opaque structure) */
+typedef struct xbt_os_rmutex_ *xbt_os_rmutex_t;
+
+XBT_PUBLIC(xbt_os_rmutex_t) xbt_os_rmutex_init(void);
+XBT_PUBLIC(void) xbt_os_rmutex_acquire(xbt_os_rmutex_t rmutex);
+XBT_PUBLIC(void) xbt_os_rmutex_release(xbt_os_rmutex_t rmutex);
+XBT_PUBLIC(void) xbt_os_rmutex_destroy(xbt_os_rmutex_t rmutex);
+
 
   /** \brief Thread condition data type (opaque structure) */
 typedef struct xbt_os_cond_ *xbt_os_cond_t;
index 897ea43..a6aafc5 100644 (file)
@@ -123,22 +123,22 @@ static void xbt_preinit(void)
   XBT_LOG_CONNECT(xbt_parmap,xbt);
   XBT_LOG_CONNECT(xbt_parmap_unit,xbt_parmap);
 
-  xbt_fifo_preinit();
-  xbt_dict_preinit();
 
   xbt_backtrace_preinit();
   xbt_os_thread_mod_preinit();
+  xbt_fifo_preinit();
+  xbt_dict_preinit();
 }
 
 static void xbt_postexit(void)
 {
-  xbt_os_thread_mod_postexit();
   xbt_backtrace_postexit();
 
   xbt_fifo_postexit();
   xbt_dict_postexit();
 
   xbt_log_postexit();
+  xbt_os_thread_mod_postexit();
 
   free(xbt_binary_name);
 #ifdef HAVE_MMAP
index 2efd81e..781d471 100644 (file)
@@ -242,6 +242,12 @@ typedef struct xbt_os_mutex_ {
   pthread_mutex_t m;
 } s_xbt_os_mutex_t;
 
+typedef struct xbt_os_rmutex_ {
+  xbt_os_mutex_t mutex;
+  xbt_os_thread_t owner;
+  int count;
+} s_xbt_os_rmutex_t;
+
 #include <time.h>
 #include <math.h>
 
@@ -352,6 +358,45 @@ void xbt_os_mutex_destroy(xbt_os_mutex_t mutex)
   free(mutex);
 }
 
+xbt_os_rmutex_t xbt_os_rmutex_init(void)
+{
+  xbt_os_rmutex_t rmutex = xbt_new0(struct xbt_os_rmutex_, 0);
+  rmutex->mutex = xbt_os_mutex_init();
+  rmutex->owner = NULL;
+  rmutex->count = 0;
+  return rmutex;
+}
+
+void xbt_os_rmutex_acquire(xbt_os_rmutex_t rmutex)
+{
+  xbt_os_thread_t self = xbt_os_thread_self();
+  xbt_assert(self != NULL, "Cannot get my own thread object (is the thread module initialized?)");
+
+  if (self != rmutex->owner) {
+    xbt_os_mutex_acquire(rmutex->mutex);
+    rmutex->owner = self;
+    rmutex->count = 1;
+  } else {
+    rmutex->count++;
+ }
+}
+
+void xbt_os_rmutex_release(xbt_os_rmutex_t rmutex)
+{
+  xbt_assert(rmutex->owner == xbt_os_thread_self());
+
+  if (--rmutex->count == 0) {
+    rmutex->owner = NULL;
+    xbt_os_mutex_release(rmutex->mutex);
+  }
+}
+
+void xbt_os_rmutex_destroy(xbt_os_rmutex_t rmutex)
+{
+  xbt_os_mutex_destroy(rmutex->mutex);
+  xbt_free(rmutex);
+}
+
 /***** condition related functions *****/
 typedef struct xbt_os_cond_ {
   /* KEEP IT IN SYNC WITH xbt_thread.c */