diff options
Diffstat (limited to 'nptl/tst-robust-fork.c')
-rw-r--r-- | nptl/tst-robust-fork.c | 184 |
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> |