summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2020-07-01 22:05:15 +0200
committerBruno Haible <bruno@clisp.org>2020-07-01 22:05:44 +0200
commit6ace6219e9804cfa643cd950494e36fab2fcc4da (patch)
tree8226a2c22c4860f878eec2e2e7eecac2cb5b6764 /tests
parent4e3f2d4cfdba14e1d89479362061a9280f2f22b6 (diff)
downloadgnulib-6ace6219e9804cfa643cd950494e36fab2fcc4da.tar.gz
tests: Refactor.
* tests/atomic-int-gnulib.h: New file, extracted from tests/test-lock.c. * tests/test-lock.c: Include it. Remove the corresponding code. * modules/lock-tests (Files): Add tests/atomic-int-gnulib.h.
Diffstat (limited to 'tests')
-rw-r--r--tests/atomic-int-gnulib.h173
-rw-r--r--tests/test-lock.c156
2 files changed, 175 insertions, 154 deletions
diff --git a/tests/atomic-int-gnulib.h b/tests/atomic-int-gnulib.h
new file mode 100644
index 0000000000..82e11a939a
--- /dev/null
+++ b/tests/atomic-int-gnulib.h
@@ -0,0 +1,173 @@
+/* Atomic integers. Useful for testing multithreaded locking primitives.
+ Copyright (C) 2005, 2008-2020 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+
+/* Whether to use 'volatile' on some variables that communicate information
+ 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 && HAVE_SEMAPHORE_H
+/* 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
+/* Mac OS X provides only named semaphores (sem_open); its facility for
+ unnamed semaphores (sem_init) does not work. */
+# if defined __APPLE__ && defined __MACH__
+# define USE_NAMED_SEMAPHORE 1
+# else
+# define USE_UNNAMED_SEMAPHORE 1
+# endif
+#endif
+
+
+#if USE_SEMAPHORE
+# include <errno.h>
+# include <fcntl.h>
+# include <semaphore.h>
+# include <unistd.h>
+#endif
+
+
+#if USE_VOLATILE
+struct atomic_int {
+ volatile int value;
+};
+static void
+init_atomic_int (struct atomic_int *ai)
+{
+}
+static int
+get_atomic_int_value (struct atomic_int *ai)
+{
+ return ai->value;
+}
+static void
+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. */
+# if USE_UNNAMED_SEMAPHORE
+struct atomic_int {
+ sem_t semaphore;
+};
+#define atomic_int_semaphore(ai) (&(ai)->semaphore)
+static void
+init_atomic_int (struct atomic_int *ai)
+{
+ sem_init (&ai->semaphore, 0, 0);
+}
+# endif
+# if USE_NAMED_SEMAPHORE
+struct atomic_int {
+ sem_t *semaphore;
+};
+#define atomic_int_semaphore(ai) ((ai)->semaphore)
+static void
+init_atomic_int (struct atomic_int *ai)
+{
+ sem_t *s;
+ unsigned int count;
+ for (count = 0; ; count++)
+ {
+ char name[80];
+ /* Use getpid() in the name, so that different processes running at the
+ same time will not interfere. Use ai in the name, so that different
+ atomic_int in the same process will not interfere. Use a count in
+ the name, so that even in the (unlikely) case that a semaphore with
+ the specified name already exists, we can try a different name. */
+ sprintf (name, "test-lock-%lu-%p-%u",
+ (unsigned long) getpid (), ai, count);
+ s = sem_open (name, O_CREAT | O_EXCL, 0600, 0);
+ if (s == SEM_FAILED)
+ {
+ if (errno == EEXIST)
+ /* Retry with a different name. */
+ continue;
+ else
+ {
+ perror ("sem_open failed");
+ abort ();
+ }
+ }
+ else
+ {
+ /* Try not to leave a semaphore hanging around on the file system
+ eternally, if we can avoid it. */
+ sem_unlink (name);
+ break;
+ }
+ }
+ ai->semaphore = s;
+}
+# endif
+static int
+get_atomic_int_value (struct atomic_int *ai)
+{
+ if (sem_trywait (atomic_int_semaphore (ai)) == 0)
+ {
+ if (sem_post (atomic_int_semaphore (ai)))
+ 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 (atomic_int_semaphore (ai)))
+ abort ();
+}
+#else
+struct atomic_int {
+ gl_lock_define (, lock)
+ int value;
+};
+static void
+init_atomic_int (struct atomic_int *ai)
+{
+ gl_lock_init (ai->lock);
+}
+static int
+get_atomic_int_value (struct atomic_int *ai)
+{
+ gl_lock_lock (ai->lock);
+ int ret = ai->value;
+ gl_lock_unlock (ai->lock);
+ return ret;
+}
+static void
+set_atomic_int_value (struct atomic_int *ai, int new_value)
+{
+ gl_lock_lock (ai->lock);
+ ai->value = new_value;
+ gl_lock_unlock (ai->lock);
+}
+#endif
diff --git a/tests/test-lock.c b/tests/test-lock.c
index 7325c89a15..08419b4207 100644
--- a/tests/test-lock.c
+++ b/tests/test-lock.c
@@ -50,28 +50,6 @@
Uncomment this to see if the operating system has a fair scheduler. */
#define EXPLICIT_YIELD 1
-/* Whether to use 'volatile' on some variables that communicate information
- 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 && HAVE_SEMAPHORE_H
-/* 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
-/* Mac OS X provides only named semaphores (sem_open); its facility for
- unnamed semaphores (sem_init) does not work. */
-# if defined __APPLE__ && defined __MACH__
-# define USE_NAMED_SEMAPHORE 1
-# else
-# define USE_UNNAMED_SEMAPHORE 1
-# endif
-#endif
-
/* Whether to print debugging messages. */
#define ENABLE_DEBUGGING 0
@@ -113,18 +91,14 @@
#include "glthread/thread.h"
#include "glthread/yield.h"
-#if USE_SEMAPHORE
-# include <errno.h>
-# include <fcntl.h>
-# include <semaphore.h>
-# include <unistd.h>
-#endif
#if HAVE_DECL_ALARM
# include <signal.h>
# include <unistd.h>
#endif
+#include "atomic-int-gnulib.h"
+
#if ENABLE_DEBUGGING
# define dbgprintf printf
#else
@@ -137,132 +111,6 @@
# define yield()
#endif
-#if USE_VOLATILE
-struct atomic_int {
- volatile int value;
-};
-static void
-init_atomic_int (struct atomic_int *ai)
-{
-}
-static int
-get_atomic_int_value (struct atomic_int *ai)
-{
- return ai->value;
-}
-static void
-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. */
-# if USE_UNNAMED_SEMAPHORE
-struct atomic_int {
- sem_t semaphore;
-};
-#define atomic_int_semaphore(ai) (&(ai)->semaphore)
-static void
-init_atomic_int (struct atomic_int *ai)
-{
- sem_init (&ai->semaphore, 0, 0);
-}
-# endif
-# if USE_NAMED_SEMAPHORE
-struct atomic_int {
- sem_t *semaphore;
-};
-#define atomic_int_semaphore(ai) ((ai)->semaphore)
-static void
-init_atomic_int (struct atomic_int *ai)
-{
- sem_t *s;
- unsigned int count;
- for (count = 0; ; count++)
- {
- char name[80];
- /* Use getpid() in the name, so that different processes running at the
- same time will not interfere. Use ai in the name, so that different
- atomic_int in the same process will not interfere. Use a count in
- the name, so that even in the (unlikely) case that a semaphore with
- the specified name already exists, we can try a different name. */
- sprintf (name, "test-lock-%lu-%p-%u",
- (unsigned long) getpid (), ai, count);
- s = sem_open (name, O_CREAT | O_EXCL, 0600, 0);
- if (s == SEM_FAILED)
- {
- if (errno == EEXIST)
- /* Retry with a different name. */
- continue;
- else
- {
- perror ("sem_open failed");
- abort ();
- }
- }
- else
- {
- /* Try not to leave a semaphore hanging around on the file system
- eternally, if we can avoid it. */
- sem_unlink (name);
- break;
- }
- }
- ai->semaphore = s;
-}
-# endif
-static int
-get_atomic_int_value (struct atomic_int *ai)
-{
- if (sem_trywait (atomic_int_semaphore (ai)) == 0)
- {
- if (sem_post (atomic_int_semaphore (ai)))
- 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 (atomic_int_semaphore (ai)))
- abort ();
-}
-#else
-struct atomic_int {
- gl_lock_define (, lock)
- int value;
-};
-static void
-init_atomic_int (struct atomic_int *ai)
-{
- gl_lock_init (ai->lock);
-}
-static int
-get_atomic_int_value (struct atomic_int *ai)
-{
- gl_lock_lock (ai->lock);
- int ret = ai->value;
- gl_lock_unlock (ai->lock);
- return ret;
-}
-static void
-set_atomic_int_value (struct atomic_int *ai, int new_value)
-{
- gl_lock_lock (ai->lock);
- ai->value = new_value;
- gl_lock_unlock (ai->lock);
-}
-#endif
-
#define ACCOUNT_COUNT 4
static int account[ACCOUNT_COUNT];