public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
* [PATCH] POSIX barrier implementation, take 2
@ 2016-02-12 10:21 Václav Haisman
  2016-02-12 14:25 ` Corinna Vinschen
  0 siblings, 1 reply; 5+ messages in thread
From: Václav Haisman @ 2016-02-12 10:21 UTC (permalink / raw)
  To: cygwin-patches


[-- Attachment #1.1: Type: text/plain, Size: 1195 bytes --]

Hi.

Here is a second take on the POSIX barrier API. This time it is tested
with the attached barrier.c file. Here is a 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.
	* cygwin/thread.h (PTHREAD_BARRIER_MAGIC)
	(PTHREAD_BARRIERATTR_MAGIC): Define.
	(class pthread_barrierattr, class pthread_barrier): Declare.
	* cygwin/thread.cc (delete_and_clear): New local helper function.
	(class pthread_barrierattr, class pthread_barrier): Implement.

-- 
VH

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: barrier.c --]
[-- Type: text/x-csrc; name="barrier.c", Size: 2978 bytes --]

#include <pthread.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>


pthread_barrier_t barrier;


#define ROUNDS 5

void *
thread_routine (void * arg)
{
  int myid = (ptrdiff_t)arg;

  for (int round = 0; round != ROUNDS; ++round)
    {
      printf ("Thread %d reporting for duty. Going to wait on barrier."
              " Round %d.\n", myid, round);
      int retval = pthread_barrier_wait (&barrier);
      if (retval == PTHREAD_BARRIER_SERIAL_THREAD)
        printf ("I, number %d, was the last thread to make it to the barrier."
                " Round %d.\n",
                myid, round);
      else if (retval != 0)
        printf ("I, number %d, got error %d on barrier. Round %d.\n",
                myid, retval, round);
      else
        printf ("I, number %d, got released by the barrier. Round %d.\n",
                myid, round);

    }

  return NULL;
}


#define COUNT 5

pthread_t threads[COUNT];


int
main ()
{
  pthread_barrierattr_t battr;
  int retval = pthread_barrierattr_init (&battr);
  if (retval != 0)
    {
      printf ("Failed to initialize barrier attribute: %d", retval);
      return retval;
    }

  retval = pthread_barrierattr_setpshared (&battr,
                                                PTHREAD_PROCESS_SHARED);
  if (retval != 0)
    {
      printf ("Failed to set PTHREAD_PROCESS_SHARED on barrier attribute:"
              " %d\n",
              retval);
      return retval;
    }

  retval = pthread_barrierattr_setpshared (&battr,
                                                PTHREAD_PROCESS_PRIVATE);
  if (retval != 0)
    {
      printf ("Failed to set PTHREAD_PROCESS_PRIVATE on barrier attribute:"
              " %d\n",
              retval);
      return retval;
    }

  retval = pthread_barrier_init (&barrier, &battr, COUNT);
  if (retval != 0)
    {
      printf ("Failed to init barrier: %d\n", retval);
      return retval;
    }

  retval = pthread_barrierattr_destroy (&battr);
  if (retval != 0)
    {
      printf ("Failed to destroy barrier attribute: %d\n", retval);
      return retval;
    }

  for (int i = 0; i != COUNT; ++i)
    {
      retval = pthread_create(&threads[i], NULL, thread_routine,
                              (void*)(ptrdiff_t)i);
      if (retval != 0)
        {
          printf ("Failed to create thread %d, error %d.\n", i, retval);
          return retval;
        }
    }

  for (int i = 0; i != COUNT; ++i)
    {
      retval = pthread_join (threads[i], NULL);
      if (retval != 0)
        {
          printf ("Failed to join thread %d, error %d.\n", i, retval);
          return retval;
        }
    }

  retval = pthread_barrier_destroy (&barrier);
  if (retval != 0)
    {
      printf ("Failed to destroy barrier: %d\n", retval);
      return retval;
    }

  return 0;
}

[-- Attachment #1.3: barrier02.patch.txt --]
[-- Type: text/plain, Size: 12535 bytes --]

diff --git a/newlib/libc/include/sys/features.h b/newlib/libc/include/sys/features.h
index 4ad7fbd..0c6043c 100644
--- a/newlib/libc/include/sys/features.h
+++ b/newlib/libc/include/sys/features.h
@@ -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
diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h
index 5dd6c75..bfe93fa 100644
--- a/newlib/libc/include/sys/types.h
+++ b/newlib/libc/include/sys/types.h
@@ -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 {
@@ -440,6 +441,7 @@ typedef struct {
 #endif
 } pthread_barrierattr_t;
 #endif /* defined(_POSIX_BARRIERS) */
+#endif /* __CYGWIN__ */
 
 /* POSIX Spin Lock Types */
 
diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index d7f4d24..18e010a 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -882,6 +882,13 @@ pthread_condattr_getpshared SIGFE
 pthread_condattr_init SIGFE
 pthread_condattr_setclock SIGFE
 pthread_condattr_setpshared 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_continue SIGFE
 pthread_create SIGFE
 pthread_detach SIGFE
diff --git a/winsup/cygwin/include/cygwin/types.h b/winsup/cygwin/include/cygwin/types.h
index 85ee7c7..b01ae95 100644
--- a/winsup/cygwin/include/cygwin/types.h
+++ b/winsup/cygwin/include/cygwin/types.h
@@ -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;
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index 9ad8b66..84e0a14 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -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);
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 8f29900..88f482c 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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,223 @@ pthread_null::getsequence_np ()
 }
 
 pthread_null pthread_null::_instance;
+
+
+
+#define LIKELY(X) __builtin_expect (!!(X), 1)
+#define UNLIKELY(X) __builtin_expect (!!(X), 0)
+
+
+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;
+  }
+}
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index a6c7358..f7bce18 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -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:

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] POSIX barrier implementation, take 2
  2016-02-12 10:21 [PATCH] POSIX barrier implementation, take 2 Václav Haisman
@ 2016-02-12 14:25 ` Corinna Vinschen
  2016-02-12 20:47   ` Václav Haisman
  2016-02-12 21:26   ` [PATCH] POSIX barrier implementation, take 3 Václav Haisman
  0 siblings, 2 replies; 5+ messages in thread
