POSIX barrier implementation, take 3
The attached patch should address all of the review comments. Modifed change log: Newlib: * libc/include/sys/features.h (_POSIX_BARRIERS): Define for Cygwin. * libc/include/sys/types.h (pthread_barrier_t) (pthread_barrierattr_t): Do not define for Cygwin. Cygwin: * common.din (pthread_barrierattr_init) (pthread_barrierattr_setpshared, pthread_barrierattr_getpshared) (pthread_barrierattr_destroy, pthread_barrier_init) (pthread_barrier_destroy, pthread_barrier_wait): Export. * include/cygwin/types.h (pthread_barrierattr_t) (pthread_barrier_t): Declare. * include/pthread.h (PTHREAD_BARRIER_SERIAL_THREAD) (pthread_barrierattr_init, pthread_barrierattr_setpshared) (pthread_barrierattr_getpshared, pthread_barrierattr_destroy) (pthread_barrier_init, pthread_barrier_destroy) (pthread_barrier_wait): Declare. * thread.h (PTHREAD_BARRIER_MAGIC) (PTHREAD_BARRIERATTR_MAGIC): Define. (class pthread_barrierattr, class pthread_barrier): Declare. * thread.cc (delete_and_clear): New local helper function. (class pthread_barrierattr, class pthread_barrier): Implement. * miscfuncs.h (likely, unlikely): New macros. -- VH
This commit is contained in:
parent
ef64aa4940
commit
813da84442
|
@ -118,10 +118,10 @@ extern "C" {
|
||||||
|
|
||||||
#define _POSIX_ADVISORY_INFO 200112L
|
#define _POSIX_ADVISORY_INFO 200112L
|
||||||
/* #define _POSIX_ASYNCHRONOUS_IO -1 */
|
/* #define _POSIX_ASYNCHRONOUS_IO -1 */
|
||||||
/* #define _POSIX_BARRIERS -1 */
|
#define _POSIX_BARRIERS 200112L
|
||||||
#define _POSIX_CHOWN_RESTRICTED 1
|
#define _POSIX_CHOWN_RESTRICTED 1
|
||||||
#define _POSIX_CLOCK_SELECTION 200112L
|
#define _POSIX_CLOCK_SELECTION 200112L
|
||||||
#define _POSIX_CPUTIME 200112L
|
#define _POSIX_CPUTIME 200112L
|
||||||
#define _POSIX_FSYNC 200112L
|
#define _POSIX_FSYNC 200112L
|
||||||
#define _POSIX_IPV6 200112L
|
#define _POSIX_IPV6 200112L
|
||||||
#define _POSIX_JOB_CONTROL 1
|
#define _POSIX_JOB_CONTROL 1
|
||||||
|
@ -140,7 +140,7 @@ extern "C" {
|
||||||
#define _POSIX_REGEXP 1
|
#define _POSIX_REGEXP 1
|
||||||
#define _POSIX_SAVED_IDS 1
|
#define _POSIX_SAVED_IDS 1
|
||||||
#define _POSIX_SEMAPHORES 200112L
|
#define _POSIX_SEMAPHORES 200112L
|
||||||
#define _POSIX_SHARED_MEMORY_OBJECTS 200112L
|
#define _POSIX_SHARED_MEMORY_OBJECTS 200112L
|
||||||
#define _POSIX_SHELL 1
|
#define _POSIX_SHELL 1
|
||||||
/* #define _POSIX_SPAWN -1 */
|
/* #define _POSIX_SPAWN -1 */
|
||||||
#define _POSIX_SPIN_LOCKS 200112L
|
#define _POSIX_SPIN_LOCKS 200112L
|
||||||
|
|
|
@ -431,6 +431,7 @@ typedef struct {
|
||||||
|
|
||||||
/* POSIX Barrier Types */
|
/* POSIX Barrier Types */
|
||||||
|
|
||||||
|
#if !defined(__CYGWIN__)
|
||||||
#if defined(_POSIX_BARRIERS)
|
#if defined(_POSIX_BARRIERS)
|
||||||
typedef __uint32_t pthread_barrier_t; /* POSIX Barrier Object */
|
typedef __uint32_t pthread_barrier_t; /* POSIX Barrier Object */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -443,7 +444,6 @@ typedef struct {
|
||||||
|
|
||||||
/* POSIX Spin Lock Types */
|
/* POSIX Spin Lock Types */
|
||||||
|
|
||||||
#if !defined (__CYGWIN__)
|
|
||||||
#if defined(_POSIX_SPIN_LOCKS)
|
#if defined(_POSIX_SPIN_LOCKS)
|
||||||
typedef __uint32_t pthread_spinlock_t; /* POSIX Spin Lock Object */
|
typedef __uint32_t pthread_spinlock_t; /* POSIX Spin Lock Object */
|
||||||
#endif /* defined(_POSIX_SPIN_LOCKS) */
|
#endif /* defined(_POSIX_SPIN_LOCKS) */
|
||||||
|
|
|
@ -869,6 +869,13 @@ pthread_attr_setscope SIGFE
|
||||||
pthread_attr_setstack SIGFE
|
pthread_attr_setstack SIGFE
|
||||||
pthread_attr_setstackaddr SIGFE
|
pthread_attr_setstackaddr SIGFE
|
||||||
pthread_attr_setstacksize SIGFE
|
pthread_attr_setstacksize SIGFE
|
||||||
|
pthread_barrierattr_init SIGFE
|
||||||
|
pthread_barrierattr_setpshared SIGFE
|
||||||
|
pthread_barrierattr_getpshared SIGFE
|
||||||
|
pthread_barrierattr_destroy SIGFE
|
||||||
|
pthread_barrier_init SIGFE
|
||||||
|
pthread_barrier_destroy SIGFE
|
||||||
|
pthread_barrier_wait SIGFE
|
||||||
pthread_cancel SIGFE
|
pthread_cancel SIGFE
|
||||||
pthread_cond_broadcast SIGFE
|
pthread_cond_broadcast SIGFE
|
||||||
pthread_cond_destroy SIGFE
|
pthread_cond_destroy SIGFE
|
||||||
|
|
|
@ -184,6 +184,8 @@ typedef struct __pthread_attr_t {char __dummy;} *pthread_attr_t;
|
||||||
typedef struct __pthread_mutexattr_t {char __dummy;} *pthread_mutexattr_t;
|
typedef struct __pthread_mutexattr_t {char __dummy;} *pthread_mutexattr_t;
|
||||||
typedef struct __pthread_condattr_t {char __dummy;} *pthread_condattr_t;
|
typedef struct __pthread_condattr_t {char __dummy;} *pthread_condattr_t;
|
||||||
typedef struct __pthread_cond_t {char __dummy;} *pthread_cond_t;
|
typedef struct __pthread_cond_t {char __dummy;} *pthread_cond_t;
|
||||||
|
typedef struct __pthread_barrierattr_t {char __dummy;} *pthread_barrierattr_t;
|
||||||
|
typedef struct __pthread_barrier_t {char __dummy;} *pthread_barrier_t;
|
||||||
|
|
||||||
/* These variables are not user alterable. This means you!. */
|
/* These variables are not user alterable. This means you!. */
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -207,6 +209,8 @@ typedef class pthread_attr *pthread_attr_t;
|
||||||
typedef class pthread_mutexattr *pthread_mutexattr_t;
|
typedef class pthread_mutexattr *pthread_mutexattr_t;
|
||||||
typedef class pthread_condattr *pthread_condattr_t;
|
typedef class pthread_condattr *pthread_condattr_t;
|
||||||
typedef class pthread_cond *pthread_cond_t;
|
typedef class pthread_cond *pthread_cond_t;
|
||||||
|
typedef class pthread_barrier *pthread_barrier_t;
|
||||||
|
typedef class pthread_barrierattr *pthread_barrierattr_t;
|
||||||
typedef class pthread_once pthread_once_t;
|
typedef class pthread_once pthread_once_t;
|
||||||
typedef class pthread_spinlock *pthread_spinlock_t;
|
typedef class pthread_spinlock *pthread_spinlock_t;
|
||||||
typedef class pthread_rwlock *pthread_rwlock_t;
|
typedef class pthread_rwlock *pthread_rwlock_t;
|
||||||
|
|
|
@ -62,6 +62,7 @@ extern "C"
|
||||||
/* process is the default */
|
/* process is the default */
|
||||||
#define PTHREAD_SCOPE_PROCESS 0
|
#define PTHREAD_SCOPE_PROCESS 0
|
||||||
#define PTHREAD_SCOPE_SYSTEM 1
|
#define PTHREAD_SCOPE_SYSTEM 1
|
||||||
|
#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
|
||||||
|
|
||||||
/* Register Fork Handlers */
|
/* Register Fork Handlers */
|
||||||
int pthread_atfork (void (*)(void), void (*)(void), void (*)(void));
|
int pthread_atfork (void (*)(void), void (*)(void), void (*)(void));
|
||||||
|
@ -133,6 +134,17 @@ int pthread_condattr_init (pthread_condattr_t *);
|
||||||
int pthread_condattr_setclock (pthread_condattr_t *, clockid_t);
|
int pthread_condattr_setclock (pthread_condattr_t *, clockid_t);
|
||||||
int pthread_condattr_setpshared (pthread_condattr_t *, int);
|
int pthread_condattr_setpshared (pthread_condattr_t *, int);
|
||||||
|
|
||||||
|
/* Barriers */
|
||||||
|
int pthread_barrierattr_init (pthread_barrierattr_t *);
|
||||||
|
int pthread_barrierattr_setpshared (pthread_barrierattr_t *, int);
|
||||||
|
int pthread_barrierattr_getpshared (const pthread_barrierattr_t *, int *);
|
||||||
|
int pthread_barrierattr_destroy (pthread_barrierattr_t *);
|
||||||
|
int pthread_barrier_init (pthread_barrier_t *,
|
||||||
|
const pthread_barrierattr_t *, unsigned);
|
||||||
|
int pthread_barrier_destroy (pthread_barrier_t *);
|
||||||
|
int pthread_barrier_wait (pthread_barrier_t *);
|
||||||
|
|
||||||
|
/* Threads */
|
||||||
int pthread_create (pthread_t *, const pthread_attr_t *,
|
int pthread_create (pthread_t *, const pthread_attr_t *,
|
||||||
void *(*)(void *), void *);
|
void *(*)(void *), void *);
|
||||||
int pthread_detach (pthread_t);
|
int pthread_detach (pthread_t);
|
||||||
|
|
|
@ -11,6 +11,10 @@ details. */
|
||||||
|
|
||||||
#ifndef _MISCFUNCS_H
|
#ifndef _MISCFUNCS_H
|
||||||
#define _MISCFUNCS_H
|
#define _MISCFUNCS_H
|
||||||
|
|
||||||
|
#define likely(X) __builtin_expect (!!(X), 1)
|
||||||
|
#define unlikely(X) __builtin_expect (!!(X), 0)
|
||||||
|
|
||||||
int __reg1 winprio_to_nice (DWORD);
|
int __reg1 winprio_to_nice (DWORD);
|
||||||
DWORD __reg1 nice_to_winprio (int &);
|
DWORD __reg1 nice_to_winprio (int &);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,17 @@ const pthread_t pthread_mutex::_new_mutex = (pthread_t) 1;
|
||||||
const pthread_t pthread_mutex::_unlocked_mutex = (pthread_t) 2;
|
const pthread_t pthread_mutex::_unlocked_mutex = (pthread_t) 2;
|
||||||
const pthread_t pthread_mutex::_destroyed_mutex = (pthread_t) 3;
|
const pthread_t pthread_mutex::_destroyed_mutex = (pthread_t) 3;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline
|
||||||
|
void
|
||||||
|
delete_and_clear (T * * const ptr)
|
||||||
|
{
|
||||||
|
delete *ptr;
|
||||||
|
*ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
pthread_mutex::no_owner()
|
pthread_mutex::no_owner()
|
||||||
{
|
{
|
||||||
|
@ -267,6 +278,23 @@ pthread_cond::is_initializer_or_object (pthread_cond_t const *cond)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
pthread_barrierattr::is_good_object (pthread_barrierattr_t const *cond)
|
||||||
|
{
|
||||||
|
if (verifyable_object_isvalid (cond, PTHREAD_BARRIERATTR_MAGIC)
|
||||||
|
!= VALID_OBJECT)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
pthread_barrier::is_good_object (pthread_barrier_t const *cond)
|
||||||
|
{
|
||||||
|
if (verifyable_object_isvalid (cond, PTHREAD_BARRIER_MAGIC) != VALID_OBJECT)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* RW locks */
|
/* RW locks */
|
||||||
inline bool
|
inline bool
|
||||||
pthread_rwlock::is_good_object (pthread_rwlock_t const *rwlock)
|
pthread_rwlock::is_good_object (pthread_rwlock_t const *rwlock)
|
||||||
|
@ -1300,6 +1328,25 @@ pthread_cond::_fixup_after_fork ()
|
||||||
api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
|
api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_barrierattr::pthread_barrierattr ()
|
||||||
|
: verifyable_object (PTHREAD_BARRIERATTR_MAGIC)
|
||||||
|
, shared (PTHREAD_PROCESS_PRIVATE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_barrierattr::~pthread_barrierattr ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_barrier::pthread_barrier ()
|
||||||
|
: verifyable_object (PTHREAD_BARRIER_MAGIC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_barrier::~pthread_barrier ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
|
pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
|
||||||
(PTHREAD_RWLOCKATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE)
|
(PTHREAD_RWLOCKATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE)
|
||||||
{
|
{
|
||||||
|
@ -3869,3 +3916,218 @@ pthread_null::getsequence_np ()
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_null pthread_null::_instance;
|
pthread_null pthread_null::_instance;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
pthread_barrierattr_init (pthread_barrierattr_t * battr)
|
||||||
|
{
|
||||||
|
if (unlikely (battr == NULL))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*battr = new pthread_barrierattr;
|
||||||
|
(*battr)->shared = PTHREAD_PROCESS_PRIVATE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
pthread_barrierattr_setpshared (pthread_barrierattr_t * battr, int shared)
|
||||||
|
{
|
||||||
|
if (unlikely (! pthread_barrierattr::is_good_object (battr)))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (unlikely (shared != PTHREAD_PROCESS_SHARED
|
||||||
|
&& shared != PTHREAD_PROCESS_PRIVATE))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
(*battr)->shared = shared;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
pthread_barrierattr_getpshared (const pthread_barrierattr_t * battr,
|
||||||
|
int * shared)
|
||||||
|
{
|
||||||
|
if (unlikely (! pthread_barrierattr::is_good_object (battr)
|
||||||
|
|| shared == NULL))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*shared = (*battr)->shared;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
pthread_barrierattr_destroy (pthread_barrierattr_t * battr)
|
||||||
|
{
|
||||||
|
if (unlikely (! pthread_barrierattr::is_good_object (battr)))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
delete_and_clear (battr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
pthread_barrier_init (pthread_barrier_t * bar,
|
||||||
|
const pthread_barrierattr_t * attr, unsigned count)
|
||||||
|
{
|
||||||
|
if (unlikely (bar == NULL))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*bar = new pthread_barrier;
|
||||||
|
return (*bar)->init (attr, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
pthread_barrier::init (const pthread_barrierattr_t * attr, unsigned count)
|
||||||
|
{
|
||||||
|
pthread_mutex_t * mutex = NULL;
|
||||||
|
|
||||||
|
if (unlikely ((attr != NULL
|
||||||
|
&& (! pthread_barrierattr::is_good_object (attr)
|
||||||
|
|| (*attr)->shared == PTHREAD_PROCESS_SHARED))
|
||||||
|
|| count == 0))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
int retval = pthread_mutex_init (&mtx, NULL);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
retval = pthread_cond_init (&cond, NULL);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
{
|
||||||
|
int ret = pthread_mutex_destroy (mutex);
|
||||||
|
if (ret != 0)
|
||||||
|
api_fatal ("pthread_mutex_destroy (%p) = %d", mutex, ret);
|
||||||
|
|
||||||
|
mtx = NULL;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt = count;
|
||||||
|
cyc = 0;
|
||||||
|
wt = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
pthread_barrier_destroy (pthread_barrier_t * bar)
|
||||||
|
{
|
||||||
|
if (unlikely (! pthread_barrier::is_good_object (bar)))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
ret = (*bar)->destroy ();
|
||||||
|
if (ret == 0)
|
||||||
|
delete_and_clear (bar);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
pthread_barrier::destroy ()
|
||||||
|
{
|
||||||
|
if (unlikely (wt != 0))
|
||||||
|
return EBUSY;
|
||||||
|
|
||||||
|
int retval = pthread_cond_destroy (&cond);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
return retval;
|
||||||
|
else
|
||||||
|
cond = NULL;
|
||||||
|
|
||||||
|
retval = pthread_mutex_destroy (&mtx);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
return retval;
|
||||||
|
else
|
||||||
|
mtx = NULL;
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
cyc = 0;
|
||||||
|
wt = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int
|
||||||
|
pthread_barrier_wait (pthread_barrier_t * bar)
|
||||||
|
{
|
||||||
|
if (unlikely (! pthread_barrier::is_good_object (bar)))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
return (*bar)->wait ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
pthread_barrier::wait ()
|
||||||
|
{
|
||||||
|
int retval = pthread_mutex_lock (&mtx);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (unlikely (wt >= cnt))
|
||||||
|
{
|
||||||
|
api_fatal ("wt >= cnt (%u >= %u)", wt, cnt);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely (++wt == cnt))
|
||||||
|
{
|
||||||
|
++cyc;
|
||||||
|
/* This is the last thread to reach the barrier. Signal the waiting
|
||||||
|
threads to wake up and continue. */
|
||||||
|
retval = pthread_cond_broadcast (&cond);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
goto cond_error;
|
||||||
|
|
||||||
|
wt = 0;
|
||||||
|
retval = pthread_mutex_unlock (&mtx);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
return PTHREAD_BARRIER_SERIAL_THREAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint64_t cycle = cyc;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
retval = pthread_cond_wait (&cond, &mtx);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
goto cond_error;
|
||||||
|
}
|
||||||
|
while (unlikely (cycle == cyc));
|
||||||
|
|
||||||
|
retval = pthread_mutex_unlock (&mtx);
|
||||||
|
if (unlikely (retval != 0))
|
||||||
|
api_fatal ("pthread_mutex_unlock (%p) = %d", &mtx, retval);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_error:
|
||||||
|
{
|
||||||
|
--wt;
|
||||||
|
int ret = pthread_mutex_unlock (&mtx);
|
||||||
|
if (unlikely (ret != 0))
|
||||||
|
api_fatal ("pthread_mutex_unlock (%p) = %d", &mtx, ret);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// -*- C++ -*-
|
||||||
/* thread.h: Locking and threading module definitions
|
/* thread.h: Locking and threading module definitions
|
||||||
|
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009,
|
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009,
|
||||||
|
@ -84,6 +85,8 @@ class pinfo;
|
||||||
#define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
|
#define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
|
||||||
#define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
|
#define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
|
||||||
#define PTHREAD_SPINLOCK_MAGIC PTHREAD_MAGIC+11
|
#define PTHREAD_SPINLOCK_MAGIC PTHREAD_MAGIC+11
|
||||||
|
#define PTHREAD_BARRIER_MAGIC PTHREAD_MAGIC+12
|
||||||
|
#define PTHREAD_BARRIERATTR_MAGIC PTHREAD_MAGIC+13
|
||||||
|
|
||||||
#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
|
#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
|
||||||
|
|
||||||
|
@ -520,6 +523,38 @@ private:
|
||||||
static fast_mutex cond_initialization_lock;
|
static fast_mutex cond_initialization_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class pthread_barrierattr: public verifyable_object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool is_good_object(pthread_barrierattr_t const *);
|
||||||
|
int shared;
|
||||||
|
|
||||||
|
pthread_barrierattr ();
|
||||||
|
~pthread_barrierattr ();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class pthread_barrier: public verifyable_object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool is_good_object(pthread_barrier_t const *);
|
||||||
|
|
||||||
|
pthread_mutex_t mtx; /* Mutex protecting everything below. */
|
||||||
|
pthread_cond_t cond; /* Conditional variable to wait on. */
|
||||||
|
unsigned cnt; /* Barrier count. Threads to wait for. */
|
||||||
|
uint64_t cyc; /* Cycle count. */
|
||||||
|
unsigned wt; /* Already waiting threads count. */
|
||||||
|
|
||||||
|
int init (const pthread_barrierattr_t *, unsigned);
|
||||||
|
int wait();
|
||||||
|
int destroy ();
|
||||||
|
|
||||||
|
pthread_barrier ();
|
||||||
|
~pthread_barrier ();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class pthread_rwlockattr: public verifyable_object
|
class pthread_rwlockattr: public verifyable_object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue