+2023-11-10 Bruno Haible <bruno@clisp.org>
+
+ tests: In multithreaded tests, use random() instead of rand().
+ * tests/test-asyncsafe-spin2.c (random_account, lock_mutator_thread):
+ Use random() instead of rand().
+ * tests/test-lock.c (random_account, lock_mutator_thread,
+ rwlock_mutator_thread, recshuffle): Likewise.
+ * tests/test-mtx.c (random_account, lock_mutator_thread, recshuffle):
+ Likewise.
+ * tests/test-pthread-mutex.c (random_account, lock_mutator_thread,
+ recshuffle): Likewise.
+ * tests/test-pthread-rwlock.c (random_account, rwlock_mutator_thread):
+ Likewise.
+ * tests/test-pthread-spin.c (random_account, lock_mutator_thread):
+ Likewise.
+ * tests/test-pthread-tss.c (perhaps_yield, worker_thread,
+ racecheck_thread): Likewise.
+ * tests/test-thread_local.c (perhaps_yield, worker_thread): Likewise.
+ * tests/test-tls.c (perhaps_yield, worker_thread, racecheck_thread):
+ Likewise.
+ * tests/test-tss.c (perhaps_yield, worker_thread, racecheck_thread):
+ Likewise.
+ * asyncsafe-spin-tests (Depends-on): Add random.
+ * lock-tests (Depends-on): Likewise.
+ * mtx-tests (Depends-on): Likewise.
+ * pthread-mutex-tests (Depends-on): Likewise.
+ * pthread-rwlock-tests (Depends-on): Likewise.
+ * pthread-spin-tests (Depends-on): Likewise.
+ * pthread-tss-tests (Depends-on): Likewise.
+ * threads-h-tests (Depends-on): Likewise.
+ * tls-tests (Depends-on): Likewise.
+ * tss-tests (Depends-on): Likewise.
+
2023-11-10 Bruno Haible <bruno@clisp.org>
random: Fix multithread-safety bug.
thread
lock
yield
+random
configure.ac:
AC_CHECK_HEADERS_ONCE([semaphore.h])
stdint
usleep
yield
+random
configure.ac:
AC_CHECK_HEADERS_ONCE([semaphore.h])
thrd
lock
stdint
+random
configure.ac:
AC_CHECK_HEADERS_ONCE([semaphore.h])
Depends-on:
pthread-thread
sched_yield
+random
configure.ac:
pthread-thread
pthread-mutex
sched_yield
+random
configure.ac:
pthread-thread
pthread-mutex
sched_yield
+random
configure.ac:
AC_CHECK_HEADERS_ONCE([semaphore.h])
pthread-thread
pthread-mutex
sched_yield
+random
configure.ac:
threads-h-c++-tests
thrd
stdint
+random
configure.ac:
AC_CHECK_DECLS_ONCE([alarm])
lock
stdint
yield
+random
configure.ac:
AC_CHECK_DECLS_ONCE([alarm])
thrd
mtx
stdint
+random
configure.ac:
AC_CHECK_DECLS_ONCE([alarm])
static int
random_account (void)
{
- return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
+ return ((unsigned long) random () >> 3) % ACCOUNT_COUNT;
}
static void
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
static int
random_account (void)
{
- return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
+ return ((unsigned long) random () >> 3) % ACCOUNT_COUNT;
}
static void
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
/* Recursive with probability 0.5. */
- if (((unsigned int) rand () >> 3) % 2)
+ if (((unsigned long) random () >> 3) % 2)
recshuffle ();
dbgprintf ("Mutator %p before unlock\n", gl_thread_self_pointer ());
static int
random_account (void)
{
- return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
+ return ((unsigned long) random () >> 3) % ACCOUNT_COUNT;
}
static void
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
/* Recursive with probability 0.5. */
- if (((unsigned int) rand () >> 3) % 2)
+ if (((unsigned long) random () >> 3) % 2)
recshuffle ();
dbgprintf ("Mutator %p before unlock\n", thrd_current_pointer ());
static int
random_account (void)
{
- return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
+ return ((unsigned long) random () >> 3) % ACCOUNT_COUNT;
}
static void
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
/* Recursive with probability 0.5. */
- if (((unsigned int) rand () >> 3) % 2)
+ if (((unsigned long) random () >> 3) % 2)
recshuffle ();
dbgprintf ("Mutator %p before unlock\n", pthread_self_pointer ());
static int
random_account (void)
{
- return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
+ return ((unsigned long) random () >> 3) % ACCOUNT_COUNT;
}
static void
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
static int
random_account (void)
{
- return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
+ return ((unsigned long) random () >> 3) % ACCOUNT_COUNT;
}
static void
i1 = random_account ();
i2 = random_account ();
- value = ((unsigned int) rand () >> 3) % 10;
+ value = ((unsigned long) random () >> 3) % 10;
account[i1] += value;
account[i2] -= value;
{
/* Call yield () only with a certain probability, otherwise the
sequence of thread activations may be too predictable. */
- if ((((unsigned int) rand () >> 3) % 4) == 0)
+ if ((((unsigned long) random () >> 3) % 4) == 0)
yield ();
}
/* Initialize the per-thread storage. */
for (i = 0; i < KEYS_COUNT; i++)
{
- values[i] = (((unsigned int) rand () >> 3) % 1000000) * THREAD_COUNT + id;
+ values[i] = (((unsigned long) random () >> 3) % 1000000) * THREAD_COUNT + id;
/* Hopefully no arithmetic overflow. */
if ((values[i] % THREAD_COUNT) != id)
abort ();
for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
{
dbgprintf ("Worker %p doing value swapping\n", pthread_self_pointer ());
- i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
- j = ((unsigned int) rand () >> 3) % KEYS_COUNT;
+ i = ((unsigned long) random () >> 3) % KEYS_COUNT;
+ j = ((unsigned long) random () >> 3) % KEYS_COUNT;
if (i != j)
{
void *vi = pthread_getspecific (mykeys[i]);
for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
{
- i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
+ i = ((unsigned long) random () >> 3) % KEYS_COUNT;
dbgprintf ("Worker %p reallocating key %d\n", pthread_self_pointer (), i);
ASSERT (pthread_key_delete (keys[i]) == 0);
ASSERT (pthread_key_create (&keys[i], destructor_table[i]) == 0);
{
/* Call yield () only with a certain probability, otherwise the
sequence of thread activations may be too predictable. */
- if ((((unsigned int) rand () >> 3) % 4) == 0)
+ if ((((unsigned long) random () >> 3) % 4) == 0)
yield ();
}
dbgprintf ("Worker %p before first assignment\n", thrd_current_pointer ());
for (i = 0; i < KEYS_COUNT; i++)
{
- *values[i] = (((unsigned int) rand () >> 3) % 1000000) * THREAD_COUNT + id;
+ *values[i] = (((unsigned long) random () >> 3) % 1000000) * THREAD_COUNT + id;
/* Hopefully no arithmetic overflow. */
if ((*values[i] % THREAD_COUNT) != id)
abort ();
for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
{
dbgprintf ("Worker %p doing value swapping\n", thrd_current_pointer ());
- i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
- j = ((unsigned int) rand () >> 3) % KEYS_COUNT;
+ i = ((unsigned long) random () >> 3) % KEYS_COUNT;
+ j = ((unsigned long) random () >> 3) % KEYS_COUNT;
if (i != j)
{
unsigned int vi = *values[i];
perhaps_yield (void)
{
/* This helps making the sequence of thread activations less predictable. */
- if ((((unsigned int) rand () >> 3) % 4) == 0)
+ if ((((unsigned long) random () >> 3) % 4) == 0)
yield ();
}
/* Initialize the per-thread storage. */
for (i = 0; i < KEYS_COUNT; i++)
{
- values[i] = (((unsigned int) rand () >> 3) % 1000000) * THREAD_COUNT + id;
+ values[i] = (((unsigned long) random () >> 3) % 1000000) * THREAD_COUNT + id;
/* Hopefully no arithmetic overflow. */
if ((values[i] % THREAD_COUNT) != id)
abort ();
for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
{
dbgprintf ("Worker %p doing value swapping\n", gl_thread_self_pointer ());
- i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
- j = ((unsigned int) rand () >> 3) % KEYS_COUNT;
+ i = ((unsigned long) random () >> 3) % KEYS_COUNT;
+ j = ((unsigned long) random () >> 3) % KEYS_COUNT;
if (i != j)
{
void *vi = gl_tls_get (mykeys[i]);
for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
{
- i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
+ i = ((unsigned long) random () >> 3) % KEYS_COUNT;
dbgprintf ("Worker %p reallocating key %d\n", gl_thread_self_pointer (), i);
gl_tls_key_destroy (keys[i]);
gl_tls_key_init (keys[i], destructor_table[i]);
{
/* Call yield () only with a certain probability, otherwise the
sequence of thread activations may be too predictable. */
- if ((((unsigned int) rand () >> 3) % 4) == 0)
+ if ((((unsigned long) random () >> 3) % 4) == 0)
yield ();
}
/* Initialize the per-thread storage. */
for (i = 0; i < KEYS_COUNT; i++)
{
- values[i] = (((unsigned int) rand () >> 3) % 1000000) * THREAD_COUNT + id;
+ values[i] = (((unsigned long) random () >> 3) % 1000000) * THREAD_COUNT + id;
/* Hopefully no arithmetic overflow. */
if ((values[i] % THREAD_COUNT) != id)
abort ();
for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
{
dbgprintf ("Worker %p doing value swapping\n", thrd_current_pointer ());
- i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
- j = ((unsigned int) rand () >> 3) % KEYS_COUNT;
+ i = ((unsigned long) random () >> 3) % KEYS_COUNT;
+ j = ((unsigned long) random () >> 3) % KEYS_COUNT;
if (i != j)
{
void *vi = tss_get (mykeys[i]);
for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
{
- i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
+ i = ((unsigned long) random () >> 3) % KEYS_COUNT;
dbgprintf ("Worker %p reallocating key %d\n", thrd_current_pointer (), i);
tss_delete (keys[i]);
ASSERT (tss_create (&keys[i], destructor_table[i]) == thrd_success);