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_ASYNCHRONOUS_IO		    -1 */
 | 
			
		||||
/* #define _POSIX_BARRIERS			    -1 */
 | 
			
		||||
#define _POSIX_BARRIERS				200112L
 | 
			
		||||
#define _POSIX_CHOWN_RESTRICTED			     1
 | 
			
		||||
#define _POSIX_CLOCK_SELECTION			200112L
 | 
			
		||||
#define _POSIX_CPUTIME			    	200112L
 | 
			
		||||
#define _POSIX_CPUTIME				200112L
 | 
			
		||||
#define _POSIX_FSYNC				200112L
 | 
			
		||||
#define _POSIX_IPV6				200112L
 | 
			
		||||
#define _POSIX_JOB_CONTROL			     1
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ extern "C" {
 | 
			
		|||
#define _POSIX_REGEXP				     1
 | 
			
		||||
#define _POSIX_SAVED_IDS			     1
 | 
			
		||||
#define _POSIX_SEMAPHORES			200112L
 | 
			
		||||
#define _POSIX_SHARED_MEMORY_OBJECTS		200112L 
 | 
			
		||||
#define _POSIX_SHARED_MEMORY_OBJECTS		200112L
 | 
			
		||||
#define _POSIX_SHELL				     1
 | 
			
		||||
/* #define _POSIX_SPAWN				    -1 */
 | 
			
		||||
#define _POSIX_SPIN_LOCKS			    200112L
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -431,6 +431,7 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
/* POSIX Barrier Types */
 | 
			
		||||
 | 
			
		||||
#if !defined(__CYGWIN__)
 | 
			
		||||
#if defined(_POSIX_BARRIERS)
 | 
			
		||||
typedef __uint32_t pthread_barrier_t;        /* POSIX Barrier Object */
 | 
			
		||||
typedef struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -443,7 +444,6 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
/* POSIX Spin Lock Types */
 | 
			
		||||
 | 
			
		||||
#if !defined (__CYGWIN__)
 | 
			
		||||
#if defined(_POSIX_SPIN_LOCKS)
 | 
			
		||||
typedef __uint32_t pthread_spinlock_t;        /* POSIX Spin Lock Object */
 | 
			
		||||
#endif /* defined(_POSIX_SPIN_LOCKS) */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -869,6 +869,13 @@ pthread_attr_setscope SIGFE
 | 
			
		|||
pthread_attr_setstack SIGFE
 | 
			
		||||
pthread_attr_setstackaddr 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_cond_broadcast 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_condattr_t {char __dummy;} *pthread_condattr_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!. */
 | 
			
		||||
typedef struct
 | 
			
		||||
| 
						 | 
				
			
			@ -207,6 +209,8 @@ typedef class pthread_attr *pthread_attr_t;
 | 
			
		|||
typedef class pthread_mutexattr *pthread_mutexattr_t;
 | 
			
		||||
typedef class pthread_condattr *pthread_condattr_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_spinlock *pthread_spinlock_t;
 | 
			
		||||
typedef class pthread_rwlock *pthread_rwlock_t;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,7 @@ extern "C"
 | 
			
		|||
/* process is the default */
 | 
			
		||||
#define PTHREAD_SCOPE_PROCESS 0
 | 
			
		||||
#define PTHREAD_SCOPE_SYSTEM 1
 | 
			
		||||
#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
 | 
			
		||||
 | 
			
		||||
/* Register Fork Handlers */
 | 
			
		||||
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_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 *,
 | 
			
		||||
		    void *(*)(void *), void *);
 | 
			
		||||
int pthread_detach (pthread_t);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,10 @@ details. */
 | 
			
		|||
 | 
			
		||||
#ifndef _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);
 | 
			
		||||
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::_destroyed_mutex = (pthread_t) 3;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
static inline
 | 
			
		||||
void
 | 
			
		||||
delete_and_clear (T * * const ptr)
 | 
			
		||||
{
 | 
			
		||||
  delete *ptr;
 | 
			
		||||
  *ptr = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline bool
 | 
			
		||||
pthread_mutex::no_owner()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -267,6 +278,23 @@ pthread_cond::is_initializer_or_object (pthread_cond_t const *cond)
 | 
			
		|||
  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 */
 | 
			
		||||
inline bool
 | 
			
		||||
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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_MAGIC), shared (PTHREAD_PROCESS_PRIVATE)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -3869,3 +3916,218 @@ pthread_null::getsequence_np ()
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
   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_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
 | 
			
		||||
#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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -520,6 +523,38 @@ private:
 | 
			
		|||
  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
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue