posixcompat: make pthread_once a wrapper over the version in libbarrelfish
authorZaheer Chothia <zchothia@inf.ethz.ch>
Wed, 17 Dec 2014 14:08:15 +0000 (15:08 +0100)
committerZaheer Chothia <zchothia@inf.ethz.ch>
Mon, 20 Apr 2015 21:09:32 +0000 (23:09 +0200)
Summary:
Both the pthread and native versions now share a single common
implementation (added in D9).  The new approach should also be faster
since it avoids a full mutex and instead only has to consult the
per-thread epoch on the common path.  I should note, I have not run
any benchmarks to confirm this and may be wrong.

Test Plan: Compiles but have not validated more thoroughly.

Differential Revision: https://code.systems.ethz.ch/D12

Signed-off-by: Zaheer Chothia <zchothia@inf.ethz.ch>

include/barrelfish/thread_sync.h
include/barrelfish/threads.h
include/pthread.h
include/sys/_pthreadtypes.h
lib/barrelfish/thread_once.c
lib/posixcompat/pthreads.c

index a026895..0d124e5 100644 (file)
@@ -16,6 +16,8 @@
 #define LIBBARRELFISH_THREAD_SYNC_H
 
 #include <stdint.h>
+#include <limits.h> // for INT_MAX
+
 #include <barrelfish_kpi/spinlocks_arch.h>
 
 /// A thread of execution
@@ -60,4 +62,7 @@ struct thread_sem {
     { 0, (struct thread *)NULL, 0 }
 #endif
 
+typedef int thread_once_t;
+#define THREAD_ONCE_INIT INT_MAX
+
 #endif
index 39c8d69..f4afb01 100644 (file)
@@ -16,7 +16,6 @@
 #define LIBBARRELFISH_THREADS_H
 
 #include <assert.h>
-#include <limits.h>
 #include <sys/cdefs.h>
 
 #include <barrelfish/caddr.h> // for struct capref.
@@ -76,9 +75,6 @@ uintptr_t thread_id(void);
 uintptr_t thread_get_id(struct thread *t);
 void thread_set_id(uintptr_t id);
 
-typedef int thread_once_t;
-#define THREAD_ONCE_INIT INT_MAX
-
 extern __thread thread_once_t thread_once_local_epoch;
 extern void thread_once_internal(thread_once_t *control, void (*func)(void));
 
index 67ae0fd..511997d 100644 (file)
@@ -47,6 +47,8 @@
 #include <sched.h>
 #include <time.h>
 
+#include <barrelfish/thread_sync.h> // for THREAD_ONCE_INIT
+
 /*
  * Run-time invariant values:
  */
 #define PTHREAD_CANCELED               ((void *) 1)
 
 /*
- * Flags for once initialization.
- */
-#define PTHREAD_NEEDS_INIT  0
-#define PTHREAD_DONE_INIT   1
-
-/*
  * Static once initialization values.
  */
-#define PTHREAD_ONCE_INIT   { PTHREAD_NEEDS_INIT, NULL }
+#define PTHREAD_ONCE_INIT   THREAD_ONCE_INIT
 
 /*
  * Static initialization values.
index 76049ee..dbb7152 100644 (file)
@@ -36,6 +36,8 @@
 #ifndef _SYS__PTHREADTYPES_H_
 #define _SYS__PTHREADTYPES_H_
 
+#include <barrelfish/thread_sync.h> // for thread_once_t
+
 /*
  * Forward structure definitions.
  *
@@ -47,7 +49,6 @@ struct pthread_cond;
 struct pthread_cond_attr;
 struct pthread_mutex;
 struct pthread_mutex_attr;
-struct pthread_once;
 struct pthread_rwlock;
 struct pthread_rwlockattr;
 struct pthread_barrier;
@@ -71,7 +72,7 @@ typedef struct        pthread_mutex_attr      *pthread_mutexattr_t;
 typedef struct pthread_cond            *pthread_cond_t;
 typedef struct pthread_cond_attr       *pthread_condattr_t;
 typedef int                            pthread_key_t;
-typedef struct pthread_once            pthread_once_t;
+typedef thread_once_t                  pthread_once_t;
 typedef struct pthread_rwlock          *pthread_rwlock_t;
 typedef struct pthread_rwlockattr      *pthread_rwlockattr_t;
 typedef struct pthread_barrier         *pthread_barrier_t;
@@ -87,12 +88,4 @@ typedef struct       pthread_spinlock        *pthread_spinlock_t;
 typedef void   *pthread_addr_t;
 typedef void   *(*pthread_startroutine_t)(void *);
 
-/*
- * Once definitions.
- */
-struct pthread_once {
-       int             state;
-       pthread_mutex_t mutex;
-};
-
 #endif /* ! _SYS__PTHREADTYPES_H_ */
index f72c278..580646b 100644 (file)
@@ -32,8 +32,6 @@
 //   "Dynamic Initialization and Destruction with Concurrency"
 //   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm
 
-#include <limits.h>
-
 #include <barrelfish/threads.h>
 
 /// Protects global_epoch and all thread_once_t writes.
index 4fd07c0..eec6311 100644 (file)
@@ -688,20 +688,6 @@ int _pthread_once(pthread_once_t *ctrl, void (*init) (void))
     if (ctrl == NULL || init == NULL) {
         return EINVAL;
     }
-
-
-    pthread_mutex_lock(&ctrl->mutex);
-
-
-    if (!ctrl->state)
-    {
-        //pthread_cleanup_push(ptw32_mcs_lock_release, &node);
-        (*init)();
-        //pthread_cleanup_pop(0);
-        ctrl->state = 1;
-    }
-
-    pthread_mutex_unlock(&ctrl->mutex);
-
+    thread_once(ctrl, init);
     return 0;
 }