diff options
Diffstat (limited to 'tests/test-lock.c')
-rw-r--r-- | tests/test-lock.c | 202 |
1 files changed, 31 insertions, 171 deletions
diff --git a/tests/test-lock.c b/tests/test-lock.c index 52ee009..5771474 100644 --- a/tests/test-lock.c +++ b/tests/test-lock.c @@ -1,5 +1,5 @@ /* Test of locking in multithreaded situations. - Copyright (C) 2005, 2008-2018 Free Software Foundation, Inc. + Copyright (C) 2005, 2008-2022 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 @@ -18,16 +18,16 @@ #include <config.h> -#if USE_POSIX_THREADS || USE_SOLARIS_THREADS || USE_PTH_THREADS || USE_WINDOWS_THREADS +#if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS +#if USE_ISOC_THREADS +# define TEST_ISOC_THREADS 1 +#endif #if USE_POSIX_THREADS # define TEST_POSIX_THREADS 1 #endif -#if USE_SOLARIS_THREADS -# define TEST_SOLARIS_THREADS 1 -#endif -#if USE_PTH_THREADS -# define TEST_PTH_THREADS 1 +#if USE_ISOC_AND_POSIX_THREADS +# define TEST_ISOC_AND_POSIX_THREADS 1 #endif #if USE_WINDOWS_THREADS # define TEST_WINDOWS_THREADS 1 @@ -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 @@ -83,27 +61,28 @@ an "OK" result even without ENABLE_LOCKING (on Linux/x86). */ #define REPEAT_COUNT 50000 +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #if !ENABLE_LOCKING +# undef USE_ISOC_THREADS # undef USE_POSIX_THREADS -# undef USE_SOLARIS_THREADS -# undef USE_PTH_THREADS +# undef USE_ISOC_AND_POSIX_THREADS # undef USE_WINDOWS_THREADS #endif #include "glthread/lock.h" #if !ENABLE_LOCKING +# if TEST_ISOC_THREADS +# define USE_ISOC_THREADS 1 +# endif # if TEST_POSIX_THREADS # define USE_POSIX_THREADS 1 # endif -# if TEST_SOLARIS_THREADS -# define USE_SOLARIS_THREADS 1 -# endif -# if TEST_PTH_THREADS -# define USE_PTH_THREADS 1 +# if TEST_ISOC_AND_POSIX_THREADS +# define USE_ISOC_AND_POSIX_THREADS 1 # endif # if TEST_WINDOWS_THREADS # define USE_WINDOWS_THREADS 1 @@ -112,13 +91,14 @@ #include "glthread/thread.h" #include "glthread/yield.h" -#if USE_SEMAPHORE -# include <errno.h> -# include <fcntl.h> -# include <semaphore.h> + +#if HAVE_DECL_ALARM +# include <signal.h> # include <unistd.h> #endif +#include "atomic-int-gnulib.h" + #if ENABLE_DEBUGGING # define dbgprintf printf #else @@ -131,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]; @@ -587,7 +441,7 @@ once_execute (void) static void * once_contender_thread (void *arg) { - int id = (int) (long) arg; + int id = (int) (intptr_t) arg; int repeat; for (repeat = 0; repeat <= REPEAT_COUNT; repeat++) @@ -641,13 +495,16 @@ test_once (void) fire_signal_state = 0; #endif +#if ENABLE_LOCKING /* Block all fire_signals. */ for (i = REPEAT_COUNT-1; i >= 0; i--) gl_rwlock_wrlock (fire_signal[i]); +#endif /* Spawn the threads. */ for (i = 0; i < THREAD_COUNT; i++) - threads[i] = gl_thread_create (once_contender_thread, (void *) (long) i); + threads[i] = + gl_thread_create (once_contender_thread, (void *) (intptr_t) i); for (repeat = 0; repeat <= REPEAT_COUNT; repeat++) { @@ -713,9 +570,12 @@ test_once (void) int main () { -#if TEST_PTH_THREADS - if (!pth_init ()) - abort (); +#if HAVE_DECL_ALARM + /* Declare failure if test takes too long, by using default abort + caused by SIGALRM. */ + int alarm_value = 600; + signal (SIGALRM, SIG_DFL); + alarm (alarm_value); #endif #if DO_TEST_LOCK |