summaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-02-09 20:07:51 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-02-09 20:07:51 +0000
commitd5ec049d44f019deaeed8adc0bd10819e5569e93 (patch)
tree26b03705007a5b239c5239124f8c9381dd83001a /nptl
parent28c30a6232aa9a54783c146590498a061fc0112a (diff)
downloadglibc-d5ec049d44f019deaeed8adc0bd10819e5569e93.tar.gz
pthread: Move some rwlock tests from nptl to sysdeps/pthread
So they can be checked with htl too.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/Makefile9
-rw-r--r--nptl/tst-rwlock-tryrdlock-stall.c355
-rw-r--r--nptl/tst-rwlock-trywrlock-stall.c108
-rw-r--r--nptl/tst-rwlock1.c116
-rw-r--r--nptl/tst-rwlock13.c70
-rw-r--r--nptl/tst-rwlock16.c182
-rw-r--r--nptl/tst-rwlock4.c189
-rw-r--r--nptl/tst-rwlock5.c84
8 files changed, 4 insertions, 1109 deletions
diff --git a/nptl/Makefile b/nptl/Makefile
index bf21413c26..3ad3024a39 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -244,10 +244,10 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
tst-robustpi6 tst-robustpi7 tst-robustpi8 tst-robustpi9 \
- tst-rwlock1 tst-rwlock2 tst-rwlock2a tst-rwlock2b tst-rwlock3 \
- tst-rwlock4 tst-rwlock5 tst-rwlock6 tst-rwlock7 tst-rwlock8 \
- tst-rwlock9 tst-rwlock10 tst-rwlock11 tst-rwlock12 tst-rwlock13 \
- tst-rwlock14 tst-rwlock15 tst-rwlock16 tst-rwlock17 tst-rwlock18 \
+ tst-rwlock2 tst-rwlock2a tst-rwlock2b tst-rwlock3 \
+ tst-rwlock6 tst-rwlock7 tst-rwlock8 \
+ tst-rwlock9 tst-rwlock10 tst-rwlock11 tst-rwlock12 \
+ tst-rwlock14 tst-rwlock15 tst-rwlock17 tst-rwlock18 \
tst-once5 \
tst-key1 tst-key2 tst-key3 tst-key4 \
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
@@ -306,7 +306,6 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-thread-exit-clobber tst-minstack-cancel tst-minstack-exit \
tst-minstack-throw \
tst-rwlock-pwn \
- tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall \
tst-unwind-thread
tests-container = tst-pthread-getattr
diff --git a/nptl/tst-rwlock-tryrdlock-stall.c b/nptl/tst-rwlock-tryrdlock-stall.c
deleted file mode 100644
index bb2a64f301..0000000000
--- a/nptl/tst-rwlock-tryrdlock-stall.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-/* For a full analysis see comment:
- https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14
-
- Provided here for reference:
-
- --- Analysis of pthread_rwlock_tryrdlock() stall ---
- A read lock begins to execute.
-
- In __pthread_rwlock_rdlock_full:
-
- We can attempt a read lock, but find that the lock is
- in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit
- is set), and the lock is held by a primary writer
- (PTHREAD_RWLOCK_WRLOCKED is set). In this case we must
- wait for explicit hand over from the writer to us or
- one of the other waiters. The read lock threads are
- about to execute:
-
- 341 r = (atomic_fetch_add_acquire (&rwlock->__data.__readers,
- 342 (1 << PTHREAD_RWLOCK_READER_SHIFT))
- 343 + (1 << PTHREAD_RWLOCK_READER_SHIFT));
-
- An unlock beings to execute.
-
- Then in __pthread_rwlock_wrunlock:
-
- 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
- ...
- 549 while (!atomic_compare_exchange_weak_release
- 550 (&rwlock->__data.__readers, &r,
- 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED)
- 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
- 553 : PTHREAD_RWLOCK_WRPHASE))))
- 554 {
- ...
- 556 }
-
- We clear PTHREAD_RWLOCK_WRLOCKED, and if there are
- no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE.
-
- Back in the read lock.
-
- The read lock adjusts __readres as above.
-
- 383 while ((r & PTHREAD_RWLOCK_WRPHASE) != 0
- 384 && (r & PTHREAD_RWLOCK_WRLOCKED) == 0)
- 385 {
- ...
- 390 if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r,
- 391 r ^ PTHREAD_RWLOCK_WRPHASE))
- 392 {
-
- And then attemps to start the read phase.
-
- Assume there happens to be a tryrdlock at this point, noting
- that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE
- is 1. So the try lock attemps to start the read phase.
-
- In __pthread_rwlock_tryrdlock:
-
- 44 if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
- 45 {
- ...
- 49 if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
- 50 && (rwlock->__data.__flags
- 51 == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP))
- 52 return EBUSY;
- 53 rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT);
- 54 }
- ...
- 89 while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers,
- 90 &r, rnew));
-
- And succeeds.
-
- Back in the write unlock:
-
- 557 if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0)
- 558 {
- ...
- 563 if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
- 564 & PTHREAD_RWLOCK_FUTEX_USED) != 0)
- 565 futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
- 566 }
-
- We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero
- and don't wake anyone. This is OK because we handed
- over to the trylock. It will be the trylock's responsibility
- to wake any waiters.
-
- Back in the read lock:
-
- The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because
- the __readers value was adjusted by the trylock, and so it falls through
- to waiting on the lock for explicit handover from either a new writer
- or a new reader.
-
- 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
- 449 1 | PTHREAD_RWLOCK_FUTEX_USED,
- 450 abstime, private);
-
- We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex
- is in use.
-
- At this point we have readers waiting on the read lock
- to unlock. The wrlock is done. The trylock is finishing
- the installation of the read phase.
-
- 92 if ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
- 93 {
- ...
- 105 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
- 106 }
-
- The trylock does note that we were the one that
- installed the read phase, but the comments are not
- correct, the execution ordering above shows that
- readers might indeed be waiting, and they are.
-
- The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED,
- and the waiting reader is never worken becuase as noted
- above it is conditional on the futex being used.
-
- The solution is for the trylock thread to inspect
- PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers.
-
- --- Analysis of pthread_rwlock_trywrlock() stall ---
-
- A write lock begins to execute, takes the write lock,
- and then releases the lock...
-
- In pthread_rwlock_wrunlock():
-
- 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
- ...
- 549 while (!atomic_compare_exchange_weak_release
- 550 (&rwlock->__data.__readers, &r,
- 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED)
- 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
- 553 : PTHREAD_RWLOCK_WRPHASE))))
- 554 {
- ...
- 556 }
-
- ... leaving it in the write phase with zero readers
- (the case where we leave the write phase in place
- during a write unlock).
-
- A write trylock begins to execute.
-
- In __pthread_rwlock_trywrlock:
-
- 40 while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0)
- 41 && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
- 42 || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0))))
- 43 {
-
- The lock is not locked.
-
- There are no readers.
-
- 45 if (atomic_compare_exchange_weak_acquire (
- 46 &rwlock->__data.__readers, &r,
- 47 r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
-
- We atomically install the write phase and we take the
- exclusive write lock.
-
- 48 {
- 49 atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
-
- We get this far.
-
- A reader lock begins to execute.
-
- In pthread_rwlock_rdlock:
-
- 437 for (;;)
- 438 {
- 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
- 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
- 441 {
- 442 int private = __pthread_rwlock_get_private (rwlock);
- 443 if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
- 444 && (!atomic_compare_exchange_weak_relaxed
- 445 (&rwlock->__data.__wrphase_futex,
- 446 &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)))
- 447 continue;
- 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
- 449 1 | PTHREAD_RWLOCK_FUTEX_USED,
- 450 abstime, private);
-
- We are in a write phase, so the while() on line 439 is true.
-
- The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set
- since this is the first reader to lock.
-
- The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED
- on the expectation that this reader will be woken during
- the handoff.
-
- Back in pthread_rwlock_trywrlock:
-
- 50 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
- 51 atomic_store_relaxed (&rwlock->__data.__cur_writer,
- 52 THREAD_GETMEM (THREAD_SELF, tid));
- 53 return 0;
- 54 }
- ...
- 57 }
-
- We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED,
- and so in the unlock we will not awaken the waiting reader.
-
- The solution to this is to realize that if we did not start the write
- phase we need not write 1 or any other value to __wrphase_futex.
- This ensures that any readers (which saw __wrphase_futex != 0) can
- set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to
- wake them.
-
- If we installed the write phase then all other readers are looping
- here:
-
- In __pthread_rwlock_rdlock_full:
-
- 437 for (;;)
- 438 {
- 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
- 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
- 441 {
- ...
- 508 }
-
- waiting for the write phase to be installed or removed before they
- can begin waiting on __wrphase_futex (part of the algorithm), or
- taking a concurrent read lock, and thus we can safely write 1 to
- __wrphase_futex.
-
- If we did not install the write phase then the readers may already
- be waiting on the futex, the original writer wrote 1 to __wrphase_futex
- as part of starting the write phase, and we cannot also write 1
- without loosing the PTHREAD_RWLOCK_FUTEX_USED bit.
-
- ---
-
- Summary for the pthread_rwlock_tryrdlock() stall:
-
- The stall is caused by pthread_rwlock_tryrdlock failing to check
- that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex
- and then waking the futex.
-
- The fix for bug 23844 ensures that waiters on __wrphase_futex are
- correctly woken. Before the fix the test stalls as readers can
- wait forever on __wrphase_futex. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <support/xthread.h>
-#include <errno.h>
-
-/* We need only one lock to reproduce the issue. We will need multiple
- threads to get the exact case where we have a read, try, and unlock
- all interleaving to produce the case where the readers are waiting
- and the try fails to wake them. */
-pthread_rwlock_t onelock;
-
-/* The number of threads is arbitrary but empirically chosen to have
- enough threads that we see the condition where waiting readers are
- not woken by a successful tryrdlock. */
-#define NTHREADS 32
-
-_Atomic int do_exit;
-
-void *
-run_loop (void *arg)
-{
- int i = 0, ret;
- while (!do_exit)
- {
- /* Arbitrarily choose if we are the writer or reader. Choose a
- high enough ratio of readers to writers to make it likely
- that readers block (and eventually are susceptable to
- stalling).
-
- If we are a writer, take the write lock, and then unlock.
- If we are a reader, try the lock, then lock, then unlock. */
- if ((i % 8) != 0)
- xpthread_rwlock_wrlock (&onelock);
- else
- {
- if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0)
- {
- if (ret == EBUSY)
- xpthread_rwlock_rdlock (&onelock);
- else
- exit (EXIT_FAILURE);
- }
- }
- /* Thread does some work and then unlocks. */
- xpthread_rwlock_unlock (&onelock);
- i++;
- }
- return NULL;
-}
-
-int
-do_test (void)
-{
- int i;
- pthread_t tids[NTHREADS];
- xpthread_rwlock_init (&onelock, NULL);
- for (i = 0; i < NTHREADS; i++)
- tids[i] = xpthread_create (NULL, run_loop, NULL);
- /* Run for some amount of time. Empirically speaking exercising
- the stall via pthread_rwlock_tryrdlock is much harder, and on
- a 3.5GHz 4 core x86_64 VM system it takes somewhere around
- 20-200s to stall, approaching 100% stall past 200s. We can't
- wait that long for a regression test so we just test for 20s,
- and expect the stall to happen with a 5-10% chance (enough for
- developers to see). */
- sleep (20);
- /* Then exit. */
- printf ("INFO: Exiting...\n");
- do_exit = 1;
- /* If any readers stalled then we will timeout waiting for them. */
- for (i = 0; i < NTHREADS; i++)
- xpthread_join (tids[i]);
- printf ("INFO: Done.\n");
- xpthread_rwlock_destroy (&onelock);
- printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n");
- return 0;
-}
-
-#define TIMEOUT 30
-#include <support/test-driver.c>
diff --git a/nptl/tst-rwlock-trywrlock-stall.c b/nptl/tst-rwlock-trywrlock-stall.c
deleted file mode 100644
index b4e60c5af3..0000000000
--- a/nptl/tst-rwlock-trywrlock-stall.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Bug 23844: Test for pthread_rwlock_trywrlock stalls.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c.
-
- Summary for the pthread_rwlock_trywrlock() stall:
-
- The stall is caused by pthread_rwlock_trywrlock setting
- __wrphase_futex futex to 1 and loosing the
- PTHREAD_RWLOCK_FUTEX_USED bit.
-
- The fix for bug 23844 ensures that waiters on __wrphase_futex are
- correctly woken. Before the fix the test stalls as readers can
- wait forever on __wrphase_futex. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <support/xthread.h>
-#include <errno.h>
-
-/* We need only one lock to reproduce the issue. We will need multiple
- threads to get the exact case where we have a read, try, and unlock
- all interleaving to produce the case where the readers are waiting
- and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a
- subsequent unlock fails to wake them. */
-pthread_rwlock_t onelock;
-
-/* The number of threads is arbitrary but empirically chosen to have
- enough threads that we see the condition where waiting readers are
- not woken by a successful unlock. */
-#define NTHREADS 32
-
-_Atomic int do_exit;
-
-void *
-run_loop (void *arg)
-{
- int i = 0, ret;
- while (!do_exit)
- {
- /* Arbitrarily choose if we are the writer or reader. Choose a
- high enough ratio of readers to writers to make it likely
- that readers block (and eventually are susceptable to
- stalling).
-
- If we are a writer, take the write lock, and then unlock.
- If we are a reader, try the lock, then lock, then unlock. */
- if ((i % 8) != 0)
- {
- if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0)
- {
- if (ret == EBUSY)
- xpthread_rwlock_wrlock (&onelock);
- else
- exit (EXIT_FAILURE);
- }
- }
- else
- xpthread_rwlock_rdlock (&onelock);
- /* Thread does some work and then unlocks. */
- xpthread_rwlock_unlock (&onelock);
- i++;
- }
- return NULL;
-}
-
-int
-do_test (void)
-{
- int i;
- pthread_t tids[NTHREADS];
- xpthread_rwlock_init (&onelock, NULL);
- for (i = 0; i < NTHREADS; i++)
- tids[i] = xpthread_create (NULL, run_loop, NULL);
- /* Run for some amount of time. The pthread_rwlock_tryrwlock stall
- is very easy to trigger and happens in seconds under the test
- conditions. */
- sleep (10);
- /* Then exit. */
- printf ("INFO: Exiting...\n");
- do_exit = 1;
- /* If any readers stalled then we will timeout waiting for them. */
- for (i = 0; i < NTHREADS; i++)
- xpthread_join (tids[i]);
- printf ("INFO: Done.\n");
- xpthread_rwlock_destroy (&onelock);
- printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n");
- return 0;
-}
-
-#include <support/test-driver.c>
diff --git a/nptl/tst-rwlock1.c b/nptl/tst-rwlock1.c
deleted file mode 100644
index d14d3036a2..0000000000
--- a/nptl/tst-rwlock1.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <pthread.h>
-#include <stdio.h>
-
-
-static int
-do_test (void)
-{
- pthread_rwlock_t r;
-
- if (pthread_rwlock_init (&r, NULL) != 0)
- {
- puts ("rwlock_init failed");
- return 1;
- }
- puts ("rwlock_init succeeded");
-
- if (pthread_rwlock_rdlock (&r) != 0)
- {
- puts ("1st rwlock_rdlock failed");
- return 1;
- }
- puts ("1st rwlock_rdlock succeeded");
-
- if (pthread_rwlock_rdlock (&r) != 0)
- {
- puts ("2nd rwlock_rdlock failed");
- return 1;
- }
- puts ("2nd rwlock_rdlock succeeded");
-
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("1st rwlock_unlock failed");
- return 1;
- }
- puts ("1st rwlock_unlock succeeded");
-
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("2nd rwlock_unlock failed");
- return 1;
- }
- puts ("2nd rwlock_unlock succeeded");
-
- if (pthread_rwlock_wrlock (&r) != 0)
- {
- puts ("1st rwlock_wrlock failed");
- return 1;
- }
- puts ("1st rwlock_wrlock succeeded");
-
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("3rd rwlock_unlock failed");
- return 1;
- }
- puts ("3rd rwlock_unlock succeeded");
-
- if (pthread_rwlock_wrlock (&r) != 0)
- {
- puts ("2nd rwlock_wrlock failed");
- return 1;
- }
- puts ("2nd rwlock_wrlock succeeded");
-
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("4th rwlock_unlock failed");
- return 1;
- }
- puts ("4th rwlock_unlock succeeded");
-
- if (pthread_rwlock_rdlock (&r) != 0)
- {
- puts ("3rd rwlock_rdlock failed");
- return 1;
- }
- puts ("3rd rwlock_rdlock succeeded");
-
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("5th rwlock_unlock failed");
- return 1;
- }
- puts ("5th rwlock_unlock succeeded");
-
- if (pthread_rwlock_destroy (&r) != 0)
- {
- puts ("rwlock_destroy failed");
- return 1;
- }
- puts ("rwlock_destroy succeeded");
-
- return 0;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/nptl/tst-rwlock13.c b/nptl/tst-rwlock13.c
deleted file mode 100644
index 749ec4b621..0000000000
--- a/nptl/tst-rwlock13.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (C) 2004-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-
-
-static int
-do_test (void)
-{
- pthread_rwlock_t r;
- int ret;
-
- memset (&r, 0xaa, sizeof (r));
- if ((ret = pthread_rwlock_init (&r, NULL)) != 0)
- {
- printf ("rwlock_init failed: %d\n", ret);
- return 1;
- }
-
- if ((ret = pthread_rwlock_rdlock (&r)) != 0)
- {
- printf ("rwlock_rdlock failed: %d\n", ret);
- return 1;
- }
-
- if ((ret = pthread_rwlock_unlock (&r)) != 0)
- {
- printf ("rwlock_unlock failed: %d\n", ret);
- return 1;
- }
-
- if ((ret = pthread_rwlock_wrlock (&r)) != 0)
- {
- printf ("rwlock_wrlock failed: %d\n", ret);
- return 1;
- }
-
- if ((ret = pthread_rwlock_unlock (&r)) != 0)
- {
- printf ("second rwlock_unlock failed: %d\n", ret);
- return 1;
- }
-
- if ((ret = pthread_rwlock_destroy (&r)) != 0)
- {
- printf ("second rwlock_destroy failed: %d\n", ret);
- return 1;
- }
-
- return 0;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/nptl/tst-rwlock16.c b/nptl/tst-rwlock16.c
deleted file mode 100644
index 29720c9d8d..0000000000
--- a/nptl/tst-rwlock16.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* Copyright (C) 2015-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-/* This tests that with a reader-preferring rwlock, all readers are woken if
- one reader "steals" lock ownership from a blocked writer. */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <semaphore.h>
-#include <unistd.h>
-
-/* If we strictly prefer writers over readers, a program must not expect
- that, in the presence of concurrent writers, one reader will also acquire
- the lock when another reader has already done so. Thus, use the
- default rwlock type that does not strictly prefer writers. */
-static pthread_rwlock_t r = PTHREAD_RWLOCK_INITIALIZER;
-
-static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
-
-/* Avoid using glibc-internal atomic operations. */
-static sem_t stop;
-static int consumer_stop = 0;
-
-static void *
-writer (void *arg)
-{
- int s;
-
- do
- {
- if (pthread_rwlock_wrlock (&r) != 0)
- {
- puts ("wrlock failed");
- exit (EXIT_FAILURE);
- }
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("unlock failed");
- exit (EXIT_FAILURE);
- }
- sem_getvalue (&stop, &s);
- }
- while (s == 0);
- return NULL;
-}
-
-static void *
-reader_producer (void *arg)
-{
- int s;
-
- do
- {
- if (pthread_rwlock_rdlock (&r) != 0)
- {
- puts ("rdlock reader failed");
- exit (EXIT_FAILURE);
- }
-
- sem_getvalue (&stop, &s);
-
- pthread_mutex_lock (&m);
- if (s != 0)
- consumer_stop = 1;
- pthread_cond_signal (&cv);
- pthread_mutex_unlock (&m);
-
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("unlock reader failed");
- exit (EXIT_FAILURE);
- }
- }
- while (s == 0);
- puts ("producer finished");
- return NULL;
-}
-
-static void *
-reader_consumer (void *arg)
-{
- int s;
-
- do
- {
- if (pthread_rwlock_rdlock (&r) != 0)
- {
- puts ("rdlock reader failed");
- exit (EXIT_FAILURE);
- }
-
- pthread_mutex_lock (&m);
- s = consumer_stop;
- if (s == 0)
- pthread_cond_wait (&cv, &m);
- pthread_mutex_unlock (&m);
-
- if (pthread_rwlock_unlock (&r) != 0)
- {
- puts ("unlock reader failed");
- exit (EXIT_FAILURE);
- }
- }
- while (s == 0);
- puts ("consumer finished");
- return NULL;
-}
-
-
-static int
-do_test (void)
-{
- pthread_t w1, w2, rp, rc;
-
- if (pthread_create (&w1, NULL, writer, NULL) != 0)
- {
- puts ("create failed");
- return 1;
- }
- if (pthread_create (&w2, NULL, writer, NULL) != 0)
- {
- puts ("create failed");
- return 1;
- }
- if (pthread_create (&rc, NULL, reader_consumer, NULL) != 0)
- {
- puts ("create failed");
- return 1;
- }
- if (pthread_create (&rp, NULL, reader_producer, NULL) != 0)
- {
- puts ("create failed");
- return 1;
- }
-
- sleep (2);
- sem_post (&stop);
-
- if (pthread_join (w1, NULL) != 0)
- {
- puts ("w1 join failed");
- return 1;
- }
- if (pthread_join (w2, NULL) != 0)
- {
- puts ("w2 join failed");
- return 1;
- }
- if (pthread_join (rp, NULL) != 0)
- {
- puts ("reader_producer join failed");
- return 1;
- }
- if (pthread_join (rc, NULL) != 0)
- {
- puts ("reader_consumer join failed");
- return 1;
- }
-
- return 0;
-}
-
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/nptl/tst-rwlock4.c b/nptl/tst-rwlock4.c
deleted file mode 100644
index 479107a5f2..0000000000
--- a/nptl/tst-rwlock4.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-
-
-static int
-do_test (void)
-{
- size_t ps = sysconf (_SC_PAGESIZE);
- char tmpfname[] = "/tmp/tst-rwlock4.XXXXXX";
- char data[ps];
- void *mem;
- int fd;
- pthread_rwlock_t *r;
- pthread_rwlockattr_t a;
- pid_t pid;
- char *p;
- int err;
- int s;
-
- fd = mkstemp (tmpfname);
- if (fd == -1)
- {
- printf ("cannot open temporary file: %m\n");
- return 1;
- }
-
- /* Make sure it is always removed. */
- unlink (tmpfname);
-
- /* Create one page of data. */
- memset (data, '\0', ps);
-
- /* Write the data to the file. */
- if (write (fd, data, ps) != (ssize_t) ps)
- {
- puts ("short write");
- return 1;
- }
-
- mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (mem == MAP_FAILED)
- {
- printf ("mmap failed: %m\n");
- return 1;
- }
-
- r = (pthread_rwlock_t *) (((uintptr_t) mem + __alignof (pthread_rwlock_t))
- & ~(__alignof (pthread_rwlock_t) - 1));
- p = (char *) (r + 1);
-
- if (pthread_rwlockattr_init (&a) != 0)
- {
- puts ("rwlockattr_init failed");
- return 1;
- }
-
- if (pthread_rwlockattr_getpshared (&a, &s) != 0)
- {
- puts ("1st rwlockattr_getpshared failed");
- return 1;
- }
-
- if (s != PTHREAD_PROCESS_PRIVATE)
- {
- puts ("default pshared value wrong");
- return 1;
- }
-
- if (pthread_rwlockattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
- {
- puts ("rwlockattr_setpshared failed");
- return 1;
- }
-
- if (pthread_rwlockattr_getpshared (&a, &s) != 0)
- {
- puts ("2nd rwlockattr_getpshared failed");
- return 1;
- }
-
- if (s != PTHREAD_PROCESS_SHARED)
- {
- puts ("pshared value after setpshared call wrong");
- return 1;
- }
-
- if (pthread_rwlock_init (r, &a) != 0)
- {
- puts ("rwlock_init failed");
- return 1;
- }
-
- if (pthread_rwlock_rdlock (r) != 0)
- {
- puts ("rwlock_rdlock failed");
- return 1;
- }
-
- if (pthread_rwlockattr_destroy (&a) != 0)
- {
- puts ("rwlockattr_destroy failed");
- return 1;
- }
-
- err = pthread_rwlock_trywrlock (r);
- if (err == 0)
- {
- puts ("rwlock_trywrlock succeeded");
- return 1;
- }
- else if (err != EBUSY)
- {
- puts ("rwlock_trywrlock didn't return EBUSY");
- return 1;
- }
-
- *p = 0;
-
- puts ("going to fork now");
- pid = fork ();
- if (pid == -1)
- {
- puts ("fork failed");
- return 1;
- }
- else if (pid == 0)
- {
- /* Play some lock ping-pong. It's our turn to unlock first. */
- if ((*p)++ != 0)
- {
- puts ("child: *p != 0");
- return 1;
- }
-
- if (pthread_rwlock_unlock (r) != 0)
- {
- puts ("child: 1st rwlock_unlock failed");
- return 1;
- }
-
- puts ("child done");
- }
- else
- {
- if (pthread_rwlock_wrlock (r) != 0)
- {
- puts ("parent: rwlock_wrlock failed");
- return 1;
- }
-
- if (*p != 1)
- {
- puts ("*p != 1");
- return 1;
- }
-
- puts ("parent done");
- }
-
- return 0;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/nptl/tst-rwlock5.c b/nptl/tst-rwlock5.c
deleted file mode 100644
index c589764196..0000000000
--- a/nptl/tst-rwlock5.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <pthread.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
-
-static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
-static pthread_rwlock_t r;
-
-
-static void *
-tf (void *arg)
-{
- if (pthread_rwlock_wrlock (&r) == 0)
- {
- puts ("child: rwlock_wrlock succeeded");
- exit (1);
- }
-
- puts ("child: rwlock_wrlock returned");
-
- exit (1);
-}
-
-
-static int
-do_test (void)
-{
- pthread_t th;
-
- if (pthread_rwlock_init (&r, NULL) != 0)
- {
- puts ("rwlock_init failed");
- return 1;
- }
-
- if (pthread_rwlock_wrlock (&r) != 0)
- {
- puts ("rwlock_wrlock failed");
- return 1;
- }
-
- if (pthread_mutex_lock (&m) != 0)
- {
- puts ("mutex_lock failed");
- return 1;
- }
-
- if (pthread_create (&th, NULL, tf, NULL) != 0)
- {
- puts ("create failed");
- return 1;
- }
-
- delayed_exit (1);
- /* This call should never return. */
- xpthread_mutex_lock (&m);
-
- puts ("2nd mutex_lock returned");
- return 1;
-}