aboutsummaryrefslogtreecommitdiff
path: root/lib/libpthread
diff options
context:
space:
mode:
authorEnji Cooper <ngie@FreeBSD.org>2023-08-11 08:41:49 +0000
committerEnji Cooper <ngie@FreeBSD.org>2023-08-11 08:41:49 +0000
commitdc9c7dc6ec9ecb5449d71d79ae13f9782c866b73 (patch)
tree77811130a73711377eb46a3e3eb9fac15fdcf746 /lib/libpthread
parentd328162dcb73d9041fe8ceb9fbae7276c3dacb53 (diff)
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/Makefile11
-rw-r--r--lib/libpthread/h_resolv.c27
-rw-r--r--lib/libpthread/h_thread_local_dtor.cpp80
-rw-r--r--[-rwxr-xr-x]lib/libpthread/t_atexit.sh0
-rw-r--r--lib/libpthread/t_call_once.c89
-rw-r--r--[-rwxr-xr-x]lib/libpthread/t_cancel.sh0
-rw-r--r--lib/libpthread/t_cnd.c175
-rw-r--r--lib/libpthread/t_cond.c6
-rw-r--r--lib/libpthread/t_condwait.c23
-rw-r--r--[-rwxr-xr-x]lib/libpthread/t_exit.sh0
-rw-r--r--lib/libpthread/t_join.c11
-rw-r--r--lib/libpthread/t_mtx.c212
-rw-r--r--lib/libpthread/t_mutex.c162
-rw-r--r--lib/libpthread/t_once.c5
-rw-r--r--[-rwxr-xr-x]lib/libpthread/t_resolv.sh0
-rw-r--r--lib/libpthread/t_swapcontext.c24
-rw-r--r--lib/libpthread/t_thrd.c237
-rw-r--r--lib/libpthread/t_thread_local_dtor.sh41
-rw-r--r--lib/libpthread/t_tss.c174
19 files changed, 1071 insertions, 206 deletions
diff --git a/lib/libpthread/Makefile b/lib/libpthread/Makefile
index cb84bcd0a807..6e689f263a1b 100644
--- a/lib/libpthread/Makefile
+++ b/lib/libpthread/Makefile
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.12 2016/10/30 16:17:16 kamil Exp $
+# $NetBSD: Makefile,v 1.15 2020/06/21 07:06:05 lukem Exp $
NOMAN= # defined
@@ -38,6 +38,7 @@ TESTS_C+= t_sigsuspend
TESTS_C+= t_siglongjmp
TESTS_C+= t_sleep
TESTS_C+= t_swapcontext
+TESTS_SH+= t_thread_local_dtor
TESTS_C+= t_timedmutex
LDADD.t_sem+= -lrt
@@ -47,6 +48,14 @@ PROGS= h_atexit
PROGS+= h_cancel
PROGS+= h_exit
PROGS+= h_resolv
+PROGS_CXX+= h_thread_local_dtor
+
+TESTS_C+= t_call_once t_cnd t_mtx t_thrd t_tss # C11 threads(3)
+
+COPTS.h_thread_local_dtor.cpp+= -std=c++11
+# Deal with questionable warning and header quality in libstdc++.
+COPTS.h_thread_local_dtor.cpp+= ${${ACTIVE_CC} == "gcc" :? -Wno-ctor-dtor-privacy -Wno-sign-compare -Wno-shadow :}
+SRCS.h_thread_local_dtor= h_thread_local_dtor.cpp
FILESDIR= ${TESTSDIR}
FILES= d_mach
diff --git a/lib/libpthread/h_resolv.c b/lib/libpthread/h_resolv.c
index 9c5fedcc2e7f..977cc02ec51f 100644
--- a/lib/libpthread/h_resolv.c
+++ b/lib/libpthread/h_resolv.c
@@ -1,4 +1,4 @@
-/* $NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */
+/* $NetBSD: h_resolv.c,v 1.3 2019/03/06 01:20:15 christos Exp $ */
/*-
* Copyright (c) 2004, 2008 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $");
+__RCSID("$NetBSD: h_resolv.c,v 1.3 2019/03/06 01:20:15 christos Exp $");
#include <pthread.h>
#include <stdio.h>
@@ -56,7 +56,7 @@ static void usage(void) __attribute__((__noreturn__));
static void load(const char *);
static void resolvone(int);
static void *resolvloop(void *);
-static void run(int *);
+static pthread_t run(int *);
static pthread_mutex_t stats = PTHREAD_MUTEX_INITIALIZER;
@@ -77,7 +77,7 @@ load(const char *fname)
char *line;
if ((fp = fopen(fname, "r")) == NULL)
- err(1, "Cannot open `%s'", fname);
+ err(EXIT_FAILURE, "Cannot open `%s'", fname);
while ((line = fgetln(fp, &len)) != NULL) {
char c = line[len];
char *ptr;
@@ -130,18 +130,20 @@ resolvloop(void *p)
return NULL;
}
-static void
+static pthread_t
run(int *nhosts)
{
pthread_t self = pthread_self();
if (pthread_create(&self, NULL, resolvloop, nhosts) != 0)
- err(1, "pthread_create");
+ err(EXIT_FAILURE, "pthread_create");
+ return self;
}
int
main(int argc, char *argv[])
{
int nthreads = NTHREADS;
+ pthread_t *threads;
int nhosts = NHOSTS;
int i, c, done, *nleft;
hosts = sl_init();
@@ -170,16 +172,18 @@ main(int argc, char *argv[])
usage();
if ((nleft = malloc(nthreads * sizeof(int))) == NULL)
- err(1, "malloc");
+ err(EXIT_FAILURE, "malloc");
if ((ask = calloc(hosts->sl_cur, sizeof(int))) == NULL)
- err(1, "calloc");
+ err(EXIT_FAILURE, "calloc");
if ((got = calloc(hosts->sl_cur, sizeof(int))) == NULL)
- err(1, "calloc");
+ err(EXIT_FAILURE, "calloc");
+ if ((threads = malloc(nthreads * sizeof(pthread_t))) == NULL)
+ err(EXIT_FAILURE, "calloc");
for (i = 0; i < nthreads; i++) {
nleft[i] = nhosts;
- run(&nleft[i]);
+ threads[i] = run(&nleft[i]);
}
for (done = 0; !done;) {
@@ -200,6 +204,9 @@ main(int argc, char *argv[])
c++;
}
}
+ for (i = 0; i < nthreads; i++)
+ pthread_join(threads[i], NULL);
+ free(threads);
free(nleft);
free(ask);
free(got);
diff --git a/lib/libpthread/h_thread_local_dtor.cpp b/lib/libpthread/h_thread_local_dtor.cpp
new file mode 100644
index 000000000000..337c207502db
--- /dev/null
+++ b/lib/libpthread/h_thread_local_dtor.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Tavian Barnes. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: h_thread_local_dtor.cpp,v 1.1 2017/07/11 15:21:36 joerg Exp $");
+
+#include <cstdlib>
+#include <thread>
+
+static int seq;
+
+class OrderChecker {
+public:
+ explicit OrderChecker(int n) : n_{n} { }
+
+ ~OrderChecker() {
+ if (seq != n_) {
+ printf("Unexpected sequence point: %d\n", 3);
+ _Exit(1);
+ }
+ ++seq;
+ }
+
+private:
+ int n_;
+};
+
+template <int ID>
+class CreatesThreadLocalInDestructor {
+public:
+ ~CreatesThreadLocalInDestructor() {
+ thread_local OrderChecker checker{ID};
+ }
+};
+
+OrderChecker global{7};
+
+void thread_fn() {
+ static OrderChecker fn_static{5};
+ thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
+ thread_local OrderChecker fn_thread_local{1};
+ thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
+}
+
+int main() {
+ static OrderChecker fn_static{6};
+
+ std::thread{thread_fn}.join();
+ if (seq != 3) {
+ printf("Unexpected sequence point: %d\n", 3);
+ _Exit(1);
+ }
+
+ thread_local OrderChecker fn_thread_local{4};
+ thread_local CreatesThreadLocalInDestructor<3> creates_tl;
+
+ return 0;
+}
diff --git a/lib/libpthread/t_atexit.sh b/lib/libpthread/t_atexit.sh
index 7b99618e5bf3..7b99618e5bf3 100755..100644
--- a/lib/libpthread/t_atexit.sh
+++ b/lib/libpthread/t_atexit.sh
diff --git a/lib/libpthread/t_call_once.c b/lib/libpthread/t_call_once.c
new file mode 100644
index 000000000000..92774ecced26
--- /dev/null
+++ b/lib/libpthread/t_call_once.c
@@ -0,0 +1,89 @@
+/* $NetBSD: t_call_once.c,v 1.1 2019/04/24 11:43:19 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Kamil Rytarowski.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2019\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_call_once.c,v 1.1 2019/04/24 11:43:19 kamil Exp $");
+
+#include <threads.h>
+
+#include <atf-c.h>
+
+ATF_TC(call_once);
+ATF_TC_HEAD(call_once, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 call_once(3)");
+}
+
+#define CO_THREADS 8
+
+static int co_val;
+static once_flag oflag = ONCE_FLAG_INIT;
+
+static void
+called_once(void)
+{
+
+ ++co_val;
+}
+
+static int
+co_func(void *arg __unused)
+{
+
+ call_once(&oflag, called_once);
+
+ return 0;
+}
+
+ATF_TC_BODY(call_once, tc)
+{
+ thrd_t t[CO_THREADS];
+ size_t i;
+
+ for (i = 0; i < CO_THREADS; i++) {
+ ATF_REQUIRE_EQ(thrd_create(&t[i], co_func, NULL), thrd_success);
+ }
+
+ for (i = 0; i < CO_THREADS; i++) {
+ ATF_REQUIRE_EQ(thrd_join(t[i], NULL), thrd_success);
+ }
+
+ ATF_REQUIRE_EQ(co_val, 1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, call_once);
+
+ return atf_no_error();
+}
diff --git a/lib/libpthread/t_cancel.sh b/lib/libpthread/t_cancel.sh
index 4a0701ef3c76..4a0701ef3c76 100755..100644
--- a/lib/libpthread/t_cancel.sh
+++ b/lib/libpthread/t_cancel.sh
diff --git a/lib/libpthread/t_cnd.c b/lib/libpthread/t_cnd.c
new file mode 100644
index 000000000000..c7846594f0a4
--- /dev/null
+++ b/lib/libpthread/t_cnd.c
@@ -0,0 +1,175 @@
+/* $NetBSD: t_cnd.c,v 1.1 2019/04/24 11:43:19 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Kamil Rytarowski.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2019\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_cnd.c,v 1.1 2019/04/24 11:43:19 kamil Exp $");
+
+#include <stdbool.h>
+#include <threads.h>
+#include <time.h>
+
+#include <atf-c.h>
+
+ATF_TC(cnd_init);
+ATF_TC_HEAD(cnd_init, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 cnd_init(3)");
+}
+
+ATF_TC_BODY(cnd_init, tc)
+{
+ cnd_t c;
+
+ ATF_REQUIRE_EQ(cnd_init(&c), thrd_success);
+ cnd_destroy(&c);
+}
+
+#define B_THREADS 8
+
+static mtx_t b_m;
+static cnd_t b_c;
+static bool b_finished;
+
+static int
+b_func(void *arg)
+{
+ bool signal;
+
+ signal = (bool)(intptr_t)arg;
+
+ ATF_REQUIRE_EQ(mtx_lock(&b_m), thrd_success);
+ while (!b_finished) {
+ ATF_REQUIRE_EQ(cnd_wait(&b_c, &b_m), thrd_success);
+ }
+ ATF_REQUIRE_EQ(mtx_unlock(&b_m), thrd_success);
+
+ if (signal) {
+ ATF_REQUIRE_EQ(cnd_signal(&b_c), thrd_success);
+ }
+
+ return 0;
+}
+
+static void
+cnd_notify(bool signal)
+{
+ size_t i;
+ thrd_t t[B_THREADS];
+ void *n;
+
+ n = (void *)(intptr_t)signal;
+
+ ATF_REQUIRE_EQ(mtx_init(&b_m, mtx_plain), thrd_success);
+ ATF_REQUIRE_EQ(cnd_init(&b_c), thrd_success);
+
+ for (i = 0; i < B_THREADS; i++) {
+ ATF_REQUIRE_EQ(thrd_create(&t[i], b_func, n), thrd_success);
+ }
+
+ ATF_REQUIRE_EQ(mtx_lock(&b_m), thrd_success);
+ b_finished = true;
+ ATF_REQUIRE_EQ(mtx_unlock(&b_m), thrd_success);
+
+ if (signal) {
+ ATF_REQUIRE_EQ(cnd_signal(&b_c), thrd_success);
+ } else {
+ ATF_REQUIRE_EQ(cnd_broadcast(&b_c), thrd_success);
+ }
+
+ for (i = 0; i < B_THREADS; i++) {
+ ATF_REQUIRE_EQ(thrd_join(t[i], NULL), thrd_success);
+ }
+
+ mtx_destroy(&b_m);
+ cnd_destroy(&b_c);
+}
+
+ATF_TC(cnd_broadcast);
+ATF_TC_HEAD(cnd_broadcast, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 cnd_broadcast(3)");
+}
+
+ATF_TC_BODY(cnd_broadcast, tc)
+{
+
+ cnd_notify(false);
+}
+
+ATF_TC(cnd_signal);
+ATF_TC_HEAD(cnd_signal, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 cnd_signal(3)");
+}
+
+ATF_TC_BODY(cnd_signal, tc)
+{
+
+ cnd_notify(true);
+}
+
+ATF_TC(cnd_timedwait);
+ATF_TC_HEAD(cnd_timedwait, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 cnd_timedwait(3)");
+}
+
+ATF_TC_BODY(cnd_timedwait, tc)
+{
+ mtx_t m;
+ cnd_t c;
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain), thrd_success);
+ ATF_REQUIRE_EQ(cnd_init(&c), thrd_success);
+
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(cnd_timedwait(&c, &m, &ts), thrd_timedout);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+
+ mtx_destroy(&m);
+ cnd_destroy(&c);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, cnd_init);
+ ATF_TP_ADD_TC(tp, cnd_broadcast);
+ ATF_TP_ADD_TC(tp, cnd_signal);
+ ATF_TP_ADD_TC(tp, cnd_timedwait);
+
+ return atf_no_error();
+}
diff --git a/lib/libpthread/t_cond.c b/lib/libpthread/t_cond.c
index 83a3833015d1..8c93d706af23 100644
--- a/lib/libpthread/t_cond.c
+++ b/lib/libpthread/t_cond.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_cond.c,v 1.7 2016/07/03 14:24:59 christos Exp $ */
+/* $NetBSD: t_cond.c,v 1.8 2020/06/10 21:46:50 ad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_cond.c,v 1.7 2016/07/03 14:24:59 christos Exp $");
+__RCSID("$NetBSD: t_cond.c,v 1.8 2020/06/10 21:46:50 ad Exp $");
#include <sys/time.h>
@@ -329,7 +329,7 @@ pthread_cond_timedwait_func(void *arg)
* Sometimes we catch ESRCH.
* This should never happen.
*/
- ATF_REQUIRE(rv == ETIMEDOUT);
+ ATF_REQUIRE(rv == ETIMEDOUT || rv == 0);
PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
}
}
diff --git a/lib/libpthread/t_condwait.c b/lib/libpthread/t_condwait.c
index 58b4a8bc155a..fcdaa27acf94 100644
--- a/lib/libpthread/t_condwait.c
+++ b/lib/libpthread/t_condwait.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_condwait.c,v 1.5 2017/01/16 16:29:19 christos Exp $ */
+/* $NetBSD: t_condwait.c,v 1.10 2022/12/11 10:02:53 kre Exp $ */
/*
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -26,7 +26,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_condwait.c,v 1.5 2017/01/16 16:29:19 christos Exp $");
+__RCSID("$NetBSD: t_condwait.c,v 1.10 2022/12/11 10:02:53 kre Exp $");
#include <sys/time.h>
#include <errno.h>
@@ -43,7 +43,7 @@ __RCSID("$NetBSD: t_condwait.c,v 1.5 2017/01/16 16:29:19 christos Exp $");
#include "h_common.h"
-#define WAITTIME 2 /* Timeout wait secound */
+#define WAITTIME 2 /* Timeout wait in seconds */
static const int debug = 1;
@@ -78,21 +78,18 @@ run(void *param)
case ETIMEDOUT:
/* Timeout */
ATF_REQUIRE_EQ(clock_gettime(clck, &te), 0);
- timespecsub(&te, &to, &to);
if (debug) {
printf("timeout: %lld.%09ld sec\n",
(long long)te.tv_sec, te.tv_nsec);
+ timespecsub(&te, &to, &to);
printf("elapsed: %lld.%09ld sec\n",
(long long)to.tv_sec, to.tv_nsec);
}
- if (isQEMU()) {
- double to_seconds = to.tv_sec + 1e-9 * to.tv_nsec;
- ATF_REQUIRE(to_seconds >= WAITTIME * 0.9);
- /* Loose upper limit because of qemu timing bugs */
- ATF_REQUIRE(to_seconds < WAITTIME * 2.5);
- } else {
- ATF_REQUIRE_EQ(to.tv_sec, WAITTIME);
- }
+ if (clck == CLOCK_MONOTONIC)
+ ATF_REQUIRE(timespeccmp(&te, &ts, >=));
+ break;
+ case 0:
+ atf_tc_fail("pthread_cond_timedwait returned before timeout");
break;
default:
ATF_REQUIRE_MSG(0, "pthread_cond_timedwait: %s", strerror(ret));
@@ -141,5 +138,5 @@ ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, cond_wait_real);
ATF_TP_ADD_TC(tp, cond_wait_mono);
- return 0;
+ return atf_no_error();
}
diff --git a/lib/libpthread/t_exit.sh b/lib/libpthread/t_exit.sh
index 7fbd689f5a68..7fbd689f5a68 100755..100644
--- a/lib/libpthread/t_exit.sh
+++ b/lib/libpthread/t_exit.sh
diff --git a/lib/libpthread/t_join.c b/lib/libpthread/t_join.c
index 7f6f8348acfa..3823b0b77968 100644
--- a/lib/libpthread/t_join.c
+++ b/lib/libpthread/t_join.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $ */
+/* $NetBSD: t_join.c,v 1.10 2020/01/29 13:40:23 kamil Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $");
+__RCSID("$NetBSD: t_join.c,v 1.10 2020/01/29 13:40:23 kamil Exp $");
#include <errno.h>
#include <pthread.h>
@@ -104,6 +104,7 @@ threadfunc1(void *arg)
error = true;
ATF_REQUIRE(pthread_attr_setstacksize(&attr, STACKSIZE * (i + 1)) == 0);
+ ATF_REQUIRE(pthread_attr_setguardsize(&attr, STACKSIZE * (i + 2)) == 0);
rv = pthread_create(&thread[i], &attr, threadfunc2, (void *)i);
@@ -148,13 +149,15 @@ threadfunc2(void *arg)
static uintptr_t i = 0;
uintptr_t j;
pthread_attr_t attr;
- size_t stacksize;
+ size_t stacksize, guardsize;
j = (uintptr_t)arg;
- ATF_REQUIRE(pthread_attr_get_np(pthread_self(), &attr) == 0);
+ ATF_REQUIRE(pthread_getattr_np(pthread_self(), &attr) == 0);
ATF_REQUIRE(pthread_attr_getstacksize(&attr, &stacksize) == 0);
ATF_REQUIRE(stacksize == STACKSIZE * (j + 1));
+ ATF_REQUIRE(pthread_attr_getguardsize(&attr, &guardsize) == 0);
+ ATF_REQUIRE(guardsize == STACKSIZE * (j + 2));
ATF_REQUIRE(pthread_attr_destroy(&attr) == 0);
if (i++ == j)
diff --git a/lib/libpthread/t_mtx.c b/lib/libpthread/t_mtx.c
new file mode 100644
index 000000000000..c559ff9087db
--- /dev/null
+++ b/lib/libpthread/t_mtx.c
@@ -0,0 +1,212 @@
+/* $NetBSD: t_mtx.c,v 1.2 2020/06/11 11:40:54 martin Exp $ */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Kamil Rytarowski.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2019\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mtx.c,v 1.2 2020/06/11 11:40:54 martin Exp $");
+
+#include <time.h>
+#include <threads.h>
+
+#include <atf-c.h>
+
+ATF_TC(mtx_init);
+ATF_TC_HEAD(mtx_init, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 mtx_init(3)");
+}
+
+ATF_TC_BODY(mtx_init, tc)
+{
+ mtx_t m;
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain | mtx_recursive), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed | mtx_recursive), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_recursive), thrd_error);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain | mtx_timed), thrd_error);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, -1), thrd_error);
+}
+
+ATF_TC(mtx_lock);
+ATF_TC_HEAD(mtx_lock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 mtx_lock(3)");
+}
+
+ATF_TC_BODY(mtx_lock, tc)
+{
+ mtx_t m;
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain | mtx_recursive), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed | mtx_recursive), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+}
+
+ATF_TC(mtx_timedlock);
+ATF_TC_HEAD(mtx_timedlock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 mtx_timedlock(3)");
+}
+
+ATF_TC_BODY(mtx_timedlock, tc)
+{
+ mtx_t m;
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed), thrd_success);
+ ATF_REQUIRE_EQ(mtx_timedlock(&m, &ts), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_timedlock(&m, &ts), thrd_timedout);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed | mtx_recursive), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_timedlock(&m, &ts), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed | mtx_recursive), thrd_success);
+ ATF_REQUIRE_EQ(mtx_timedlock(&m, &ts), thrd_success);
+ ATF_REQUIRE_EQ(mtx_timedlock(&m, &ts), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed | mtx_recursive), thrd_success);
+ ATF_REQUIRE_EQ(mtx_timedlock(&m, &ts), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+}
+
+ATF_TC(mtx_trylock);
+ATF_TC_HEAD(mtx_trylock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 mtx_trylock(3)");
+}
+
+ATF_TC_BODY(mtx_trylock, tc)
+{
+ mtx_t m;
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain), thrd_success);
+ ATF_REQUIRE_EQ(mtx_trylock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_trylock(&m), thrd_busy);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_plain | mtx_recursive), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_trylock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed), thrd_success);
+ ATF_REQUIRE_EQ(mtx_trylock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_trylock(&m), thrd_busy);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+
+ ATF_REQUIRE_EQ(mtx_init(&m, mtx_timed | mtx_recursive), thrd_success);
+ ATF_REQUIRE_EQ(mtx_lock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_trylock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ ATF_REQUIRE_EQ(mtx_unlock(&m), thrd_success);
+ mtx_destroy(&m);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mtx_init);
+ ATF_TP_ADD_TC(tp, mtx_lock);
+ ATF_TP_ADD_TC(tp, mtx_timedlock);
+ ATF_TP_ADD_TC(tp, mtx_trylock);
+
+ return atf_no_error();
+}
diff --git a/lib/libpthread/t_mutex.c b/lib/libpthread/t_mutex.c
index b706e462f3db..cef0d53e8fe8 100644
--- a/lib/libpthread/t_mutex.c
+++ b/lib/libpthread/t_mutex.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_mutex.c,v 1.15 2017/01/16 16:23:41 christos Exp $ */
+/* $NetBSD: t_mutex.c,v 1.20 2022/05/07 05:13:17 rin Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_mutex.c,v 1.15 2017/01/16 16:23:41 christos Exp $");
+__RCSID("$NetBSD: t_mutex.c,v 1.20 2022/05/07 05:13:17 rin Exp $");
#include <sys/time.h> /* For timespecadd */
#include <inttypes.h> /* For UINT16_MAX */
@@ -148,9 +148,7 @@ ATF_TC(mutex2);
ATF_TC_HEAD(mutex2, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks mutexes");
-#if defined(__powerpc__)
- atf_tc_set_md_var(tc, "timeout", "40");
-#endif
+ atf_tc_set_md_var(tc, "timeout", "600");
}
ATF_TC_BODY(mutex2, tc)
{
@@ -160,10 +158,6 @@ ATF_TC_BODY(mutex2, tc)
printf("1: Mutex-test 2\n");
-#if defined(__powerpc__)
- atf_tc_expect_timeout("PR port-powerpc/44387");
-#endif
-
PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
global_x = 0;
@@ -188,14 +182,6 @@ ATF_TC_BODY(mutex2, tc)
printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
global_x, (long)joinval);
ATF_REQUIRE_EQ(global_x, 20000000);
-
-#if defined(__powerpc__)
- /* XXX force a timeout in ppc case since an un-triggered race
- otherwise looks like a "failure" */
- /* We sleep for longer than the timeout to make ATF not
- complain about unexpected success */
- sleep(41);
-#endif
}
static void *
@@ -219,9 +205,7 @@ ATF_TC_HEAD(mutex3, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks mutexes using a static "
"initializer");
-#if defined(__powerpc__)
- atf_tc_set_md_var(tc, "timeout", "40");
-#endif
+ atf_tc_set_md_var(tc, "timeout", "600");
}
ATF_TC_BODY(mutex3, tc)
{
@@ -231,10 +215,6 @@ ATF_TC_BODY(mutex3, tc)
printf("1: Mutex-test 3\n");
-#if defined(__powerpc__)
- atf_tc_expect_timeout("PR port-powerpc/44387");
-#endif
-
global_x = 0;
count = count2 = 10000000;
@@ -257,14 +237,6 @@ ATF_TC_BODY(mutex3, tc)
printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
global_x, (long)joinval);
ATF_REQUIRE_EQ(global_x, 20000000);
-
-#if defined(__powerpc__)
- /* XXX force a timeout in ppc case since an un-triggered race
- otherwise looks like a "failure" */
- /* We sleep for longer than the timeout to make ATF not
- complain about unexpected success */
- sleep(41);
-#endif
}
static void *
@@ -401,131 +373,6 @@ ATF_TC_BODY(mutex5, tc)
PTHREAD_REQUIRE(pthread_join(child, NULL));
}
-static pthread_mutex_t mutex6;
-static int start = 0;
-static uintmax_t high_cnt = 0, low_cnt = 0, MAX_LOOP = 100000000;
-
-static void *
-high_prio(void* arg)
-{
- struct sched_param param;
- int policy;
- param.sched_priority = min_fifo_prio + 10;
- pthread_t childid = pthread_self();
-
- PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, &param));
- PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, &param));
- printf("high protect = %d, prio = %d\n",
- _sched_protect(-2), param.sched_priority);
- ATF_REQUIRE_EQ(policy, 1);
- printf("high prio = %d\n", param.sched_priority);
- sleep(1);
- long tmp = 0;
- for (int i = 0; i < 20; i++) {
- while (high_cnt < MAX_LOOP) {
- tmp += (123456789 % 1234) * (987654321 % 54321);
- high_cnt += 1;
- }
- high_cnt = 0;
- sleep(1);
- }
- PTHREAD_REQUIRE(mutex_lock(&mutex6, &ts_lengthy));
- if (start == 0) start = 2;
- PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6));
-
- return 0;
-}
-
-static void *
-low_prio(void* arg)
-{
- struct sched_param param;
- int policy;
- param.sched_priority = min_fifo_prio;
- pthread_t childid = pthread_self();
- int res = _sched_protect(max_fifo_prio);
- ATF_REQUIRE_EQ(res, 0);
- PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, &param));
- PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, &param));
- printf("low protect = %d, prio = %d\n", _sched_protect(-2),
- param.sched_priority);
- ATF_REQUIRE_EQ(policy, 1);
- printf("low prio = %d\n", param.sched_priority);
- sleep(1);
- long tmp = 0;
- for (int i = 0; i < 20; i++) {
- while (low_cnt < MAX_LOOP) {
- tmp += (123456789 % 1234) * (987654321 % 54321);
- low_cnt += 1;
- }
- low_cnt = 0;
- sleep(1);
- }
- PTHREAD_REQUIRE(mutex_lock(&mutex6, &ts_lengthy));
- if (start == 0)
- start = 1;
- PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6));
-
- return 0;
-}
-
-ATF_TC(mutex6);
-ATF_TC_HEAD(mutex6, tc)
-{
- atf_tc_set_md_var(tc, "descr",
- "Checks scheduling for priority ceiling");
- atf_tc_set_md_var(tc, "require.user", "root");
-}
-
-/*
- * 1. main thread sets itself to be a realtime task and launched two tasks,
- * one has higher priority and the other has lower priority.
- * 2. each child thread(low and high priority thread) sets its scheduler and
- * priority.
- * 3. each child thread did several rounds of computation, after each round it
- * sleep 1 second.
- * 4. the child thread with low priority will call _sched_protect to increase
- * its protect priority.
- * 5. We verify the thread with low priority runs first.
- *
- * Why does it work? From the main thread, we launched the high
- * priority thread first. This gives this thread the benefit of
- * starting first. The low priority thread did not call _sched_protect(2).
- * The high priority thread should finish the task first. After each
- * round of computation, we call sleep, to put the task into the
- * sleep queue, and wake up again after the timer expires. This
- * gives the scheduler the chance to decide which task to run. So,
- * the thread with real high priority will always block the thread
- * with real low priority.
- *
- */
-ATF_TC_BODY(mutex6, tc)
-{
- struct sched_param param;
- int res;
- pthread_t high, low;
-
- min_fifo_prio = sched_get_priority_min(SCHED_FIFO);
- max_fifo_prio = sched_get_priority_max(SCHED_FIFO);
- PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
- printf("min_fifo_prio = %d, max_fifo_info = %d\n", min_fifo_prio,
- max_fifo_prio);
-
- param.sched_priority = min_fifo_prio;
- res = sched_setscheduler(getpid(), SCHED_FIFO, &param);
- printf("previous policy used = %d\n", res);
-
- res = sched_getscheduler(getpid());
- ATF_REQUIRE_EQ(res, 1);
- PTHREAD_REQUIRE(pthread_create(&high, NULL, high_prio, NULL));
- PTHREAD_REQUIRE(pthread_create(&low, NULL, low_prio, NULL));
- sleep(5);
- PTHREAD_REQUIRE(pthread_join(low, NULL));
- PTHREAD_REQUIRE(pthread_join(high, NULL));
-
- ATF_REQUIRE_EQ(start, 1);
-}
-
ATF_TC(mutexattr1);
ATF_TC_HEAD(mutexattr1, tc)
{
@@ -710,7 +557,6 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, mutex3);
ATF_TP_ADD_TC(tp, mutex4);
ATF_TP_ADD_TC(tp, mutex5);
- ATF_TP_ADD_TC(tp, mutex6);
ATF_TP_ADD_TC(tp, mutexattr1);
ATF_TP_ADD_TC(tp, mutexattr2);
diff --git a/lib/libpthread/t_once.c b/lib/libpthread/t_once.c
index 575d5d7ef890..650f3ee68dfd 100644
--- a/lib/libpthread/t_once.c
+++ b/lib/libpthread/t_once.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+/* $NetBSD: t_once.c,v 1.2 2017/08/25 22:59:47 ginsbach Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -29,8 +29,9 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+__RCSID("$NetBSD: t_once.c,v 1.2 2017/08/25 22:59:47 ginsbach Exp $");
+#include <sys/time.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
diff --git a/lib/libpthread/t_resolv.sh b/lib/libpthread/t_resolv.sh
index 847eadcaec24..847eadcaec24 100755..100644
--- a/lib/libpthread/t_resolv.sh
+++ b/lib/libpthread/t_resolv.sh
diff --git a/lib/libpthread/t_swapcontext.c b/lib/libpthread/t_swapcontext.c
index 677c51fc8601..69f004ead082 100644
--- a/lib/libpthread/t_swapcontext.c
+++ b/lib/libpthread/t_swapcontext.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_swapcontext.c,v 1.3 2017/01/16 16:27:06 christos Exp $ */
+/* $NetBSD: t_swapcontext.c,v 1.9 2018/02/28 21:36:50 uwe Exp $ */
/*
* Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD");
+__RCSID("$NetBSD: t_swapcontext.c,v 1.9 2018/02/28 21:36:50 uwe Exp $");
#include <sys/types.h>
#include <errno.h>
@@ -49,24 +49,18 @@ void *oself;
void *nself;
int val1, val2;
-/* ARGSUSED0 */
static void
-swapfunc(void *arg)
+swapfunc(void)
{
/*
- * If the test fails, we are very likely to crash
+ * If the test fails, we are very likely to crash
* without the opportunity to report
- */
+ */
nself = (void *)pthread_self();
printf("after swapcontext self = %p\n", nself);
ATF_REQUIRE_EQ(oself, nself);
printf("Test succeeded\n");
- /* Go back in main */
- ATF_REQUIRE(swapcontext(&nctx, &octx));
-
- /* NOTREACHED */
- return;
}
/* ARGSUSED0 */
@@ -75,15 +69,15 @@ threadfunc(void *arg)
{
nctx.uc_stack.ss_sp = stack;
nctx.uc_stack.ss_size = sizeof(stack);
-
- makecontext(&nctx, (void *)*swapfunc, 0);
-
+ nctx.uc_link = &octx;
+
+ makecontext(&nctx, swapfunc, 0);
+
oself = (void *)pthread_self();
printf("before swapcontext self = %p\n", oself);
ATF_REQUIRE_MSG(swapcontext(&octx, &nctx) != -1, "swapcontext failed: %s",
strerror(errno));
- /* NOTREACHED */
return NULL;
}
diff --git a/lib/libpthread/t_thrd.c b/lib/libpthread/t_thrd.c
new file mode 100644
index 000000000000..7cbebdae9d27
--- /dev/null
+++ b/lib/libpthread/t_thrd.c
@@ -0,0 +1,237 @@
+/* $NetBSD: t_thrd.c,v 1.2 2020/05/14 08:34:19 msaitoh Exp $ */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Kamil Rytarowski.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2019\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_thrd.c,v 1.2 2020/05/14 08:34:19 msaitoh Exp $");
+
+#include <signal.h>
+#include <stdbool.h>
+#include <threads.h>
+#include <time.h>
+
+#include <atf-c.h>
+
+ATF_TC(thrd_create);
+ATF_TC_HEAD(thrd_create, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 thrd_create(3)");
+}
+
+#define TC_ADDON 5
+
+static int
+tcr_func(void *arg)
+{
+ int a;
+
+ a = (int)(intptr_t)arg;
+
+ return a + TC_ADDON;
+}
+
+ATF_TC_BODY(thrd_create, tc)
+{
+ thrd_t t;
+ const int a = 5;
+ int b;
+ void *v;
+
+ v = (void *)(intptr_t)a;
+
+ ATF_REQUIRE_EQ(thrd_create(&t, tcr_func, v), thrd_success);
+ ATF_REQUIRE_EQ(thrd_join(t, &b), thrd_success);
+ ATF_REQUIRE_EQ(a + TC_ADDON, b);
+}
+
+ATF_TC(thrd_current);
+ATF_TC_HEAD(thrd_current, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 thrd_current(3)");
+}
+
+static int
+tcur_func(void *arg __unused)
+{
+
+ return 0;
+}
+
+ATF_TC_BODY(thrd_current, tc)
+{
+ thrd_t s, t;
+
+ s = thrd_current();
+
+ ATF_REQUIRE(thrd_equal(s, s) != 0);
+ ATF_REQUIRE_EQ(thrd_create(&t, tcur_func, NULL), thrd_success);
+ ATF_REQUIRE(thrd_equal(t, s) == 0);
+ ATF_REQUIRE(thrd_equal(s, t) == 0);
+ ATF_REQUIRE(thrd_equal(t, t) != 0);
+
+ ATF_REQUIRE_EQ(thrd_join(t, NULL), thrd_success);
+}
+
+ATF_TC(thrd_detach);
+ATF_TC_HEAD(thrd_detach, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 thrd_detach(3)");
+}
+
+static int
+tdet_func(void *arg __unused)
+{
+
+ return 0;
+}
+
+ATF_TC_BODY(thrd_detach, tc)
+{
+ thrd_t t;
+
+ ATF_REQUIRE_EQ(thrd_create(&t, tdet_func, NULL), thrd_success);
+ ATF_REQUIRE_EQ(thrd_detach(t), thrd_success);
+}
+
+ATF_TC(thrd_exit);
+ATF_TC_HEAD(thrd_exit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 thrd_exit(3)");
+}
+
+static void
+tex_func2(void)
+{
+
+ thrd_exit(1);
+}
+
+static int
+tex_func(void *arg __unused)
+{
+
+ tex_func2();
+
+ return -1;
+}
+
+ATF_TC_BODY(thrd_exit, tc)
+{
+ thrd_t t;
+ int b = 0;
+
+ ATF_REQUIRE_EQ(thrd_create(&t, tex_func, NULL), thrd_success);
+ ATF_REQUIRE_EQ(thrd_join(t, &b), thrd_success);
+ ATF_REQUIRE_EQ(b, 1);
+}
+
+ATF_TC(thrd_sleep);
+ATF_TC_HEAD(thrd_sleep, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 thrd_sleep(3)");
+}
+
+static int alarmed;
+
+static void
+alarm_handler(int signum)
+{
+
+ ATF_REQUIRE_EQ(signum, SIGALRM);
+ ++alarmed;
+}
+
+ATF_TC_BODY(thrd_sleep, tc)
+{
+ struct timespec start, stop, diff;
+ struct timespec ts, rem;
+ struct timespec zero;
+ struct sigaction sa;
+ struct itimerval timer;
+
+ zero.tv_sec = 0;
+ zero.tv_nsec = 0;
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = -1;
+ ATF_REQUIRE_EQ(!thrd_sleep(&ts, NULL), 0);
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1000000000/100; /* 1/100 sec */
+ ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &start), 0);
+ ATF_REQUIRE_EQ(thrd_sleep(&ts, &rem), 0);
+ ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &stop), 0);
+ timespecsub(&stop, &start, &diff);
+ ATF_REQUIRE(timespeccmp(&diff, &ts, >=));
+ ATF_REQUIRE(timespeccmp(&zero, &rem, ==));
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = 0;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = alarm_handler;
+ sigaction(SIGALRM, &sa, NULL);
+ memset(&timer, 0, sizeof(timer));
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = 100000; /* 100 msec */
+ ATF_REQUIRE_EQ(setitimer(ITIMER_MONOTONIC, &timer, NULL), 0);
+ ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &start), 0);
+ ATF_REQUIRE_EQ(!thrd_sleep(&ts, &rem), 0);
+ ATF_REQUIRE_EQ(clock_gettime(CLOCK_MONOTONIC, &stop), 0);
+ timespecsub(&stop, &start, &diff);
+ ATF_REQUIRE(timespeccmp(&diff, &ts, <));
+ ATF_REQUIRE(timespeccmp(&zero, &rem, !=));
+ ATF_REQUIRE_EQ(alarmed, 1);
+}
+
+ATF_TC(thrd_yield);
+ATF_TC_HEAD(thrd_yield, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 thrd_yield(3)");
+}
+
+ATF_TC_BODY(thrd_yield, tc)
+{
+
+ thrd_yield();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, thrd_create);
+ ATF_TP_ADD_TC(tp, thrd_current);
+ ATF_TP_ADD_TC(tp, thrd_detach);
+ ATF_TP_ADD_TC(tp, thrd_exit);
+ ATF_TP_ADD_TC(tp, thrd_sleep);
+ ATF_TP_ADD_TC(tp, thrd_yield);
+
+ return atf_no_error();
+}
diff --git a/lib/libpthread/t_thread_local_dtor.sh b/lib/libpthread/t_thread_local_dtor.sh
new file mode 100644
index 000000000000..439ebd798505
--- /dev/null
+++ b/lib/libpthread/t_thread_local_dtor.sh
@@ -0,0 +1,41 @@
+# $NetBSD: t_thread_local_dtor.sh,v 1.1 2017/07/11 15:21:36 joerg Exp $
+#
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case thread_local_dtor_order
+thread_local_dtor_order_head()
+{
+ atf_set "descr" "Checks destructor order for thread_local objects"
+}
+thread_local_dtor_order_body()
+{
+ atf_check -o ignore "$(atf_get_srcdir)/h_thread_local_dtor"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case thread_local_dtor_order
+}
diff --git a/lib/libpthread/t_tss.c b/lib/libpthread/t_tss.c
new file mode 100644
index 000000000000..7bdd231f22ca
--- /dev/null
+++ b/lib/libpthread/t_tss.c
@@ -0,0 +1,174 @@
+/* $NetBSD: t_tss.c,v 1.1 2019/04/24 11:43:19 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Kamil Rytarowski.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2019\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_tss.c,v 1.1 2019/04/24 11:43:19 kamil Exp $");
+
+#include <stdlib.h>
+#include <threads.h>
+
+#include <atf-c.h>
+
+ATF_TC(tss_create);
+ATF_TC_HEAD(tss_create, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 tss_create(3)");
+}
+
+ATF_TC_BODY(tss_create, tc)
+{
+ tss_t s;
+
+ ATF_REQUIRE_EQ(tss_create(&s, NULL), thrd_success);
+ tss_delete(s);
+}
+
+ATF_TC(tss_set);
+ATF_TC_HEAD(tss_set, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test C11 tss_set(3)");
+}
+
+ATF_TC_BODY(tss_set, tc)
+{
+ tss_t s;
+ int b = 5;
+ void *v;
+
+ v = (void *)(intptr_t)b;
+
+ ATF_REQUIRE_EQ(tss_create(&s, NULL), thrd_success);
+ ATF_REQUIRE_EQ(tss_get(s), NULL);
+ ATF_REQUIRE_EQ(tss_set(s, v), thrd_success);
+ ATF_REQUIRE_EQ(tss_get(s), v);
+
+ tss_delete(s);
+}
+
+ATF_TC(tss_destructor_main_thread);
+ATF_TC_HEAD(tss_destructor_main_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test C11 tss(3) destructor in main thread");
+}
+
+static void
+c_destructor_main(void *arg)
+{
+
+ abort();
+}
+
+ATF_TC_BODY(tss_destructor_main_thread, tc)
+{
+ tss_t s;
+ int b = 5;
+ void *v;
+
+ v = (void *)(intptr_t)b;
+
+ ATF_REQUIRE_EQ(tss_create(&s, c_destructor_main), thrd_success);
+ ATF_REQUIRE_EQ(tss_set(s, v), thrd_success);
+
+ tss_delete(s);
+
+ /* Destructor must NOT be called for tss_delete(3) */
+}
+
+ATF_TC(tss_destructor_thread_exit);
+ATF_TC_HEAD(tss_destructor_thread_exit, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test C11 tss(3) destructor on thread exit");
+}
+
+static tss_t s_empty, s_nonempty;
+static int c_iter_empty, c_iter_nonempty;
+
+static void
+c_destructor_thread_empty(void *arg)
+{
+
+ tss_set(s_empty, arg);
+ ++c_iter_empty;
+}
+
+static void
+c_destructor_thread_nonempty(void *arg)
+{
+
+ tss_set(s_nonempty, arg);
+ ++c_iter_nonempty;
+}
+
+static int
+t_func(void *arg __unused)
+{
+ int b = 5;
+ void *v;
+
+ v = (void *)(intptr_t)b;
+
+ ATF_REQUIRE_EQ(tss_set(s_nonempty, v), thrd_success);
+
+ return 0;
+}
+
+ATF_TC_BODY(tss_destructor_thread_exit, tc)
+{
+ thrd_t t;
+
+ ATF_REQUIRE_EQ(tss_create(&s_empty, c_destructor_thread_empty),
+ thrd_success);
+ ATF_REQUIRE_EQ(tss_create(&s_nonempty, c_destructor_thread_nonempty),
+ thrd_success);
+
+ ATF_REQUIRE_EQ(thrd_create(&t, t_func, NULL), thrd_success);
+ ATF_REQUIRE_EQ(thrd_join(t, NULL), thrd_success);
+
+ ATF_REQUIRE_EQ(c_iter_empty, 0);
+ ATF_REQUIRE_EQ(c_iter_nonempty, TSS_DTOR_ITERATIONS);
+
+ tss_delete(s_empty);
+ tss_delete(s_nonempty);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, tss_create);
+ ATF_TP_ADD_TC(tp, tss_set);
+ ATF_TP_ADD_TC(tp, tss_destructor_main_thread);
+ ATF_TP_ADD_TC(tp, tss_destructor_thread_exit);
+
+ return atf_no_error();
+}