]> Savannah Git Hosting - gnulib.git/commitdiff
lock tests: Prefer semaphore over mutex.
authorBruno Haible <bruno@clisp.org>
Thu, 5 Jan 2017 22:49:34 +0000 (23:49 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 5 Jan 2017 22:53:01 +0000 (23:53 +0100)
* tests/test-lock.c (USE_SEMAPHORE): New constant.
(struct atomic_int, init_atomic_int, get_atomic_int_value,
set_atomic_int_value) [USE_SEMAPHORE]: Define using a POSIX semaphore.
Suggested by Torvald Riegel <triegel@redhat.com>.

ChangeLog
tests/test-lock.c

index 11b8eaa571d09894af111ce569ed8afbff0835d3..ebd491f846e32526a564b30461a2aa69e4f38409 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        thus supporting parallel processing of each one,
        particularly build-coverage, which builds and runs tests.
 
+2017-01-05  Bruno Haible  <bruno@clisp.org>
+
+       lock tests: Prefer semaphore over mutex.
+       * tests/test-lock.c (USE_SEMAPHORE): New constant.
+       (struct atomic_int, init_atomic_int, get_atomic_int_value,
+       set_atomic_int_value) [USE_SEMAPHORE]: Define using a POSIX semaphore.
+       Suggested by Torvald Riegel <triegel@redhat.com>.
+
 2017-01-05  Bruno Haible  <bruno@clisp.org>
 
        lock: Provide guarantee to avoid writer starvation for rwlocks.
index 095511ecf833bdd915e9084780a05a1c5a013152..f3da4ccdfd2468ac8348025da9347cb6f3101bb4 100644 (file)
 #define EXPLICIT_YIELD 1
 
 /* Whether to use 'volatile' on some variables that communicate information
-   between threads.  If set to 0, a lock is used to protect these variables.
-   If set to 1, 'volatile' is used; this is theoretically equivalent but can
-   lead to much slower execution (e.g. 30x slower total run time on a 40-core
-   machine.  */
+   between threads.  If set to 0, a semaphore or a lock is used to protect
+   these variables.  If set to 1, 'volatile' is used; this is theoretically
+   equivalent but can lead to much slower execution (e.g. 30x slower total
+   run time on a 40-core machine), because 'volatile' does not imply any
+   synchronization/communication between different CPUs.  */
 #define USE_VOLATILE 0
 
+#if USE_POSIX_THREADS
+/* Whether to use a semaphore to communicate information between threads.
+   If set to 0, a lock is used. If set to 1, a semaphore is used.
+   Uncomment this to reduce the dependencies of this test.  */
+# define USE_SEMAPHORE 1
+#endif
+
 /* Whether to print debugging messages.  */
 #define ENABLE_DEBUGGING 0
 
 
 #include "glthread/thread.h"
 #include "glthread/yield.h"
+#if USE_SEMAPHORE
+# include <errno.h>
+# include <semaphore.h>
+#endif
 
 #if ENABLE_DEBUGGING
 # define dbgprintf printf
@@ -128,6 +140,41 @@ set_atomic_int_value (struct atomic_int *ai, int new_value)
 {
   ai->value = new_value;
 }
+#elif USE_SEMAPHORE
+/* This atomic_int implementation can only support the values 0 and 1.
+   It is initially 0 and can be set to 1 only once.  */
+struct atomic_int {
+  sem_t semaphore;
+};
+static void
+init_atomic_int (struct atomic_int *ai)
+{
+  sem_init (&ai->semaphore, 0, 0);
+}
+static int
+get_atomic_int_value (struct atomic_int *ai)
+{
+  if (sem_trywait (&ai->semaphore) == 0)
+    {
+      if (sem_post (&ai->semaphore))
+        abort ();
+      return 1;
+    }
+  else if (errno == EAGAIN)
+    return 0;
+  else
+    abort ();
+}
+static void
+set_atomic_int_value (struct atomic_int *ai, int new_value)
+{
+  if (new_value == 0)
+    /* It's already initialized with 0.  */
+    return;
+  /* To set the value 1: */
+  if (sem_post (&ai->semaphore))
+    abort ();
+}
 #else
 struct atomic_int {
   gl_lock_define (, lock)