From: Corinna Vinschen @ 2016-02-12 14:25 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 1992 bytes --]

Hi Václav,


the patch looks pretty good, I have just a few (minor) nits:

On Feb 12 11:20, Václav Haisman wrote:
> diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h
> index 5dd6c75..bfe93fa 100644
> --- a/newlib/libc/include/sys/types.h
> +++ b/newlib/libc/include/sys/types.h
> @@ -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 {
> @@ -440,6 +441,7 @@ typedef struct {
>  #endif
>  } pthread_barrierattr_t;
>  #endif /* defined(_POSIX_BARRIERS) */
> +#endif /* __CYGWIN__ */

Instead of adding YA `if !CYGWIN', I think it might be prudent to
just move the `if !CYGWIN' up from the following _POSIX_SPIN_LOCKS
block.

> diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
> index d7f4d24..18e010a 100644
> --- a/winsup/cygwin/common.din
> +++ b/winsup/cygwin/common.din
> @@ -882,6 +882,13 @@ pthread_condattr_getpshared SIGFE
>  pthread_condattr_init SIGFE
>  pthread_condattr_setclock SIGFE
>  pthread_condattr_setpshared 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_continue SIGFE
>  pthread_create SIGFE
>  pthread_detach SIGFE

These should be added in alphabetic order.

> +#define LIKELY(X) __builtin_expect (!!(X), 1)
> +#define UNLIKELY(X) __builtin_expect (!!(X), 0)

May I suggest to use lowercase "likely/unlikely" just as in the Linux
kernel and to move the definitions into a header like winsup.h or
miscfuncs.h?


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] POSIX barrier implementation, take 2
  2016-02-12 14:25 ` Corinna Vinschen
@ 2016-02-12 20:47   ` Václav Haisman
  2016-02-12 21:26   ` [PATCH] POSIX barrier implementation, take 3 Václav Haisman
  1 sibling, 0 replies; 5+ messages in thread
From: Václav Haisman @ 2016-02-12 20:47 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 2070 bytes --]

On 12.2.2016 15:25, Corinna Vinschen wrote:
> Hi Václav,
> 
> 
> the patch looks pretty good, I have just a few (minor) nits:
> 
> On Feb 12 11:20, Václav Haisman wrote:
>> diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h
>> index 5dd6c75..bfe93fa 100644
>> --- a/newlib/libc/include/sys/types.h
>> +++ b/newlib/libc/include/sys/types.h
>> @@ -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 {
>> @@ -440,6 +441,7 @@ typedef struct {
>>  #endif
>>  } pthread_barrierattr_t;
>>  #endif /* defined(_POSIX_BARRIERS) */
>> +#endif /* __CYGWIN__ */
> 
> Instead of adding YA `if !CYGWIN', I think it might be prudent to
> just move the `if !CYGWIN' up from the following _POSIX_SPIN_LOCKS
> block.

OK, will do.

> 
>> diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
>> index d7f4d24..18e010a 100644
>> --- a/winsup/cygwin/common.din
>> +++ b/winsup/cygwin/common.din
>> @@ -882,6 +882,13 @@ pthread_condattr_getpshared SIGFE
>>  pthread_condattr_init SIGFE
>>  pthread_condattr_setclock SIGFE
>>  pthread_condattr_setpshared 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_continue SIGFE
>>  pthread_create SIGFE
>>  pthread_detach SIGFE
> 
> These should be added in alphabetic order.

OK. I did not realize that.

> 
>> +#define LIKELY(X) __builtin_expect (!!(X), 1)
>> +#define UNLIKELY(X) __builtin_expect (!!(X), 0)
> 
> May I suggest to use lowercase "likely/unlikely" just as in the Linux
> kernel and to move the definitions into a header like winsup.h or
> miscfuncs.h?

I was not sure where to put these and then I forgot. Will fix.


-- 
VH


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] POSIX barrier implementation, take 3
  2016-02-12 14:25 ` Corinna Vinschen
  2016-02-12 20:47   ` Václav Haisman
@ 2016-02-12 21:26   ` Václav Haisman
  2016-02-13 16:05     ` Corinna Vinschen
  1 sibling, 1 reply; 5+ messages in thread
From: Václav Haisman @ 2016-02-12 21:26 UTC (permalink / raw)
  To: cygwin-patches


[-- Attachment #1.1: Type: text/plain, Size: 3121 bytes --]

On 12.2.2016 15:25, Corinna Vinschen wrote:
> Hi Václav,
> 
> 
> the patch looks pretty good, I have just a few (minor) nits:
> 
> On Feb 12 11:20, Václav Haisman wrote:
>> diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h
>> index 5dd6c75..bfe93fa 100644
>> --- a/newlib/libc/include/sys/types.h
>> +++ b/newlib/libc/include/sys/types.h
>> @@ -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 {
>> @@ -440,6 +441,7 @@ typedef struct {
>>  #endif
>>  } pthread_barrierattr_t;
>>  #endif /* defined(_POSIX_BARRIERS) */
>> +#endif /* __CYGWIN__ */
> 
> Instead of adding YA `if !CYGWIN', I think it might be prudent to
> just move the `if !CYGWIN' up from the following _POSIX_SPIN_LOCKS
> block.
> 
>> diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
>> index d7f4d24..18e010a 100644
>> --- a/winsup/cygwin/common.din
>> +++ b/winsup/cygwin/common.din
>> @@ -882,6 +882,13 @@ pthread_condattr_getpshared SIGFE
>>  pthread_condattr_init SIGFE
>>  pthread_condattr_setclock SIGFE
>>  pthread_condattr_setpshared 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_continue SIGFE
>>  pthread_create SIGFE
>>  pthread_detach SIGFE
> 
> These should be added in alphabetic order.
> 
>> +#define LIKELY(X) __builtin_expect (!!(X), 1)
>> +#define UNLIKELY(X) __builtin_expect (!!(X), 0)
> 
> May I suggest to use lowercase "likely/unlikely" just as in the Linux
> kernel and to move the definitions into a header like winsup.h or
> miscfuncs.h?
> 

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

[-- Attachment #1.2: barrier03.patch.txt --]
[-- Type: text/plain, Size: 12931 bytes --]

diff --git a/newlib/libc/include/sys/features.h b/newlib/libc/include/sys/features.h
index 4ad7fbd..0c6043c 100644
--- a/newlib/libc/include/sys/features.h
+++ b/newlib/libc/include/sys/features.h
@@ -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
diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h
index 5dd6c75..1e0d075 100644
--- a/newlib/libc/include/sys/types.h
+++ b/newlib/libc/include/sys/types.h
@@ -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) */
diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index d7f4d24..9584d09 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -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
diff --git a/winsup/cygwin/include/cygwin/types.h b/winsup/cygwin/include/cygwin/types.h
index 85ee7c7..b01ae95 100644
--- a/winsup/cygwin/include/cygwin/types.h
+++ b/winsup/cygwin/include/cygwin/types.h
@@ -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;
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index 9ad8b66..84e0a14 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -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);
diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h
index 82b413f..3a9f025 100644
--- a/winsup/cygwin/miscfuncs.h
+++ b/winsup/cygwin/miscfuncs.h
@@ -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 &);
 
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 8f29900..06a487a 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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;
+  }
+}
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index a6c7358..f7bce18 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -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:

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] POSIX barrier implementation, take 3
  2016-02-12 21:26   ` [PATCH] POSIX barrier implementation, take 3 Václav Haisman
@ 2016-02-13 16:05     ` Corinna Vinschen
  0 siblings, 0 replies; 5+ messages in thread
From: Corinna Vinschen @ 2016-02-13 16:05 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 1674 bytes --]

On Feb 12 22:25, Václav Haisman wrote:
> On 12.2.2016 15:25, Corinna Vinschen wrote:
> > Hi Václav,
> > 
> > 
> > the patch looks pretty good, I have just a few (minor) nits:
> > [...]
> 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.

Patch applied.  I added documentation changes to reflect this welcome
addition.


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-02-13 16:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-12 10:21 [PATCH] POSIX barrier implementation, take 2 Václav Haisman
2016-02-12 14:25 ` Corinna Vinschen
2016-02-12 20:47   ` Václav Haisman
2016-02-12 21:26   ` [PATCH] POSIX barrier implementation, take 3 Václav Haisman
2016-02-13 16:05     ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).