aboutsummaryrefslogtreecommitdiff
path: root/nptl/tst-robust-fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/tst-robust-fork.c')
-rw-r--r--nptl/tst-robust-fork.c184
1 files changed, 0 insertions, 184 deletions
diff --git a/nptl/tst-robust-fork.c b/nptl/tst-robust-fork.c
deleted file mode 100644
index 4a12ff000d..0000000000
--- a/nptl/tst-robust-fork.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Test the interaction of fork and robust mutexes.
- Copyright (C) 2017 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
- <http://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <support/check.h>
-#include <support/test-driver.h>
-#include <support/xthread.h>
-#include <support/xunistd.h>
-#include <sys/mman.h>
-
-/* Data shared between processes. */
-struct shared
-{
- pthread_mutex_t parent_mutex;
- pthread_mutex_t child_mutex;
-};
-
-/* These flags control which mutex settings are enabled in the parent
- and child (separately). */
-enum mutex_bits
- {
- mutex_pshared = 1,
- mutex_robust = 2,
- mutex_pi = 4,
- mutex_check = 8,
-
- /* All bits combined. */
- mutex_all_bits = 15,
- };
-
-static void
-mutex_init (pthread_mutex_t *mutex, int bits)
-{
- pthread_mutexattr_t attr;
- xpthread_mutexattr_init (&attr);
- if (bits & mutex_pshared)
- xpthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED);
- if (bits & mutex_robust)
- xpthread_mutexattr_setrobust (&attr, PTHREAD_MUTEX_ROBUST);
- if (bits & mutex_pi)
- xpthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT);
- if (bits & mutex_check)
- xpthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
- xpthread_mutex_init (mutex, &attr);
- xpthread_mutexattr_destroy (&attr);
-}
-
-static void
-one_test (int parent_bits, int child_bits, int nonshared_bits,
- bool lock_nonshared, bool lock_child)
-{
-
- struct shared *shared = xmmap (NULL, sizeof (*shared),
- PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_SHARED, -1);
- mutex_init (&shared->parent_mutex, parent_bits);
- mutex_init (&shared->child_mutex, child_bits);
-
- /* Acquire the parent mutex in the parent. */
- xpthread_mutex_lock (&shared->parent_mutex);
-
- pthread_mutex_t nonshared_mutex;
- mutex_init (&nonshared_mutex, nonshared_bits);
- if (lock_nonshared)
- xpthread_mutex_lock (&nonshared_mutex);
-
- pid_t pid = xfork ();
- if (pid == 0)
- {
- /* Child process. */
- if (lock_child)
- xpthread_mutex_lock (&shared->child_mutex);
- else
- xmunmap (shared, sizeof (*shared));
- if (lock_nonshared)
- /* Reinitialize the non-shared mutex if it was locked in the
- parent. */
- mutex_init (&nonshared_mutex, nonshared_bits);
- xpthread_mutex_lock (&nonshared_mutex);
- /* For robust mutexes, the _exit call will perform the unlock
- instead. */
- if (lock_child && !(child_bits & mutex_robust))
- xpthread_mutex_unlock (&shared->child_mutex);
- _exit (0);
- }
- /* Parent process. */
- {
- int status;
- xwaitpid (pid, &status, 0);
- TEST_VERIFY (status == 0);
- }
-
- if (parent_bits & mutex_check)
- /* Test for expected self-deadlock. This is only possible to
- detect if the mutex is error-checking. */
- TEST_VERIFY_EXIT (pthread_mutex_lock (&shared->parent_mutex) == EDEADLK);
-
- pid = xfork ();
- if (pid == 0)
- {
- /* Child process. We can perform some checks only if we are
- dealing with process-shared mutexes. */
- if (parent_bits & mutex_pshared)
- /* It must not be possible to acquire the parent mutex.
-
- NB: This check touches a mutex which has been acquired in
- the parent at fork time, so it might be deemed undefined
- behavior, pending the resolution of Austin Groups issue
- 1112. */
- TEST_VERIFY_EXIT (pthread_mutex_trylock (&shared->parent_mutex)
- == EBUSY);
- if (lock_child && (child_bits & mutex_robust))
- {
- if (!(child_bits & mutex_pshared))
- /* No further tests possible. */
- _exit (0);
- TEST_VERIFY_EXIT (pthread_mutex_lock (&shared->child_mutex)
- == EOWNERDEAD);
- xpthread_mutex_consistent (&shared->child_mutex);
- }
- else
- /* We did not acquire the lock in the first child process, or
- we unlocked the mutex again because the mutex is not a
- robust mutex. */
- xpthread_mutex_lock (&shared->child_mutex);
- xpthread_mutex_unlock (&shared->child_mutex);
- _exit (0);
- }
- /* Parent process. */
- {
- int status;
- xwaitpid (pid, &status, 0);
- TEST_VERIFY (status == 0);
- }
-
- if (lock_nonshared)
- xpthread_mutex_unlock (&nonshared_mutex);
- xpthread_mutex_unlock (&shared->parent_mutex);
- xpthread_mutex_destroy (&shared->parent_mutex);
- xpthread_mutex_destroy (&shared->child_mutex);
- xpthread_mutex_destroy (&nonshared_mutex);
- xmunmap (shared, sizeof (*shared));
-}
-
-static int
-do_test (void)
-{
- for (int parent_bits = 0; parent_bits <= mutex_all_bits; ++parent_bits)
- for (int child_bits = 0; child_bits <= mutex_all_bits; ++child_bits)
- for (int nonshared_bits = 0; nonshared_bits <= mutex_all_bits;
- ++nonshared_bits)
- for (int lock_nonshared = 0; lock_nonshared < 2; ++lock_nonshared)
- for (int lock_child = 0; lock_child < 2; ++lock_child)
- {
- if (test_verbose)
- printf ("info: parent_bits=0x%x child_bits=0x%x"
- " nonshared_bits=0x%x%s%s\n",
- parent_bits, child_bits, nonshared_bits,
- lock_nonshared ? " lock_nonshared" : "",
- lock_child ? " lock_child" : "");
- one_test (parent_bits, child_bits, nonshared_bits,
- lock_nonshared, lock_child);
- }
- return 0;
-}
-
-#include <support/test-driver.c>