aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/pthread
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-02-09 19:17:51 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-02-09 19:24:44 +0000
commitd8f1f2d9ab2144b589fdac3e381cd86e71871e43 (patch)
tree586832da5c77a4635006cfecb4515e23956ddaa6 /sysdeps/pthread
parentfaae4b2bdd692d929037c80c3315f716f02f3b00 (diff)
downloadglibc-d8f1f2d9ab2144b589fdac3e381cd86e71871e43.tar.xz
glibc-d8f1f2d9ab2144b589fdac3e381cd86e71871e43.zip
pthread: Move most cond tests from nptl to sysdeps/pthread
So they can be checked with htl too.
Diffstat (limited to 'sysdeps/pthread')
-rw-r--r--sysdeps/pthread/Makefile10
-rw-r--r--sysdeps/pthread/tst-cond-except.c109
-rw-r--r--sysdeps/pthread/tst-cond1.c96
-rw-r--r--sysdeps/pthread/tst-cond10.c172
-rw-r--r--sysdeps/pthread/tst-cond11-static.c1
-rw-r--r--sysdeps/pthread/tst-cond11.c122
-rw-r--r--sysdeps/pthread/tst-cond12.c195
-rw-r--r--sysdeps/pthread/tst-cond13.c2
-rw-r--r--sysdeps/pthread/tst-cond14.c116
-rw-r--r--sysdeps/pthread/tst-cond15.c158
-rw-r--r--sysdeps/pthread/tst-cond16.c108
-rw-r--r--sysdeps/pthread/tst-cond17.c2
-rw-r--r--sysdeps/pthread/tst-cond18.c121
-rw-r--r--sysdeps/pthread/tst-cond19.c75
-rw-r--r--sysdeps/pthread/tst-cond2.c162
-rw-r--r--sysdeps/pthread/tst-cond22.c162
-rw-r--r--sysdeps/pthread/tst-cond23.c183
-rw-r--r--sysdeps/pthread/tst-cond24.c248
-rw-r--r--sysdeps/pthread/tst-cond25.c288
-rw-r--r--sysdeps/pthread/tst-cond26.c77
-rw-r--r--sysdeps/pthread/tst-cond27.c66
-rw-r--r--sysdeps/pthread/tst-cond3.c111
-rw-r--r--sysdeps/pthread/tst-cond4.c263
-rw-r--r--sysdeps/pthread/tst-cond5.c105
-rw-r--r--sysdeps/pthread/tst-cond6.c233
-rw-r--r--sysdeps/pthread/tst-cond7.c167
-rw-r--r--sysdeps/pthread/tst-cond8-static.c1
-rw-r--r--sysdeps/pthread/tst-cond8.c276
-rw-r--r--sysdeps/pthread/tst-cond9.c149
29 files changed, 3778 insertions, 0 deletions
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
+ <https://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+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 <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <error.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+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 <drepper@redhat.com>, 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <error.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#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 <drepper@redhat.com>, 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <support/check.h>
+#include <support/test-driver.h>
+#include <support/timespec.h>
+#include <support/xthread.h>
+#include <support/xtime.h>
+
+/* 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 ==