diff options
Diffstat (limited to 'tools/regression/pthread')
| -rw-r--r-- | tools/regression/pthread/cv_cancel1/Makefile | 5 | ||||
| -rw-r--r-- | tools/regression/pthread/cv_cancel1/cv_cancel1.c | 85 | ||||
| -rw-r--r-- | tools/regression/pthread/mutex_isowned_np/Makefile | 5 | ||||
| -rw-r--r-- | tools/regression/pthread/mutex_isowned_np/mutex_isowned_np.c | 75 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/Makefile | 16 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/Test.cpp | 36 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/catch_pthread_exit.cpp | 34 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/cond_wait_cancel.cpp | 38 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/cond_wait_cancel2.cpp | 55 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/main_thread_exit.cpp | 17 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/sem_wait_cancel.cpp | 34 | ||||
| -rw-r--r-- | tools/regression/pthread/unwind/thread_normal_exit.cpp | 27 |
12 files changed, 427 insertions, 0 deletions
diff --git a/tools/regression/pthread/cv_cancel1/Makefile b/tools/regression/pthread/cv_cancel1/Makefile new file mode 100644 index 000000000000..1a27b8adfe78 --- /dev/null +++ b/tools/regression/pthread/cv_cancel1/Makefile @@ -0,0 +1,5 @@ +PROG= cv_cancel1 +MAN= +LIBADD= pthread + +.include <bsd.prog.mk> diff --git a/tools/regression/pthread/cv_cancel1/cv_cancel1.c b/tools/regression/pthread/cv_cancel1/cv_cancel1.c new file mode 100644 index 000000000000..c61a785628c1 --- /dev/null +++ b/tools/regression/pthread/cv_cancel1/cv_cancel1.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2006, David Xu <davidxu@freebsd.org> + * 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 unmodified, 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 AUTHOR ``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 AUTHOR 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 <pthread.h> +#include <stdio.h> +#include <unistd.h> + +#define NLOOPS 10 + +static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; + +static int wake; +static int stop; + +static void * +thr_routine(void *arg __unused) +{ + pthread_mutex_lock(&m); + while (wake == 0) + pthread_cond_wait(&cv, &m); + pthread_mutex_unlock(&m); + + while (stop == 0) + pthread_yield(); + return (NULL); +} + +int +main(void) +{ + pthread_t td; + int i; + void *result; + + pthread_setconcurrency(1); + for (i = 0; i < NLOOPS; ++i) { + stop = 0; + wake = 0; + + pthread_create(&td, NULL, thr_routine, NULL); + sleep(1); + printf("trying: %d\n", i); + pthread_mutex_lock(&m); + wake = 1; + pthread_cond_signal(&cv); + pthread_cancel(td); + pthread_mutex_unlock(&m); + stop = 1; + result = NULL; + pthread_join(td, &result); + if (result == PTHREAD_CANCELED) { + printf("the condition variable implementation does not\n" + "conform to SUSv3, a thread unblocked from\n" + "condition variable still can be canceled.\n"); + return (1); + } + } + + printf("OK\n"); + return (0); +} diff --git a/tools/regression/pthread/mutex_isowned_np/Makefile b/tools/regression/pthread/mutex_isowned_np/Makefile new file mode 100644 index 000000000000..31dbd470d7d5 --- /dev/null +++ b/tools/regression/pthread/mutex_isowned_np/Makefile @@ -0,0 +1,5 @@ +PROG= mutex_isowned_np +MAN= +LIBADD= pthread + +.include <bsd.prog.mk> diff --git a/tools/regression/pthread/mutex_isowned_np/mutex_isowned_np.c b/tools/regression/pthread/mutex_isowned_np/mutex_isowned_np.c new file mode 100644 index 000000000000..9032c7dd3968 --- /dev/null +++ b/tools/regression/pthread/mutex_isowned_np/mutex_isowned_np.c @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2008 Dag-Erling Smørgrav + * 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 + * in this position and unchanged. + * 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 AUTHOR 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 AUTHOR 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 <pthread.h> +#include <pthread_np.h> +#include <stdio.h> +#include <stdlib.h> + +static void * +thread(void *arg) +{ + pthread_mutex_t *mtx = arg; + + if (pthread_mutex_isowned_np(mtx) != 0) { + printf("pthread_mutex_isowned_np() returned non-zero\n" + "for a mutex held by another thread\n"); + exit(1); + } + return (NULL); +} + +int +main(void) +{ + pthread_t thr; + pthread_mutex_t mtx; + + pthread_mutex_init(&mtx, NULL); + if (pthread_mutex_isowned_np(&mtx) != 0) { + printf("pthread_mutex_isowned_np() returned non-zero\n" + "for a mutex that is not held\n"); + exit(1); + } + pthread_mutex_lock(&mtx); + if (pthread_mutex_isowned_np(&mtx) == 0) { + printf("pthread_mutex_isowned_np() returned zero\n" + "for a mutex we hold ourselves\n"); + exit(1); + } + pthread_create(&thr, NULL, thread, &mtx); + pthread_join(thr, NULL); + pthread_mutex_unlock(&mtx); + if (pthread_mutex_isowned_np(&mtx) != 0) { + printf("pthread_mutex_isowned_np() returned non-zero\n" + "for a mutex that is not held\n"); + exit(1); + } + + printf("OK\n"); + exit(0); +} diff --git a/tools/regression/pthread/unwind/Makefile b/tools/regression/pthread/unwind/Makefile new file mode 100644 index 000000000000..33d3787c0ee3 --- /dev/null +++ b/tools/regression/pthread/unwind/Makefile @@ -0,0 +1,16 @@ +all: main_thread_exit thread_normal_exit sem_wait_cancel \ + cond_wait_cancel cond_wait_cancel2 catch_pthread_exit + +.cpp: + c++ -o $@ $< -lpthread + +main_thread_exit: main_thread_exit.cpp +thread_normal_exit: thread_normal_exit.cpp +sem_wait_cancel: sem_wait_cancel.cpp +cond_wait_cancel: cond_wait_cancel.cpp +cond_wait_cancel2: cond_wait_cancel2.cpp +catch_pthread_exit: catch_pthread_exit.cpp + +clean: .PHONY + rm -rf main_thread_exit thread_normal_exit sem_wait_cancel \ + cond_wait_cancel cond_wait_cancel2 catch_pthread_exit diff --git a/tools/regression/pthread/unwind/Test.cpp b/tools/regression/pthread/unwind/Test.cpp new file mode 100644 index 000000000000..bad63be44798 --- /dev/null +++ b/tools/regression/pthread/unwind/Test.cpp @@ -0,0 +1,36 @@ + +static int destructed; +static int destructed2; + +class Test { +public: + Test() { printf("Test::Test()\n"); } + ~Test() { printf("Test::~Test()\n"); destructed = 1; } +}; + +void +cleanup_handler(void *arg __unused) +{ + destructed2 = 1; + printf("%s()\n", __func__); +} + +void +check_destruct(void) +{ + if (!destructed) + printf("Bug, object destructor is not called\n"); + else + printf("OK\n"); +} + +void +check_destruct2(void) +{ + if (!destructed) + printf("Bug, object destructor is not called\n"); + else if (!destructed2) + printf("Bug, cleanup handler is not called\n"); + else + printf("OK\n"); +} diff --git a/tools/regression/pthread/unwind/catch_pthread_exit.cpp b/tools/regression/pthread/unwind/catch_pthread_exit.cpp new file mode 100644 index 000000000000..b5074cd4beb1 --- /dev/null +++ b/tools/regression/pthread/unwind/catch_pthread_exit.cpp @@ -0,0 +1,34 @@ +/* try to catch thread exiting, and rethrow the exception */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +static int caught; + +static void * +thr_routine(void *arg __unused) +{ + try { + pthread_exit(NULL); + } catch (...) { + caught = 1; + printf("thread exiting exception caught\n"); + /* rethrow */ + throw; + } +} + +int +main() +{ + pthread_t td; + + pthread_create(&td, NULL, thr_routine, NULL); + pthread_join(td, NULL); + if (caught) + printf("OK\n"); + else + printf("failure\n"); + return (0); +} diff --git a/tools/regression/pthread/unwind/cond_wait_cancel.cpp b/tools/regression/pthread/unwind/cond_wait_cancel.cpp new file mode 100644 index 000000000000..d241b55909b6 --- /dev/null +++ b/tools/regression/pthread/unwind/cond_wait_cancel.cpp @@ -0,0 +1,38 @@ +/* Test stack unwinding for pthread_cond_wait function */ + +#include <pthread.h> +#include <stdio.h> +#include <semaphore.h> +#include <unistd.h> + +#include "Test.cpp" + +static pthread_mutex_t mtx; +static pthread_cond_t cv; + +static void * +thr(void *arg __unused) +{ + Test t; + + pthread_mutex_lock(&mtx); + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); + printf("Bug, thread shouldn't be here.\n"); + return (0); +} + +int +main() +{ + pthread_t td; + + pthread_mutex_init(&mtx, NULL); + pthread_cond_init(&cv, NULL); + pthread_create(&td, NULL, thr, NULL); + sleep(1); + pthread_cancel(td); + pthread_join(td, NULL); + check_destruct(); + return (0); +} diff --git a/tools/regression/pthread/unwind/cond_wait_cancel2.cpp b/tools/regression/pthread/unwind/cond_wait_cancel2.cpp new file mode 100644 index 000000000000..1763e115435b --- /dev/null +++ b/tools/regression/pthread/unwind/cond_wait_cancel2.cpp @@ -0,0 +1,55 @@ +/* + * + * Test stack unwinding for mixed pthread_cleanup_push/pop and C++ + * object, both should work together. + * + */ + +#include <pthread.h> +#include <stdio.h> +#include <semaphore.h> +#include <unistd.h> + +#include "Test.cpp" + +static pthread_mutex_t mtx; +static pthread_cond_t cv; + +static void f() +{ + Test t; + + pthread_mutex_lock(&mtx); + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); + printf("Bug, thread shouldn't be here.\n"); +} + +static void g() +{ + f(); +} + +static void * +thr(void *arg __unused) +{ + pthread_cleanup_push(cleanup_handler, NULL); + g(); + pthread_cleanup_pop(0); + return (0); +} + +int +main() +{ + pthread_t td; + + pthread_mutex_init(&mtx, NULL); + pthread_cond_init(&cv, NULL); + pthread_create(&td, NULL, thr, NULL); + sleep(1); + pthread_cancel(td); + pthread_join(td, NULL); + check_destruct2(); + return (0); +} diff --git a/tools/regression/pthread/unwind/main_thread_exit.cpp b/tools/regression/pthread/unwind/main_thread_exit.cpp new file mode 100644 index 000000000000..c3ee859a5f0f --- /dev/null +++ b/tools/regression/pthread/unwind/main_thread_exit.cpp @@ -0,0 +1,17 @@ +/* check unwinding for main thread */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include "Test.cpp" + +int +main() +{ + Test test; + + atexit(check_destruct); + pthread_exit((void *)1); + return (0); +} diff --git a/tools/regression/pthread/unwind/sem_wait_cancel.cpp b/tools/regression/pthread/unwind/sem_wait_cancel.cpp new file mode 100644 index 000000000000..45f881c521fe --- /dev/null +++ b/tools/regression/pthread/unwind/sem_wait_cancel.cpp @@ -0,0 +1,34 @@ +/* Test stack unwinding for libc's sem */ + +#include <pthread.h> +#include <stdio.h> +#include <semaphore.h> +#include <unistd.h> + +#include "Test.cpp" + +static sem_t sem; + +static void * +thr(void *arg __unused) +{ + Test t; + + sem_wait(&sem); + printf("Bug, thread shouldn't be here.\n"); + return (0); +} + +int +main() +{ + pthread_t td; + + sem_init(&sem, 0, 0); + pthread_create(&td, NULL, thr, NULL); + sleep(1); + pthread_cancel(td); + pthread_join(td, NULL); + check_destruct(); + return (0); +} diff --git a/tools/regression/pthread/unwind/thread_normal_exit.cpp b/tools/regression/pthread/unwind/thread_normal_exit.cpp new file mode 100644 index 000000000000..3549db432f38 --- /dev/null +++ b/tools/regression/pthread/unwind/thread_normal_exit.cpp @@ -0,0 +1,27 @@ +/* test stack unwinding for a new thread */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include "Test.cpp" + +static void * +thr_routine(void *arg __unused) +{ + Test test; + + pthread_exit(NULL); + printf("Bug, thread shouldn't be here\n"); +} + +int +main() +{ + pthread_t td; + + pthread_create(&td, NULL, thr_routine, NULL); + pthread_join(td, NULL); + check_destruct(); + return (0); +} |
