From d8f1f2d9ab2144b589fdac3e381cd86e71871e43 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 9 Feb 2020 19:17:51 +0000 Subject: pthread: Move most cond tests from nptl to sysdeps/pthread So they can be checked with htl too. --- nptl/Makefile | 11 +- nptl/tst-cond-except.c | 109 -------------- nptl/tst-cond1.c | 96 ------------ nptl/tst-cond10.c | 172 --------------------- nptl/tst-cond11-static.c | 1 - nptl/tst-cond11.c | 122 --------------- nptl/tst-cond12.c | 195 ------------------------ nptl/tst-cond13.c | 2 - nptl/tst-cond14.c | 116 --------------- nptl/tst-cond15.c | 158 -------------------- nptl/tst-cond16.c | 106 ------------- nptl/tst-cond17.c | 2 - nptl/tst-cond18.c | 119 --------------- nptl/tst-cond19.c | 75 ---------- nptl/tst-cond2.c | 162 -------------------- nptl/tst-cond22.c | 162 -------------------- nptl/tst-cond23.c | 183 ----------------------- nptl/tst-cond24.c | 248 ------------------------------- nptl/tst-cond25.c | 288 ------------------------------------ nptl/tst-cond26.c | 77 ---------- nptl/tst-cond27.c | 66 --------- nptl/tst-cond3.c | 111 -------------- nptl/tst-cond4.c | 263 -------------------------------- nptl/tst-cond5.c | 105 ------------- nptl/tst-cond6.c | 233 ----------------------------- nptl/tst-cond7.c | 167 --------------------- nptl/tst-cond8-static.c | 1 - nptl/tst-cond8.c | 276 ---------------------------------- nptl/tst-cond9.c | 149 ------------------- sysdeps/mach/hurd/i386/Makefile | 11 ++ sysdeps/pthread/Makefile | 10 ++ sysdeps/pthread/tst-cond-except.c | 109 ++++++++++++++ sysdeps/pthread/tst-cond1.c | 96 ++++++++++++ sysdeps/pthread/tst-cond10.c | 172 +++++++++++++++++++++ sysdeps/pthread/tst-cond11-static.c | 1 + sysdeps/pthread/tst-cond11.c | 122 +++++++++++++++ sysdeps/pthread/tst-cond12.c | 195 ++++++++++++++++++++++++ sysdeps/pthread/tst-cond13.c | 2 + sysdeps/pthread/tst-cond14.c | 116 +++++++++++++++ sysdeps/pthread/tst-cond15.c | 158 ++++++++++++++++++++ sysdeps/pthread/tst-cond16.c | 108 ++++++++++++++ sysdeps/pthread/tst-cond17.c | 2 + sysdeps/pthread/tst-cond18.c | 121 +++++++++++++++ sysdeps/pthread/tst-cond19.c | 75 ++++++++++ sysdeps/pthread/tst-cond2.c | 162 ++++++++++++++++++++ sysdeps/pthread/tst-cond22.c | 162 ++++++++++++++++++++ sysdeps/pthread/tst-cond23.c | 183 +++++++++++++++++++++++ sysdeps/pthread/tst-cond24.c | 248 +++++++++++++++++++++++++++++++ sysdeps/pthread/tst-cond25.c | 288 ++++++++++++++++++++++++++++++++++++ sysdeps/pthread/tst-cond26.c | 77 ++++++++++ sysdeps/pthread/tst-cond27.c | 66 +++++++++ sysdeps/pthread/tst-cond3.c | 111 ++++++++++++++ sysdeps/pthread/tst-cond4.c | 263 ++++++++++++++++++++++++++++++++ sysdeps/pthread/tst-cond5.c | 105 +++++++++++++ sysdeps/pthread/tst-cond6.c | 233 +++++++++++++++++++++++++++++ sysdeps/pthread/tst-cond7.c | 167 +++++++++++++++++++++ sysdeps/pthread/tst-cond8-static.c | 1 + sysdeps/pthread/tst-cond8.c | 276 ++++++++++++++++++++++++++++++++++ sysdeps/pthread/tst-cond9.c | 149 +++++++++++++++++++ 59 files changed, 3792 insertions(+), 3772 deletions(-) delete mode 100644 nptl/tst-cond-except.c delete mode 100644 nptl/tst-cond1.c delete mode 100644 nptl/tst-cond10.c delete mode 100644 nptl/tst-cond11-static.c delete mode 100644 nptl/tst-cond11.c delete mode 100644 nptl/tst-cond12.c delete mode 100644 nptl/tst-cond13.c delete mode 100644 nptl/tst-cond14.c delete mode 100644 nptl/tst-cond15.c delete mode 100644 nptl/tst-cond16.c delete mode 100644 nptl/tst-cond17.c delete mode 100644 nptl/tst-cond18.c delete mode 100644 nptl/tst-cond19.c delete mode 100644 nptl/tst-cond2.c delete mode 100644 nptl/tst-cond22.c delete mode 100644 nptl/tst-cond23.c delete mode 100644 nptl/tst-cond24.c delete mode 100644 nptl/tst-cond25.c delete mode 100644 nptl/tst-cond26.c delete mode 100644 nptl/tst-cond27.c delete mode 100644 nptl/tst-cond3.c delete mode 100644 nptl/tst-cond4.c delete mode 100644 nptl/tst-cond5.c delete mode 100644 nptl/tst-cond6.c delete mode 100644 nptl/tst-cond7.c delete mode 100644 nptl/tst-cond8-static.c delete mode 100644 nptl/tst-cond8.c delete mode 100644 nptl/tst-cond9.c create mode 100644 sysdeps/pthread/tst-cond-except.c create mode 100644 sysdeps/pthread/tst-cond1.c create mode 100644 sysdeps/pthread/tst-cond10.c create mode 100644 sysdeps/pthread/tst-cond11-static.c create mode 100644 sysdeps/pthread/tst-cond11.c create mode 100644 sysdeps/pthread/tst-cond12.c create mode 100644 sysdeps/pthread/tst-cond13.c create mode 100644 sysdeps/pthread/tst-cond14.c create mode 100644 sysdeps/pthread/tst-cond15.c create mode 100644 sysdeps/pthread/tst-cond16.c create mode 100644 sysdeps/pthread/tst-cond17.c create mode 100644 sysdeps/pthread/tst-cond18.c create mode 100644 sysdeps/pthread/tst-cond19.c create mode 100644 sysdeps/pthread/tst-cond2.c create mode 100644 sysdeps/pthread/tst-cond22.c create mode 100644 sysdeps/pthread/tst-cond23.c create mode 100644 sysdeps/pthread/tst-cond24.c create mode 100644 sysdeps/pthread/tst-cond25.c create mode 100644 sysdeps/pthread/tst-cond26.c create mode 100644 sysdeps/pthread/tst-cond27.c create mode 100644 sysdeps/pthread/tst-cond3.c create mode 100644 sysdeps/pthread/tst-cond4.c create mode 100644 sysdeps/pthread/tst-cond5.c create mode 100644 sysdeps/pthread/tst-cond6.c create mode 100644 sysdeps/pthread/tst-cond7.c create mode 100644 sysdeps/pthread/tst-cond8-static.c create mode 100644 sysdeps/pthread/tst-cond8.c create mode 100644 sysdeps/pthread/tst-cond9.c diff --git a/nptl/Makefile b/nptl/Makefile index 51a0be008b..8fadd1d025 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -239,12 +239,7 @@ tests = tst-attr2 tst-attr3 tst-default-attr \ tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \ tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ tst-mutexpi9 \ - tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ - tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \ - tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ - tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 tst-cond25 \ - tst-cond26 tst-cond27 \ - tst-cond-except \ + tst-cond11 tst-cond20 tst-cond21 tst-cond22 tst-cond26 tst-cond27 \ tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \ tst-robust6 tst-robust7 tst-robust8 tst-robust9 \ tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \ @@ -450,12 +445,12 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \ $(common-objpfx)libc.a tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \ - tst-cancel21-static tst-cancel24-static tst-cond8-static \ + tst-cancel21-static tst-cancel24-static \ tst-mutex8-static tst-mutexpi8-static tst-sem11-static \ tst-sem12-static tst-cond11-static tests += tst-cancel21-static tst-cancel24-static \ - tst-cond8-static tst-cond11-static + tst-cond11-static tests-internal += tst-sem11-static tst-sem12-static tst-stackguard1-static xtests-static += tst-setuid1-static diff --git a/nptl/tst-cond-except.c b/nptl/tst-cond-except.c deleted file mode 100644 index 8526e241e6..0000000000 --- a/nptl/tst-cond-except.c +++ /dev/null @@ -1,109 +0,0 @@ -/* Verify that exception table for pthread_cond_wait is correct. - Copyright (C) 2012-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 - . */ - -#include -#include -#include -#include -#include - -pthread_mutex_t mutex; -pthread_cond_t cond; - -#define CHECK_RETURN_VAL_OR_FAIL(ret,str) \ - ({ if ((ret) != 0) \ - { \ - printf ("%s failed: %s\n", (str), strerror (ret)); \ - ret = 1; \ - goto out; \ - } \ - }) - - -void -clean (void *arg) -{ - puts ("clean: Unlocking mutex..."); - pthread_mutex_unlock ((pthread_mutex_t *) arg); - puts ("clean: Mutex unlocked..."); -} - -void * -thr (void *arg) -{ - int ret = 0; - pthread_mutexattr_t mutexAttr; - ret = pthread_mutexattr_init (&mutexAttr); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_init"); - - ret = pthread_mutexattr_setprotocol (&mutexAttr, PTHREAD_PRIO_INHERIT); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_setprotocol"); - - ret = pthread_mutex_init (&mutex, &mutexAttr); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_init"); - - ret = pthread_cond_init (&cond, 0); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_init"); - - puts ("th: Init done, entering wait..."); - - pthread_cleanup_push (clean, (void *) &mutex); - ret = pthread_mutex_lock (&mutex); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_lock"); - while (1) - { - ret = pthread_cond_wait (&cond, &mutex); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_wait"); - } - pthread_cleanup_pop (1); - -out: - return (void *) (uintptr_t) ret; -} - -int -do_test (void) -{ - pthread_t thread; - int ret = 0; - void *thr_ret = 0; - ret = pthread_create (&thread, 0, thr, &thr_ret); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_create"); - - puts ("main: Thread created, waiting a bit..."); - sleep (2); - - puts ("main: Cancelling thread..."); - ret = pthread_cancel (thread); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cancel"); - - puts ("main: Joining th..."); - ret = pthread_join (thread, NULL); - CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_join"); - - if (thr_ret != NULL) - return 1; - - puts ("main: Joined thread, done!"); - -out: - return ret; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond1.c b/nptl/tst-cond1.c deleted file mode 100644 index 47c68d443b..0000000000 --- a/nptl/tst-cond1.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include - - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - - -static void * -tf (void *p) -{ - int err; - - err = pthread_mutex_lock (&mut); - if (err != 0) - error (EXIT_FAILURE, err, "child: cannot get mutex"); - - puts ("child: got mutex; signalling"); - - pthread_cond_signal (&cond); - - puts ("child: unlock"); - - err = pthread_mutex_unlock (&mut); - if (err != 0) - error (EXIT_FAILURE, err, "child: cannot unlock"); - - puts ("child: done"); - - return NULL; -} - - -static int -do_test (void) -{ - pthread_t th; - int err; - - printf ("&cond = %p\n&mut = %p\n", &cond, &mut); - - puts ("parent: get mutex"); - - err = pthread_mutex_lock (&mut); - if (err != 0) - error (EXIT_FAILURE, err, "parent: cannot get mutex"); - - puts ("parent: create child"); - - err = pthread_create (&th, NULL, tf, NULL); - if (err != 0) - error (EXIT_FAILURE, err, "parent: cannot create thread"); - - puts ("parent: wait for condition"); - - /* This test will fail on spurious wake-ups, which are allowed; however, - the current implementation shouldn't produce spurious wake-ups in the - scenario we are testing here. */ - err = pthread_cond_wait (&cond, &mut); - if (err != 0) - error (EXIT_FAILURE, err, "parent: cannot wait fir signal"); - - puts ("parent: got signal"); - - err = pthread_join (th, NULL); - if (err != 0) - error (EXIT_FAILURE, err, "parent: failed to join"); - - puts ("done"); - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond10.c b/nptl/tst-cond10.c deleted file mode 100644 index b89c452467..0000000000 --- a/nptl/tst-cond10.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - 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 - . */ - -#include -#include -#include -#include -#include - - -#define N 10 -#define ROUNDS 100 - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; -static pthread_barrier_t bN1; -static pthread_barrier_t b2; - - -static void * -tf (void *p) -{ - if (pthread_mutex_lock (&mut) != 0) - { - puts ("child: 1st mutex_lock failed"); - exit (1); - } - - int e = pthread_barrier_wait (&b2); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("child: 1st barrier_wait failed"); - exit (1); - } - - if (pthread_cond_wait (&cond, &mut) != 0) - { - puts ("child: cond_wait failed"); - exit (1); - } - - if (pthread_mutex_unlock (&mut) != 0) - { - puts ("child: mutex_unlock failed"); - exit (1); - } - - e = pthread_barrier_wait (&bN1); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("child: 2nd barrier_wait failed"); - exit (1); - } - - return NULL; -} - - -static int -do_test (void) -{ - if (pthread_barrier_init (&bN1, NULL, N + 1) != 0) - { - puts ("barrier_init failed"); - exit (1); - } - - if (pthread_barrier_init (&b2, NULL, 2) != 0) - { - puts ("barrier_init failed"); - exit (1); - } - - pthread_attr_t at; - - if (pthread_attr_init (&at) != 0) - { - puts ("attr_init failed"); - return 1; - } - - if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0) - { - puts ("attr_setstacksize failed"); - return 1; - } - - int r; - for (r = 0; r < ROUNDS; ++r) - { - printf ("round %d\n", r + 1); - - int i; - pthread_t th[N]; - for (i = 0; i < N; ++i) - { - if (pthread_create (&th[i], &at, tf, NULL) != 0) - { - puts ("create failed"); - exit (1); - } - - int e = pthread_barrier_wait (&b2); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("parent: 1st barrier_wait failed"); - exit (1); - } - } - - if (pthread_mutex_lock (&mut) != 0) - { - puts ("parent: mutex_lock failed"); - exit (1); - } - if (pthread_mutex_unlock (&mut) != 0) - { - puts ("parent: mutex_unlock failed"); - exit (1); - } - - /* N single signal calls. Without locking. This tests that no - signal gets lost. */ - for (i = 0; i < N; ++i) - if (pthread_cond_signal (&cond) != 0) - { - puts ("cond_signal failed"); - exit (1); - } - - int e = pthread_barrier_wait (&bN1); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("parent: 2nd barrier_wait failed"); - exit (1); - } - - for (i = 0; i < N; ++i) - if (pthread_join (th[i], NULL) != 0) - { - puts ("join failed"); - exit (1); - } - } - - if (pthread_attr_destroy (&at) != 0) - { - puts ("attr_destroy failed"); - return 1; - } - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond11-static.c b/nptl/tst-cond11-static.c deleted file mode 100644 index 9bccb8ec8b..0000000000 --- a/nptl/tst-cond11-static.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cond11.c" diff --git a/nptl/tst-cond11.c b/nptl/tst-cond11.c deleted file mode 100644 index 209e2f0c8d..0000000000 --- a/nptl/tst-cond11.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* A bogus clock value that tells run_test to use pthread_cond_timedwait - rather than pthread_condclockwait. */ -#define CLOCK_USE_ATTR_CLOCK (-1) - -#if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 -static int -run_test (clockid_t attr_clock, clockid_t wait_clock) -{ - pthread_condattr_t condattr; - pthread_cond_t cond; - pthread_mutexattr_t mutattr; - pthread_mutex_t mut; - - verbose_printf ("attr_clock = %d\n", (int) attr_clock); - - TEST_COMPARE (pthread_condattr_init (&condattr), 0); - TEST_COMPARE (pthread_condattr_setclock (&condattr, attr_clock), 0); - - clockid_t attr_clock_read; - TEST_COMPARE (pthread_condattr_getclock (&condattr, &attr_clock_read), 0); - TEST_COMPARE (attr_clock, attr_clock_read); - - TEST_COMPARE (pthread_cond_init (&cond, &condattr), 0); - TEST_COMPARE (pthread_condattr_destroy (&condattr), 0); - - xpthread_mutexattr_init (&mutattr); - xpthread_mutexattr_settype (&mutattr, PTHREAD_MUTEX_ERRORCHECK); - xpthread_mutex_init (&mut, &mutattr); - xpthread_mutexattr_destroy (&mutattr); - - xpthread_mutex_lock (&mut); - TEST_COMPARE (pthread_mutex_lock (&mut), EDEADLK); - - struct timespec ts_timeout; - xclock_gettime (wait_clock == CLOCK_USE_ATTR_CLOCK ? attr_clock : wait_clock, - &ts_timeout); - - /* Wait one second. */ - ++ts_timeout.tv_sec; - - if (wait_clock == CLOCK_USE_ATTR_CLOCK) { - TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT); - TEST_TIMESPEC_BEFORE_NOW (ts_timeout, attr_clock); - } else { - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, wait_clock, &ts_timeout), - ETIMEDOUT); - TEST_TIMESPEC_BEFORE_NOW (ts_timeout, wait_clock); - } - - xpthread_mutex_unlock (&mut); - xpthread_mutex_destroy (&mut); - TEST_COMPARE (pthread_cond_destroy (&cond), 0); - - return 0; -} -#endif - - -static int -do_test (void) -{ -#if !defined _POSIX_CLOCK_SELECTION || _POSIX_CLOCK_SELECTION == -1 - - FAIL_UNSUPPORTED ("_POSIX_CLOCK_SELECTION not supported, test skipped"); - -#else - - run_test (CLOCK_REALTIME, CLOCK_USE_ATTR_CLOCK); - -# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 -# if _POSIX_MONOTONIC_CLOCK == 0 - int e = sysconf (_SC_MONOTONIC_CLOCK); - if (e < 0) - puts ("CLOCK_MONOTONIC not supported"); - else if (e == 0) - FAIL_RET ("sysconf (_SC_MONOTONIC_CLOCK) must not return 0"); - else - { -# endif - run_test (CLOCK_MONOTONIC, CLOCK_USE_ATTR_CLOCK); - run_test (CLOCK_REALTIME, CLOCK_MONOTONIC); - run_test (CLOCK_MONOTONIC, CLOCK_MONOTONIC); - run_test (CLOCK_MONOTONIC, CLOCK_REALTIME); - } -# else - puts ("_POSIX_MONOTONIC_CLOCK not defined"); -# endif - - return 0; -#endif -} - -#include diff --git a/nptl/tst-cond12.c b/nptl/tst-cond12.c deleted file mode 100644 index 474bedc39c..0000000000 --- a/nptl/tst-cond12.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static char fname[] = "/tmp/tst-cond12-XXXXXX"; -static int fd; - - -static void prepare (void); -#define PREPARE(argc, argv) prepare () - -static int do_test (void); -#define TEST_FUNCTION do_test () - -#include "../test-skeleton.c" - - -static void -prepare (void) -{ - fd = mkstemp (fname); - if (fd == -1) - { - printf ("mkstemp failed: %m\n"); - exit (1); - } - add_temp_file (fname); - if (ftruncate (fd, 1000) < 0) - { - printf ("ftruncate failed: %m\n"); - exit (1); - } -} - - -static int -do_test (void) -{ - struct - { - pthread_mutex_t m; - pthread_cond_t c; - int var; - } *p = mmap (NULL, sizeof (*p), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (p == MAP_FAILED) - { - printf ("initial mmap failed: %m\n"); - return 1; - } - - pthread_mutexattr_t ma; - if (pthread_mutexattr_init (&ma) != 0) - { - puts ("mutexattr_init failed"); - return 1; - } - if (pthread_mutexattr_setpshared (&ma, 1) != 0) - { - puts ("mutexattr_setpshared failed"); - return 1; - } - if (pthread_mutex_init (&p->m, &ma) != 0) - { - puts ("mutex_init failed"); - return 1; - } - if (pthread_mutexattr_destroy (&ma) != 0) - { - puts ("mutexattr_destroy failed"); - return 1; - } - - pthread_condattr_t ca; - if (pthread_condattr_init (&ca) != 0) - { - puts ("condattr_init failed"); - return 1; - } - if (pthread_condattr_setpshared (&ca, 1) != 0) - { - puts ("condattr_setpshared failed"); - return 1; - } - if (pthread_cond_init (&p->c, &ca) != 0) - { - puts ("mutex_init failed"); - return 1; - } - if (pthread_condattr_destroy (&ca) != 0) - { - puts ("condattr_destroy failed"); - return 1; - } - - if (pthread_mutex_lock (&p->m) != 0) - { - puts ("initial mutex_lock failed"); - return 1; - } - - p->var = 42; - - pid_t pid = fork (); - if (pid == -1) - { - printf ("fork failed: %m\n"); - return 1; - } - - if (pid == 0) - { - void *oldp = p; - p = mmap (NULL, sizeof (*p), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - - if (p == oldp) - { - puts ("child: mapped to same address"); - kill (getppid (), SIGKILL); - exit (1); - } - - munmap (oldp, sizeof (*p)); - - if (pthread_mutex_lock (&p->m) != 0) - { - puts ("child: mutex_lock failed"); - kill (getppid (), SIGKILL); - exit (1); - } - - p->var = 0; - -#ifndef USE_COND_SIGNAL - if (pthread_cond_broadcast (&p->c) != 0) - { - puts ("child: cond_broadcast failed"); - kill (getppid (), SIGKILL); - exit (1); - } -#else - if (pthread_cond_signal (&p->c) != 0) - { - puts ("child: cond_signal failed"); - kill (getppid (), SIGKILL); - exit (1); - } -#endif - - if (pthread_mutex_unlock (&p->m) != 0) - { - puts ("child: mutex_unlock failed"); - kill (getppid (), SIGKILL); - exit (1); - } - - exit (0); - } - - do - pthread_cond_wait (&p->c, &p->m); - while (p->var != 0); - - if (TEMP_FAILURE_RETRY (waitpid (pid, NULL, 0)) != pid) - { - printf ("waitpid failed: %m\n"); - kill (pid, SIGKILL); - return 1; - } - - return 0; -} diff --git a/nptl/tst-cond13.c b/nptl/tst-cond13.c deleted file mode 100644 index 29d79b533e..0000000000 --- a/nptl/tst-cond13.c +++ /dev/null @@ -1,2 +0,0 @@ -#define USE_COND_SIGNAL 1 -#include "tst-cond12.c" diff --git a/nptl/tst-cond14.c b/nptl/tst-cond14.c deleted file mode 100644 index e2d897ac3b..0000000000 --- a/nptl/tst-cond14.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2004-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2004. - - 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 - . */ - -#include -#include -#include -#include -#include - - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER; - -static void * -tf (void *p) -{ - if (pthread_mutex_lock (&mut) != 0) - { - printf ("%s: 1st mutex_lock failed\n", __func__); - exit (1); - } - if (pthread_mutex_lock (&mut) != 0) - { - printf ("%s: 2nd mutex_lock failed\n", __func__); - exit (1); - } - if (pthread_mutex_lock (&mut) != 0) - { - printf ("%s: 3rd mutex_lock failed\n", __func__); - exit (1); - } - - if (pthread_mutex_unlock (&mut2) != 0) - { - printf ("%s: mutex_unlock failed\n", __func__); - exit (1); - } - - if (pthread_cond_wait (&cond, &mut) != 0) - { - printf ("%s: cond_wait failed\n", __func__); - exit (1); - } - - puts ("child: done"); - - return NULL; -} - - -static int -do_test (void) -{ - if (pthread_mutex_lock (&mut2) != 0) - { - puts ("1st mutex_lock failed"); - return 1; - } - - puts ("parent: create child"); - - pthread_t th; - int err = pthread_create (&th, NULL, tf, NULL); - if (err != 0) - { - printf ("parent: cannot create thread: %s\n", strerror (err)); - return 1; - } - - /* We have to synchronize with the child. */ - if (pthread_mutex_lock (&mut2) != 0) - { - puts ("2nd mutex_lock failed"); - return 1; - } - - /* Give the child to reach to pthread_cond_wait. */ - sleep (1); - - if (pthread_cond_signal (&cond) != 0) - { - puts ("cond_signal failed"); - return 1; - } - - err = pthread_join (th, NULL); - if (err != 0) - { - printf ("parent: failed to join: %s\n", strerror (err)); - return 1; - } - - puts ("done"); - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond15.c b/nptl/tst-cond15.c deleted file mode 100644 index fefab95996..0000000000 --- a/nptl/tst-cond15.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (C) 2004-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2004. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include - - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER; - -static void * -tf (void *p) -{ - if (pthread_mutex_lock (&mut) != 0) - { - printf ("%s: 1st mutex_lock failed\n", __func__); - exit (1); - } - if (pthread_mutex_lock (&mut) != 0) - { - printf ("%s: 2nd mutex_lock failed\n", __func__); - exit (1); - } - if (pthread_mutex_lock (&mut) != 0) - { - printf ("%s: 3rd mutex_lock failed\n", __func__); - exit (1); - } - - if (pthread_mutex_unlock (&mut2) != 0) - { - printf ("%s: mutex_unlock failed\n", __func__); - exit (1); - } - - struct timeval tv; - gettimeofday (&tv, NULL); - struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_sec += p == NULL ? 100 : 1; - - int err = pthread_cond_timedwait (&cond, &mut, &ts); - if ((err != 0 && p == NULL) || (err != ETIMEDOUT && p != NULL)) - { - printf ("%s: cond_wait failed\n", __func__); - exit (1); - } - - if (pthread_mutex_unlock (&mut) != 0) - { - printf ("%s: 1st mutex_unlock failed\n", __func__); - exit (1); - } - if (pthread_mutex_unlock (&mut) != 0) - { - printf ("%s: 2nd mutex_unlock failed\n", __func__); - exit (1); - } - if (pthread_mutex_unlock (&mut) != 0) - { - printf ("%s: 3rd mutex_unlock failed\n", __func__); - exit (1); - } - - puts ("child: done"); - - return NULL; -} - - -static int -do_test (void) -{ - if (pthread_mutex_lock (&mut2) != 0) - { - puts ("1st mutex_lock failed"); - return 1; - } - - puts ("parent: create 1st child"); - - pthread_t th; - int err = pthread_create (&th, NULL, tf, NULL); - if (err != 0) - { - printf ("parent: cannot 1st create thread: %s\n", strerror (err)); - return 1; - } - - /* We have to synchronize with the child. */ - if (pthread_mutex_lock (&mut2) != 0) - { - puts ("2nd mutex_lock failed"); - return 1; - } - - /* Give the child to reach to pthread_cond_wait. */ - sleep (1); - - if (pthread_cond_signal (&cond) != 0) - { - puts ("cond_signal failed"); - return 1; - } - - err = pthread_join (th, NULL); - if (err != 0) - { - printf ("parent: failed to join: %s\n", strerror (err)); - return 1; - } - - - puts ("parent: create 2nd child"); - - err = pthread_create (&th, NULL, tf, (void *) 1l); - if (err != 0) - { - printf ("parent: cannot 2nd create thread: %s\n", strerror (err)); - return 1; - } - - err = pthread_join (th, NULL); - if (err != 0) - { - printf ("parent: failed to join: %s\n", strerror (err)); - return 1; - } - - puts ("done"); - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond16.c b/nptl/tst-cond16.c deleted file mode 100644 index 61e3cbe980..0000000000 --- a/nptl/tst-cond16.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (C) 2004-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2004. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include - -pthread_cond_t cv = PTHREAD_COND_INITIALIZER; -pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; -bool n, exiting; -FILE *f; -enum { count = 8 }; /* Number of worker threads. */ - -void * -tf (void *dummy) -{ - bool loop = true; - - while (loop) - { - pthread_mutex_lock (&lock); - while (n && !exiting) - pthread_cond_wait (&cv, &lock); - n = true; - pthread_mutex_unlock (&lock); - - fputs (".", f); - - pthread_mutex_lock (&lock); - n = false; - if (exiting) - loop = false; -#ifdef UNLOCK_AFTER_BROADCAST - pthread_cond_broadcast (&cv); - pthread_mutex_unlock (&lock); -#else - pthread_mutex_unlock (&lock); - pthread_cond_broadcast (&cv); -#endif - } - - return NULL; -} - -int -do_test (void) -{ - f = fopen ("/dev/null", "w"); - if (f == NULL) - { - printf ("couldn't open /dev/null, %m\n"); - return 1; - } - - pthread_t th[count]; - pthread_attr_t attr; - int i, ret, sz; - pthread_attr_init (&attr); - sz = sysconf (_SC_PAGESIZE); - if (sz < PTHREAD_STACK_MIN) - sz = PTHREAD_STACK_MIN; - pthread_attr_setstacksize (&attr, sz); - for (i = 0; i < count; ++i) - if ((ret = pthread_create (&th[i], &attr, tf, NULL)) != 0) - { - errno = ret; - printf ("pthread_create %d failed: %m\n", i); - return 1; - } - - struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 }; - while (nanosleep (&ts, &ts) != 0); - - pthread_mutex_lock (&lock); - exiting = true; - pthread_mutex_unlock (&lock); - - for (i = 0; i < count; ++i) - pthread_join (th[i], NULL); - - fclose (f); - return 0; -} - -#define TEST_FUNCTION do_test () -#define TIMEOUT 40 -#include "../test-skeleton.c" diff --git a/nptl/tst-cond17.c b/nptl/tst-cond17.c deleted file mode 100644 index 0586fa59ac..0000000000 --- a/nptl/tst-cond17.c +++ /dev/null @@ -1,2 +0,0 @@ -#define UNLOCK_AFTER_BROADCAST 1 -#include "tst-cond16.c" diff --git a/nptl/tst-cond18.c b/nptl/tst-cond18.c deleted file mode 100644 index f984c3ce88..0000000000 --- a/nptl/tst-cond18.c +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (C) 2004-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2004. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include - -pthread_cond_t cv = PTHREAD_COND_INITIALIZER; -pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; -bool exiting; -int fd, spins, nn; -enum { count = 8 }; /* Number of worker threads. */ - -void * -tf (void *id) -{ - pthread_mutex_lock (&lock); - - if ((long) id == 0) - { - while (!exiting) - { - if ((spins++ % 1000) == 0) - write (fd, ".", 1); - pthread_mutex_unlock (&lock); - - pthread_mutex_lock (&lock); - int njobs = rand () % (count + 1); - nn = njobs; - if ((rand () % 30) == 0) - pthread_cond_broadcast (&cv); - else - while (njobs--) - pthread_cond_signal (&cv); - } - - pthread_cond_broadcast (&cv); - } - else - { - while (!exiting) - { - while (!nn && !exiting) - pthread_cond_wait (&cv, &lock); - --nn; - pthread_mutex_unlock (&lock); - - pthread_mutex_lock (&lock); - } - } - - pthread_mutex_unlock (&lock); - return NULL; -} - -int -do_test (void) -{ - fd = open ("/dev/null", O_WRONLY); - if (fd < 0) - { - printf ("couldn't open /dev/null, %m\n"); - return 1; - } - - pthread_t th[count + 1]; - pthread_attr_t attr; - int i, ret, sz; - pthread_attr_init (&attr); - sz = sysconf (_SC_PAGESIZE); - if (sz < PTHREAD_STACK_MIN) - sz = PTHREAD_STACK_MIN; - pthread_attr_setstacksize (&attr, sz); - - for (i = 0; i <= count; ++i) - if ((ret = pthread_create (&th[i], &attr, tf, (void *) (long) i)) != 0) - { - errno = ret; - printf ("pthread_create %d failed: %m\n", i); - return 1; - } - - struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 }; - while (nanosleep (&ts, &ts) != 0); - - pthread_mutex_lock (&lock); - exiting = true; - pthread_mutex_unlock (&lock); - - for (i = 0; i < count; ++i) - pthread_join (th[i], NULL); - - close (fd); - return 0; -} - -#define TEST_FUNCTION do_test () -#define TIMEOUT 40 -#include "../test-skeleton.c" diff --git a/nptl/tst-cond19.c b/nptl/tst-cond19.c deleted file mode 100644 index e6c1caeeea..0000000000 --- a/nptl/tst-cond19.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (C) 2004-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2004. - - 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 - . */ - -#include -#include -#include -#include -#include - - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - - -static int -do_test (void) -{ - int result = 0; - struct timespec ts; - - if (clock_gettime (CLOCK_REALTIME, &ts) != 0) - { - puts ("clock_gettime failed"); - return 1; - } - - ts.tv_nsec = -1; - - int e = pthread_cond_timedwait (&cond, &mut, &ts); - if (e == 0) - { - puts ("first cond_timedwait did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("first cond_timedwait did not return EINVAL"); - result = 1; - } - - ts.tv_nsec = 2000000000; - - e = pthread_cond_timedwait (&cond, &mut, &ts); - if (e == 0) - { - puts ("second cond_timedwait did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("second cond_timedwait did not return EINVAL"); - result = 1; - } - - return result; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond2.c b/nptl/tst-cond2.c deleted file mode 100644 index 6752cca05f..0000000000 --- a/nptl/tst-cond2.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include - - -static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - -static pthread_barrier_t bar; - - -static void * -tf (void *a) -{ - int i = (long int) a; - int err; - - printf ("child %d: lock\n", i); - - err = pthread_mutex_lock (&mut); - if (err != 0) - error (EXIT_FAILURE, err, "locking in child failed"); - - printf ("child %d: sync\n", i); - - int e = pthread_barrier_wait (&bar); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("child: barrier_wait failed"); - exit (1); - } - - printf ("child %d: wait\n", i); - - err = pthread_cond_wait (&cond, &mut); - if (err != 0) - error (EXIT_FAILURE, err, "child %d: failed to wait", i); - - printf ("child %d: woken up\n", i); - - err = pthread_mutex_unlock (&mut); - if (err != 0) - error (EXIT_FAILURE, err, "child %d: unlock[2] failed", i); - - printf ("child %d: done\n", i); - - return NULL; -} - - -#define N 10 - - -static int -do_test (void) -{ - pthread_t th[N]; - int i; - int err; - - printf ("&cond = %p\n&mut = %p\n", &cond, &mut); - - if (pthread_barrier_init (&bar, NULL, 2) != 0) - { - puts ("barrier_init failed"); - exit (1); - } - - pthread_attr_t at; - - if (pthread_attr_init (&at) != 0) - { - puts ("attr_init failed"); - return 1; - } - - if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0) - { - puts ("attr_setstacksize failed"); - return 1; - } - - for (i = 0; i < N; ++i) - { - printf ("create thread %d\n", i); - - err = pthread_create (&th[i], &at, tf, (void *) (long int) i); - if (err != 0) - error (EXIT_FAILURE, err, "cannot create thread %d", i); - - printf ("wait for child %d\n", i); - - /* Wait for the child to start up and get the mutex for the - conditional variable. */ - int e = pthread_barrier_wait (&bar); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("barrier_wait failed"); - exit (1); - } - } - - if (pthread_attr_destroy (&at) != 0) - { - puts ("attr_destroy failed"); - return 1; - } - - puts ("get lock outselves"); - - err = pthread_mutex_lock (&mut); - if (err != 0) - error (EXIT_FAILURE, err, "mut locking failed"); - - puts ("broadcast"); - - /* Wake up all threads. */ - err = pthread_cond_broadcast (&cond); - if (err != 0) - error (EXIT_FAILURE, err, "parent: broadcast failed"); - - err = pthread_mutex_unlock (&mut); - if (err != 0) - error (EXIT_FAILURE, err, "mut unlocking failed"); - - /* Join all threads. */ - for (i = 0; i < N; ++i) - { - printf ("join thread %d\n", i); - - err = pthread_join (th[i], NULL); - if (err != 0) - error (EXIT_FAILURE, err, "join of child %d failed", i); - } - - puts ("done"); - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c deleted file mode 100644 index 64f19ea0a5..0000000000 --- a/nptl/tst-cond22.c +++ /dev/null @@ -1,162 +0,0 @@ -#include -#include -#include - - -static pthread_barrier_t b; -static pthread_cond_t c = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; - - -static void -cl (void *arg) -{ - pthread_mutex_unlock (&m); -} - - -static void * -tf (void *arg) -{ - if (pthread_mutex_lock (&m) != 0) - { - printf ("%s: mutex_lock failed\n", __func__); - exit (1); - } - int e = pthread_barrier_wait (&b); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - printf ("%s: barrier_wait failed\n", __func__); - exit (1); - } - pthread_cleanup_push (cl, NULL); - /* We have to loop here because the cancellation might come after - the cond_wait call left the cancelable area and is then waiting - on the mutex. In this case the beginning of the second cond_wait - call will cause the cancellation to happen. */ - do - if (pthread_cond_wait (&c, &m) != 0) - { - printf ("%s: cond_wait failed\n", __func__); - exit (1); - } - while (arg == NULL); - pthread_cleanup_pop (0); - if (pthread_mutex_unlock (&m) != 0) - { - printf ("%s: mutex_unlock failed\n", __func__); - exit (1); - } - return NULL; -} - - -static int -do_test (void) -{ - int status = 0; - - if (pthread_barrier_init (&b, NULL, 2) != 0) - { - puts ("barrier_init failed"); - return 1; - } - - pthread_t th; - if (pthread_create (&th, NULL, tf, NULL) != 0) - { - puts ("1st create failed"); - return 1; - } - int e = pthread_barrier_wait (&b); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("1st barrier_wait failed"); - return 1; - } - if (pthread_mutex_lock (&m) != 0) - { - puts ("1st mutex_lock failed"); - return 1; - } - if (pthread_cond_signal (&c) != 0) - { - puts ("1st cond_signal failed"); - return 1; - } - if (pthread_cancel (th) != 0) - { - puts ("cancel failed"); - return 1; - } - if (pthread_mutex_unlock (&m) != 0) - { - puts ("1st mutex_unlock failed"); - return 1; - } - void *res; - if (pthread_join (th, &res) != 0) - { - puts ("1st join failed"); - return 1; - } - if (res != PTHREAD_CANCELED) - { - puts ("first thread not canceled"); - status = 1; - } - - printf ("cond = { %llu, %llu, %u/%u/%u, %u/%u/%u, %u, %u }\n", - c.__data.__wseq, c.__data.__g1_start, - c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0], - c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1], - c.__data.__g1_orig_size, c.__data.__wrefs); - - if (pthread_create (&th, NULL, tf, (void *) 1l) != 0) - { - puts ("2nd create failed"); - return 1; - } - e = pthread_barrier_wait (&b); - if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("2nd barrier_wait failed"); - return 1; - } - if (pthread_mutex_lock (&m) != 0) - { - puts ("2nd mutex_lock failed"); - return 1; - } - if (pthread_cond_signal (&c) != 0) - { - puts ("2nd cond_signal failed"); - return 1; - } - if (pthread_mutex_unlock (&m) != 0) - { - puts ("2nd mutex_unlock failed"); - return 1; - } - if (pthread_join (th, &res) != 0) - { - puts ("2nd join failed"); - return 1; - } - if (res != NULL) - { - puts ("2nd thread canceled"); - status = 1; - } - - printf ("cond = { %llu, %llu, %u/%u/%u, %u/%u/%u, %u, %u }\n", - c.__data.__wseq, c.__data.__g1_start, - c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0], - c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1], - c.__data.__g1_orig_size, c.__data.__wrefs); - - return status; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond23.c b/nptl/tst-cond23.c deleted file mode 100644 index 7ffe2ec1a9..0000000000 --- a/nptl/tst-cond23.c +++ /dev/null @@ -1,183 +0,0 @@ -/* Copyright (C) 2008-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2008. - - 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 - . */ - -#include -#include -#include -#include -#include - - -#if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 -static int -check (pthread_condattr_t *condattr, int pshared, clockid_t cl) -{ - clockid_t cl2; - if (pthread_condattr_getclock (condattr, &cl2) != 0) - { - puts ("condattr_getclock failed"); - return 1; - } - if (cl != cl2) - { - printf ("condattr_getclock returned wrong value: %d, expected %d\n", - (int) cl2, (int) cl); - return 1; - } - - int p; - if (pthread_condattr_getpshared (condattr, &p) != 0) - { - puts ("condattr_getpshared failed"); - return 1; - } - else if (p != pshared) - { - printf ("condattr_getpshared returned wrong value: %d, expected %d\n", - p, pshared); - return 1; - } - - return 0; -} - -static int -run_test (clockid_t cl) -{ - pthread_condattr_t condattr; - - printf ("clock = %d\n", (int) cl); - - if (pthread_condattr_init (&condattr) != 0) - { - puts ("condattr_init failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_PRIVATE, CLOCK_REALTIME)) - return 1; - - if (pthread_condattr_setpshared (&condattr, PTHREAD_PROCESS_SHARED) != 0) - { - puts ("1st condattr_setpshared failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_SHARED, CLOCK_REALTIME)) - return 1; - - if (pthread_condattr_setclock (&condattr, cl) != 0) - { - puts ("1st condattr_setclock failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_SHARED, cl)) - return 1; - - if (pthread_condattr_setpshared (&condattr, PTHREAD_PROCESS_PRIVATE) != 0) - { - puts ("2nd condattr_setpshared failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_PRIVATE, cl)) - return 1; - - if (pthread_condattr_setclock (&condattr, CLOCK_REALTIME) != 0) - { - puts ("2nd condattr_setclock failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_PRIVATE, CLOCK_REALTIME)) - return 1; - - if (pthread_condattr_setclock (&condattr, cl) != 0) - { - puts ("3rd condattr_setclock failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_PRIVATE, cl)) - return 1; - - if (pthread_condattr_setpshared (&condattr, PTHREAD_PROCESS_SHARED) != 0) - { - puts ("3rd condattr_setpshared failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_SHARED, cl)) - return 1; - - if (pthread_condattr_setclock (&condattr, CLOCK_REALTIME) != 0) - { - puts ("4th condattr_setclock failed"); - return 1; - } - - if (check (&condattr, PTHREAD_PROCESS_SHARED, CLOCK_REALTIME)) - return 1; - - if (pthread_condattr_destroy (&condattr) != 0) - { - puts ("condattr_destroy failed"); - return 1; - } - - return 0; -} -#endif - - -static int -do_test (void) -{ -#if !defined _POSIX_CLOCK_SELECTION || _POSIX_CLOCK_SELECTION == -1 - - puts ("_POSIX_CLOCK_SELECTION not supported, test skipped"); - return 0; - -#else - - int res = run_test (CLOCK_REALTIME); - -# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 -# if _POSIX_MONOTONIC_CLOCK == 0 - int e = sysconf (_SC_MONOTONIC_CLOCK); - if (e < 0) - puts ("CLOCK_MONOTONIC not supported"); - else if (e == 0) - { - puts ("sysconf (_SC_MONOTONIC_CLOCK) must not return 0"); - res = 1; - } - else -# endif - res |= run_test (CLOCK_MONOTONIC); -# else - puts ("_POSIX_MONOTONIC_CLOCK not defined"); -# endif - - return res; -#endif -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond24.c b/nptl/tst-cond24.c deleted file mode 100644 index a2896f32cc..0000000000 --- a/nptl/tst-cond24.c +++ /dev/null @@ -1,248 +0,0 @@ -/* Verify that condition variables synchronized by PI mutexes don't hang. - Copyright (C) 2012-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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define THREADS_NUM 5 -#define MAXITER 50000 - -static pthread_mutex_t mutex; -static pthread_mutexattr_t mutex_attr; -static pthread_cond_t cond; -static pthread_t threads[THREADS_NUM]; -static int pending = 0; - -typedef void * (*threadfunc) (void *); - -void * -thread_fun_timed (void *arg) -{ - int *ret = arg; - int rv, i; - - printf ("Started thread_fun_timed[%d]\n", *ret); - - for (i = 0; i < MAXITER / THREADS_NUM; i++) - { - rv = pthread_mutex_lock (&mutex); - if (rv) - { - printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); - *ret = 1; - goto out; - } - - while (!pending) - { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += 20; - rv = pthread_cond_timedwait (&cond, &mutex, &ts); - - /* There should be no timeout either. */ - if (rv) - { - printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv); - *ret = 1; - goto out; - } - } - - pending--; - - rv = pthread_mutex_unlock (&mutex); - if (rv) - { - printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); - *ret = 1; - goto out; - } - } - - *ret = 0; - -out: - return ret; -} - -void * -thread_fun (void *arg) -{ - int *ret = arg; - int rv, i; - - printf ("Started thread_fun[%d]\n", *ret); - - for (i = 0; i < MAXITER / THREADS_NUM; i++) - { - rv = pthread_mutex_lock (&mutex); - if (rv) - { - printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); - *ret = 1; - goto out; - } - - while (!pending) - { - rv = pthread_cond_wait (&cond, &mutex); - - if (rv) - { - printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv); - *ret = 1; - goto out; - } - } - - pending--; - - rv = pthread_mutex_unlock (&mutex); - if (rv) - { - printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); - *ret = 1; - goto out; - } - } - - *ret = 0; - -out: - return ret; -} - -static int -do_test_wait (threadfunc f) -{ - int i; - int rv; - int counter = 0; - int retval[THREADS_NUM]; - - puts ("Starting test"); - - rv = pthread_mutexattr_init (&mutex_attr); - if (rv) - { - printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv); - return 1; - } - - rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT); - if (rv) - { - printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv); - return 1; - } - - rv = pthread_mutex_init (&mutex, &mutex_attr); - if (rv) - { - printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv); - return 1; - } - - rv = pthread_cond_init (&cond, NULL); - if (rv) - { - printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv); - return 1; - } - - for (i = 0; i < THREADS_NUM; i++) - { - retval[i] = i; - rv = pthread_create (&threads[i], NULL, f, &retval[i]); - if (rv) - { - printf ("pthread_create: %s(%d)\n", strerror (rv), rv); - return 1; - } - } - - for (; counter < MAXITER; counter++) - { - rv = pthread_mutex_lock (&mutex); - if (rv) - { - printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); - return 1; - } - - if (!(counter % 100)) - printf ("counter: %d\n", counter); - pending += 1; - - rv = pthread_cond_signal (&cond); - if (rv) - { - printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv); - return 1; - } - - rv = pthread_mutex_unlock (&mutex); - if (rv) - { - printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); - return 1; - } - } - - for (i = 0; i < THREADS_NUM; i++) - { - void *ret; - rv = pthread_join (threads[i], &ret); - if (rv) - { - printf ("pthread_join: %s(%d)\n", strerror (rv), rv); - return 1; - } - if (ret && *(int *)ret) - { - printf ("Thread %d returned with an error\n", i); - return 1; - } - } - - return 0; -} - -static int -do_test (void) -{ - puts ("Testing pthread_cond_wait"); - int ret = do_test_wait (thread_fun); - if (ret) - return ret; - - puts ("Testing pthread_cond_timedwait"); - return do_test_wait (thread_fun_timed); -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond25.c b/nptl/tst-cond25.c deleted file mode 100644 index 72954f893c..0000000000 --- a/nptl/tst-cond25.c +++ /dev/null @@ -1,288 +0,0 @@ -/* Verify that condition variables synchronized by PI mutexes don't hang on - on cancellation. - Copyright (C) 2012-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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUM 5 -#define ITERS 10000 -#define COUNT 100 - -typedef void *(*thr_func) (void *); - -pthread_mutex_t mutex; -pthread_cond_t cond; - -void cleanup (void *u) -{ - /* pthread_cond_wait should always return with the mutex locked. The - pthread_mutex_unlock implementation does not actually check whether we - own the mutex for several mutex kinds, so check this explicitly. */ - int ret = pthread_mutex_trylock (&mutex); - if (ret != EDEADLK && ret != EBUSY) - { - printf ("mutex not locked in cleanup %d\n", ret); - abort (); - } - if (pthread_mutex_unlock (&mutex)) - abort (); -} - -void * -signaller (void *u) -{ - int i, ret = 0; - void *tret = NULL; - - for (i = 0; i < ITERS; i++) - { - if ((ret = pthread_mutex_lock (&mutex)) != 0) - { - tret = (void *)1; - printf ("signaller:mutex_lock failed: %s\n", strerror (ret)); - goto out; - } - if ((ret = pthread_cond_signal (&cond)) != 0) - { - tret = (void *)1; - printf ("signaller:signal failed: %s\n", strerror (ret)); - goto unlock_out; - } - if ((ret = pthread_mutex_unlock (&mutex)) != 0) - { - tret = (void *)1; - printf ("signaller:mutex_unlock failed: %s\n", strerror (ret)); - goto out; - } - pthread_testcancel (); - } - -out: - return tret; - -unlock_out: - if ((ret = pthread_mutex_unlock (&mutex)) != 0) - printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret)); - goto out; -} - -void * -waiter (void *u) -{ - int i, ret = 0; - void *tret = NULL; - int seq = (uintptr_t) u; - - for (i = 0; i < ITERS / NUM; i++) - { - if ((ret = pthread_mutex_lock (&mutex)) != 0) - { - tret = (void *) (uintptr_t) 1; - printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret)); - goto out; - } - pthread_cleanup_push (cleanup, NULL); - - if ((ret = pthread_cond_wait (&cond, &mutex)) != 0) - { - tret = (void *) (uintptr_t) 1; - printf ("waiter[%u]:wait failed: %s\n", seq, strerror (ret)); - goto unlock_out; - } - - if ((ret = pthread_mutex_unlock (&mutex)) != 0) - { - tret = (void *) (uintptr_t) 1; - printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret)); - goto out; - } - pthread_cleanup_pop (0); - } - -out: - puts ("waiter tests done"); - return tret; - -unlock_out: - if ((ret = pthread_mutex_unlock (&mutex)) != 0) - printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret)); - goto out; -} - -void * -timed_waiter (void *u) -{ - int i, ret; - void *tret = NULL; - int seq = (uintptr_t) u; - - for (i = 0; i < ITERS / NUM; i++) - { - struct timespec ts; - - if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0) - { - tret = (void *) (uintptr_t) 1; - printf ("%u:clock_gettime failed: %s\n", seq, strerror (errno)); - goto out; - } - ts.tv_sec += 20; - - if ((ret = pthread_mutex_lock (&mutex)) != 0) - { - tret = (void *) (uintptr_t) 1; - printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret)); - goto out; - } - pthread_cleanup_push (cleanup, NULL); - - /* We should not time out either. */ - if ((ret = pthread_cond_timedwait (&cond, &mutex, &ts)) != 0) - { - tret = (void *) (uintptr_t) 1; - printf ("waiter[%u]:timedwait failed: %s\n", seq, strerror (ret)); - goto unlock_out; - } - if ((ret = pthread_mutex_unlock (&mutex)) != 0) - { - tret = (void *) (uintptr_t) 1; - printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret)); - goto out; - } - pthread_cleanup_pop (0); - } - -out: - puts ("timed_waiter tests done"); - return tret; - -unlock_out: - if ((ret = pthread_mutex_unlock (&mutex)) != 0) - printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror (ret)); - goto out; -} - -int -do_test_wait (thr_func f) -{ - pthread_t w[NUM]; - pthread_t s; - pthread_mutexattr_t attr; - int i, j, ret = 0; - void *thr_ret; - - for (i = 0; i < COUNT; i++) - { - if ((ret = pthread_mutexattr_init (&attr)) != 0) - { - printf ("mutexattr_init failed: %s\n", strerror (ret)); - goto out; - } - - if ((ret = pthread_mutexattr_setprotocol (&attr, - PTHREAD_PRIO_INHERIT)) != 0) - { - printf ("mutexattr_setprotocol failed: %s\n", strerror (ret)); - goto out; - } - - if ((ret = pthread_cond_init (&cond, NULL)) != 0) - { - printf ("cond_init failed: %s\n", strerror (ret)); - goto out; - } - - if ((ret = pthread_mutex_init (&mutex, &attr)) != 0) - { - printf ("mutex_init failed: %s\n", strerror (ret)); - goto out; - } - - for (j = 0; j < NUM; j++) - if ((ret = pthread_create (&w[j], NULL, - f, (void *) (uintptr_t) j)) != 0) - { - printf ("waiter[%d]: create failed: %s\n", j, strerror (ret)); - goto out; - } - - if ((ret = pthread_create (&s, NULL, signaller, NULL)) != 0) - { - printf ("signaller: create failed: %s\n", strerror (ret)); - goto out; - } - - for (j = 0; j < NUM; j++) - { - pthread_cancel (w[j]); - - if ((ret = pthread_join (w[j], &thr_ret)) != 0) - { - printf ("waiter[%d]: join failed: %s\n", j, strerror (ret)); - goto out; - } - - if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED) - { - ret = 1; - goto out; - } - } - - /* The signalling thread could have ended before it was cancelled. */ - pthread_cancel (s); - - if ((ret = pthread_join (s, &thr_ret)) != 0) - { - printf ("signaller: join failed: %s\n", strerror (ret)); - goto out; - } - - if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED) - { - ret = 1; - goto out; - } - } - -out: - return ret; -} - -int -do_test (int argc, char **argv) -{ - int ret = do_test_wait (waiter); - - if (ret) - return ret; - - return do_test_wait (timed_waiter); -} - -#include "../test-skeleton.c" diff --git a/nptl/tst-cond26.c b/nptl/tst-cond26.c deleted file mode 100644 index e647da00c2..0000000000 --- a/nptl/tst-cond26.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Test unsupported/bad clocks passed to pthread_cond_clockwait. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - -#define NOT_A_VALID_CLOCK 123456 - -static int -do_test (void) -{ - xpthread_mutex_lock (&mut); - - const struct timespec ts = make_timespec (0, 0); - - /* These clocks are meaningless to sem_clockwait. */ -#if defined(CLOCK_PROCESS_CPUTIME_ID) - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, - CLOCK_PROCESS_CPUTIME_ID, &ts), EINVAL); -#endif -#if defined(CLOCK_THREAD_CPUTIME_ID) - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, - CLOCK_THREAD_CPUTIME_ID, &ts), EINVAL); -#endif - - /* These clocks might be meaningful, but are currently unsupported - by pthread_cond_clockwait. */ -#if defined(CLOCK_REALTIME_COARSE) - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, - CLOCK_REALTIME_COARSE, &ts), EINVAL); -#endif -#if defined(CLOCK_MONOTONIC_RAW) - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, - CLOCK_MONOTONIC_RAW, &ts), EINVAL); -#endif -#if defined(CLOCK_MONOTONIC_COARSE) - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, - CLOCK_MONOTONIC_COARSE, &ts), EINVAL); -#endif -#if defined(CLOCK_BOOTTIME) - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, - CLOCK_BOOTTIME, &ts), EINVAL); -#endif - - /* This is a completely invalid clock. */ - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, - NOT_A_VALID_CLOCK, &ts), EINVAL); - - return 0; -} - -#include diff --git a/nptl/tst-cond27.c b/nptl/tst-cond27.c deleted file mode 100644 index c8142abf9e..0000000000 --- a/nptl/tst-cond27.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Test pthread_cond_clockwait timeout. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - - -static int -do_test_clock (clockid_t clockid) -{ - /* Get the mutex. */ - xpthread_mutex_lock (&mut); - - /* Waiting for the condition will fail. But we want the timeout here. */ - const struct timespec ts_now = xclock_now (clockid); - const struct timespec ts_timeout = - timespec_add (ts_now, make_timespec (0, 500000000)); - - /* In theory pthread_cond_clockwait could return zero here due to - spurious wakeup. However that can't happen without a signal or an - additional waiter. */ - TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, clockid, &ts_timeout), - ETIMEDOUT); - - xpthread_mutex_unlock (&mut); - - return 0; -} - -static int -do_test (void) -{ - do_test_clock (CLOCK_MONOTONIC); - do_test_clock (CLOCK_REALTIME); - return 0; -} - -#include diff --git a/nptl/tst-cond3.c b/nptl/tst-cond3.c deleted file mode 100644 index fb4209d0bb..0000000000 --- a/nptl/tst-cond3.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include -#include - -static int do_test (void); - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" - -/* Note that this test requires more than the standard. It is - required that there are no spurious wakeups if only more readers - are added. This is a reasonable demand. */ - - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - - -#define N 10 - - -static void * -tf (void *arg) -{ - int i = (long int) arg; - int err; - - /* Get the mutex. */ - err = pthread_mutex_lock (&mut); - if (err != 0) - { - printf ("child %d mutex_lock failed: %s\n", i, strerror (err)); - exit (1); - } - - /* This call should never return. */ - xpthread_cond_wait (&cond, &mut); - puts ("error: pthread_cond_wait in tf returned"); - - /* We should never get here. */ - exit (1); - - return NULL; -} - - -static int -do_test (void) -{ - int err; - int i; - - for (i = 0; i < N; ++i) - { - pthread_t th; - - if (i != 0) - { - /* Release the mutex. */ - err = pthread_mutex_unlock (&mut); - if (err != 0) - { - printf ("mutex_unlock %d failed: %s\n", i, strerror (err)); - return 1; - } - } - - err = pthread_create (&th, NULL, tf, (void *) (long int) i); - if (err != 0) - { - printf ("create %d failed: %s\n", i, strerror (err)); - return 1; - } - - /* Get the mutex. */ - err = pthread_mutex_lock (&mut); - if (err != 0) - { - printf ("mutex_lock %d failed: %s\n", i, strerror (err)); - return 1; - } - } - - delayed_exit (1); - - /* This call should never return. */ - xpthread_cond_wait (&cond, &mut); - - puts ("error: pthread_cond_wait in do_test returned"); - return 1; -} diff --git a/nptl/tst-cond4.c b/nptl/tst-cond4.c deleted file mode 100644 index 4d4bad3a76..0000000000 --- a/nptl/tst-cond4.c +++ /dev/null @@ -1,263 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int *condition; - -static int -do_test (void) -{ - size_t ps = sysconf (_SC_PAGESIZE); - char tmpfname[] = "/tmp/tst-cond4.XXXXXX"; - char data[ps]; - void *mem; - int fd; - pthread_mutexattr_t ma; - pthread_mutex_t *mut1; - pthread_mutex_t *mut2; - pthread_condattr_t ca; - pthread_cond_t *cond; - pid_t pid; - int result = 0; - int p; - - 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; - } - - mut1 = (pthread_mutex_t *) (((uintptr_t) mem - + __alignof (pthread_mutex_t)) - & ~(__alignof (pthread_mutex_t) - 1)); - mut2 = mut1 + 1; - - cond = (pthread_cond_t *) (((uintptr_t) (mut2 + 1) - + __alignof (pthread_cond_t)) - & ~(__alignof (pthread_cond_t) - 1)); - - condition = (int *) (((uintptr_t) (cond + 1) + __alignof (int)) - & ~(__alignof (int) - 1)); - - if (pthread_mutexattr_init (&ma) != 0) - { - puts ("mutexattr_init failed"); - return 1; - } - - if (pthread_mutexattr_getpshared (&ma, &p) != 0) - { - puts ("1st mutexattr_getpshared failed"); - return 1; - } - - if (p != PTHREAD_PROCESS_PRIVATE) - { - puts ("default pshared value wrong"); - return 1; - } - - if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0) - { - puts ("mutexattr_setpshared failed"); - return 1; - } - - if (pthread_mutexattr_getpshared (&ma, &p) != 0) - { - puts ("2nd mutexattr_getpshared failed"); - return 1; - } - - if (p != PTHREAD_PROCESS_SHARED) - { - puts ("pshared value after setpshared call wrong"); - return 1; - } - - if (pthread_mutex_init (mut1, &ma) != 0) - { - puts ("1st mutex_init failed"); - return 1; - } - - if (pthread_mutex_init (mut2, &ma) != 0) - { - puts ("2nd mutex_init failed"); - return 1; - } - - if (pthread_condattr_init (&ca) != 0) - { - puts ("condattr_init failed"); - return 1; - } - - if (pthread_condattr_getpshared (&ca, &p) != 0) - { - puts ("1st condattr_getpshared failed"); - return 1; - } - - if (p != PTHREAD_PROCESS_PRIVATE) - { - puts ("default value for pshared in condattr wrong"); - return 1; - } - - if (pthread_condattr_setpshared (&ca, PTHREAD_PROCESS_SHARED) != 0) - { - puts ("condattr_setpshared failed"); - return 1; - } - - if (pthread_condattr_getpshared (&ca, &p) != 0) - { - puts ("2nd condattr_getpshared failed"); - return 1; - } - - if (p != PTHREAD_PROCESS_SHARED) - { - puts ("pshared condattr still not set"); - return 1; - } - - if (pthread_cond_init (cond, &ca) != 0) - { - puts ("cond_init failed"); - return 1; - } - - if (pthread_mutex_lock (mut1) != 0) - { - puts ("parent: 1st mutex_lock failed"); - return 1; - } - - puts ("going to fork now"); - pid = fork (); - if (pid == -1) - { - puts ("fork failed"); - return 1; - } - else if (pid == 0) - { - if (pthread_mutex_lock (mut2) != 0) - { - puts ("child: mutex_lock failed"); - return 1; - } - - if (pthread_mutex_unlock (mut1) != 0) - { - puts ("child: 1st mutex_unlock failed"); - return 1; - } - - do - if (pthread_cond_wait (cond, mut2) != 0) - { - puts ("child: cond_wait failed"); - return 1; - } - while (*condition == 0); - - if (pthread_mutex_unlock (mut2) != 0) - { - puts ("child: 2nd mutex_unlock failed"); - return 1; - } - - puts ("child done"); - } - else - { - int status; - - if (pthread_mutex_lock (mut1) != 0) - { - puts ("parent: 2nd mutex_lock failed"); - return 1; - } - - if (pthread_mutex_lock (mut2) != 0) - { - puts ("parent: 3rd mutex_lock failed"); - return 1; - } - - if (pthread_cond_signal (cond) != 0) - { - puts ("parent: cond_signal failed"); - return 1; - } - - *condition = 1; - - if (pthread_mutex_unlock (mut2) != 0) - { - puts ("parent: mutex_unlock failed"); - return 1; - } - - puts ("waiting for child"); - - waitpid (pid, &status, 0); - result |= status; - - puts ("parent done"); - } - - return result; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond5.c b/nptl/tst-cond5.c deleted file mode 100644 index e2ea541c46..0000000000 --- a/nptl/tst-cond5.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include -#include -#include -#include - - -static pthread_mutex_t mut; -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - - -static int -do_test (void) -{ - pthread_mutexattr_t ma; - int err; - struct timespec ts; - struct timeval tv; - - if (pthread_mutexattr_init (&ma) != 0) - { - puts ("mutexattr_init failed"); - exit (1); - } - - if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0) - { - puts ("mutexattr_settype failed"); - exit (1); - } - - if (pthread_mutex_init (&mut, &ma) != 0) - { - puts ("mutex_init failed"); - exit (1); - } - - /* Get the mutex. */ - if (pthread_mutex_lock (&mut) != 0) - { - puts ("mutex_lock failed"); - exit (1); - } - - /* Waiting for the condition will fail. But we want the timeout here. */ - if (gettimeofday (&tv, NULL) != 0) - { - puts ("gettimeofday failed"); - exit (1); - } - - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_nsec += 500000000; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } - err = pthread_cond_timedwait (&cond, &mut, &ts); - if (err == 0) - { - /* This could in theory happen but here without any signal and - additional waiter it should not. */ - puts ("cond_timedwait succeeded"); - exit (1); - } - else if (err != ETIMEDOUT) - { - printf ("cond_timedwait returned with %s\n", strerror (err)); - exit (1); - } - - err = pthread_mutex_unlock (&mut); - if (err != 0) - { - printf ("mutex_unlock failed: %s\n", strerror (err)); - exit (1); - } - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond6.c b/nptl/tst-cond6.c deleted file mode 100644 index 0c9426d0d7..0000000000 --- a/nptl/tst-cond6.c +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int *condition; - -static int -do_test (void) -{ - size_t ps = sysconf (_SC_PAGESIZE); - char tmpfname[] = "/tmp/tst-cond6.XXXXXX"; - char data[ps]; - void *mem; - int fd; - pthread_mutexattr_t ma; - pthread_mutex_t *mut1; - pthread_mutex_t *mut2; - pthread_condattr_t ca; - pthread_cond_t *cond; - pid_t pid; - int result = 0; - - fd = mkstemp (tmpfname); - if (fd == -1) - { - printf ("cannot open temporary file: %m\n"); - exit (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"); - exit (1); - } - - mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (mem == MAP_FAILED) - { - printf ("mmap failed: %m\n"); - exit (1); - } - - mut1 = (pthread_mutex_t *) (((uintptr_t) mem - + __alignof (pthread_mutex_t)) - & ~(__alignof (pthread_mutex_t) - 1)); - mut2 = mut1 + 1; - - cond = (pthread_cond_t *) (((uintptr_t) (mut2 + 1) - + __alignof (pthread_cond_t)) - & ~(__alignof (pthread_cond_t) - 1)); - - condition = (int *) (((uintptr_t) (cond + 1) + __alignof (int)) - & ~(__alignof (int) - 1)); - - if (pthread_mutexattr_init (&ma) != 0) - { - puts ("mutexattr_init failed"); - exit (1); - } - - if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0) - { - puts ("mutexattr_setpshared failed"); - exit (1); - } - - if (pthread_mutex_init (mut1, &ma) != 0) - { - puts ("1st mutex_init failed"); - exit (1); - } - - if (pthread_mutex_init (mut2, &ma) != 0) - { - puts ("2nd mutex_init failed"); - exit (1); - } - - if (pthread_condattr_init (&ca) != 0) - { - puts ("condattr_init failed"); - exit (1); - } - - if (pthread_condattr_setpshared (&ca, PTHREAD_PROCESS_SHARED) != 0) - { - puts ("condattr_setpshared failed"); - exit (1); - } - - if (pthread_cond_init (cond, &ca) != 0) - { - puts ("cond_init failed"); - exit (1); - } - - if (pthread_mutex_lock (mut1) != 0) - { - puts ("parent: 1st mutex_lock failed"); - exit (1); - } - - puts ("going to fork now"); - pid = fork (); - if (pid == -1) - { - puts ("fork failed"); - exit (1); - } - else if (pid == 0) - { - struct timespec ts; - struct timeval tv; - - if (pthread_mutex_lock (mut2) != 0) - { - puts ("child: mutex_lock failed"); - exit (1); - } - - if (pthread_mutex_unlock (mut1) != 0) - { - puts ("child: 1st mutex_unlock failed"); - exit (1); - } - - if (gettimeofday (&tv, NULL) != 0) - { - puts ("gettimeofday failed"); - exit (1); - } - - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_nsec += 500000000; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } - - do - if (pthread_cond_timedwait (cond, mut2, &ts) != 0) - { - puts ("child: cond_wait failed"); - exit (1); - } - while (*condition == 0); - - if (pthread_mutex_unlock (mut2) != 0) - { - puts ("child: 2nd mutex_unlock failed"); - exit (1); - } - - puts ("child done"); - } - else - { - int status; - - if (pthread_mutex_lock (mut1) != 0) - { - puts ("parent: 2nd mutex_lock failed"); - exit (1); - } - - if (pthread_mutex_lock (mut2) != 0) - { - puts ("parent: 3rd mutex_lock failed"); - exit (1); - } - - if (pthread_cond_signal (cond) != 0) - { - puts ("parent: cond_signal failed"); - exit (1); - } - - *condition = 1; - - if (pthread_mutex_unlock (mut2) != 0) - { - puts ("parent: mutex_unlock failed"); - exit (1); - } - - puts ("waiting for child"); - - waitpid (pid, &status, 0); - result |= status; - - puts ("parent done"); - } - - return result; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond7.c b/nptl/tst-cond7.c deleted file mode 100644 index 48502bd720..0000000000 --- a/nptl/tst-cond7.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef struct - { - pthread_cond_t cond; - pthread_mutex_t lock; - pthread_t h; - } T; - - -static volatile bool done; - - -static void * -tf (void *arg) -{ - puts ("child created"); - - if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0 - || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0) - { - puts ("cannot set cancellation options"); - exit (1); - } - - T *t = (T *) arg; - - if (pthread_mutex_lock (&t->lock) != 0) - { - puts ("child: lock failed"); - exit (1); - } - - done = true; - - if (pthread_cond_signal (&t->cond) != 0) - { - puts ("child: cond_signal failed"); - exit (1); - } - - if (pthread_cond_wait (&t->cond, &t->lock) != 0) - { - puts ("child: cond_wait failed"); - exit (1); - } - - if (pthread_mutex_unlock (&t->lock) != 0) - { - puts ("child: unlock failed"); - exit (1); - } - - return NULL; -} - - -static int -do_test (void) -{ - int i; -#define N 100 - T *t[N]; - for (i = 0; i < N; ++i) - { - printf ("round %d\n", i); - - t[i] = (T *) malloc (sizeof (T)); - if (t[i] == NULL) - { - puts ("out of memory"); - exit (1); - } - - if (pthread_mutex_init (&t[i]->lock, NULL) != 0 - || pthread_cond_init (&t[i]->cond, NULL) != 0) - { - puts ("an _init function failed"); - exit (1); - } - - if (pthread_mutex_lock (&t[i]->lock) != 0) - { - puts ("initial mutex_lock failed"); - exit (1); - } - - done = false; - - if (pthread_create (&t[i]->h, NULL, tf, t[i]) != 0) - { - puts ("pthread_create failed"); - exit (1); - } - - do - if (pthread_cond_wait (&t[i]->cond, &t[i]->lock) != 0) - { - puts ("cond_wait failed"); - exit (1); - } - while (! done); - - /* Release the lock since the cancel handler will get it. */ - if (pthread_mutex_unlock (&t[i]->lock) != 0) - { - puts ("mutex_unlock failed"); - exit (1); - } - - if (pthread_cancel (t[i]->h) != 0) - { - puts ("cancel failed"); - exit (1); - } - - puts ("parent: joining now"); - - void *result; - if (pthread_join (t[i]->h, &result) != 0) - { - puts ("join failed"); - exit (1); - } - - if (result != PTHREAD_CANCELED) - { - puts ("result != PTHREAD_CANCELED"); - exit (1); - } - } - - for (i = 0; i < N; ++i) - free (t[i]); - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond8-static.c b/nptl/tst-cond8-static.c deleted file mode 100644 index fed35db60d..0000000000 --- a/nptl/tst-cond8-static.c +++ /dev/null @@ -1 +0,0 @@ -#include "tst-cond8.c" diff --git a/nptl/tst-cond8.c b/nptl/tst-cond8.c deleted file mode 100644 index 61f7583844..0000000000 --- a/nptl/tst-cond8.c +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - 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 - . */ - -#include -#include -#include -#include -#include -#include - - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; - -static pthread_barrier_t bar; - - -static void -ch (void *arg) -{ - int e = pthread_mutex_lock (&mut); - if (e == 0) - { - puts ("mutex not locked at all by cond_wait"); - exit (1); - } - - if (e != EDEADLK) - { - puts ("no deadlock error signaled"); - exit (1); - } - - if (pthread_mutex_unlock (&mut) != 0) - { - puts ("ch: cannot unlock mutex"); - exit (1); - } - - puts ("ch done"); -} - - -static void * -tf1 (void *p) -{ - int err; - - if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0 - || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0) - { - puts ("cannot set cancellation options"); - exit (1); - } - - err = pthread_mutex_lock (&mut); - if (err != 0) - { - puts ("child: cannot get mutex"); - exit (1); - } - - err = pthread_barrier_wait (&bar); - if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) - { - printf ("barrier_wait returned %d\n", err); - exit (1); - } - - puts ("child: got mutex; waiting"); - - pthread_cleanup_push (ch, NULL); - - pthread_cond_wait (&cond, &mut); - - pthread_cleanup_pop (0); - - puts ("child: cond_wait should not have returned"); - - return NULL; -} - - -static void * -tf2 (void *p) -{ - int err; - - if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0 - || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0) - { - puts ("cannot set cancellation options"); - exit (1); - } - - err = pthread_mutex_lock (&mut); - if (err != 0) - { - puts ("child: cannot get mutex"); - exit (1); - } - - err = pthread_barrier_wait (&bar); - if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) - { - printf ("barrier_wait returned %d\n", err); - exit (1); - } - - puts ("child: got mutex; waiting"); - - pthread_cleanup_push (ch, NULL); - - /* Current time. */ - struct timeval tv; - (void) gettimeofday (&tv, NULL); - /* +1000 seconds in correct format. */ - struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_sec += 1000; - - pthread_cond_timedwait (&cond, &mut, &ts); - - pthread_cleanup_pop (0); - - puts ("child: cond_wait should not have returned"); - - return NULL; -} - - -static int -do_test (void) -{ - pthread_t th; - int err; - - printf ("&cond = %p\n&mut = %p\n", &cond, &mut); - - puts ("parent: get mutex"); - - err = pthread_barrier_init (&bar, NULL, 2); - if (err != 0) - { - puts ("parent: cannot init barrier"); - exit (1); - } - - puts ("parent: create child"); - - err = pthread_create (&th, NULL, tf1, NULL); - if (err != 0) - { - puts ("parent: cannot create thread"); - exit (1); - } - - puts ("parent: wait for child to lock mutex"); - - err = pthread_barrier_wait (&bar); - if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("parent: cannot wait for barrier"); - exit (1); - } - - err = pthread_mutex_lock (&mut); - if (err != 0) - { - puts ("parent: mutex_lock failed"); - exit (1); - } - - err = pthread_mutex_unlock (&mut); - if (err != 0) - { - puts ("parent: mutex_unlock failed"); - exit (1); - } - - if (pthread_cancel (th) != 0) - { - puts ("cannot cancel thread"); - exit (1); - } - - void *r; - err = pthread_join (th, &r); - if (err != 0) - { - puts ("parent: failed to join"); - exit (1); - } - - if (r != PTHREAD_CANCELED) - { - puts ("child hasn't been canceled"); - exit (1); - } - - - - puts ("parent: create 2nd child"); - - err = pthread_create (&th, NULL, tf2, NULL); - if (err != 0) - { - puts ("parent: cannot create thread"); - exit (1); - } - - puts ("parent: wait for child to lock mutex"); - - err = pthread_barrier_wait (&bar); - if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) - { - puts ("parent: cannot wait for barrier"); - exit (1); - } - - err = pthread_mutex_lock (&mut); - if (err != 0) - { - puts ("parent: mutex_lock failed"); - exit (1); - } - - err = pthread_mutex_unlock (&mut); - if (err != 0) - { - puts ("parent: mutex_unlock failed"); - exit (1); - } - - if (pthread_cancel (th) != 0) - { - puts ("cannot cancel thread"); - exit (1); - } - - err = pthread_join (th, &r); - if (err != 0) - { - puts ("parent: failed to join"); - exit (1); - } - - if (r != PTHREAD_CANCELED) - { - puts ("child hasn't been canceled"); - exit (1); - } - - puts ("done"); - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-cond9.c b/nptl/tst-cond9.c deleted file mode 100644 index e83870d393..0000000000 --- a/nptl/tst-cond9.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (C) 2003-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2003. - - 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 - . */ - -#include -#include -#include -#include -#include -#include - - -static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; - - -static void * -tf (void *arg) -{ - int err = pthread_cond_wait (&cond, &mut); - if (err == 0) - { - puts ("cond_wait did not fail"); - exit (1); - } - - if (err != EPERM) - { - printf ("cond_wait didn't return EPERM but %d\n", err); - exit (1); - } - - - /* Current time. */ - struct timeval tv; - (void) gettimeofday (&tv, NULL); - /* +1000 seconds in correct format. */ - struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_sec += 1000; - - err = pthread_cond_timedwait (&cond, &mut, &ts); - if (err == 0) - { - puts ("cond_timedwait did not fail"); - exit (1); - } - - if (err != EPERM) - { - printf ("cond_timedwait didn't return EPERM but %d\n", err); - exit (1); - } - - return (void *) 1l; -} - - -static int -do_test (void) -{ - pthread_t th; - int err; - - printf ("&cond = %p\n&mut = %p\n", &cond, &mut); - - err = pthread_cond_wait (&cond, &mut); - if (err == 0) - { - puts ("cond_wait did not fail"); - exit (1); - } - - if (err != EPERM) - { - printf ("cond_wait didn't return EPERM but %d\n", err); - exit (1); - } - - - /* Current time. */ - struct timeval tv; - (void) gettimeofday (&tv, NULL); - /* +1000 seconds in correct format. */ - struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_sec += 1000; - - err = pthread_cond_timedwait (&cond, &mut, &ts); - if (err == 0) - { - puts ("cond_timedwait did not fail"); - exit (1); - } - - if (err != EPERM) - { - printf ("cond_timedwait didn't return EPERM but %d\n", err); - exit (1); - } - - if (pthread_mutex_lock (&mut) != 0) - { - puts ("parent: mutex_lock failed"); - exit (1); - } - - puts ("creating thread"); - - if (pthread_create (&th, NULL, tf, NULL) != 0) - { - puts ("create failed"); - exit (1); - } - - void *r; - if (pthread_join (th, &r) != 0) - { - puts ("join failed"); - exit (1); - } - if (r != (void *) 1l) - { - puts ("thread has wrong return value"); - exit (1); - } - - puts ("done"); - - return 0; -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/sysdeps/mach/hurd/i386/Makefile b/sysdeps/mach/hurd/i386/Makefile index 584d9275c9..fa89fc1cf8 100644 --- a/sysdeps/mach/hurd/i386/Makefile +++ b/sysdeps/mach/hurd/i386/Makefile @@ -104,6 +104,17 @@ endif # For bug 25521 ifeq ($(subdir),htl) test-xfail-tst-mutex4 = yes +test-xfail-tst-cond4 = yes +test-xfail-tst-cond6 = yes +test-xfail-tst-cond12 = yes +test-xfail-tst-cond13 = yes +test-xfail-tst-cond23 = yes +endif + +# For bug 25522 +ifeq ($(subdir),htl) +test-xfail-tst-cond24 = yes +test-xfail-tst-cond25 = yes endif ifeq ($(subdir),elf) diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index 5117110210..2c33c5c904 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -45,7 +45,17 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ tst-attr1 \ tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ tst-basic7 \ + tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ + tst-cond8 tst-cond9 tst-cond10 tst-cond12 tst-cond13 \ + tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ + tst-cond23 tst-cond24 tst-cond25 \ + tst-cond-except \ tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex6 tst-mutex10 \ tst-spin1 tst-spin2 tst-spin3 tst-spin4 +ifeq ($(build-shared),yes) +tests-static += tst-cond8-static +tests += tst-cond8-static +endif + endif diff --git a/sysdeps/pthread/tst-cond-except.c b/sysdeps/pthread/tst-cond-except.c new file mode 100644 index 0000000000..8526e241e6 --- /dev/null +++ b/sysdeps/pthread/tst-cond-except.c @@ -0,0 +1,109 @@ +/* Verify that exception table for pthread_cond_wait is correct. + Copyright (C) 2012-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 + . */ + +#include +#include +#include +#include +#include + +pthread_mutex_t mutex; +pthread_cond_t cond; + +#define CHECK_RETURN_VAL_OR_FAIL(ret,str) \ + ({ if ((ret) != 0) \ + { \ + printf ("%s failed: %s\n", (str), strerror (ret)); \ + ret = 1; \ + goto out; \ + } \ + }) + + +void +clean (void *arg) +{ + puts ("clean: Unlocking mutex..."); + pthread_mutex_unlock ((pthread_mutex_t *) arg); + puts ("clean: Mutex unlocked..."); +} + +void * +thr (void *arg) +{ + int ret = 0; + pthread_mutexattr_t mutexAttr; + ret = pthread_mutexattr_init (&mutexAttr); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_init"); + + ret = pthread_mutexattr_setprotocol (&mutexAttr, PTHREAD_PRIO_INHERIT); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_setprotocol"); + + ret = pthread_mutex_init (&mutex, &mutexAttr); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_init"); + + ret = pthread_cond_init (&cond, 0); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_init"); + + puts ("th: Init done, entering wait..."); + + pthread_cleanup_push (clean, (void *) &mutex); + ret = pthread_mutex_lock (&mutex); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_lock"); + while (1) + { + ret = pthread_cond_wait (&cond, &mutex); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_wait"); + } + pthread_cleanup_pop (1); + +out: + return (void *) (uintptr_t) ret; +} + +int +do_test (void) +{ + pthread_t thread; + int ret = 0; + void *thr_ret = 0; + ret = pthread_create (&thread, 0, thr, &thr_ret); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_create"); + + puts ("main: Thread created, waiting a bit..."); + sleep (2); + + puts ("main: Cancelling thread..."); + ret = pthread_cancel (thread); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cancel"); + + puts ("main: Joining th..."); + ret = pthread_join (thread, NULL); + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_join"); + + if (thr_ret != NULL) + return 1; + + puts ("main: Joined thread, done!"); + +out: + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond1.c b/sysdeps/pthread/tst-cond1.c new file mode 100644 index 0000000000..47c68d443b --- /dev/null +++ b/sysdeps/pthread/tst-cond1.c @@ -0,0 +1,96 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include +#include +#include + + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; + + +static void * +tf (void *p) +{ + int err; + + err = pthread_mutex_lock (&mut); + if (err != 0) + error (EXIT_FAILURE, err, "child: cannot get mutex"); + + puts ("child: got mutex; signalling"); + + pthread_cond_signal (&cond); + + puts ("child: unlock"); + + err = pthread_mutex_unlock (&mut); + if (err != 0) + error (EXIT_FAILURE, err, "child: cannot unlock"); + + puts ("child: done"); + + return NULL; +} + + +static int +do_test (void) +{ + pthread_t th; + int err; + + printf ("&cond = %p\n&mut = %p\n", &cond, &mut); + + puts ("parent: get mutex"); + + err = pthread_mutex_lock (&mut); + if (err != 0) + error (EXIT_FAILURE, err, "parent: cannot get mutex"); + + puts ("parent: create child"); + + err = pthread_create (&th, NULL, tf, NULL); + if (err != 0) + error (EXIT_FAILURE, err, "parent: cannot create thread"); + + puts ("parent: wait for condition"); + + /* This test will fail on spurious wake-ups, which are allowed; however, + the current implementation shouldn't produce spurious wake-ups in the + scenario we are testing here. */ + err = pthread_cond_wait (&cond, &mut); + if (err != 0) + error (EXIT_FAILURE, err, "parent: cannot wait fir signal"); + + puts ("parent: got signal"); + + err = pthread_join (th, NULL); + if (err != 0) + error (EXIT_FAILURE, err, "parent: failed to join"); + + puts ("done"); + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond10.c b/sysdeps/pthread/tst-cond10.c new file mode 100644 index 0000000000..b89c452467 --- /dev/null +++ b/sysdeps/pthread/tst-cond10.c @@ -0,0 +1,172 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + 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 + . */ + +#include +#include +#include +#include +#include + + +#define N 10 +#define ROUNDS 100 + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; +static pthread_barrier_t bN1; +static pthread_barrier_t b2; + + +static void * +tf (void *p) +{ + if (pthread_mutex_lock (&mut) != 0) + { + puts ("child: 1st mutex_lock failed"); + exit (1); + } + + int e = pthread_barrier_wait (&b2); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("child: 1st barrier_wait failed"); + exit (1); + } + + if (pthread_cond_wait (&cond, &mut) != 0) + { + puts ("child: cond_wait failed"); + exit (1); + } + + if (pthread_mutex_unlock (&mut) != 0) + { + puts ("child: mutex_unlock failed"); + exit (1); + } + + e = pthread_barrier_wait (&bN1); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("child: 2nd barrier_wait failed"); + exit (1); + } + + return NULL; +} + + +static int +do_test (void) +{ + if (pthread_barrier_init (&bN1, NULL, N + 1) != 0) + { + puts ("barrier_init failed"); + exit (1); + } + + if (pthread_barrier_init (&b2, NULL, 2) != 0) + { + puts ("barrier_init failed"); + exit (1); + } + + pthread_attr_t at; + + if (pthread_attr_init (&at) != 0) + { + puts ("attr_init failed"); + return 1; + } + + if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0) + { + puts ("attr_setstacksize failed"); + return 1; + } + + int r; + for (r = 0; r < ROUNDS; ++r) + { + printf ("round %d\n", r + 1); + + int i; + pthread_t th[N]; + for (i = 0; i < N; ++i) + { + if (pthread_create (&th[i], &at, tf, NULL) != 0) + { + puts ("create failed"); + exit (1); + } + + int e = pthread_barrier_wait (&b2); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: 1st barrier_wait failed"); + exit (1); + } + } + + if (pthread_mutex_lock (&mut) != 0) + { + puts ("parent: mutex_lock failed"); + exit (1); + } + if (pthread_mutex_unlock (&mut) != 0) + { + puts ("parent: mutex_unlock failed"); + exit (1); + } + + /* N single signal calls. Without locking. This tests that no + signal gets lost. */ + for (i = 0; i < N; ++i) + if (pthread_cond_signal (&cond) != 0) + { + puts ("cond_signal failed"); + exit (1); + } + + int e = pthread_barrier_wait (&bN1); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: 2nd barrier_wait failed"); + exit (1); + } + + for (i = 0; i < N; ++i) + if (pthread_join (th[i], NULL) != 0) + { + puts ("join failed"); + exit (1); + } + } + + if (pthread_attr_destroy (&at) != 0) + { + puts ("attr_destroy failed"); + return 1; + } + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond11-static.c b/sysdeps/pthread/tst-cond11-static.c new file mode 100644 index 0000000000..9bccb8ec8b --- /dev/null +++ b/sysdeps/pthread/tst-cond11-static.c @@ -0,0 +1 @@ +#include "tst-cond11.c" diff --git a/sysdeps/pthread/tst-cond11.c b/sysdeps/pthread/tst-cond11.c new file mode 100644 index 0000000000..209e2f0c8d --- /dev/null +++ b/sysdeps/pthread/tst-cond11.c @@ -0,0 +1,122 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* A bogus clock value that tells run_test to use pthread_cond_timedwait + rather than pthread_condclockwait. */ +#define CLOCK_USE_ATTR_CLOCK (-1) + +#if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 +static int +run_test (clockid_t attr_clock, clockid_t wait_clock) +{ + pthread_condattr_t condattr; + pthread_cond_t cond; + pthread_mutexattr_t mutattr; + pthread_mutex_t mut; + + verbose_printf ("attr_clock = %d\n", (int) attr_clock); + + TEST_COMPARE (pthread_condattr_init (&condattr), 0); + TEST_COMPARE (pthread_condattr_setclock (&condattr, attr_clock), 0); + + clockid_t attr_clock_read; + TEST_COMPARE (pthread_condattr_getclock (&condattr, &attr_clock_read), 0); + TEST_COMPARE (attr_clock, attr_clock_read); + + TEST_COMPARE (pthread_cond_init (&cond, &condattr), 0); + TEST_COMPARE (pthread_condattr_destroy (&condattr), 0); + + xpthread_mutexattr_init (&mutattr); + xpthread_mutexattr_settype (&mutattr, PTHREAD_MUTEX_ERRORCHECK); + xpthread_mutex_init (&mut, &mutattr); + xpthread_mutexattr_destroy (&mutattr); + + xpthread_mutex_lock (&mut); + TEST_COMPARE (pthread_mutex_lock (&mut), EDEADLK); + + struct timespec ts_timeout; + xclock_gettime (wait_clock == CLOCK_USE_ATTR_CLOCK ? attr_clock : wait_clock, + &ts_timeout); + + /* Wait one second. */ + ++ts_timeout.tv_sec; + + if (wait_clock == CLOCK_USE_ATTR_CLOCK) { + TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT); + TEST_TIMESPEC_BEFORE_NOW (ts_timeout, attr_clock); + } else { + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, wait_clock, &ts_timeout), + ETIMEDOUT); + TEST_TIMESPEC_BEFORE_NOW (ts_timeout, wait_clock); + } + + xpthread_mutex_unlock (&mut); + xpthread_mutex_destroy (&mut); + TEST_COMPARE (pthread_cond_destroy (&cond), 0); + + return 0; +} +#endif + + +static int +do_test (void) +{ +#if !defined _POSIX_CLOCK_SELECTION || _POSIX_CLOCK_SELECTION == -1 + + FAIL_UNSUPPORTED ("_POSIX_CLOCK_SELECTION not supported, test skipped"); + +#else + + run_test (CLOCK_REALTIME, CLOCK_USE_ATTR_CLOCK); + +# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 +# if _POSIX_MONOTONIC_CLOCK == 0 + int e = sysconf (_SC_MONOTONIC_CLOCK); + if (e < 0) + puts ("CLOCK_MONOTONIC not supported"); + else if (e == 0) + FAIL_RET ("sysconf (_SC_MONOTONIC_CLOCK) must not return 0"); + else + { +# endif + run_test (CLOCK_MONOTONIC, CLOCK_USE_ATTR_CLOCK); + run_test (CLOCK_REALTIME, CLOCK_MONOTONIC); + run_test (CLOCK_MONOTONIC, CLOCK_MONOTONIC); + run_test (CLOCK_MONOTONIC, CLOCK_REALTIME); + } +# else + puts ("_POSIX_MONOTONIC_CLOCK not defined"); +# endif + + return 0; +#endif +} + +#include diff --git a/sysdeps/pthread/tst-cond12.c b/sysdeps/pthread/tst-cond12.c new file mode 100644 index 0000000000..474bedc39c --- /dev/null +++ b/sysdeps/pthread/tst-cond12.c @@ -0,0 +1,195 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +static char fname[] = "/tmp/tst-cond12-XXXXXX"; +static int fd; + + +static void prepare (void); +#define PREPARE(argc, argv) prepare () + +static int do_test (void); +#define TEST_FUNCTION do_test () + +#include "../test-skeleton.c" + + +static void +prepare (void) +{ + fd = mkstemp (fname); + if (fd == -1) + { + printf ("mkstemp failed: %m\n"); + exit (1); + } + add_temp_file (fname); + if (ftruncate (fd, 1000) < 0) + { + printf ("ftruncate failed: %m\n"); + exit (1); + } +} + + +static int +do_test (void) +{ + struct + { + pthread_mutex_t m; + pthread_cond_t c; + int var; + } *p = mmap (NULL, sizeof (*p), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (p == MAP_FAILED) + { + printf ("initial mmap failed: %m\n"); + return 1; + } + + pthread_mutexattr_t ma; + if (pthread_mutexattr_init (&ma) != 0) + { + puts ("mutexattr_init failed"); + return 1; + } + if (pthread_mutexattr_setpshared (&ma, 1) != 0) + { + puts ("mutexattr_setpshared failed"); + return 1; + } + if (pthread_mutex_init (&p->m, &ma) != 0) + { + puts ("mutex_init failed"); + return 1; + } + if (pthread_mutexattr_destroy (&ma) != 0) + { + puts ("mutexattr_destroy failed"); + return 1; + } + + pthread_condattr_t ca; + if (pthread_condattr_init (&ca) != 0) + { + puts ("condattr_init failed"); + return 1; + } + if (pthread_condattr_setpshared (&ca, 1) != 0) + { + puts ("condattr_setpshared failed"); + return 1; + } + if (pthread_cond_init (&p->c, &ca) != 0) + { + puts ("mutex_init failed"); + return 1; + } + if (pthread_condattr_destroy (&ca) != 0) + { + puts ("condattr_destroy failed"); + return 1; + } + + if (pthread_mutex_lock (&p->m) != 0) + { + puts ("initial mutex_lock failed"); + return 1; + } + + p->var = 42; + + pid_t pid = fork (); + if (pid == -1) + { + printf ("fork failed: %m\n"); + return 1; + } + + if (pid == 0) + { + void *oldp = p; + p = mmap (NULL, sizeof (*p), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + + if (p == oldp) + { + puts ("child: mapped to same address"); + kill (getppid (), SIGKILL); + exit (1); + } + + munmap (oldp, sizeof (*p)); + + if (pthread_mutex_lock (&p->m) != 0) + { + puts ("child: mutex_lock failed"); + kill (getppid (), SIGKILL); + exit (1); + } + + p->var = 0; + +#ifndef USE_COND_SIGNAL + if (pthread_cond_broadcast (&p->c) != 0) + { + puts ("child: cond_broadcast failed"); + kill (getppid (), SIGKILL); + exit (1); + } +#else + if (pthread_cond_signal (&p->c) != 0) + { + puts ("child: cond_signal failed"); + kill (getppid (), SIGKILL); + exit (1); + } +#endif + + if (pthread_mutex_unlock (&p->m) != 0) + { + puts ("child: mutex_unlock failed"); + kill (getppid (), SIGKILL); + exit (1); + } + + exit (0); + } + + do + pthread_cond_wait (&p->c, &p->m); + while (p->var != 0); + + if (TEMP_FAILURE_RETRY (waitpid (pid, NULL, 0)) != pid) + { + printf ("waitpid failed: %m\n"); + kill (pid, SIGKILL); + return 1; + } + + return 0; +} diff --git a/sysdeps/pthread/tst-cond13.c b/sysdeps/pthread/tst-cond13.c new file mode 100644 index 0000000000..29d79b533e --- /dev/null +++ b/sysdeps/pthread/tst-cond13.c @@ -0,0 +1,2 @@ +#define USE_COND_SIGNAL 1 +#include "tst-cond12.c" diff --git a/sysdeps/pthread/tst-cond14.c b/sysdeps/pthread/tst-cond14.c new file mode 100644 index 0000000000..e2d897ac3b --- /dev/null +++ b/sysdeps/pthread/tst-cond14.c @@ -0,0 +1,116 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + + 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 + . */ + +#include +#include +#include +#include +#include + + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER; + +static void * +tf (void *p) +{ + if (pthread_mutex_lock (&mut) != 0) + { + printf ("%s: 1st mutex_lock failed\n", __func__); + exit (1); + } + if (pthread_mutex_lock (&mut) != 0) + { + printf ("%s: 2nd mutex_lock failed\n", __func__); + exit (1); + } + if (pthread_mutex_lock (&mut) != 0) + { + printf ("%s: 3rd mutex_lock failed\n", __func__); + exit (1); + } + + if (pthread_mutex_unlock (&mut2) != 0) + { + printf ("%s: mutex_unlock failed\n", __func__); + exit (1); + } + + if (pthread_cond_wait (&cond, &mut) != 0) + { + printf ("%s: cond_wait failed\n", __func__); + exit (1); + } + + puts ("child: done"); + + return NULL; +} + + +static int +do_test (void) +{ + if (pthread_mutex_lock (&mut2) != 0) + { + puts ("1st mutex_lock failed"); + return 1; + } + + puts ("parent: create child"); + + pthread_t th; + int err = pthread_create (&th, NULL, tf, NULL); + if (err != 0) + { + printf ("parent: cannot create thread: %s\n", strerror (err)); + return 1; + } + + /* We have to synchronize with the child. */ + if (pthread_mutex_lock (&mut2) != 0) + { + puts ("2nd mutex_lock failed"); + return 1; + } + + /* Give the child to reach to pthread_cond_wait. */ + sleep (1); + + if (pthread_cond_signal (&cond) != 0) + { + puts ("cond_signal failed"); + return 1; + } + + err = pthread_join (th, NULL); + if (err != 0) + { + printf ("parent: failed to join: %s\n", strerror (err)); + return 1; + } + + puts ("done"); + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond15.c b/sysdeps/pthread/tst-cond15.c new file mode 100644 index 0000000000..fefab95996 --- /dev/null +++ b/sysdeps/pthread/tst-cond15.c @@ -0,0 +1,158 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include + + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER; + +static void * +tf (void *p) +{ + if (pthread_mutex_lock (&mut) != 0) + { + printf ("%s: 1st mutex_lock failed\n", __func__); + exit (1); + } + if (pthread_mutex_lock (&mut) != 0) + { + printf ("%s: 2nd mutex_lock failed\n", __func__); + exit (1); + } + if (pthread_mutex_lock (&mut) != 0) + { + printf ("%s: 3rd mutex_lock failed\n", __func__); + exit (1); + } + + if (pthread_mutex_unlock (&mut2) != 0) + { + printf ("%s: mutex_unlock failed\n", __func__); + exit (1); + } + + struct timeval tv; + gettimeofday (&tv, NULL); + struct timespec ts; + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_sec += p == NULL ? 100 : 1; + + int err = pthread_cond_timedwait (&cond, &mut, &ts); + if ((err != 0 && p == NULL) || (err != ETIMEDOUT && p != NULL)) + { + printf ("%s: cond_wait failed\n", __func__); + exit (1); + } + + if (pthread_mutex_unlock (&mut) != 0) + { + printf ("%s: 1st mutex_unlock failed\n", __func__); + exit (1); + } + if (pthread_mutex_unlock (&mut) != 0) + { + printf ("%s: 2nd mutex_unlock failed\n", __func__); + exit (1); + } + if (pthread_mutex_unlock (&mut) != 0) + { + printf ("%s: 3rd mutex_unlock failed\n", __func__); + exit (1); + } + + puts ("child: done"); + + return NULL; +} + + +static int +do_test (void) +{ + if (pthread_mutex_lock (&mut2) != 0) + { + puts ("1st mutex_lock failed"); + return 1; + } + + puts ("parent: create 1st child"); + + pthread_t th; + int err = pthread_create (&th, NULL, tf, NULL); + if (err != 0) + { + printf ("parent: cannot 1st create thread: %s\n", strerror (err)); + return 1; + } + + /* We have to synchronize with the child. */ + if (pthread_mutex_lock (&mut2) != 0) + { + puts ("2nd mutex_lock failed"); + return 1; + } + + /* Give the child to reach to pthread_cond_wait. */ + sleep (1); + + if (pthread_cond_signal (&cond) != 0) + { + puts ("cond_signal failed"); + return 1; + } + + err = pthread_join (th, NULL); + if (err != 0) + { + printf ("parent: failed to join: %s\n", strerror (err)); + return 1; + } + + + puts ("parent: create 2nd child"); + + err = pthread_create (&th, NULL, tf, (void *) 1l); + if (err != 0) + { + printf ("parent: cannot 2nd create thread: %s\n", strerror (err)); + return 1; + } + + err = pthread_join (th, NULL); + if (err != 0) + { + printf ("parent: failed to join: %s\n", strerror (err)); + return 1; + } + + puts ("done"); + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond16.c b/sysdeps/pthread/tst-cond16.c new file mode 100644 index 0000000000..daadd87860 --- /dev/null +++ b/sysdeps/pthread/tst-cond16.c @@ -0,0 +1,108 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2004. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include + +pthread_cond_t cv = PTHREAD_COND_INITIALIZER; +pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +bool n, exiting; +FILE *f; +enum { count = 8 }; /* Number of worker threads. */ + +void * +tf (void *dummy) +{ + bool loop = true; + + while (loop) + { + pthread_mutex_lock (&lock); + while (n && !exiting) + pthread_cond_wait (&cv, &lock); + n = true; + pthread_mutex_unlock (&lock); + + fputs (".", f); + + pthread_mutex_lock (&lock); + n = false; + if (exiting) + loop = false; +#ifdef UNLOCK_AFTER_BROADCAST + pthread_cond_broadcast (&cv); + pthread_mutex_unlock (&lock); +#else + pthread_mutex_unlock (&lock); + pthread_cond_broadcast (&cv); +#endif + } + + return NULL; +} + +int +do_test (void) +{ + f = fopen ("/dev/null", "w"); + if (f == NULL) + { + printf ("couldn't open /dev/null, %m\n"); + return 1; + } + + pthread_t th[count]; + pthread_attr_t attr; + int i, ret, sz; + pthread_attr_init (&attr); + sz = sysconf (_SC_PAGESIZE); +#ifdef PTHREAD_STACK_MIN + if (sz < PTHREAD_STACK_MIN) + sz = PTHREAD_STACK_MIN; +#endif + pthread_attr_setstacksize (&attr, sz); + for (i = 0; i < count; ++i) + if ((ret = pthread_create (&th[i], &attr, tf, NULL)) != 0) + { + errno = ret; + printf ("pthread_create %d failed: %m\n", i); + return 1; + } + + struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 }; + while (nanosleep (&ts, &ts) != 0); + + pthread_mutex_lock (&lock); + exiting = true; + pthread_mutex_unlock (&lock); + + for (i = 0; i < count; ++i) + pthread_join (th[i], NULL); + + fclose (f); + return 0; +} + +#define TEST_FUNCTION do_test () +#define TIMEOUT 40 +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond17.c b/sysdeps/pthread/tst-cond17.c new file mode 100644 index 0000000000..0586fa59ac --- /dev/null +++ b/sysdeps/pthread/tst-cond17.c @@ -0,0 +1,2 @@ +#define UNLOCK_AFTER_BROADCAST 1 +#include "tst-cond16.c" diff --git a/sysdeps/pthread/tst-cond18.c b/sysdeps/pthread/tst-cond18.c new file mode 100644 index 0000000000..38c35d7602 --- /dev/null +++ b/sysdeps/pthread/tst-cond18.c @@ -0,0 +1,121 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2004. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + +pthread_cond_t cv = PTHREAD_COND_INITIALIZER; +pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +bool exiting; +int fd, spins, nn; +enum { count = 8 }; /* Number of worker threads. */ + +void * +tf (void *id) +{ + pthread_mutex_lock (&lock); + + if ((long) id == 0) + { + while (!exiting) + { + if ((spins++ % 1000) == 0) + write (fd, ".", 1); + pthread_mutex_unlock (&lock); + + pthread_mutex_lock (&lock); + int njobs = rand () % (count + 1); + nn = njobs; + if ((rand () % 30) == 0) + pthread_cond_broadcast (&cv); + else + while (njobs--) + pthread_cond_signal (&cv); + } + + pthread_cond_broadcast (&cv); + } + else + { + while (!exiting) + { + while (!nn && !exiting) + pthread_cond_wait (&cv, &lock); + --nn; + pthread_mutex_unlock (&lock); + + pthread_mutex_lock (&lock); + } + } + + pthread_mutex_unlock (&lock); + return NULL; +} + +int +do_test (void) +{ + fd = open ("/dev/null", O_WRONLY); + if (fd < 0) + { + printf ("couldn't open /dev/null, %m\n"); + return 1; + } + + pthread_t th[count + 1]; + pthread_attr_t attr; + int i, ret, sz; + pthread_attr_init (&attr); + sz = sysconf (_SC_PAGESIZE); +#ifdef PTHREAD_STACK_MIN + if (sz < PTHREAD_STACK_MIN) + sz = PTHREAD_STACK_MIN; +#endif + pthread_attr_setstacksize (&attr, sz); + + for (i = 0; i <= count; ++i) + if ((ret = pthread_create (&th[i], &attr, tf, (void *) (long) i)) != 0) + { + errno = ret; + printf ("pthread_create %d failed: %m\n", i); + return 1; + } + + struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 }; + while (nanosleep (&ts, &ts) != 0); + + pthread_mutex_lock (&lock); + exiting = true; + pthread_mutex_unlock (&lock); + + for (i = 0; i < count; ++i) + pthread_join (th[i], NULL); + + close (fd); + return 0; +} + +#define TEST_FUNCTION do_test () +#define TIMEOUT 40 +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond19.c b/sysdeps/pthread/tst-cond19.c new file mode 100644 index 0000000000..e6c1caeeea --- /dev/null +++ b/sysdeps/pthread/tst-cond19.c @@ -0,0 +1,75 @@ +/* Copyright (C) 2004-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + + 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 + . */ + +#include +#include +#include +#include +#include + + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; + + +static int +do_test (void) +{ + int result = 0; + struct timespec ts; + + if (clock_gettime (CLOCK_REALTIME, &ts) != 0) + { + puts ("clock_gettime failed"); + return 1; + } + + ts.tv_nsec = -1; + + int e = pthread_cond_timedwait (&cond, &mut, &ts); + if (e == 0) + { + puts ("first cond_timedwait did not fail"); + result = 1; + } + else if (e != EINVAL) + { + puts ("first cond_timedwait did not return EINVAL"); + result = 1; + } + + ts.tv_nsec = 2000000000; + + e = pthread_cond_timedwait (&cond, &mut, &ts); + if (e == 0) + { + puts ("second cond_timedwait did not fail"); + result = 1; + } + else if (e != EINVAL) + { + puts ("second cond_timedwait did not return EINVAL"); + result = 1; + } + + return result; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond2.c b/sysdeps/pthread/tst-cond2.c new file mode 100644 index 0000000000..6752cca05f --- /dev/null +++ b/sysdeps/pthread/tst-cond2.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include +#include +#include + + +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +static pthread_barrier_t bar; + + +static void * +tf (void *a) +{ + int i = (long int) a; + int err; + + printf ("child %d: lock\n", i); + + err = pthread_mutex_lock (&mut); + if (err != 0) + error (EXIT_FAILURE, err, "locking in child failed"); + + printf ("child %d: sync\n", i); + + int e = pthread_barrier_wait (&bar); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("child: barrier_wait failed"); + exit (1); + } + + printf ("child %d: wait\n", i); + + err = pthread_cond_wait (&cond, &mut); + if (err != 0) + error (EXIT_FAILURE, err, "child %d: failed to wait", i); + + printf ("child %d: woken up\n", i); + + err = pthread_mutex_unlock (&mut); + if (err != 0) + error (EXIT_FAILURE, err, "child %d: unlock[2] failed", i); + + printf ("child %d: done\n", i); + + return NULL; +} + + +#define N 10 + + +static int +do_test (void) +{ + pthread_t th[N]; + int i; + int err; + + printf ("&cond = %p\n&mut = %p\n", &cond, &mut); + + if (pthread_barrier_init (&bar, NULL, 2) != 0) + { + puts ("barrier_init failed"); + exit (1); + } + + pthread_attr_t at; + + if (pthread_attr_init (&at) != 0) + { + puts ("attr_init failed"); + return 1; + } + + if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0) + { + puts ("attr_setstacksize failed"); + return 1; + } + + for (i = 0; i < N; ++i) + { + printf ("create thread %d\n", i); + + err = pthread_create (&th[i], &at, tf, (void *) (long int) i); + if (err != 0) + error (EXIT_FAILURE, err, "cannot create thread %d", i); + + printf ("wait for child %d\n", i); + + /* Wait for the child to start up and get the mutex for the + conditional variable. */ + int e = pthread_barrier_wait (&bar); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("barrier_wait failed"); + exit (1); + } + } + + if (pthread_attr_destroy (&at) != 0) + { + puts ("attr_destroy failed"); + return 1; + } + + puts ("get lock outselves"); + + err = pthread_mutex_lock (&mut); + if (err != 0) + error (EXIT_FAILURE, err, "mut locking failed"); + + puts ("broadcast"); + + /* Wake up all threads. */ + err = pthread_cond_broadcast (&cond); + if (err != 0) + error (EXIT_FAILURE, err, "parent: broadcast failed"); + + err = pthread_mutex_unlock (&mut); + if (err != 0) + error (EXIT_FAILURE, err, "mut unlocking failed"); + + /* Join all threads. */ + for (i = 0; i < N; ++i) + { + printf ("join thread %d\n", i); + + err = pthread_join (th[i], NULL); + if (err != 0) + error (EXIT_FAILURE, err, "join of child %d failed", i); + } + + puts ("done"); + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond22.c b/sysdeps/pthread/tst-cond22.c new file mode 100644 index 0000000000..64f19ea0a5 --- /dev/null +++ b/sysdeps/pthread/tst-cond22.c @@ -0,0 +1,162 @@ +#include +#include +#include + + +static pthread_barrier_t b; +static pthread_cond_t c = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; + + +static void +cl (void *arg) +{ + pthread_mutex_unlock (&m); +} + + +static void * +tf (void *arg) +{ + if (pthread_mutex_lock (&m) != 0) + { + printf ("%s: mutex_lock failed\n", __func__); + exit (1); + } + int e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __func__); + exit (1); + } + pthread_cleanup_push (cl, NULL); + /* We have to loop here because the cancellation might come after + the cond_wait call left the cancelable area and is then waiting + on the mutex. In this case the beginning of the second cond_wait + call will cause the cancellation to happen. */ + do + if (pthread_cond_wait (&c, &m) != 0) + { + printf ("%s: cond_wait failed\n", __func__); + exit (1); + } + while (arg == NULL); + pthread_cleanup_pop (0); + if (pthread_mutex_unlock (&m) != 0) + { + printf ("%s: mutex_unlock failed\n", __func__); + exit (1); + } + return NULL; +} + + +static int +do_test (void) +{ + int status = 0; + + if (pthread_barrier_init (&b, NULL, 2) != 0) + { + puts ("barrier_init failed"); + return 1; + } + + pthread_t th; + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("1st create failed"); + return 1; + } + int e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("1st barrier_wait failed"); + return 1; + } + if (pthread_mutex_lock (&m) != 0) + { + puts ("1st mutex_lock failed"); + return 1; + } + if (pthread_cond_signal (&c) != 0) + { + puts ("1st cond_signal failed"); + return 1; + } + if (pthread_cancel (th) != 0) + { + puts ("cancel failed"); + return 1; + } + if (pthread_mutex_unlock (&m) != 0) + { + puts ("1st mutex_unlock failed"); + return 1; + } + void *res; + if (pthread_join (th, &res) != 0) + { + puts ("1st join failed"); + return 1; + } + if (res != PTHREAD_CANCELED) + { + puts ("first thread not canceled"); + status = 1; + } + + printf ("cond = { %llu, %llu, %u/%u/%u, %u/%u/%u, %u, %u }\n", + c.__data.__wseq, c.__data.__g1_start, + c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0], + c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1], + c.__data.__g1_orig_size, c.__data.__wrefs); + + if (pthread_create (&th, NULL, tf, (void *) 1l) != 0) + { + puts ("2nd create failed"); + return 1; + } + e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("2nd barrier_wait failed"); + return 1; + } + if (pthread_mutex_lock (&m) != 0) + { + puts ("2nd mutex_lock failed"); + return 1; + } + if (pthread_cond_signal (&c) != 0) + { + puts ("2nd cond_signal failed"); + return 1; + } + if (pthread_mutex_unlock (&m) != 0) + { + puts ("2nd mutex_unlock failed"); + return 1; + } + if (pthread_join (th, &res) != 0) + { + puts ("2nd join failed"); + return 1; + } + if (res != NULL) + { + puts ("2nd thread canceled"); + status = 1; + } + + printf ("cond = { %llu, %llu, %u/%u/%u, %u/%u/%u, %u, %u }\n", + c.__data.__wseq, c.__data.__g1_start, + c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0], + c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1], + c.__data.__g1_orig_size, c.__data.__wrefs); + + return status; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond23.c b/sysdeps/pthread/tst-cond23.c new file mode 100644 index 0000000000..7ffe2ec1a9 --- /dev/null +++ b/sysdeps/pthread/tst-cond23.c @@ -0,0 +1,183 @@ +/* Copyright (C) 2008-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2008. + + 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 + . */ + +#include +#include +#include +#include +#include + + +#if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 +static int +check (pthread_condattr_t *condattr, int pshared, clockid_t cl) +{ + clockid_t cl2; + if (pthread_condattr_getclock (condattr, &cl2) != 0) + { + puts ("condattr_getclock failed"); + return 1; + } + if (cl != cl2) + { + printf ("condattr_getclock returned wrong value: %d, expected %d\n", + (int) cl2, (int) cl); + return 1; + } + + int p; + if (pthread_condattr_getpshared (condattr, &p) != 0) + { + puts ("condattr_getpshared failed"); + return 1; + } + else if (p != pshared) + { + printf ("condattr_getpshared returned wrong value: %d, expected %d\n", + p, pshared); + return 1; + } + + return 0; +} + +static int +run_test (clockid_t cl) +{ + pthread_condattr_t condattr; + + printf ("clock = %d\n", (int) cl); + + if (pthread_condattr_init (&condattr) != 0) + { + puts ("condattr_init failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_PRIVATE, CLOCK_REALTIME)) + return 1; + + if (pthread_condattr_setpshared (&condattr, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("1st condattr_setpshared failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_SHARED, CLOCK_REALTIME)) + return 1; + + if (pthread_condattr_setclock (&condattr, cl) != 0) + { + puts ("1st condattr_setclock failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_SHARED, cl)) + return 1; + + if (pthread_condattr_setpshared (&condattr, PTHREAD_PROCESS_PRIVATE) != 0) + { + puts ("2nd condattr_setpshared failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_PRIVATE, cl)) + return 1; + + if (pthread_condattr_setclock (&condattr, CLOCK_REALTIME) != 0) + { + puts ("2nd condattr_setclock failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_PRIVATE, CLOCK_REALTIME)) + return 1; + + if (pthread_condattr_setclock (&condattr, cl) != 0) + { + puts ("3rd condattr_setclock failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_PRIVATE, cl)) + return 1; + + if (pthread_condattr_setpshared (&condattr, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("3rd condattr_setpshared failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_SHARED, cl)) + return 1; + + if (pthread_condattr_setclock (&condattr, CLOCK_REALTIME) != 0) + { + puts ("4th condattr_setclock failed"); + return 1; + } + + if (check (&condattr, PTHREAD_PROCESS_SHARED, CLOCK_REALTIME)) + return 1; + + if (pthread_condattr_destroy (&condattr) != 0) + { + puts ("condattr_destroy failed"); + return 1; + } + + return 0; +} +#endif + + +static int +do_test (void) +{ +#if !defined _POSIX_CLOCK_SELECTION || _POSIX_CLOCK_SELECTION == -1 + + puts ("_POSIX_CLOCK_SELECTION not supported, test skipped"); + return 0; + +#else + + int res = run_test (CLOCK_REALTIME); + +# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 +# if _POSIX_MONOTONIC_CLOCK == 0 + int e = sysconf (_SC_MONOTONIC_CLOCK); + if (e < 0) + puts ("CLOCK_MONOTONIC not supported"); + else if (e == 0) + { + puts ("sysconf (_SC_MONOTONIC_CLOCK) must not return 0"); + res = 1; + } + else +# endif + res |= run_test (CLOCK_MONOTONIC); +# else + puts ("_POSIX_MONOTONIC_CLOCK not defined"); +# endif + + return res; +#endif +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond24.c b/sysdeps/pthread/tst-cond24.c new file mode 100644 index 0000000000..a2896f32cc --- /dev/null +++ b/sysdeps/pthread/tst-cond24.c @@ -0,0 +1,248 @@ +/* Verify that condition variables synchronized by PI mutexes don't hang. + Copyright (C) 2012-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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define THREADS_NUM 5 +#define MAXITER 50000 + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mutex_attr; +static pthread_cond_t cond; +static pthread_t threads[THREADS_NUM]; +static int pending = 0; + +typedef void * (*threadfunc) (void *); + +void * +thread_fun_timed (void *arg) +{ + int *ret = arg; + int rv, i; + + printf ("Started thread_fun_timed[%d]\n", *ret); + + for (i = 0; i < MAXITER / THREADS_NUM; i++) + { + rv = pthread_mutex_lock (&mutex); + if (rv) + { + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + + while (!pending) + { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 20; + rv = pthread_cond_timedwait (&cond, &mutex, &ts); + + /* There should be no timeout either. */ + if (rv) + { + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + pending--; + + rv = pthread_mutex_unlock (&mutex); + if (rv) + { + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + *ret = 0; + +out: + return ret; +} + +void * +thread_fun (void *arg) +{ + int *ret = arg; + int rv, i; + + printf ("Started thread_fun[%d]\n", *ret); + + for (i = 0; i < MAXITER / THREADS_NUM; i++) + { + rv = pthread_mutex_lock (&mutex); + if (rv) + { + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + + while (!pending) + { + rv = pthread_cond_wait (&cond, &mutex); + + if (rv) + { + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + pending--; + + rv = pthread_mutex_unlock (&mutex); + if (rv) + { + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); + *ret = 1; + goto out; + } + } + + *ret = 0; + +out: + return ret; +} + +static int +do_test_wait (threadfunc f) +{ + int i; + int rv; + int counter = 0; + int retval[THREADS_NUM]; + + puts ("Starting test"); + + rv = pthread_mutexattr_init (&mutex_attr); + if (rv) + { + printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT); + if (rv) + { + printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_mutex_init (&mutex, &mutex_attr); + if (rv) + { + printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_cond_init (&cond, NULL); + if (rv) + { + printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv); + return 1; + } + + for (i = 0; i < THREADS_NUM; i++) + { + retval[i] = i; + rv = pthread_create (&threads[i], NULL, f, &retval[i]); + if (rv) + { + printf ("pthread_create: %s(%d)\n", strerror (rv), rv); + return 1; + } + } + + for (; counter < MAXITER; counter++) + { + rv = pthread_mutex_lock (&mutex); + if (rv) + { + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv); + return 1; + } + + if (!(counter % 100)) + printf ("counter: %d\n", counter); + pending += 1; + + rv = pthread_cond_signal (&cond); + if (rv) + { + printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv); + return 1; + } + + rv = pthread_mutex_unlock (&mutex); + if (rv) + { + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv); + return 1; + } + } + + for (i = 0; i < THREADS_NUM; i++) + { + void *ret; + rv = pthread_join (threads[i], &ret); + if (rv) + { + printf ("pthread_join: %s(%d)\n", strerror (rv), rv); + return 1; + } + if (ret && *(int *)ret) + { + printf ("Thread %d returned with an error\n", i); + return 1; + } + } + + return 0; +} + +static int +do_test (void) +{ + puts ("Testing pthread_cond_wait"); + int ret = do_test_wait (thread_fun); + if (ret) + return ret; + + puts ("Testing pthread_cond_timedwait"); + return do_test_wait (thread_fun_timed); +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond25.c b/sysdeps/pthread/tst-cond25.c new file mode 100644 index 0000000000..72954f893c --- /dev/null +++ b/sysdeps/pthread/tst-cond25.c @@ -0,0 +1,288 @@ +/* Verify that condition variables synchronized by PI mutexes don't hang on + on cancellation. + Copyright (C) 2012-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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM 5 +#define ITERS 10000 +#define COUNT 100 + +typedef void *(*thr_func) (void *); + +pthread_mutex_t mutex; +pthread_cond_t cond; + +void cleanup (void *u) +{ + /* pthread_cond_wait should always return with the mutex locked. The + pthread_mutex_unlock implementation does not actually check whether we + own the mutex for several mutex kinds, so check this explicitly. */ + int ret = pthread_mutex_trylock (&mutex); + if (ret != EDEADLK && ret != EBUSY) + { + printf ("mutex not locked in cleanup %d\n", ret); + abort (); + } + if (pthread_mutex_unlock (&mutex)) + abort (); +} + +void * +signaller (void *u) +{ + int i, ret = 0; + void *tret = NULL; + + for (i = 0; i < ITERS; i++) + { + if ((ret = pthread_mutex_lock (&mutex)) != 0) + { + tret = (void *)1; + printf ("signaller:mutex_lock failed: %s\n", strerror (ret)); + goto out; + } + if ((ret = pthread_cond_signal (&cond)) != 0) + { + tret = (void *)1; + printf ("signaller:signal failed: %s\n", strerror (ret)); + goto unlock_out; + } + if ((ret = pthread_mutex_unlock (&mutex)) != 0) + { + tret = (void *)1; + printf ("signaller:mutex_unlock failed: %s\n", strerror (ret)); + goto out; + } + pthread_testcancel (); + } + +out: + return tret; + +unlock_out: + if ((ret = pthread_mutex_unlock (&mutex)) != 0) + printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret)); + goto out; +} + +void * +waiter (void *u) +{ + int i, ret = 0; + void *tret = NULL; + int seq = (uintptr_t) u; + + for (i = 0; i < ITERS / NUM; i++) + { + if ((ret = pthread_mutex_lock (&mutex)) != 0) + { + tret = (void *) (uintptr_t) 1; + printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret)); + goto out; + } + pthread_cleanup_push (cleanup, NULL); + + if ((ret = pthread_cond_wait (&cond, &mutex)) != 0) + { + tret = (void *) (uintptr_t) 1; + printf ("waiter[%u]:wait failed: %s\n", seq, strerror (ret)); + goto unlock_out; + } + + if ((ret = pthread_mutex_unlock (&mutex)) != 0) + { + tret = (void *) (uintptr_t) 1; + printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret)); + goto out; + } + pthread_cleanup_pop (0); + } + +out: + puts ("waiter tests done"); + return tret; + +unlock_out: + if ((ret = pthread_mutex_unlock (&mutex)) != 0) + printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret)); + goto out; +} + +void * +timed_waiter (void *u) +{ + int i, ret; + void *tret = NULL; + int seq = (uintptr_t) u; + + for (i = 0; i < ITERS / NUM; i++) + { + struct timespec ts; + + if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0) + { + tret = (void *) (uintptr_t) 1; + printf ("%u:clock_gettime failed: %s\n", seq, strerror (errno)); + goto out; + } + ts.tv_sec += 20; + + if ((ret = pthread_mutex_lock (&mutex)) != 0) + { + tret = (void *) (uintptr_t) 1; + printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret)); + goto out; + } + pthread_cleanup_push (cleanup, NULL); + + /* We should not time out either. */ + if ((ret = pthread_cond_timedwait (&cond, &mutex, &ts)) != 0) + { + tret = (void *) (uintptr_t) 1; + printf ("waiter[%u]:timedwait failed: %s\n", seq, strerror (ret)); + goto unlock_out; + } + if ((ret = pthread_mutex_unlock (&mutex)) != 0) + { + tret = (void *) (uintptr_t) 1; + printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret)); + goto out; + } + pthread_cleanup_pop (0); + } + +out: + puts ("timed_waiter tests done"); + return tret; + +unlock_out: + if ((ret = pthread_mutex_unlock (&mutex)) != 0) + printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror (ret)); + goto out; +} + +int +do_test_wait (thr_func f) +{ + pthread_t w[NUM]; + pthread_t s; + pthread_mutexattr_t attr; + int i, j, ret = 0; + void *thr_ret; + + for (i = 0; i < COUNT; i++) + { + if ((ret = pthread_mutexattr_init (&attr)) != 0) + { + printf ("mutexattr_init failed: %s\n", strerror (ret)); + goto out; + } + + if ((ret = pthread_mutexattr_setprotocol (&attr, + PTHREAD_PRIO_INHERIT)) != 0) + { + printf ("mutexattr_setprotocol failed: %s\n", strerror (ret)); + goto out; + } + + if ((ret = pthread_cond_init (&cond, NULL)) != 0) + { + printf ("cond_init failed: %s\n", strerror (ret)); + goto out; + } + + if ((ret = pthread_mutex_init (&mutex, &attr)) != 0) + { + printf ("mutex_init failed: %s\n", strerror (ret)); + goto out; + } + + for (j = 0; j < NUM; j++) + if ((ret = pthread_create (&w[j], NULL, + f, (void *) (uintptr_t) j)) != 0) + { + printf ("waiter[%d]: create failed: %s\n", j, strerror (ret)); + goto out; + } + + if ((ret = pthread_create (&s, NULL, signaller, NULL)) != 0) + { + printf ("signaller: create failed: %s\n", strerror (ret)); + goto out; + } + + for (j = 0; j < NUM; j++) + { + pthread_cancel (w[j]); + + if ((ret = pthread_join (w[j], &thr_ret)) != 0) + { + printf ("waiter[%d]: join failed: %s\n", j, strerror (ret)); + goto out; + } + + if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED) + { + ret = 1; + goto out; + } + } + + /* The signalling thread could have ended before it was cancelled. */ + pthread_cancel (s); + + if ((ret = pthread_join (s, &thr_ret)) != 0) + { + printf ("signaller: join failed: %s\n", strerror (ret)); + goto out; + } + + if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED) + { + ret = 1; + goto out; + } + } + +out: + return ret; +} + +int +do_test (int argc, char **argv) +{ + int ret = do_test_wait (waiter); + + if (ret) + return ret; + + return do_test_wait (timed_waiter); +} + +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond26.c b/sysdeps/pthread/tst-cond26.c new file mode 100644 index 0000000000..e647da00c2 --- /dev/null +++ b/sysdeps/pthread/tst-cond26.c @@ -0,0 +1,77 @@ +/* Test unsupported/bad clocks passed to pthread_cond_clockwait. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; + +#define NOT_A_VALID_CLOCK 123456 + +static int +do_test (void) +{ + xpthread_mutex_lock (&mut); + + const struct timespec ts = make_timespec (0, 0); + + /* These clocks are meaningless to sem_clockwait. */ +#if defined(CLOCK_PROCESS_CPUTIME_ID) + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, + CLOCK_PROCESS_CPUTIME_ID, &ts), EINVAL); +#endif +#if defined(CLOCK_THREAD_CPUTIME_ID) + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, + CLOCK_THREAD_CPUTIME_ID, &ts), EINVAL); +#endif + + /* These clocks might be meaningful, but are currently unsupported + by pthread_cond_clockwait. */ +#if defined(CLOCK_REALTIME_COARSE) + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, + CLOCK_REALTIME_COARSE, &ts), EINVAL); +#endif +#if defined(CLOCK_MONOTONIC_RAW) + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, + CLOCK_MONOTONIC_RAW, &ts), EINVAL); +#endif +#if defined(CLOCK_MONOTONIC_COARSE) + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, + CLOCK_MONOTONIC_COARSE, &ts), EINVAL); +#endif +#if defined(CLOCK_BOOTTIME) + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, + CLOCK_BOOTTIME, &ts), EINVAL); +#endif + + /* This is a completely invalid clock. */ + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, + NOT_A_VALID_CLOCK, &ts), EINVAL); + + return 0; +} + +#include diff --git a/sysdeps/pthread/tst-cond27.c b/sysdeps/pthread/tst-cond27.c new file mode 100644 index 0000000000..c8142abf9e --- /dev/null +++ b/sysdeps/pthread/tst-cond27.c @@ -0,0 +1,66 @@ +/* Test pthread_cond_clockwait timeout. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + + +static int +do_test_clock (clockid_t clockid) +{ + /* Get the mutex. */ + xpthread_mutex_lock (&mut); + + /* Waiting for the condition will fail. But we want the timeout here. */ + const struct timespec ts_now = xclock_now (clockid); + const struct timespec ts_timeout = + timespec_add (ts_now, make_timespec (0, 500000000)); + + /* In theory pthread_cond_clockwait could return zero here due to + spurious wakeup. However that can't happen without a signal or an + additional waiter. */ + TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, clockid, &ts_timeout), + ETIMEDOUT); + + xpthread_mutex_unlock (&mut); + + return 0; +} + +static int +do_test (void) +{ + do_test_clock (CLOCK_MONOTONIC); + do_test_clock (CLOCK_REALTIME); + return 0; +} + +#include diff --git a/sysdeps/pthread/tst-cond3.c b/sysdeps/pthread/tst-cond3.c new file mode 100644 index 0000000000..fb4209d0bb --- /dev/null +++ b/sysdeps/pthread/tst-cond3.c @@ -0,0 +1,111 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include +#include +#include +#include + +static int do_test (void); + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +/* Note that this test requires more than the standard. It is + required that there are no spurious wakeups if only more readers + are added. This is a reasonable demand. */ + + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; + + +#define N 10 + + +static void * +tf (void *arg) +{ + int i = (long int) arg; + int err; + + /* Get the mutex. */ + err = pthread_mutex_lock (&mut); + if (err != 0) + { + printf ("child %d mutex_lock failed: %s\n", i, strerror (err)); + exit (1); + } + + /* This call should never return. */ + xpthread_cond_wait (&cond, &mut); + puts ("error: pthread_cond_wait in tf returned"); + + /* We should never get here. */ + exit (1); + + return NULL; +} + + +static int +do_test (void) +{ + int err; + int i; + + for (i = 0; i < N; ++i) + { + pthread_t th; + + if (i != 0) + { + /* Release the mutex. */ + err = pthread_mutex_unlock (&mut); + if (err != 0) + { + printf ("mutex_unlock %d failed: %s\n", i, strerror (err)); + return 1; + } + } + + err = pthread_create (&th, NULL, tf, (void *) (long int) i); + if (err != 0) + { + printf ("create %d failed: %s\n", i, strerror (err)); + return 1; + } + + /* Get the mutex. */ + err = pthread_mutex_lock (&mut); + if (err != 0) + { + printf ("mutex_lock %d failed: %s\n", i, strerror (err)); + return 1; + } + } + + delayed_exit (1); + + /* This call should never return. */ + xpthread_cond_wait (&cond, &mut); + + puts ("error: pthread_cond_wait in do_test returned"); + return 1; +} diff --git a/sysdeps/pthread/tst-cond4.c b/sysdeps/pthread/tst-cond4.c new file mode 100644 index 0000000000..4d4bad3a76 --- /dev/null +++ b/sysdeps/pthread/tst-cond4.c @@ -0,0 +1,263 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int *condition; + +static int +do_test (void) +{ + size_t ps = sysconf (_SC_PAGESIZE); + char tmpfname[] = "/tmp/tst-cond4.XXXXXX"; + char data[ps]; + void *mem; + int fd; + pthread_mutexattr_t ma; + pthread_mutex_t *mut1; + pthread_mutex_t *mut2; + pthread_condattr_t ca; + pthread_cond_t *cond; + pid_t pid; + int result = 0; + int p; + + 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; + } + + mut1 = (pthread_mutex_t *) (((uintptr_t) mem + + __alignof (pthread_mutex_t)) + & ~(__alignof (pthread_mutex_t) - 1)); + mut2 = mut1 + 1; + + cond = (pthread_cond_t *) (((uintptr_t) (mut2 + 1) + + __alignof (pthread_cond_t)) + & ~(__alignof (pthread_cond_t) - 1)); + + condition = (int *) (((uintptr_t) (cond + 1) + __alignof (int)) + & ~(__alignof (int) - 1)); + + if (pthread_mutexattr_init (&ma) != 0) + { + puts ("mutexattr_init failed"); + return 1; + } + + if (pthread_mutexattr_getpshared (&ma, &p) != 0) + { + puts ("1st mutexattr_getpshared failed"); + return 1; + } + + if (p != PTHREAD_PROCESS_PRIVATE) + { + puts ("default pshared value wrong"); + return 1; + } + + if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("mutexattr_setpshared failed"); + return 1; + } + + if (pthread_mutexattr_getpshared (&ma, &p) != 0) + { + puts ("2nd mutexattr_getpshared failed"); + return 1; + } + + if (p != PTHREAD_PROCESS_SHARED) + { + puts ("pshared value after setpshared call wrong"); + return 1; + } + + if (pthread_mutex_init (mut1, &ma) != 0) + { + puts ("1st mutex_init failed"); + return 1; + } + + if (pthread_mutex_init (mut2, &ma) != 0) + { + puts ("2nd mutex_init failed"); + return 1; + } + + if (pthread_condattr_init (&ca) != 0) + { + puts ("condattr_init failed"); + return 1; + } + + if (pthread_condattr_getpshared (&ca, &p) != 0) + { + puts ("1st condattr_getpshared failed"); + return 1; + } + + if (p != PTHREAD_PROCESS_PRIVATE) + { + puts ("default value for pshared in condattr wrong"); + return 1; + } + + if (pthread_condattr_setpshared (&ca, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("condattr_setpshared failed"); + return 1; + } + + if (pthread_condattr_getpshared (&ca, &p) != 0) + { + puts ("2nd condattr_getpshared failed"); + return 1; + } + + if (p != PTHREAD_PROCESS_SHARED) + { + puts ("pshared condattr still not set"); + return 1; + } + + if (pthread_cond_init (cond, &ca) != 0) + { + puts ("cond_init failed"); + return 1; + } + + if (pthread_mutex_lock (mut1) != 0) + { + puts ("parent: 1st mutex_lock failed"); + return 1; + } + + puts ("going to fork now"); + pid = fork (); + if (pid == -1) + { + puts ("fork failed"); + return 1; + } + else if (pid == 0) + { + if (pthread_mutex_lock (mut2) != 0) + { + puts ("child: mutex_lock failed"); + return 1; + } + + if (pthread_mutex_unlock (mut1) != 0) + { + puts ("child: 1st mutex_unlock failed"); + return 1; + } + + do + if (pthread_cond_wait (cond, mut2) != 0) + { + puts ("child: cond_wait failed"); + return 1; + } + while (*condition == 0); + + if (pthread_mutex_unlock (mut2) != 0) + { + puts ("child: 2nd mutex_unlock failed"); + return 1; + } + + puts ("child done"); + } + else + { + int status; + + if (pthread_mutex_lock (mut1) != 0) + { + puts ("parent: 2nd mutex_lock failed"); + return 1; + } + + if (pthread_mutex_lock (mut2) != 0) + { + puts ("parent: 3rd mutex_lock failed"); + return 1; + } + + if (pthread_cond_signal (cond) != 0) + { + puts ("parent: cond_signal failed"); + return 1; + } + + *condition = 1; + + if (pthread_mutex_unlock (mut2) != 0) + { + puts ("parent: mutex_unlock failed"); + return 1; + } + + puts ("waiting for child"); + + waitpid (pid, &status, 0); + result |= status; + + puts ("parent done"); + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond5.c b/sysdeps/pthread/tst-cond5.c new file mode 100644 index 0000000000..e2ea541c46 --- /dev/null +++ b/sysdeps/pthread/tst-cond5.c @@ -0,0 +1,105 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include +#include +#include +#include +#include +#include + + +static pthread_mutex_t mut; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + + +static int +do_test (void) +{ + pthread_mutexattr_t ma; + int err; + struct timespec ts; + struct timeval tv; + + if (pthread_mutexattr_init (&ma) != 0) + { + puts ("mutexattr_init failed"); + exit (1); + } + + if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0) + { + puts ("mutexattr_settype failed"); + exit (1); + } + + if (pthread_mutex_init (&mut, &ma) != 0) + { + puts ("mutex_init failed"); + exit (1); + } + + /* Get the mutex. */ + if (pthread_mutex_lock (&mut) != 0) + { + puts ("mutex_lock failed"); + exit (1); + } + + /* Waiting for the condition will fail. But we want the timeout here. */ + if (gettimeofday (&tv, NULL) != 0) + { + puts ("gettimeofday failed"); + exit (1); + } + + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_nsec += 500000000; + if (ts.tv_nsec >= 1000000000) + { + ts.tv_nsec -= 1000000000; + ++ts.tv_sec; + } + err = pthread_cond_timedwait (&cond, &mut, &ts); + if (err == 0) + { + /* This could in theory happen but here without any signal and + additional waiter it should not. */ + puts ("cond_timedwait succeeded"); + exit (1); + } + else if (err != ETIMEDOUT) + { + printf ("cond_timedwait returned with %s\n", strerror (err)); + exit (1); + } + + err = pthread_mutex_unlock (&mut); + if (err != 0) + { + printf ("mutex_unlock failed: %s\n", strerror (err)); + exit (1); + } + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond6.c b/sysdeps/pthread/tst-cond6.c new file mode 100644 index 0000000000..0c9426d0d7 --- /dev/null +++ b/sysdeps/pthread/tst-cond6.c @@ -0,0 +1,233 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int *condition; + +static int +do_test (void) +{ + size_t ps = sysconf (_SC_PAGESIZE); + char tmpfname[] = "/tmp/tst-cond6.XXXXXX"; + char data[ps]; + void *mem; + int fd; + pthread_mutexattr_t ma; + pthread_mutex_t *mut1; + pthread_mutex_t *mut2; + pthread_condattr_t ca; + pthread_cond_t *cond; + pid_t pid; + int result = 0; + + fd = mkstemp (tmpfname); + if (fd == -1) + { + printf ("cannot open temporary file: %m\n"); + exit (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"); + exit (1); + } + + mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (mem == MAP_FAILED) + { + printf ("mmap failed: %m\n"); + exit (1); + } + + mut1 = (pthread_mutex_t *) (((uintptr_t) mem + + __alignof (pthread_mutex_t)) + & ~(__alignof (pthread_mutex_t) - 1)); + mut2 = mut1 + 1; + + cond = (pthread_cond_t *) (((uintptr_t) (mut2 + 1) + + __alignof (pthread_cond_t)) + & ~(__alignof (pthread_cond_t) - 1)); + + condition = (int *) (((uintptr_t) (cond + 1) + __alignof (int)) + & ~(__alignof (int) - 1)); + + if (pthread_mutexattr_init (&ma) != 0) + { + puts ("mutexattr_init failed"); + exit (1); + } + + if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("mutexattr_setpshared failed"); + exit (1); + } + + if (pthread_mutex_init (mut1, &ma) != 0) + { + puts ("1st mutex_init failed"); + exit (1); + } + + if (pthread_mutex_init (mut2, &ma) != 0) + { + puts ("2nd mutex_init failed"); + exit (1); + } + + if (pthread_condattr_init (&ca) != 0) + { + puts ("condattr_init failed"); + exit (1); + } + + if (pthread_condattr_setpshared (&ca, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("condattr_setpshared failed"); + exit (1); + } + + if (pthread_cond_init (cond, &ca) != 0) + { + puts ("cond_init failed"); + exit (1); + } + + if (pthread_mutex_lock (mut1) != 0) + { + puts ("parent: 1st mutex_lock failed"); + exit (1); + } + + puts ("going to fork now"); + pid = fork (); + if (pid == -1) + { + puts ("fork failed"); + exit (1); + } + else if (pid == 0) + { + struct timespec ts; + struct timeval tv; + + if (pthread_mutex_lock (mut2) != 0) + { + puts ("child: mutex_lock failed"); + exit (1); + } + + if (pthread_mutex_unlock (mut1) != 0) + { + puts ("child: 1st mutex_unlock failed"); + exit (1); + } + + if (gettimeofday (&tv, NULL) != 0) + { + puts ("gettimeofday failed"); + exit (1); + } + + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_nsec += 500000000; + if (ts.tv_nsec >= 1000000000) + { + ts.tv_nsec -= 1000000000; + ++ts.tv_sec; + } + + do + if (pthread_cond_timedwait (cond, mut2, &ts) != 0) + { + puts ("child: cond_wait failed"); + exit (1); + } + while (*condition == 0); + + if (pthread_mutex_unlock (mut2) != 0) + { + puts ("child: 2nd mutex_unlock failed"); + exit (1); + } + + puts ("child done"); + } + else + { + int status; + + if (pthread_mutex_lock (mut1) != 0) + { + puts ("parent: 2nd mutex_lock failed"); + exit (1); + } + + if (pthread_mutex_lock (mut2) != 0) + { + puts ("parent: 3rd mutex_lock failed"); + exit (1); + } + + if (pthread_cond_signal (cond) != 0) + { + puts ("parent: cond_signal failed"); + exit (1); + } + + *condition = 1; + + if (pthread_mutex_unlock (mut2) != 0) + { + puts ("parent: mutex_unlock failed"); + exit (1); + } + + puts ("waiting for child"); + + waitpid (pid, &status, 0); + result |= status; + + puts ("parent done"); + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond7.c b/sysdeps/pthread/tst-cond7.c new file mode 100644 index 0000000000..48502bd720 --- /dev/null +++ b/sysdeps/pthread/tst-cond7.c @@ -0,0 +1,167 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef struct + { + pthread_cond_t cond; + pthread_mutex_t lock; + pthread_t h; + } T; + + +static volatile bool done; + + +static void * +tf (void *arg) +{ + puts ("child created"); + + if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0 + || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0) + { + puts ("cannot set cancellation options"); + exit (1); + } + + T *t = (T *) arg; + + if (pthread_mutex_lock (&t->lock) != 0) + { + puts ("child: lock failed"); + exit (1); + } + + done = true; + + if (pthread_cond_signal (&t->cond) != 0) + { + puts ("child: cond_signal failed"); + exit (1); + } + + if (pthread_cond_wait (&t->cond, &t->lock) != 0) + { + puts ("child: cond_wait failed"); + exit (1); + } + + if (pthread_mutex_unlock (&t->lock) != 0) + { + puts ("child: unlock failed"); + exit (1); + } + + return NULL; +} + + +static int +do_test (void) +{ + int i; +#define N 100 + T *t[N]; + for (i = 0; i < N; ++i) + { + printf ("round %d\n", i); + + t[i] = (T *) malloc (sizeof (T)); + if (t[i] == NULL) + { + puts ("out of memory"); + exit (1); + } + + if (pthread_mutex_init (&t[i]->lock, NULL) != 0 + || pthread_cond_init (&t[i]->cond, NULL) != 0) + { + puts ("an _init function failed"); + exit (1); + } + + if (pthread_mutex_lock (&t[i]->lock) != 0) + { + puts ("initial mutex_lock failed"); + exit (1); + } + + done = false; + + if (pthread_create (&t[i]->h, NULL, tf, t[i]) != 0) + { + puts ("pthread_create failed"); + exit (1); + } + + do + if (pthread_cond_wait (&t[i]->cond, &t[i]->lock) != 0) + { + puts ("cond_wait failed"); + exit (1); + } + while (! done); + + /* Release the lock since the cancel handler will get it. */ + if (pthread_mutex_unlock (&t[i]->lock) != 0) + { + puts ("mutex_unlock failed"); + exit (1); + } + + if (pthread_cancel (t[i]->h) != 0) + { + puts ("cancel failed"); + exit (1); + } + + puts ("parent: joining now"); + + void *result; + if (pthread_join (t[i]->h, &result) != 0) + { + puts ("join failed"); + exit (1); + } + + if (result != PTHREAD_CANCELED) + { + puts ("result != PTHREAD_CANCELED"); + exit (1); + } + } + + for (i = 0; i < N; ++i) + free (t[i]); + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond8-static.c b/sysdeps/pthread/tst-cond8-static.c new file mode 100644 index 0000000000..fed35db60d --- /dev/null +++ b/sysdeps/pthread/tst-cond8-static.c @@ -0,0 +1 @@ +#include "tst-cond8.c" diff --git a/sysdeps/pthread/tst-cond8.c b/sysdeps/pthread/tst-cond8.c new file mode 100644 index 0000000000..61f7583844 --- /dev/null +++ b/sysdeps/pthread/tst-cond8.c @@ -0,0 +1,276 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + 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 + . */ + +#include +#include +#include +#include +#include +#include + + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + +static pthread_barrier_t bar; + + +static void +ch (void *arg) +{ + int e = pthread_mutex_lock (&mut); + if (e == 0) + { + puts ("mutex not locked at all by cond_wait"); + exit (1); + } + + if (e != EDEADLK) + { + puts ("no deadlock error signaled"); + exit (1); + } + + if (pthread_mutex_unlock (&mut) != 0) + { + puts ("ch: cannot unlock mutex"); + exit (1); + } + + puts ("ch done"); +} + + +static void * +tf1 (void *p) +{ + int err; + + if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0 + || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0) + { + puts ("cannot set cancellation options"); + exit (1); + } + + err = pthread_mutex_lock (&mut); + if (err != 0) + { + puts ("child: cannot get mutex"); + exit (1); + } + + err = pthread_barrier_wait (&bar); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("barrier_wait returned %d\n", err); + exit (1); + } + + puts ("child: got mutex; waiting"); + + pthread_cleanup_push (ch, NULL); + + pthread_cond_wait (&cond, &mut); + + pthread_cleanup_pop (0); + + puts ("child: cond_wait should not have returned"); + + return NULL; +} + + +static void * +tf2 (void *p) +{ + int err; + + if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0 + || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0) + { + puts ("cannot set cancellation options"); + exit (1); + } + + err = pthread_mutex_lock (&mut); + if (err != 0) + { + puts ("child: cannot get mutex"); + exit (1); + } + + err = pthread_barrier_wait (&bar); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("barrier_wait returned %d\n", err); + exit (1); + } + + puts ("child: got mutex; waiting"); + + pthread_cleanup_push (ch, NULL); + + /* Current time. */ + struct timeval tv; + (void) gettimeofday (&tv, NULL); + /* +1000 seconds in correct format. */ + struct timespec ts; + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_sec += 1000; + + pthread_cond_timedwait (&cond, &mut, &ts); + + pthread_cleanup_pop (0); + + puts ("child: cond_wait should not have returned"); + + return NULL; +} + + +static int +do_test (void) +{ + pthread_t th; + int err; + + printf ("&cond = %p\n&mut = %p\n", &cond, &mut); + + puts ("parent: get mutex"); + + err = pthread_barrier_init (&bar, NULL, 2); + if (err != 0) + { + puts ("parent: cannot init barrier"); + exit (1); + } + + puts ("parent: create child"); + + err = pthread_create (&th, NULL, tf1, NULL); + if (err != 0) + { + puts ("parent: cannot create thread"); + exit (1); + } + + puts ("parent: wait for child to lock mutex"); + + err = pthread_barrier_wait (&bar); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: cannot wait for barrier"); + exit (1); + } + + err = pthread_mutex_lock (&mut); + if (err != 0) + { + puts ("parent: mutex_lock failed"); + exit (1); + } + + err = pthread_mutex_unlock (&mut); + if (err != 0) + { + puts ("parent: mutex_unlock failed"); + exit (1); + } + + if (pthread_cancel (th) != 0) + { + puts ("cannot cancel thread"); + exit (1); + } + + void *r; + err = pthread_join (th, &r); + if (err != 0) + { + puts ("parent: failed to join"); + exit (1); + } + + if (r != PTHREAD_CANCELED) + { + puts ("child hasn't been canceled"); + exit (1); + } + + + + puts ("parent: create 2nd child"); + + err = pthread_create (&th, NULL, tf2, NULL); + if (err != 0) + { + puts ("parent: cannot create thread"); + exit (1); + } + + puts ("parent: wait for child to lock mutex"); + + err = pthread_barrier_wait (&bar); + if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("parent: cannot wait for barrier"); + exit (1); + } + + err = pthread_mutex_lock (&mut); + if (err != 0) + { + puts ("parent: mutex_lock failed"); + exit (1); + } + + err = pthread_mutex_unlock (&mut); + if (err != 0) + { + puts ("parent: mutex_unlock failed"); + exit (1); + } + + if (pthread_cancel (th) != 0) + { + puts ("cannot cancel thread"); + exit (1); + } + + err = pthread_join (th, &r); + if (err != 0) + { + puts ("parent: failed to join"); + exit (1); + } + + if (r != PTHREAD_CANCELED) + { + puts ("child hasn't been canceled"); + exit (1); + } + + puts ("done"); + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-cond9.c b/sysdeps/pthread/tst-cond9.c new file mode 100644 index 0000000000..e83870d393 --- /dev/null +++ b/sysdeps/pthread/tst-cond9.c @@ -0,0 +1,149 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + 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 + . */ + +#include +#include +#include +#include +#include +#include + + +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + + +static void * +tf (void *arg) +{ + int err = pthread_cond_wait (&cond, &mut); + if (err == 0) + { + puts ("cond_wait did not fail"); + exit (1); + } + + if (err != EPERM) + { + printf ("cond_wait didn't return EPERM but %d\n", err); + exit (1); + } + + + /* Current time. */ + struct timeval tv; + (void) gettimeofday (&tv, NULL); + /* +1000 seconds in correct format. */ + struct timespec ts; + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_sec += 1000; + + err = pthread_cond_timedwait (&cond, &mut, &ts); + if (err == 0) + { + puts ("cond_timedwait did not fail"); + exit (1); + } + + if (err != EPERM) + { + printf ("cond_timedwait didn't return EPERM but %d\n", err); + exit (1); + } + + return (void *) 1l; +} + + +static int +do_test (void) +{ + pthread_t th; + int err; + + printf ("&cond = %p\n&mut = %p\n", &cond, &mut); + + err = pthread_cond_wait (&cond, &mut); + if (err == 0) + { + puts ("cond_wait did not fail"); + exit (1); + } + + if (err != EPERM) + { + printf ("cond_wait didn't return EPERM but %d\n", err); + exit (1); + } + + + /* Current time. */ + struct timeval tv; + (void) gettimeofday (&tv, NULL); + /* +1000 seconds in correct format. */ + struct timespec ts; + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_sec += 1000; + + err = pthread_cond_timedwait (&cond, &mut, &ts); + if (err == 0) + { + puts ("cond_timedwait did not fail"); + exit (1); + } + + if (err != EPERM) + { + printf ("cond_timedwait didn't return EPERM but %d\n", err); + exit (1); + } + + if (pthread_mutex_lock (&mut) != 0) + { + puts ("parent: mutex_lock failed"); + exit (1); + } + + puts ("creating thread"); + + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("create failed"); + exit (1); + } + + void *r; + if (pthread_join (th, &r) != 0) + { + puts ("join failed"); + exit (1); + } + if (r != (void *) 1l) + { + puts ("thread has wrong return value"); + exit (1); + } + + puts ("done"); + + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" -- cgit 1.4.1