diff options
author | Ed Maste <emaste@FreeBSD.org> | 2010-11-13 22:22:18 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2010-11-13 22:22:18 +0000 |
commit | 13ec45d6449d744a84d862496feadda5caabddb9 (patch) | |
tree | 7d9c8ef935652d99b24bfb3a071cd78e9bb8d01f /lib/libc_r/test | |
parent | d79326ecc875fe7885e8b19012c3c1fcf8ad89d3 (diff) |
Remove libc_r threading library. It has been disconnected from the build
for four years (since r162846).
Submitted by: Alexander Best arundel@
Notes
Notes:
svn path=/head/; revision=215269
Diffstat (limited to 'lib/libc_r/test')
-rw-r--r-- | lib/libc_r/test/Makefile | 115 | ||||
-rw-r--r-- | lib/libc_r/test/README | 28 | ||||
-rw-r--r-- | lib/libc_r/test/guard_b.c | 151 | ||||
-rw-r--r-- | lib/libc_r/test/guard_b.exp | 3 | ||||
-rwxr-xr-x | lib/libc_r/test/guard_s.pl | 69 | ||||
-rw-r--r-- | lib/libc_r/test/hello_b.c | 13 | ||||
-rw-r--r-- | lib/libc_r/test/hello_d.c | 38 | ||||
-rw-r--r-- | lib/libc_r/test/hello_d.exp | 1 | ||||
-rw-r--r-- | lib/libc_r/test/hello_s.c | 47 | ||||
-rw-r--r-- | lib/libc_r/test/join_leak_d.c | 112 | ||||
-rw-r--r-- | lib/libc_r/test/join_leak_d.exp | 2 | ||||
-rw-r--r-- | lib/libc_r/test/mutex_d.c | 1555 | ||||
-rw-r--r-- | lib/libc_r/test/mutex_d.exp | 290 | ||||
-rwxr-xr-x | lib/libc_r/test/propagate_s.pl | 74 | ||||
-rw-r--r-- | lib/libc_r/test/sem_d.c | 133 | ||||
-rw-r--r-- | lib/libc_r/test/sem_d.exp | 22 | ||||
-rw-r--r-- | lib/libc_r/test/sigsuspend_d.c | 288 | ||||
-rw-r--r-- | lib/libc_r/test/sigsuspend_d.exp | 8 | ||||
-rw-r--r-- | lib/libc_r/test/sigwait_d.c | 304 | ||||
-rw-r--r-- | lib/libc_r/test/sigwait_d.exp | 10 | ||||
-rwxr-xr-x | lib/libc_r/test/verify | 474 |
21 files changed, 0 insertions, 3737 deletions
diff --git a/lib/libc_r/test/Makefile b/lib/libc_r/test/Makefile deleted file mode 100644 index 0eb530c3ef14..000000000000 --- a/lib/libc_r/test/Makefile +++ /dev/null @@ -1,115 +0,0 @@ -# -# $FreeBSD$ -# -# Automated test suite for libc_r (pthreads). -# - -# File lists. - -# Tests written in C. -CTESTS := hello_d.c hello_s.c join_leak_d.c mutex_d.c sem_d.c sigsuspend_d.c \ - sigwait_d.c - -# C programs that are used internally by the tests. The build system merely -# compiles these. -BTESTS := guard_b.c hello_b.c - -# Tests written in perl. -PTESTS := guard_s.pl propagate_s.pl - -# Munge the file lists to their final executable names (strip the .c). -CTESTS := $(CTESTS:R) -BTESTS := $(BTESTS:R) - -CPPFLAGS := -D_LIBC_R_ -D_REENTRANT -CFLAGS := -Wall -pipe -g3 -LDFLAGS_A := -static -LDFLAGS_P := -pg -LDFLAGS_S := -LIBS := -lc_r - -# Flags passed to verify. "-v" or "-u" may be useful. -VFLAGS := - -all : default - -# Only use the following suffixes, in order to avoid any strange built-in rules. -.SUFFIXES : -.SUFFIXES : .c .o .d .pl - -# Clear out all paths, then set just one (default path) for the main build -# directory. -.PATH : -.PATH : . - -# Build the C programs. -.for bin in $(CTESTS) $(BTESTS) -$(bin)_a : $(bin:S/$/&.c/) - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/) - $(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_A) $(LIBS) - @$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_a.o \2/g\" > $(@:R:S/$/&.d/)" - -$(bin)_p : $(bin:S/$/&.c/) - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/) - $(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_P) $(LIBS) - @$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_p.o \2/g\" > $(@:R:S/$/&.d/)" - -$(bin)_s : $(bin:S/$/&.c/) - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/) - $(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_S) $(LIBS) - @$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_s.o \2/g\" > $(@:R:S/$/&.d/)" -.endfor - -# Dependency file inclusion. -.for depfile in $(CTESTS:R:S/$/&_a.d/) $(BTESTS:R:S/$/&_a.d/) \ - $(CTESTS:R:S/$/&_p.d/) $(BTESTS:R:S/$/&_p.d/) \ - $(CTESTS:R:S/$/&_s.d/) $(BTESTS:R:S/$/&_s.d/) -.if exists($(depfile)) -.include "$(depfile)" -.endif -.endfor - -default : check - -tests_a : $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/) -tests_p : $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/) -tests_s : $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/) - -tests : tests_a tests_p tests_s - -check_a : tests_a -.for bin in $(CTESTS) $(BTESTS) - @cp $(bin)_a $(bin) -.endfor - @echo "Test static library:" - @./verify $(VFLAGS) $(CTESTS) $(PTESTS) - -check_p : tests_p -.for bin in $(CTESTS) $(BTESTS) - @cp $(bin)_p $(bin) -.endfor - @echo "Test profile library:" - @./verify $(VFLAGS) $(CTESTS) $(PTESTS) - -check_s : tests_s -.for bin in $(CTESTS) $(BTESTS) - @cp $(bin)_s $(bin) -.endfor - @echo "Test shared library:" - @./verify $(VFLAGS) $(CTESTS) $(PTESTS) - -check : check_a check_p check_s - -clean : - rm -f *~ - rm -f *.core - rm -f *.out - rm -f *.perf - rm -f *.diff - rm -f *.gmon - rm -f $(CTESTS) $(BTESTS) - rm -f $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/) - rm -f $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/) - rm -f $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/) - rm -f *.d - rm -f *.o diff --git a/lib/libc_r/test/README b/lib/libc_r/test/README deleted file mode 100644 index 507ea4e19f74..000000000000 --- a/lib/libc_r/test/README +++ /dev/null @@ -1,28 +0,0 @@ -$FreeBSD$ - -This test suite is meant to test general functionality of pthreads, as well as -provide a simple framework for regression tests. In general, this test suite -can be used with any pthreads library, but in reality there are a number of -libc_r-specific aspects to this test suite which would require some effort to -get around if testing another pthreads library. - -This test suite assumes that libc_r is installed. - -There are two forms of test that the 'verify' script understands. The simpler -form is the diff format, where the output of the test program is diff'ed with -the correspondingly named .exp file. If there is diff output, the test fails. -The sequence test format is somewhat more complex, and is documented in the -command line usage output for verify. The advantage of this format is that it -allows multiple tests to pass/fail within one program. - -There is no driving need for test naming consistency, but the existing tests -generally follow these conventions: - -<name>_d.c <name>_d.exp : Diff mode C test and expected output file. -<name>_s.c : Sequence mode C test. -<name>_b*.c : Back end C program used by perl tests. -<name>_d.pl <name>_d.pl.exp : Diff mode perl test and expected output file. -<name>_s.pl : Sequence mode perl test. - -<name> is something descriptive, such as "pr14685" in the case of a PR-related -regression test, or "mutex" in the case of a test of mutexes. diff --git a/lib/libc_r/test/guard_b.c b/lib/libc_r/test/guard_b.c deleted file mode 100644 index 35aa4067cc48..000000000000 --- a/lib/libc_r/test/guard_b.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. - * - * $FreeBSD$ - * - * Test thread stack guard functionality. - */ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <pthread.h> - -#define FRAME_SIZE 1024 -#define FRAME_OVERHEAD 40 - -struct args -{ - void *top; /* Top of thread's initial stack frame. */ - int cur; /* Recursion depth. */ - int max; /* Maximum recursion depth. */ -}; - -void * -recurse(void *args) -{ - int top; - struct args *parms = (struct args *)args; - char filler[FRAME_SIZE - FRAME_OVERHEAD]; - - /* Touch the memory in this stack frame. */ - top = 0xa5; - memset(filler, 0xa5, sizeof(filler)); - - if (parms->top == NULL) { - /* Initial stack frame. */ - parms->top = (void*)⊤ - } - - /* - * Make sure frame size is what we expect. Getting this right involves - * hand tweaking, so just print a warning rather than aborting. - */ - if (parms->top - (void *)&top != FRAME_SIZE * parms->cur) { - fprintf(stderr, "Stack size (%d) != expected (%d), frame %d\n", - (int)(parms->top - (void *)&top), FRAME_SIZE * parms->cur, - parms->cur); - } - - parms->cur++; - if (parms->cur < parms->max) - recurse(args); - - return NULL; -} - - -int -main(int argc, char **argv) -{ - size_t def_stacksize, def_guardsize; - size_t stacksize, guardsize; - pthread_t thread; - pthread_attr_t attr; - struct args args; - - if (argc != 3) { - fprintf(stderr, "usage: guard_b <stacksize> <guardsize>\n"); - exit(1); - } - fprintf(stderr, "Test begin\n"); - - stacksize = strtoul(argv[1], NULL, 10); - guardsize = strtoul(argv[2], NULL, 10); - - assert(pthread_attr_init(&attr) == 0); - /* - * Exercise the attribute APIs more thoroughly than is strictly - * necessary for the meat of this test program. - */ - assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0); - assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0); - if (def_stacksize != stacksize) { - assert(pthread_attr_setstacksize(&attr, stacksize) == 0); - assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0); - assert(def_stacksize == stacksize); - } - if (def_guardsize != guardsize) { - assert(pthread_attr_setguardsize(&attr, guardsize) == 0); - assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0); - assert(def_guardsize >= guardsize); - } - - /* - * Create a thread that will come just short of overflowing the thread - * stack. We need to leave a bit of breathing room in case the thread - * is context switched, and we also have to take care not to call any - * functions in the deepest stack frame. - */ - args.top = NULL; - args.cur = 0; - args.max = (stacksize / FRAME_SIZE) - 1; - fprintf(stderr, "No overflow:\n"); - assert(pthread_create(&thread, &attr, recurse, &args) == 0); - assert(pthread_join(thread, NULL) == 0); - - /* - * Create a thread that will barely of overflow the thread stack. This - * should cause a segfault. - */ - args.top = NULL; - args.cur = 0; - args.max = (stacksize / FRAME_SIZE) + 1; - fprintf(stderr, "Overflow:\n"); - assert(pthread_create(&thread, &attr, recurse, &args) == 0); - assert(pthread_join(thread, NULL) == 0); - - /* Not reached. */ - fprintf(stderr, "Unexpected success\n"); - abort(); - - return 0; -} diff --git a/lib/libc_r/test/guard_b.exp b/lib/libc_r/test/guard_b.exp deleted file mode 100644 index 8e5b9e426a21..000000000000 --- a/lib/libc_r/test/guard_b.exp +++ /dev/null @@ -1,3 +0,0 @@ -Test begin -No overflow: -Overflow: diff --git a/lib/libc_r/test/guard_s.pl b/lib/libc_r/test/guard_s.pl deleted file mode 100755 index 7802ff3c38d6..000000000000 --- a/lib/libc_r/test/guard_s.pl +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright (C) 2001 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer -# unmodified other than the allowable addition of one or more -# copyright notices. -# 2. Redistributions in binary form must reproduce the above copyright -# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. -# -# $FreeBSD$ -# -# Test thread stack guard functionality. The C test program needs to be driven -# by this script because it segfaults when the stack guard is hit. -# - -print "1..30\n"; - -$i = 0; -# Iterates 10 times. -for ($stacksize = 65536; $stacksize < 131072; $stacksize += 7168) -{ - # Iterates 3 times (1024, 4096, 7168). - for ($guardsize = 1024; $guardsize < 8192; $guardsize += 3072) - { - $i++; - - print "stacksize: $stacksize, guardsize: $guardsize\n"; - - `./guard_b $stacksize $guardsize >guard_b.out 2>&1`; - - if (! -f "./guard_b.out") - { - print "not ok $i\n"; - } - else - { - `diff guard_b.exp guard_b.out >guard_b.diff 2>&1`; - if ($?) - { - # diff returns non-zero if there is a difference. - print "not ok $i\n"; - } - else - { - print "ok $i\n"; - } - } - } -} diff --git a/lib/libc_r/test/hello_b.c b/lib/libc_r/test/hello_b.c deleted file mode 100644 index 2eefa7f48bfe..000000000000 --- a/lib/libc_r/test/hello_b.c +++ /dev/null @@ -1,13 +0,0 @@ -/**************************************************************************** - * - * Back end C programs can be anything compilable. - * - * $FreeBSD$ - * - ****************************************************************************/ - -int -main() -{ - return 0; -} diff --git a/lib/libc_r/test/hello_d.c b/lib/libc_r/test/hello_d.c deleted file mode 100644 index 6d77526f16c7..000000000000 --- a/lib/libc_r/test/hello_d.c +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** - * - * Simple diff mode test. - * - * $FreeBSD$ - * - ****************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <pthread.h> - -void * -entry(void * a_arg) -{ - fprintf(stderr, "Hello world\n"); - - return NULL; -} - -int -main() -{ - pthread_t thread; - int error; - - error = pthread_create(&thread, NULL, entry, NULL); - if (error) - fprintf(stderr, "Error in pthread_create(): %s\n", - strerror(error)); - - error = pthread_join(thread, NULL); - if (error) - fprintf(stderr, "Error in pthread_join(): %s\n", - strerror(error)); - - return 0; -} diff --git a/lib/libc_r/test/hello_d.exp b/lib/libc_r/test/hello_d.exp deleted file mode 100644 index 802992c4220d..000000000000 --- a/lib/libc_r/test/hello_d.exp +++ /dev/null @@ -1 +0,0 @@ -Hello world diff --git a/lib/libc_r/test/hello_s.c b/lib/libc_r/test/hello_s.c deleted file mode 100644 index 942bf2dae0ae..000000000000 --- a/lib/libc_r/test/hello_s.c +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** - * - * Simple sequence mode test. - * - * $FreeBSD$ - * - ****************************************************************************/ - -#include <stdio.h> -#include <string.h> -#include <pthread.h> - -void * -entry(void * a_arg) -{ - fprintf(stderr, "ok 1\n"); - fprintf(stderr, "ok \n"); - fprintf(stderr, "ok 3\n"); - - return NULL; -} - -int -main() -{ - pthread_t thread; - int error; - - fprintf(stderr, "1..3\n"); - - fprintf(stderr, "Some random text\n"); - - error = pthread_create(&thread, NULL, entry, NULL); - fprintf(stderr, "More unimportant text\n"); - if (error) - fprintf(stderr,"Error in pthread_create(): %s\n", - strerror(error)); - - error = pthread_join(thread, NULL); - if (error) - fprintf(stderr, "Error in pthread_join(): %s\n", - strerror(error)); - - fprintf(stderr, "Hello world\n"); - - return 0; -} diff --git a/lib/libc_r/test/join_leak_d.c b/lib/libc_r/test/join_leak_d.c deleted file mode 100644 index 9a351400e316..000000000000 --- a/lib/libc_r/test/join_leak_d.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2001 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. - * - * $FreeBSD$ - * - * Test for leaked joined threads. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <string.h> -#include <pthread.h> - -#define NITERATIONS 16384 -#define MAXGROWTH 16384 - -void * -thread_entry(void *a_arg) -{ - return NULL; -} - -int -main(void) -{ - pthread_t thread; - int i, error; - char *brk, *nbrk; - unsigned growth; - - fprintf(stderr, "Test begin\n"); - - /* Get an initial brk value. */ - brk = sbrk(0); - - /* Create threads and join them, one at a time. */ - for (i = 0; i < NITERATIONS; i++) { - if ((error = pthread_create(&thread, NULL, thread_entry, NULL)) - != 0) { - if (error == EAGAIN) { - i--; - continue; - } - fprintf(stderr, "Error in pthread_create(): %s\n", - strerror(error)); - exit(1); - } - if ((error = pthread_join(thread, NULL)) != 0) { - fprintf(stderr, "Error in pthread_join(): %s\n", - strerror(error)); - exit(1); - } - } - - /* Get a final brk value. */ - nbrk = sbrk(0); - - /* - * Check that the amount of heap space allocated is below an acceptable - * threshold. We could just compare brk and nbrk, but the test could - * conceivably break if the internals of the threads library changes. - */ - if (nbrk > brk) { - /* Heap grows up. */ - growth = nbrk - brk; - } else if (nbrk <= brk) { - /* Heap grows down, or no growth. */ - growth = brk - nbrk; - } - - if (growth > MAXGROWTH) { - fprintf(stderr, "Heap growth exceeded maximum (%u > %u)\n", - growth, MAXGROWTH); - } -#if (0) - else { - fprintf(stderr, "Heap growth acceptable (%u <= %u)\n", - growth, MAXGROWTH); - } -#endif - - fprintf(stderr, "Test end\n"); - return 0; -} diff --git a/lib/libc_r/test/join_leak_d.exp b/lib/libc_r/test/join_leak_d.exp deleted file mode 100644 index 369a88dd2404..000000000000 --- a/lib/libc_r/test/join_leak_d.exp +++ /dev/null @@ -1,2 +0,0 @@ -Test begin -Test end diff --git a/lib/libc_r/test/mutex_d.c b/lib/libc_r/test/mutex_d.c deleted file mode 100644 index 2f0c868aad85..000000000000 --- a/lib/libc_r/test/mutex_d.c +++ /dev/null @@ -1,1555 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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. - * - * $FreeBSD$ - */ -#include <stdlib.h> -#include <unistd.h> - -#include <sys/ioctl.h> -#include <assert.h> -#include <errno.h> -#include <inttypes.h> -#include "pthread.h" -#include <sched.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <sysexits.h> - -#if defined(_LIBC_R_) -#include <pthread_np.h> -#endif - -#ifndef NELEMENTS -#define NELEMENTS(arr) (sizeof (arr) / sizeof (arr[0])) -#endif - -#ifndef NUM_THREADS -#define NUM_THREADS 10 -#endif - -#define MAX_THREAD_CMDS 10 - -static void log_error(const char *, ...) __printflike(1, 2); -static void log_trace (const char *, ...) __printflike(1, 2); -static void log (const char *, ...) __printflike(1, 2); - -/*------------------------------------------------------------ - * Types - *----------------------------------------------------------*/ - -typedef enum { - STAT_INITIAL, /* initial state */ - STAT_WAITCONDVAR, /* waiting for condition variable signal */ - STAT_WAITMUTEX /* waiting for mutex lock */ -} thread_status_t; - -typedef enum { - FLAGS_REPORT_WAITCONDMUTEX = 0x01, - FLAGS_REPORT_WAITCONDVAR = 0x02, - FLAGS_REPORT_WAITMUTEX = 0x04, - FLAGS_REPORT_BUSY_LOOP = 0x08, - FLAGS_IS_BUSY = 0x10, - FLAGS_WAS_BUSY = 0x20 -} thread_flags_t; - -typedef enum { - CMD_NONE, - CMD_TAKE_MUTEX, - CMD_RELEASE_MUTEX, - CMD_WAIT_FOR_SIGNAL, - CMD_BUSY_LOOP, - CMD_PROTECTED_OP, - CMD_RELEASE_ALL -} thread_cmd_id_t; - -typedef struct { - thread_cmd_id_t cmd_id; - pthread_mutex_t *mutex; - pthread_cond_t *cond; -} thread_cmd_t; - -typedef struct { - pthread_cond_t cond_var; - thread_status_t status; - thread_cmd_t cmd; - int flags; - int priority; - int ret; - pthread_t tid; - u_int8_t id; -} thread_state_t; - -typedef enum { - M_POSIX, - M_SS2_DEFAULT, - M_SS2_ERRORCHECK, - M_SS2_NORMAL, - M_SS2_RECURSIVE -} mutex_kind_t; - - -/*------------------------------------------------------------ - * Constants - *----------------------------------------------------------*/ - -const char *protocol_strs[] = { - "PTHREAD_PRIO_NONE", - "PTHREAD_PRIO_INHERIT", - "PTHREAD_PRIO_PROTECT" -}; - -const int protocols[] = { - PTHREAD_PRIO_NONE, - PTHREAD_PRIO_INHERIT, - PTHREAD_PRIO_PROTECT -}; - -const char *mutextype_strs[] = { - "POSIX (type not specified)", - "SS2 PTHREAD_MUTEX_DEFAULT", - "SS2 PTHREAD_MUTEX_ERRORCHECK", - "SS2 PTHREAD_MUTEX_NORMAL", - "SS2 PTHREAD_MUTEX_RECURSIVE" -}; - -const int mutex_types[] = { - 0, /* M_POSIX */ - PTHREAD_MUTEX_DEFAULT, /* M_SS2_DEFAULT */ - PTHREAD_MUTEX_ERRORCHECK, /* M_SS2_ERRORCHECK */ - PTHREAD_MUTEX_NORMAL, /* M_SS2_NORMAL */ - PTHREAD_MUTEX_RECURSIVE /* M_SS2_RECURSIVE */ -}; - - -/*------------------------------------------------------------ - * Objects - *----------------------------------------------------------*/ - -static int done = 0; -static int trace_enabled = 0; -static int use_global_condvar = 0; -static thread_state_t states[NUM_THREADS]; -static int pipefd[2]; - -static pthread_mutex_t waiter_mutex; -static pthread_mutex_t cond_mutex; -static pthread_cond_t cond_var; - -static FILE *logfile; -static int error_count = 0, pass_count = 0, total = 0; - - -/*------------------------------------------------------------ - * Prototypes - *----------------------------------------------------------*/ -extern char *strtok_r(char *str, const char *sep, char **last); - - -/*------------------------------------------------------------ - * Functions - *----------------------------------------------------------*/ - -#ifdef DEBUG -static void -kern_switch (pthread_t pthread_out, pthread_t pthread_in) -{ - if (pthread_out != NULL) - printf ("Swapping out thread 0x%x, ", (int) pthread_out); - else - printf ("Swapping out kernel thread, "); - - if (pthread_in != NULL) - printf ("swapping in thread 0x%x\n", (int) pthread_in); - else - printf ("swapping in kernel thread.\n"); -} -#endif - - -static void -log_error (const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - fprintf (logfile, "FAIL: "); - vfprintf (logfile, fmt, ap); - error_count = error_count + 1; - total = total + 1; -} - - -static void -log_pass (void) -{ - fprintf (logfile, "PASS\n"); - pass_count = pass_count + 1; - total = total + 1; -} - - -static void -log_trace (const char *fmt, ...) -{ - va_list ap; - - if (trace_enabled) { - va_start (ap, fmt); - vfprintf (logfile, fmt, ap); - } -} - - -static void -log (const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - vfprintf (logfile, fmt, ap); -} - - -static void -check_result (int expected, int actual) -{ - if (expected != actual) - log_error ("expected %d, returned %d\n", expected, actual); - else - log_pass (); -} - - -/* - * Check to see that the threads ran in the specified order. - */ -static void -check_run_order (char *order) -{ - const char *sep = ":,"; - char *tok, *last, *idstr, *endptr; - int expected_id, bytes, count = 0, errors = 0; - u_int8_t id; - - assert ((tok = (char *) malloc (strlen(order) + 1)) != NULL); - strcpy (tok, order); /* tok has to be larger than order */ - assert (ioctl (pipefd[0], FIONREAD, &bytes) == 0); - log_trace ("%d bytes read from FIFO.\n", bytes); - - for (idstr = strtok_r (tok, sep, &last); - (idstr != NULL) && (count < bytes); - idstr = strtok_r (NULL, sep, &last)) { - - /* Get the expected id: */ - expected_id = (int) strtol (idstr, &endptr, 10); - assert ((endptr != NULL) && (*endptr == '\0')); - - /* Read the actual id from the pipe: */ - assert (read (pipefd[0], &id, sizeof (id)) == sizeof (id)); - count = count + sizeof (id); - - if (id != expected_id) { - log_trace ("Thread %d ran out of order.\n", id); - errors = errors + 1; - } - else { - log_trace ("Thread %d at priority %d reporting.\n", - (int) id, states[id].priority); - } - } - - if (count < bytes) { - /* Clear the pipe: */ - while (count < bytes) { - read (pipefd[0], &id, sizeof (id)); - count = count + 1; - errors = errors + 1; - } - } - else if (bytes < count) - errors = errors + count - bytes; - - if (errors == 0) - log_pass (); - else - log_error ("%d threads ran out of order", errors); -} - - -static void * -waiter (void *arg) -{ - thread_state_t *statep = (thread_state_t *) arg; - pthread_mutex_t *held_mutex[MAX_THREAD_CMDS]; - int held_mutex_owned[MAX_THREAD_CMDS]; - sigset_t mask; - struct timeval tv1, tv2; - thread_cmd_t cmd; - int i, mutex_count = 0; - - statep->status = STAT_INITIAL; - - /* Block all signals except for interrupt.*/ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_BLOCK, &mask, NULL); - - while (done == 0) { - /* Wait for signal from the main thread to continue. */ - statep->status = STAT_WAITMUTEX; - log_trace ("Thread %d: locking cond_mutex.\n", - (int) statep->id); - pthread_mutex_lock (&cond_mutex); - - /* Do we report our status. */ - if (statep->flags & FLAGS_REPORT_WAITCONDMUTEX) - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: waiting for cond_var.\n", - (int) statep->id); - - /* Wait for a command. */ - statep->status = STAT_WAITCONDVAR; - - /* - * The threads are allowed commanded to wait either on - * their own unique condition variable (so they may be - * separately signaled) or on one global condition variable - * (so they may be signaled together). - */ - if (use_global_condvar != 0) - pthread_cond_wait (&cond_var, &cond_mutex); - else - pthread_cond_wait (&statep->cond_var, &cond_mutex); - - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_WAITCONDVAR) { - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: wrote to pipe.\n", - (int) statep->id); - } - log_trace ("Thread %d: received cond_var signal.\n", - (int) statep->id); - - /* Get a copy of the command before releasing the mutex. */ - cmd = statep->cmd; - - /* Clear the command after copying it. */ - statep->cmd.cmd_id = CMD_NONE; - - /* Unlock the condition variable mutex. */ - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - /* Peform the command.*/ - switch (cmd.cmd_id) { - case CMD_TAKE_MUTEX: - statep->ret = pthread_mutex_lock (cmd.mutex); - if (statep->ret == 0) { - assert (mutex_count < sizeof (held_mutex)); - held_mutex[mutex_count] = cmd.mutex; - held_mutex_owned[mutex_count] = 1; - mutex_count++; - } - else { - held_mutex_owned[mutex_count] = 0; - log_trace ("Thread id %d unable to lock mutex, " - "error = %d\n", (int) statep->id, - statep->ret); - } - break; - - case CMD_RELEASE_MUTEX: - assert ((mutex_count <= sizeof (held_mutex)) && - (mutex_count > 0)); - mutex_count--; - if (held_mutex_owned[mutex_count] != 0) - assert (pthread_mutex_unlock - (held_mutex[mutex_count]) == 0); - break; - - case CMD_WAIT_FOR_SIGNAL: - assert (pthread_mutex_lock (cmd.mutex) == 0); - assert (pthread_cond_wait (cmd.cond, cmd.mutex) == 0); - assert (pthread_mutex_unlock (cmd.mutex) == 0); - break; - - case CMD_BUSY_LOOP: - log_trace ("Thread %d: Entering busy loop.\n", - (int) statep->id); - /* Spin for 15 seconds. */ - assert (gettimeofday (&tv2, NULL) == 0); - tv1.tv_sec = tv2.tv_sec + 5; - tv1.tv_usec = tv2.tv_usec; - statep->flags |= FLAGS_IS_BUSY; - while (timercmp (&tv2, &tv1,<)) { - assert (gettimeofday (&tv2, NULL) == 0); - } - statep->flags &= ~FLAGS_IS_BUSY; - statep->flags |= FLAGS_WAS_BUSY; - - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_BUSY_LOOP) - write (pipefd[1], &statep->id, - sizeof (statep->id)); - - log_trace ("Thread %d: Leaving busy loop.\n", - (int) statep->id); - break; - - case CMD_PROTECTED_OP: - assert (pthread_mutex_lock (cmd.mutex) == 0); - statep->flags |= FLAGS_WAS_BUSY; - /* Do we report our status? */ - if (statep->flags & FLAGS_REPORT_BUSY_LOOP) - write (pipefd[1], &statep->id, - sizeof (statep->id)); - - assert (pthread_mutex_unlock (cmd.mutex) == 0); - break; - - case CMD_RELEASE_ALL: - assert ((mutex_count <= sizeof (held_mutex)) && - (mutex_count > 0)); - for (i = mutex_count - 1; i >= 0; i--) { - if (held_mutex_owned[i] != 0) - assert (pthread_mutex_unlock - (held_mutex[i]) == 0); - } - mutex_count = 0; - break; - - case CMD_NONE: - default: - break; - } - - /* Wait for the big giant waiter lock. */ - statep->status = STAT_WAITMUTEX; - log_trace ("Thread %d: waiting for big giant lock.\n", - (int) statep->id); - pthread_mutex_lock (&waiter_mutex); - if (statep->flags & FLAGS_REPORT_WAITMUTEX) - write (pipefd[1], &statep->id, sizeof (statep->id)); - log_trace ("Thread %d: got big giant lock.\n", - (int) statep->id); - statep->status = STAT_INITIAL; - pthread_mutex_unlock (&waiter_mutex); - } - - log_trace ("Thread %d: Exiting thread 0x%" PRIxPTR "\n", - (int) statep->id, (uintptr_t) pthread_self()); - pthread_exit (arg); - return (NULL); -} - - -static void * -lock_twice (void *arg) -{ - thread_state_t *statep = (thread_state_t *) arg; - sigset_t mask; - - statep->status = STAT_INITIAL; - - /* Block all signals except for interrupt.*/ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_BLOCK, &mask, NULL); - - /* Wait for a signal to continue. */ - log_trace ("Thread %d: locking cond_mutex.\n", (int) statep->id); - pthread_mutex_lock (&cond_mutex); - - log_trace ("Thread %d: waiting for cond_var.\n", (int) statep->id); - statep->status = STAT_WAITCONDVAR; - pthread_cond_wait (&cond_var, &cond_mutex); - - log_trace ("Thread %d: received cond_var signal.\n", (int) statep->id); - - /* Unlock the condition variable mutex. */ - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - statep->status = STAT_WAITMUTEX; - /* Lock the mutex once. */ - assert (pthread_mutex_lock (statep->cmd.mutex) == 0); - - /* Lock it again and capture the error. */ - statep->ret = pthread_mutex_lock (statep->cmd.mutex); - statep->status = 0; - - assert (pthread_mutex_unlock (statep->cmd.mutex) == 0); - - /* Unlock it again if it is locked recursively. */ - if (statep->ret == 0) - pthread_mutex_unlock (statep->cmd.mutex); - - log_trace ("Thread %d: Exiting thread 0x%" PRIxPTR "\n", - (int) statep->id, (uintptr_t) pthread_self()); - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - log ("Signal handler caught signal %d, thread id 0x%" PRIxPTR "\n", - signo, (uintptr_t) pthread_self()); - - if (signo == SIGINT) - done = 1; -} - - -static void -send_cmd (int id, thread_cmd_id_t cmd) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = NULL; - states[id].cmd.cond = NULL; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -send_mutex_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = m; - states[id].cmd.cond = NULL; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -send_mutex_cv_cmd (int id, thread_cmd_id_t cmd, pthread_mutex_t *m, - pthread_cond_t *cv) -{ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (states[id].status == STAT_WAITCONDVAR); - states[id].cmd.cmd_id = cmd; - states[id].cmd.mutex = m; - states[id].cmd.cond = cv; - /* Clear the busy flags. */ - states[id].flags &= ~(FLAGS_WAS_BUSY | FLAGS_IS_BUSY); - assert (pthread_cond_signal (&states[id].cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); -} - - -static void -mutex_init_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - mutex_kind_t mkind; - int mproto, ret; - - /* - * Initialize a mutex attribute. - * - * pthread_mutexattr_init not tested for: ENOMEM - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* - * Initialize a mutex. - * - * pthread_mutex_init not tested for: EAGAIN ENOMEM EPERM EBUSY - */ - log ("Testing pthread_mutex_init\n"); - log ("--------------------------\n"); - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - log (" Protocol %s, Type %s - ", - protocol_strs[mproto], mutextype_strs[mkind]); - ret = pthread_mutex_init (&mutex, &mattr); - check_result (/* expected */ 0, ret); - assert (pthread_mutex_destroy (&mutex) == 0); - - /* - * Destroy a mutex attribute. - * - * XXX - There should probably be a magic number - * associated with a mutex attribute so that - * destroy can be reasonably sure the attribute - * is valid. - * - * pthread_mutexattr_destroy not tested for: EINVAL - */ - assert (pthread_mutexattr_destroy (&mattr) == 0); - } - } -} - - -static void -mutex_destroy_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - pthread_condattr_t cattr; - pthread_cond_t cv; - pthread_attr_t pattr; - int mproto, ret; - mutex_kind_t mkind; - thread_state_t state; - - /* - * Destroy a mutex. - * - * XXX - There should probably be a magic number associated - * with a mutex so that destroy can be reasonably sure - * the mutex is valid. - * - * pthread_mutex_destroy not tested for: - */ - log ("Testing pthread_mutex_destroy\n"); - log ("-----------------------------\n"); - - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_DETACHED) == 0); - state.flags = 0; /* No flags yet. */ - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Destruction of unused mutex - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ 0, ret); - - log (" Destruction of mutex locked by self - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - assert (pthread_mutex_lock (&mutex) == 0); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - assert (pthread_mutex_unlock (&mutex) == 0); - assert (pthread_mutex_destroy (&mutex) == 0); - - log (" Destruction of mutex locked by another " - "thread - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - send_mutex_cmd (0, CMD_TAKE_MUTEX, &mutex); - sleep (1); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - send_cmd (0, CMD_RELEASE_ALL); - sleep (1); - assert (pthread_mutex_destroy (&mutex) == 0); - - log (" Destruction of mutex while being used in " - "cond_wait - "); - assert (pthread_mutex_init (&mutex, &mattr) == 0); - assert (pthread_condattr_init (&cattr) == 0); - assert (pthread_cond_init (&cv, &cattr) == 0); - send_mutex_cv_cmd (0, CMD_WAIT_FOR_SIGNAL, &mutex, &cv); - sleep (1); - ret = pthread_mutex_destroy (&mutex); - check_result (/* expected */ EBUSY, ret); - pthread_cond_signal (&cv); - sleep (1); - assert (pthread_mutex_destroy (&mutex) == 0); - } - } -} - - -static void -mutex_lock_test (void) -{ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - pthread_attr_t pattr; - int mproto, ret; - mutex_kind_t mkind; - thread_state_t state; - - /* - * Lock a mutex. - * - * pthread_lock not tested for: - */ - log ("Testing pthread_mutex_lock\n"); - log ("--------------------------\n"); - - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_DETACHED) == 0); - state.flags = 0; /* No flags yet. */ - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Lock on unlocked mutex - "); - ret = pthread_mutex_lock (&mutex); - check_result (/* expected */ 0, ret); - pthread_mutex_unlock (&mutex); - - log (" Lock on invalid mutex - "); - ret = pthread_mutex_lock (NULL); - check_result (/* expected */ EINVAL, ret); - - log (" Lock on mutex held by self - "); - assert (pthread_create (&state.tid, &pattr, lock_twice, - (void *) &state) == 0); - /* Let the thread start. */ - sleep (1); - state.cmd.mutex = &mutex; - state.ret = 0xdeadbeef; - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_signal (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - /* Let the thread receive and process the command. */ - sleep (1); - - switch (mkind) { - case M_POSIX: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_DEFAULT: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_ERRORCHECK: - check_result (/* expected */ EDEADLK, - state.ret); - break; - case M_SS2_NORMAL: - check_result (/* expected */ 0xdeadbeef, - state.ret); - break; - case M_SS2_RECURSIVE: - check_result (/* expected */ 0, state.ret); - break; - } - pthread_mutex_destroy (&mutex); - pthread_mutexattr_destroy (&mattr); - } - } -} - - -static void -mutex_unlock_test (void) -{ - const int test_thread_id = 0; /* ID of test thread */ - pthread_mutexattr_t mattr; - pthread_mutex_t mutex; - int mproto, ret; - mutex_kind_t mkind; - - /* - * Unlock a mutex. - * - * pthread_unlock not tested for: - */ - log ("Testing pthread_mutex_unlock\n"); - log ("----------------------------\n"); - - for (mproto = 0; mproto < NELEMENTS(protocols); mproto++) { - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - /* Initialize the mutex attribute. */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutexattr_setprotocol (&mattr, - protocols[mproto]) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - /* Create the mutex. */ - assert (pthread_mutex_init (&mutex, &mattr) == 0); - - log (" Protocol %s, Type %s\n", - protocol_strs[mproto], mutextype_strs[mkind]); - - log (" Unlock on mutex held by self - "); - assert (pthread_mutex_lock (&mutex) == 0); - ret = pthread_mutex_unlock (&mutex); - check_result (/* expected */ 0, ret); - - log (" Unlock on invalid mutex - "); - ret = pthread_mutex_unlock (NULL); - check_result (/* expected */ EINVAL, ret); - - log (" Unlock on mutex locked by another thread - "); - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &mutex); - sleep (1); - ret = pthread_mutex_unlock (&mutex); - switch (mkind) { - case M_POSIX: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_DEFAULT: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_ERRORCHECK: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_NORMAL: - check_result (/* expected */ EPERM, ret); - break; - case M_SS2_RECURSIVE: - check_result (/* expected */ EPERM, ret); - break; - } - if (ret == 0) { - /* - * If for some reason we were able to unlock - * the mutex, relock it so that the test - * thread has no problems releasing the mutex. - */ - pthread_mutex_lock (&mutex); - } - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - pthread_mutex_destroy (&mutex); - pthread_mutexattr_destroy (&mattr); - } - } -} - - -static void -queueing_order_test (void) -{ - int i; - - log ("Testing queueing order\n"); - log ("----------------------\n"); - assert (pthread_mutex_lock (&waiter_mutex) == 0); - /* - * Tell the threads to report when they take the waiters mutex. - */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - for (i = 0; i < NUM_THREADS; i++) { - states[i].flags = FLAGS_REPORT_WAITMUTEX; - assert (pthread_cond_signal (&states[i].cond_var) == 0); - } - assert (pthread_mutex_unlock (&cond_mutex) == 0); - - /* Signal the threads to continue. */ - sleep (1); - - /* Use the global condition variable next time. */ - use_global_condvar = 1; - - /* Release the waiting threads and allow them to run again. */ - assert (pthread_mutex_unlock (&waiter_mutex) == 0); - sleep (1); - - log (" Queueing order on a mutex - "); - check_run_order ("9,8,7,6,5,4,3,2,1,0"); - for (i = 0; i < NUM_THREADS; i = i + 1) { - /* Tell the threads to report when they've been signaled. */ - states[i].flags = FLAGS_REPORT_WAITCONDVAR; - } - - /* - * Prevent the threads from continuing their loop after we - * signal them. - */ - assert (pthread_mutex_lock (&waiter_mutex) == 0); - - - log (" Queueing order on a condition variable - "); - /* - * Signal one thread to run and see that the highest priority - * thread executes. - */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_signal (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - sleep (1); - if (states[NUM_THREADS - 1].status != STAT_WAITMUTEX) - log_error ("highest priority thread does not run.\n"); - - /* Signal the remaining threads. */ - assert (pthread_mutex_lock (&cond_mutex) == 0); - assert (pthread_cond_broadcast (&cond_var) == 0); - assert (pthread_mutex_unlock (&cond_mutex) == 0); - sleep (1); - - check_run_order ("9,8,7,6,5,4,3,2,1,0"); - for (i = 0; i < NUM_THREADS; i = i + 1) { - /* Tell the threads not to report anything. */ - states[i].flags = 0; - } - - /* Use the thread unique condition variable next time. */ - use_global_condvar = 0; - - /* Allow the threads to continue their loop. */ - assert (pthread_mutex_unlock (&waiter_mutex) == 0); - sleep (1); -} - - -static void -mutex_prioceiling_test (void) -{ - const int test_thread_id = 0; /* ID of test thread */ - pthread_mutexattr_t mattr; - struct sched_param param; - pthread_mutex_t m[3]; - mutex_kind_t mkind; - int i, ret, policy, my_prio, old_ceiling; - - log ("Testing priority ceilings\n"); - log ("-------------------------\n"); - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - - log (" Protype PTHREAD_PRIO_PROTECT, Type %s\n", - mutextype_strs[mkind]); - - /* - * Initialize and create a mutex. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* Get this threads current priority. */ - assert (pthread_getschedparam (pthread_self(), &policy, - ¶m) == 0); - my_prio = param.sched_priority; /* save for later use */ - log_trace ("Current scheduling policy %d, priority %d\n", - policy, my_prio); - - /* - * Initialize and create 3 priority protection mutexes with - * default (max priority) ceilings. - */ - assert (pthread_mutexattr_setprotocol(&mattr, - PTHREAD_PRIO_PROTECT) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - for (i = 0; i < 3; i++) - assert (pthread_mutex_init (&m[i], &mattr) == 0); - - /* - * Set the ceiling priorities for the 3 priority protection - * mutexes to, 5 less than, equal to, and 5 greater than, - * this threads current priority. - */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_setprioceiling (&m[i], - my_prio - 5 + 5*i, &old_ceiling) == 0); - - /* - * Check that if we attempt to take a mutex whose priority - * ceiling is lower than our priority, we get an error. - */ - log (" Lock with ceiling priority < thread priority - "); - ret = pthread_mutex_lock (&m[0]); - check_result (/* expected */ EINVAL, ret); - if (ret == 0) - pthread_mutex_unlock (&m[0]); - - /* - * Check that we can take a mutex whose priority ceiling - * is equal to our priority. - */ - log (" Lock with ceiling priority = thread priority - "); - ret = pthread_mutex_lock (&m[1]); - check_result (/* expected */ 0, ret); - if (ret == 0) - pthread_mutex_unlock (&m[1]); - - /* - * Check that we can take a mutex whose priority ceiling - * is higher than our priority. - */ - log (" Lock with ceiling priority > thread priority - "); - ret = pthread_mutex_lock (&m[2]); - check_result (/* expected */ 0, ret); - if (ret == 0) - pthread_mutex_unlock (&m[2]); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it doesn't block this thread (since the - * priority ceiling of mutex 0 and the priority of the test - * thread are both less than the priority of this thread). - */ - log (" Preemption with ceiling priority < thread " - "priority - "); - /* Have the test thread take mutex 0. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[0]); - sleep (1); - - log_trace ("Sending busy command.\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if (states[test_thread_id].flags & - (FLAGS_IS_BUSY | FLAGS_WAS_BUSY)) - log_error ("test thread inproperly preempted us.\n"); - else { - /* Let the thread finish its busy loop. */ - sleep (6); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - } - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 0. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it preempts this thread (since the priority - * ceiling of mutex 1 is the same as the priority of this - * thread). The test thread should not run to completion - * as its time quantum should expire before the 5 seconds - * are up. - */ - log (" Preemption with ceiling priority = thread " - "priority - "); - - /* Have the test thread take mutex 1. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_IS_BUSY) == 0) - log_error ("test thread did not switch in on yield.\n"); - else if (states[test_thread_id].flags & FLAGS_WAS_BUSY) - log_error ("test thread ran to completion.\n"); - else { - /* Let the thread finish its busy loop. */ - sleep (6); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - } - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 1. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Set the scheduling policy of the test thread to SCHED_FIFO - * and have it go into a busy loop for 5 seconds. This - * thread is SCHED_RR, and since the priority ceiling of - * mutex 1 is the same as the priority of this thread, the - * test thread should run to completion once it is switched - * in. - */ - log (" SCHED_FIFO scheduling and ceiling priority = " - "thread priority - "); - param.sched_priority = states[test_thread_id].priority; - assert (pthread_setschedparam (states[test_thread_id].tid, - SCHED_FIFO, ¶m) == 0); - - /* Have the test thread take mutex 1. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) { - log_error ("test thread did not run to completion.\n"); - /* Let the thread finish it's busy loop. */ - sleep (6); - } - else - log_pass (); - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Restore the test thread scheduling parameters. */ - param.sched_priority = states[test_thread_id].priority; - assert (pthread_setschedparam (states[test_thread_id].tid, - SCHED_RR, ¶m) == 0); - - /* Have the test thread release mutex 1. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* - * Have the test thread go into a busy loop for 5 seconds - * and see that it preempts this thread (since the priority - * ceiling of mutex 2 is the greater than the priority of - * this thread). The test thread should run to completion - * and block this thread because its active priority is - * higher. - */ - log (" SCHED_FIFO scheduling and ceiling priority > " - "thread priority - "); - /* Have the test thread take mutex 2. */ - send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[2]); - sleep (1); - - log_trace ("Sending busy\n"); - send_cmd (test_thread_id, CMD_BUSY_LOOP); - log_trace ("Busy sent, yielding\n"); - pthread_yield (); - log_trace ("Returned from yield.\n"); - if ((states[test_thread_id].flags & FLAGS_IS_BUSY) != 0) { - log_error ("test thread did not run to completion.\n"); - /* Let the thread finish it's busy loop. */ - sleep (6); - } - else if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) - log_error ("test thread never finished.\n"); - else - log_pass (); - states[test_thread_id].flags &= ~FLAGS_WAS_BUSY; - - /* Have the test thread release mutex 2. */ - send_cmd (test_thread_id, CMD_RELEASE_ALL); - sleep (1); - - /* Destroy the mutexes. */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_destroy (&m[i]) == 0); - } -} - - -static void -mutex_prioinherit_test (void) -{ - pthread_mutexattr_t mattr; - struct sched_param param; - pthread_mutex_t m[3]; - mutex_kind_t mkind; - int i, policy, my_prio; - - /* Get this threads current priority. */ - assert (pthread_getschedparam (pthread_self(), &policy, - ¶m) == 0); - my_prio = param.sched_priority; /* save for later use */ - log_trace ("Current scheduling policy %d, priority %d\n", - policy, my_prio); - - log ("Testing priority inheritence\n"); - log ("----------------------------\n"); - for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) { - - log (" Protype PTHREAD_PRIO_INHERIT, Type %s\n", - mutextype_strs[mkind]); - - /* - * Initialize and create a mutex. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - - /* - * Initialize and create 3 priority inheritence mutexes with - * default (max priority) ceilings. - */ - assert (pthread_mutexattr_setprotocol(&mattr, - PTHREAD_PRIO_INHERIT) == 0); - - /* - * Ensure that the first mutex type is a POSIX - * compliant mutex. - */ - if (mkind != M_POSIX) { - assert (pthread_mutexattr_settype (&mattr, - mutex_types[mkind]) == 0); - } - - for (i = 0; i < 3; i++) - assert (pthread_mutex_init (&m[i], &mattr) == 0); - - /* - * Test setup: - * Thread 4 - take mutex 0, 1 - * Thread 2 - enter protected busy loop with mutex 0 - * Thread 3 - enter protected busy loop with mutex 1 - * Thread 4 - enter protected busy loop with mutex 2 - * Thread 5 - enter busy loop - * Thread 6 - enter protected busy loop with mutex 0 - * Thread 4 - releases mutexes 1 and 0. - * - * Expected results: - * Threads complete in order 4, 6, 5, 3, 2 - */ - log (" Simple inheritence test - "); - - /* - * Command thread 4 to take mutexes 0 and 1. - */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]); - sleep (1); /* Allow command to be received. */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[1]); - sleep (1); - - /* - * Tell the threads to report themselves when they are - * at the bottom of their loop (waiting on wait_mutex). - */ - for (i = 0; i < NUM_THREADS; i++) - states[i].flags |= FLAGS_REPORT_WAITMUTEX; - - /* - * Command thread 2 to take mutex 0 and thread 3 to take - * mutex 1, both via a protected operation command. Since - * thread 4 owns mutexes 0 and 1, both threads 2 and 3 - * will block until the mutexes are released by thread 4. - */ - log_trace ("Commanding protected operation to thread 2.\n"); - send_mutex_cmd (2, CMD_PROTECTED_OP, &m[0]); - log_trace ("Commanding protected operation to thread 3.\n"); - send_mutex_cmd (3, CMD_PROTECTED_OP, &m[1]); - sleep (1); - - /* - * Command thread 4 to take mutex 2 via a protected operation - * and thread 5 to enter a busy loop for 5 seconds. Since - * thread 5 has higher priority than thread 4, thread 5 will - * enter the busy loop before thread 4 is activated. - */ - log_trace ("Commanding protected operation to thread 4.\n"); - send_mutex_cmd (4, CMD_PROTECTED_OP, &m[2]); - log_trace ("Commanding busy loop to thread 5.\n"); - send_cmd (5, CMD_BUSY_LOOP); - sleep (1); - if ((states[5].flags & FLAGS_IS_BUSY) == 0) - log_error ("thread 5 is not running.\n"); - log_trace ("Commanding protected operation thread 6.\n"); - send_mutex_cmd (6, CMD_PROTECTED_OP, &m[0]); - sleep (1); - if ((states[4].flags & FLAGS_WAS_BUSY) == 0) - log_error ("thread 4 failed to inherit priority.\n"); - states[4].flags = 0; - send_cmd (4, CMD_RELEASE_ALL); - sleep (5); - check_run_order ("4,6,5,3,2"); - - /* - * Clear the flags. - */ - for (i = 0; i < NUM_THREADS; i++) - states[i].flags = 0; - - /* - * Test setup: - * Thread 2 - enter busy loop (SCHED_FIFO) - * Thread 4 - take mutex 0 - * Thread 4 - priority change to same priority as thread 2 - * Thread 4 - release mutex 0 - * - * Expected results: - * Since thread 4 owns a priority mutex, it should be - * placed at the front of the run queue (for its new - * priority slot) when its priority is lowered to the - * same priority as thread 2. If thread 4 did not own - * a priority mutex, then it would have been added to - * the end of the run queue and thread 2 would have - * executed until it blocked (because it's scheduling - * policy is SCHED_FIFO). - * - */ - log (" Inheritence test with change of priority - "); - - /* - * Change threads 2 and 4 scheduling policies to be - * SCHED_FIFO. - */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[2].tid, SCHED_FIFO, - ¶m) == 0); - param.sched_priority = states[4].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_FIFO, - ¶m) == 0); - - /* - * Command thread 4 to take mutex 0. - */ - send_mutex_cmd (4, CMD_TAKE_MUTEX, &m[0]); - sleep (1); - - /* - * Command thread 2 to enter busy loop. - */ - send_cmd (2, CMD_BUSY_LOOP); - sleep (1); /* Allow command to be received. */ - - /* - * Command thread 4 to enter busy loop. - */ - send_cmd (4, CMD_BUSY_LOOP); - sleep (1); /* Allow command to be received. */ - - /* Have threads 2 and 4 report themselves. */ - states[2].flags = FLAGS_REPORT_WAITMUTEX; - states[4].flags = FLAGS_REPORT_WAITMUTEX; - - /* Change the priority of thread 4. */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_FIFO, - ¶m) == 0); - sleep (5); - check_run_order ("4,2"); - - /* Clear the flags */ - states[2].flags = 0; - states[4].flags = 0; - - /* Reset the policies. */ - param.sched_priority = states[2].priority; - assert (pthread_setschedparam (states[2].tid, SCHED_RR, - ¶m) == 0); - param.sched_priority = states[4].priority; - assert (pthread_setschedparam (states[4].tid, SCHED_RR, - ¶m) == 0); - - send_cmd (4, CMD_RELEASE_MUTEX); - sleep (1); - - /* Destroy the mutexes. */ - for (i = 0; i < 3; i++) - assert (pthread_mutex_destroy (&m[i]) == 0); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_mutexattr_t mattr; - pthread_condattr_t cattr; - pthread_attr_t pattr; - int i, policy, main_prio; - void * exit_status; - sigset_t mask; - struct sigaction act; - struct sched_param param; - - logfile = stdout; - - assert (pthread_getschedparam (pthread_self (), &policy, ¶m) == 0); - main_prio = param.sched_priority; - - /* Setupt our signal mask. */ - sigfillset (&mask); - sigdelset (&mask, SIGINT); - sigprocmask (SIG_SETMASK, &mask, NULL); - - /* Install a signal handler for SIGINT */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGINT); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGINT, &act, NULL); - - /* - * Initialize the thread attribute. - */ - assert (pthread_attr_init (&pattr) == 0); - assert (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) == 0); - - /* - * Initialize and create the waiter and condvar mutexes. - */ - assert (pthread_mutexattr_init (&mattr) == 0); - assert (pthread_mutex_init (&waiter_mutex, &mattr) == 0); - assert (pthread_mutex_init (&cond_mutex, &mattr) == 0); - - /* - * Initialize and create a condition variable. - */ - assert (pthread_condattr_init (&cattr) == 0); - assert (pthread_cond_init (&cond_var, &cattr) == 0); - - /* Create a pipe to catch the results of thread wakeups. */ - assert (pipe (pipefd) == 0); - -#ifdef DEBUG - assert (pthread_switch_add_np (kern_switch) == 0); -#endif - - /* - * Create the waiting threads. - */ - for (i = 0; i < NUM_THREADS; i++) { - assert (pthread_cond_init (&states[i].cond_var, &cattr) == 0); - states[i].id = (u_int8_t) i; /* NUM_THREADS must be <= 256 */ - states[i].status = 0; - states[i].cmd.cmd_id = CMD_NONE; - states[i].flags = 0; /* No flags yet. */ - assert (pthread_create (&states[i].tid, &pattr, waiter, - (void *) &states[i]) == 0); - param.sched_priority = main_prio - 10 + i; - states[i].priority = param.sched_priority; - assert (pthread_setschedparam (states[i].tid, SCHED_OTHER, - ¶m) == 0); -#if defined(_LIBC_R_) - { - char buf[30]; - - snprintf (buf, sizeof(buf), "waiter_%d", i); - pthread_set_name_np (states[i].tid, buf); - } -#endif - } - - /* Allow the threads to start. */ - sleep (1); - log_trace ("Done creating threads.\n"); - - log ("\n"); - mutex_init_test (); - log ("\n"); - mutex_destroy_test (); - log ("\n"); - mutex_lock_test (); - log ("\n"); - mutex_unlock_test (); - log ("\n"); - queueing_order_test (); - log ("\n"); - mutex_prioinherit_test (); - log ("\n"); - mutex_prioceiling_test (); - log ("\n"); - - log ("Total tests %d, passed %d, failed %d\n", - total, pass_count, error_count); - - /* Set the done flag and signal the threads to exit. */ - log_trace ("Setting done flag.\n"); - done = 1; - - /* - * Wait for the threads to finish. - */ - log_trace ("Trying to join threads.\n"); - for (i = 0; i < NUM_THREADS; i++) { - send_cmd (i, CMD_NONE); - assert (pthread_join (states[i].tid, &exit_status) == 0); - } - - /* Clean up after ourselves. */ - close (pipefd[0]); - close (pipefd[1]); - - if (error_count != 0) - exit (EX_OSERR); /* any better ideas??? */ - else - exit (EX_OK); -} diff --git a/lib/libc_r/test/mutex_d.exp b/lib/libc_r/test/mutex_d.exp deleted file mode 100644 index de8a4e42d8e2..000000000000 --- a/lib/libc_r/test/mutex_d.exp +++ /dev/null @@ -1,290 +0,0 @@ - -Testing pthread_mutex_init --------------------------- - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS - -Testing pthread_mutex_destroy ------------------------------ - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Destruction of unused mutex - PASS - Destruction of mutex locked by self - PASS - Destruction of mutex locked by another thread - PASS - Destruction of mutex while being used in cond_wait - PASS - -Testing pthread_mutex_lock --------------------------- - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock on unlocked mutex - PASS - Lock on invalid mutex - PASS - Lock on mutex held by self - PASS - -Testing pthread_mutex_unlock ----------------------------- - Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Unlock on mutex held by self - PASS - Unlock on invalid mutex - PASS - Unlock on mutex locked by another thread - PASS - -Testing queueing order ----------------------- - Queueing order on a mutex - PASS - Queueing order on a condition variable - PASS - -Testing priority inheritence ----------------------------- - Protype PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Simple inheritence test - PASS - Inheritence test with change of priority - PASS - -Testing priority ceilings -------------------------- - Protype PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - Lock with ceiling priority < thread priority - PASS - Lock with ceiling priority = thread priority - PASS - Lock with ceiling priority > thread priority - PASS - Preemption with ceiling priority < thread priority - PASS - Preemption with ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority = thread priority - PASS - SCHED_FIFO scheduling and ceiling priority > thread priority - PASS - -Total tests 212, passed 212, failed 0 diff --git a/lib/libc_r/test/propagate_s.pl b/lib/libc_r/test/propagate_s.pl deleted file mode 100755 index 9cd5fb054ae1..000000000000 --- a/lib/libc_r/test/propagate_s.pl +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as -# the first lines of this file unmodified other than the possible -# addition of one or more copyright notices. -# 2. Redistributions in binary form must reproduce the above copyright -# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. -# -########################################################################### -# -# Verify that no cancellation points are propagated inside of libc_r. -# -# $FreeBSD$ -# - -@CPOINTS = ("aio_suspend", "close", "creat", "fcntl", "fsync", "mq_receive", - "mq_send", "msync", "nanosleep", "open", "pause", - "pthread_cond_timedwait", "pthread_cond_wait", "pthread_join", - "pthread_testcancel", "read", "sem_wait", "sigsuspend", - "sigtimedwait", "sigwait", "sigwaitinfo", "sleep", "system", - "tcdrain", "wait", "waitpid", "write"); - -print "1..1\n"; - -$cpoints = join '\|', @CPOINTS; -$regexp = "\" U \\(" . $cpoints . "\\\)\$\""; - -`nm -a /usr/lib/libc.a |grep $regexp >propagate_s.out`; -if (!open (NMOUT, "<./propagate_s.out")) -{ - print "not ok 1\n"; -} -else -{ - $propagations = 0; - - while (<NMOUT>) - { - $propagations++; - print "$_\n"; - } - if ($propagations != 0) - { - print "$propagations propagation(s)\n"; - print "not ok 1\n"; - } - else - { - print "ok 1\n"; - } - close NMOUT; - unlink "propagate_s.out"; -} diff --git a/lib/libc_r/test/sem_d.c b/lib/libc_r/test/sem_d.c deleted file mode 100644 index b834591852d9..000000000000 --- a/lib/libc_r/test/sem_d.c +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** - * - * Copyright (C) 2000 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. - * - **************************************************************************** - * - * sem test. - * - * $FreeBSD$ - * - ****************************************************************************/ - -#include <assert.h> -#include <stdio.h> -#include <fcntl.h> -#include <errno.h> -#include <semaphore.h> -#include <pthread.h> - -#define NTHREADS 10 - -void * -entry(void * a_arg) -{ - sem_t * sem = (sem_t *) a_arg; - - sem_wait(sem); - fprintf(stderr, "Got semaphore\n"); - - return NULL; -} - -int -main() -{ - sem_t sem_a, sem_b; - pthread_t threads[NTHREADS]; - unsigned i; - int val; - - fprintf(stderr, "Test begin\n"); - -#ifdef _LIBC_R_ - assert(-1 == sem_init(&sem_b, 1, 0)); - assert(EPERM == errno); -#endif - - assert(0 == sem_init(&sem_b, 0, 0)); - assert(0 == sem_getvalue(&sem_b, &val)); - assert(0 == val); - - assert(0 == sem_post(&sem_b)); - assert(0 == sem_getvalue(&sem_b, &val)); - assert(1 == val); - - assert(0 == sem_wait(&sem_b)); - assert(-1 == sem_trywait(&sem_b)); - assert(EAGAIN == errno); - assert(0 == sem_post(&sem_b)); - assert(0 == sem_trywait(&sem_b)); - assert(0 == sem_post(&sem_b)); - assert(0 == sem_wait(&sem_b)); - assert(0 == sem_post(&sem_b)); - -#ifdef _LIBC_R_ - assert(SEM_FAILED == sem_open("/foo", O_CREAT | O_EXCL, 0644, 0)); - assert(ENOSYS == errno); - - assert(-1 == sem_close(&sem_b)); - assert(ENOSYS == errno); - - assert(-1 == sem_unlink("/foo")); - assert(ENOSYS == errno); -#endif - - assert(0 == sem_destroy(&sem_b)); - - assert(0 == sem_init(&sem_a, 0, 0)); - - for (i = 0; i < NTHREADS; i++) { - pthread_create(&threads[i], NULL, entry, (void *) &sem_a); - } - - for (i = 0; i < NTHREADS; i++) { - assert(0 == sem_post(&sem_a)); - } - - for (i = 0; i < NTHREADS; i++) { - pthread_join(threads[i], NULL); - } - - for (i = 0; i < NTHREADS; i++) { - pthread_create(&threads[i], NULL, entry, (void *) &sem_a); - } - - for (i = 0; i < NTHREADS; i++) { - assert(0 == sem_post(&sem_a)); - } - - for (i = 0; i < NTHREADS; i++) { - pthread_join(threads[i], NULL); - } - - assert(0 == sem_destroy(&sem_a)); - - fprintf(stderr, "Test end\n"); - return 0; -} diff --git a/lib/libc_r/test/sem_d.exp b/lib/libc_r/test/sem_d.exp deleted file mode 100644 index b0de3da1f5e6..000000000000 --- a/lib/libc_r/test/sem_d.exp +++ /dev/null @@ -1,22 +0,0 @@ -Test begin -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Got semaphore -Test end diff --git a/lib/libc_r/test/sigsuspend_d.c b/lib/libc_r/test/sigsuspend_d.c deleted file mode 100644 index d2420ed84456..000000000000 --- a/lib/libc_r/test/sigsuspend_d.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS 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. - * - * $FreeBSD$ - */ -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> - -#if defined(_LIBC_R_) -#include <pthread_np.h> -#endif - -static int sigcounts[NSIG + 1]; -static int sigfifo[NSIG + 1]; -static int fifo_depth = 0; -static sigset_t suspender_mask; -static pthread_t suspender_tid; - - -static void * -sigsuspender (void *arg) -{ - int save_count, status, i; - sigset_t run_mask; - - /* Run with all signals blocked. */ - sigfillset (&run_mask); - sigprocmask (SIG_SETMASK, &run_mask, NULL); - - /* Allow these signals to wake us up during a sigsuspend. */ - sigfillset (&suspender_mask); /* Default action */ - sigdelset (&suspender_mask, SIGINT); /* terminate */ - sigdelset (&suspender_mask, SIGHUP); /* terminate */ - sigdelset (&suspender_mask, SIGQUIT); /* create core image */ - sigdelset (&suspender_mask, SIGURG); /* ignore */ - sigdelset (&suspender_mask, SIGIO); /* ignore */ - sigdelset (&suspender_mask, SIGUSR2); /* terminate */ - - while (sigcounts[SIGINT] == 0) { - save_count = sigcounts[SIGUSR2]; - - status = sigsuspend (&suspender_mask); - if ((status == 0) || (errno != EINTR)) { - fprintf (stderr, "Unable to suspend for signals, " - "errno %d, return value %d\n", - errno, status); - exit (1); - } - for (i = 0; i < fifo_depth; i++) - fprintf (stderr, "Sigsuspend woke up by signal %d\n", - sigfifo[i]); - fifo_depth = 0; - } - - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - sigset_t set, suspend_set; - pthread_t self; - - if ((signo >= 0) && (signo <= NSIG)) - sigcounts[signo]++; - - /* - * If we are running on behalf of the suspender thread, - * ensure that we have the correct mask set. - */ - self = pthread_self (); - if (self == suspender_tid) { - sigfifo[fifo_depth] = signo; - fifo_depth++; - fprintf (stderr, - " -> Suspender thread signal handler caught signal %d\n", - signo); - - /* Get the current signal mask. */ - sigprocmask (SIG_SETMASK, NULL, &set); - - /* The handler should run with the current signal masked. */ - suspend_set = suspender_mask; - sigaddset(&suspend_set, signo); - - if (memcmp(&set, &suspend_set, sizeof(set))) - fprintf (stderr, - " >>> FAIL: sigsuspender signal handler running " - "with incorrect mask.\n"); - } - else - fprintf (stderr, - " -> Main thread signal handler caught signal %d\n", - signo); -} - - -static void -send_thread_signal (pthread_t tid, int signo) -{ - if (pthread_kill (tid, signo) != 0) { - fprintf (stderr, "Unable to send thread signal, errno %d.\n", - errno); - exit (1); - } -} - - -static void -send_process_signal (int signo) -{ - if (kill (getpid (), signo) != 0) { - fprintf (stderr, "Unable to send process signal, errno %d.\n", - errno); - exit (1); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_attr_t pattr; - void * exit_status; - struct sigaction act; - sigset_t oldset; - sigset_t newset; - - /* Initialize our signal counts. */ - memset ((void *) sigcounts, 0, NSIG * sizeof (int)); - - /* Ignore signal SIGIO. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGIO); - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - sigaction (SIGIO, &act, NULL); - - /* Install a signal handler for SIGURG. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGURG); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGURG, &act, NULL); - - /* Install a signal handler for SIGXCPU */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGXCPU); - sigaction (SIGXCPU, &act, NULL); - - /* Get our current signal mask. */ - sigprocmask (SIG_SETMASK, NULL, &oldset); - - /* Mask out SIGUSR1 and SIGUSR2. */ - newset = oldset; - sigaddset (&newset, SIGUSR1); - sigaddset (&newset, SIGUSR2); - sigprocmask (SIG_SETMASK, &newset, NULL); - - /* Install a signal handler for SIGUSR1 */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGUSR1); - sigaction (SIGUSR1, &act, NULL); - - /* Install a signal handler for SIGUSR2 */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGUSR2); - sigaction (SIGUSR2, &act, NULL); - - /* - * Initialize the thread attribute. - */ - if ((pthread_attr_init (&pattr) != 0) || - (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) != 0)) { - fprintf (stderr, "Unable to initialize thread attributes.\n"); - exit (1); - } - - /* - * Create the sigsuspender thread. - */ - if (pthread_create (&suspender_tid, &pattr, sigsuspender, NULL) != 0) { - fprintf (stderr, "Unable to create thread, errno %d.\n", errno); - exit (1); - } -#if defined(_LIBC_R) - pthread_set_name_np (suspender_tid, "sigsuspender"); -#endif - - /* - * Verify that an ignored signal doesn't cause a wakeup. - * We don't have a handler installed for SIGIO. - */ - send_thread_signal (suspender_tid, SIGIO); - sleep (1); - send_process_signal (SIGIO); - sleep (1); - if (sigcounts[SIGIO] != 0) - fprintf (stderr, "FAIL: sigsuspend wakes up for ignored signal " - "SIGIO.\n"); - - /* - * Verify that a signal with a default action of ignore, for - * which we have a signal handler installed, will release a - * sigsuspend. - */ - send_thread_signal (suspender_tid, SIGURG); - sleep (1); - send_process_signal (SIGURG); - sleep (1); - if (sigcounts[SIGURG] != 2) - fprintf (stderr, - "FAIL: sigsuspend doesn't wake up for SIGURG.\n"); - - /* - * Verify that a SIGUSR2 signal will release a sigsuspended - * thread. - */ - send_thread_signal (suspender_tid, SIGUSR2); - sleep (1); - send_process_signal (SIGUSR2); - sleep (1); - if (sigcounts[SIGUSR2] != 2) - fprintf (stderr, - "FAIL: sigsuspend doesn't wake up for SIGUSR2.\n"); - - /* - * Verify that a signal, blocked in both the main and - * sigsuspender threads, does not cause the signal handler - * to be called. - */ - send_thread_signal (suspender_tid, SIGUSR1); - sleep (1); - send_process_signal (SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 0) - fprintf (stderr, "FAIL: signal hander called for SIGUSR1.\n"); - - /* - * Verify that we can still kill the process for a signal - * not being waited on by sigwait. - */ - send_process_signal (SIGPIPE); - fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n"); - - /* - * Wait for the thread to finish. - */ - pthread_join (suspender_tid, &exit_status); - - return (0); -} diff --git a/lib/libc_r/test/sigsuspend_d.exp b/lib/libc_r/test/sigsuspend_d.exp deleted file mode 100644 index 901fa50dd2d1..000000000000 --- a/lib/libc_r/test/sigsuspend_d.exp +++ /dev/null @@ -1,8 +0,0 @@ - -> Suspender thread signal handler caught signal 16 -Sigsuspend woke up by signal 16 - -> Suspender thread signal handler caught signal 16 -Sigsuspend woke up by signal 16 - -> Suspender thread signal handler caught signal 31 -Sigsuspend woke up by signal 31 - -> Suspender thread signal handler caught signal 31 -Sigsuspend woke up by signal 31 diff --git a/lib/libc_r/test/sigwait_d.c b/lib/libc_r/test/sigwait_d.c deleted file mode 100644 index f3ccd6b98491..000000000000 --- a/lib/libc_r/test/sigwait_d.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Daniel M. Eischen. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS 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. - * - * $FreeBSD$ - */ -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> - -#if defined(_LIBC_R_) -#include <pthread_np.h> -#endif - -static int sigcounts[NSIG + 1]; -static sigset_t wait_mask; -static pthread_mutex_t waiter_mutex; - - -static void * -sigwaiter (void *arg) -{ - int signo; - sigset_t mask; - - /* Block SIGHUP */ - sigemptyset (&mask); - sigaddset (&mask, SIGHUP); - sigprocmask (SIG_BLOCK, &mask, NULL); - - while (sigcounts[SIGINT] == 0) { - if (sigwait (&wait_mask, &signo) != 0) { - fprintf (stderr, - "Unable to wait for signal, errno %d\n", - errno); - exit (1); - } - sigcounts[signo]++; - fprintf (stderr, "Sigwait caught signal %d\n", signo); - - /* Allow the main thread to prevent the sigwait. */ - pthread_mutex_lock (&waiter_mutex); - pthread_mutex_unlock (&waiter_mutex); - } - - pthread_exit (arg); - return (NULL); -} - - -static void -sighandler (int signo) -{ - fprintf (stderr, " -> Signal handler caught signal %d\n", signo); - - if ((signo >= 0) && (signo <= NSIG)) - sigcounts[signo]++; -} - -static void -send_thread_signal (pthread_t tid, int signo) -{ - if (pthread_kill (tid, signo) != 0) { - fprintf (stderr, "Unable to send thread signal, errno %d.\n", - errno); - exit (1); - } -} - -static void -send_process_signal (int signo) -{ - if (kill (getpid (), signo) != 0) { - fprintf (stderr, "Unable to send process signal, errno %d.\n", - errno); - exit (1); - } -} - - -int main (int argc, char *argv[]) -{ - pthread_mutexattr_t mattr; - pthread_attr_t pattr; - pthread_t tid; - void * exit_status; - struct sigaction act; - - /* Initialize our signal counts. */ - memset ((void *) sigcounts, 0, NSIG * sizeof (int)); - - /* Setup our wait mask. */ - sigemptyset (&wait_mask); /* Default action */ - sigaddset (&wait_mask, SIGHUP); /* terminate */ - sigaddset (&wait_mask, SIGINT); /* terminate */ - sigaddset (&wait_mask, SIGQUIT); /* create core image */ - sigaddset (&wait_mask, SIGURG); /* ignore */ - sigaddset (&wait_mask, SIGIO); /* ignore */ - sigaddset (&wait_mask, SIGUSR1); /* terminate */ - - /* Ignore signals SIGHUP and SIGIO. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGHUP); - sigaddset (&act.sa_mask, SIGIO); - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - sigaction (SIGHUP, &act, NULL); - sigaction (SIGIO, &act, NULL); - - /* Install a signal handler for SIGURG */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGURG); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGURG, &act, NULL); - - /* Install a signal handler for SIGXCPU */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGXCPU); - sigaction (SIGXCPU, &act, NULL); - - /* - * Initialize the thread attribute. - */ - if ((pthread_attr_init (&pattr) != 0) || - (pthread_attr_setdetachstate (&pattr, - PTHREAD_CREATE_JOINABLE) != 0)) { - fprintf (stderr, "Unable to initialize thread attributes.\n"); - exit (1); - } - - /* - * Initialize and create a mutex. - */ - if ((pthread_mutexattr_init (&mattr) != 0) || - (pthread_mutex_init (&waiter_mutex, &mattr) != 0)) { - fprintf (stderr, "Unable to create waiter mutex.\n"); - exit (1); - } - - /* - * Create the sigwaiter thread. - */ - if (pthread_create (&tid, &pattr, sigwaiter, NULL) != 0) { - fprintf (stderr, "Unable to create thread.\n"); - exit (1); - } -#if defined(_LIBC_R_) - pthread_set_name_np (tid, "sigwaiter"); -#endif - - /* - * Verify that an ignored signal doesn't cause a wakeup. - * We don't have a handler installed for SIGIO. - */ - send_thread_signal (tid, SIGIO); - sleep (1); - send_process_signal (SIGIO); - sleep (1); - if (sigcounts[SIGIO] != 0) - fprintf (stderr, - "FAIL: sigwait wakes up for ignored signal SIGIO.\n"); - - /* - * Verify that a signal with a default action of ignore, for - * which we have a signal handler installed, will release a sigwait. - */ - send_thread_signal (tid, SIGURG); - sleep (1); - send_process_signal (SIGURG); - sleep (1); - if (sigcounts[SIGURG] != 2) - fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGURG.\n"); - - /* - * Verify that a signal with a default action that terminates - * the process will release a sigwait. - */ - send_thread_signal (tid, SIGUSR1); - sleep (1); - send_process_signal (SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 2) - fprintf (stderr, - "FAIL: sigwait doesn't wake up for SIGUSR1.\n"); - - /* - * Verify that if we install a signal handler for a previously - * ignored signal, an occurrence of this signal will release - * the (already waiting) sigwait. - */ - - /* Install a signal handler for SIGHUP. */ - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGHUP); - act.sa_handler = sighandler; - act.sa_flags = SA_RESTART; - sigaction (SIGHUP, &act, NULL); - - /* Sending SIGHUP should release the sigwait. */ - send_process_signal (SIGHUP); - sleep (1); - send_thread_signal (tid, SIGHUP); - sleep (1); - if (sigcounts[SIGHUP] != 2) - fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n"); - - /* - * Verify that a pending signal in the waiters mask will - * cause sigwait to return the pending signal. We do this - * by taking the waiters mutex and signaling the waiter to - * release him from the sigwait. The waiter will block - * on taking the mutex, and we can then send the waiter a - * signal which should be added to his pending signals. - * The next time the waiter does a sigwait, he should - * return with the pending signal. - */ - sigcounts[SIGHUP] = 0; - pthread_mutex_lock (&waiter_mutex); - /* Release the waiter from sigwait. */ - send_process_signal (SIGHUP); - sleep (1); - if (sigcounts[SIGHUP] != 1) - fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n"); - /* - * Add SIGHUP to the process pending signals. Since there is - * a signal handler installed for SIGHUP and this signal is - * blocked from the waiter thread and unblocked in the main - * thread, the signal handler should be called once for SIGHUP. - */ - send_process_signal (SIGHUP); - /* Release the waiter thread and allow him to run. */ - pthread_mutex_unlock (&waiter_mutex); - sleep (1); - if (sigcounts[SIGHUP] != 2) - fprintf (stderr, - "FAIL: sigwait doesn't return for pending SIGHUP.\n"); - - /* - * Repeat the above test using pthread_kill and SIGUSR1. - */ - sigcounts[SIGUSR1] = 0; - pthread_mutex_lock (&waiter_mutex); - /* Release the waiter from sigwait. */ - send_thread_signal (tid, SIGUSR1); - sleep (1); - if (sigcounts[SIGUSR1] != 1) - fprintf (stderr, - "FAIL: sigwait doesn't wake up for SIGUSR1.\n"); - /* Add SIGUSR1 to the waiters pending signals. */ - send_thread_signal (tid, SIGUSR1); - /* Release the waiter thread and allow him to run. */ - pthread_mutex_unlock (&waiter_mutex); - sleep (1); - if (sigcounts[SIGUSR1] != 2) - fprintf (stderr, - "FAIL: sigwait doesn't return for pending SIGUSR1.\n"); - - /* - * Verify that we can still kill the process for a signal - * not being waited on by sigwait. - */ - send_process_signal (SIGPIPE); - fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n"); - - /* - * Wait for the thread to finish. - */ - pthread_join (tid, &exit_status); - - return (0); -} diff --git a/lib/libc_r/test/sigwait_d.exp b/lib/libc_r/test/sigwait_d.exp deleted file mode 100644 index 2e9b2c492525..000000000000 --- a/lib/libc_r/test/sigwait_d.exp +++ /dev/null @@ -1,10 +0,0 @@ -Sigwait caught signal 16 -Sigwait caught signal 16 -Sigwait caught signal 30 -Sigwait caught signal 30 -Sigwait caught signal 1 -Sigwait caught signal 1 -Sigwait caught signal 1 - -> Signal handler caught signal 1 -Sigwait caught signal 30 -Sigwait caught signal 30 diff --git a/lib/libc_r/test/verify b/lib/libc_r/test/verify deleted file mode 100755 index 2863e5c3fa0c..000000000000 --- a/lib/libc_r/test/verify +++ /dev/null @@ -1,474 +0,0 @@ -#!/usr/bin/perl -w -#-*-mode:perl-*- -############################################################################# -# -# Copyright (C) 1999-2001 Jason Evans <jasone@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(s), this list of conditions and the following disclaimer as -# the first lines of this file unmodified other than the possible -# addition of one or more copyright notices. -# 2. Redistributions in binary form must reproduce the above copyright -# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. -# -############################################################################# -# -# Test harness. -# -# $FreeBSD$ -# -############################################################################# - -# Shut off buffering. -select(STDOUT); -$| = 1; - -# -# Parse command-line arguments. -# -use Getopt::Long; -Getopt::Long::config("bundling"); # Allow -hv rather than forcing -h -v. - -# Set option defaults for optional arguments. -$opt_help = 0; -$opt_verbose = 0; -$opt_quiet = 0; -$opt_srcdir = "."; -$opt_objdir = "."; -$opt_ustats = 0; -$opt_zero = 0; - -$opt_retval = -&GetOptions("h|help" => \$opt_help, - "v|verbose" => \$opt_verbose, - "q|quiet" => \$opt_quiet, - "s|srcdir=s" => \$opt_srcdir, - "o|objdir=s" => \$opt_objdir, - "u|ustats" => \$opt_ustats, - "z|zero" => \$opt_zero - ); - -if ($opt_help) -{ - &usage(); - exit(0); -} - -if ($opt_retval == 0) -{ - &usage(); - exit 1; -} - -if ($opt_verbose && $opt_quiet) -{ - print STDERR "-v and -q are incompatible\n"; - &usage(); - exit 1; -} - -if ($#ARGV + 1 == 0) -{ - print STDERR "No tests specified\n"; - &usage(); - exit 1; -} - -if ($opt_verbose) -{ - print STDERR "Option values: h:$opt_help, v:$opt_verbose, " - . "s:\"$opt_srcdir\", o:\"$opt_objdir\" " - . "q:$opt_quiet, u:$opt_ustats, z:$opt_zero\n"; - printf STDERR "Tests (%d total): @ARGV\n", $#ARGV + 1; -} - -# -# Create and print header. -# -@TSTATS = -( - "--------------------------------------------------------------------------\n", - "Test c_user c_system c_total chng\n", - " passed/FAILED h_user h_system h_total %% chng\n" - ); - -if (!$opt_quiet) -{ - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } -} - -# -# Run sequence test(s). -# -$total_utime = 0.0; # Total user time. -$total_stime = 0.0; # Total system time. -$total_hutime = 0.0; # Total historical user time. -$total_hstime = 0.0; # Total historical system time. -$total_ntime = 0.0; # Total time for tests that have historical data. - -foreach $test (@ARGV) -{ - # Strip out any whitespace in $test. - $test =~ s/^\s*(.*)\s*$/$1/; - - $okay = 1; - - if (-e "$opt_srcdir/$test.exp") - { - # Diff mode. - - ($okay, $utime, $stime) = &run_test($test); - - if (-e "$opt_objdir/$test.out") - { - `diff $opt_srcdir/$test.exp $opt_objdir/$test.out > $opt_objdir/$test.diff 2>&1`; - if ($?) - { - # diff returns non-zero if there is a difference. - $okay = 0; - } - } - else - { - $okay = 0; - if ($opt_verbose) - { - print STDERR - "Nonexistent output file \"$opt_objdir/$test.out\"\n"; - } - } - - ($hutime, $hstime) = &print_stats($test, $okay, 0, 0, $utime, $stime); - } - else - { - # Sequence mode. - - ($okay, $utime, $stime) = &run_test($test); - - if (open (STEST_OUT, "<$opt_objdir/$test.out")) - { - $num_subtests = 0; - $num_failed_subtests = 0; - - while (defined($line = <STEST_OUT>)) - { - if ($line =~ /1\.\.(\d+)/) - { - $num_subtests = $1; - last; - } - } - if ($num_subtests == 0) - { - $okay = 0; - if ($opt_verbose) - { - print STDERR "Malformed or missing 1..n line\n"; - } - } - else - { - for ($subtest = 1; $subtest <= $num_subtests; $subtest++) - { - while (defined($line = <STEST_OUT>)) - { - if ($line =~ /^not\s+ok\s+(\d+)?/) - { - $not = 1; - $test_num = $1; - last; - } - elsif ($line =~ /^ok\s+(\d+)?/) - { - $not = 0; - $test_num = $1; - last; - } - } - if (defined($line)) - { - if (defined($test_num) && ($test_num != $subtest)) - { - # There was no output printed for one or more tests. - for (; $subtest < $test_num; $subtest++) - { - $num_failed_subtests++; - } - } - if ($not) - { - $num_failed_subtests++; - } - } - else - { - for (; $subtest <= $num_subtests; $subtest++) - { - $num_failed_subtests++; - } - } - } - - if (0 < $num_failed_subtests) - { - $okay = 0; - } - } - } - else - { - if (!$opt_quiet) - { - print STDERR "Cannot open output file \"$opt_objdir/$test.out\"\n"; - } - exit 1; - } - - ($hutime, $hstime) = &print_stats($test, $okay, - $num_failed_subtests, $num_subtests, - $utime, $stime); - } - - $total_hutime += $hutime; - $total_hstime += $hstime; - - if ($okay) - { - $total_utime += $utime; - $total_stime += $stime; - } - else - { - @FAILED_TESTS = (@FAILED_TESTS, $test); - } - - # If there were historical data, add the run time to the total time to - # compare against the historical run time. - if (0 < ($hutime + $hstime)) - { - $total_ntime += $utime + $stime; - } -} - -# Print summary stats. -$tt_str = sprintf ("%d / %d passed (%5.2f%%%%)", - ($#ARGV + 1) - ($#FAILED_TESTS + 1), - $#ARGV + 1, - (($#ARGV + 1) - ($#FAILED_TESTS + 1)) - / ($#ARGV + 1) * 100); - -$t_str = sprintf ("Totals %7.2f %7.2f %7.2f" - . " %7.2f\n" - . " %s %7.2f %7.2f %7.2f %7.2f%%%%\n", - $total_utime, $total_stime, $total_utime + $total_stime, - ($total_ntime - ($total_hutime + $total_hstime)), - $tt_str . ' ' x (40 - length($tt_str)), - $total_hutime, $total_hstime, $total_hutime + $total_hstime, - ($total_hutime + $total_hstime == 0.0) ? 0.0 : - (($total_ntime - - ($total_hutime + $total_hstime)) - / ($total_hutime + $total_hstime) * 100)); - -@TSTATS = ("--------------------------------------------------------------------------\n", - $t_str, - "--------------------------------------------------------------------------\n" - ); -if (!$opt_quiet) -{ - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } -} - -if ($#FAILED_TESTS >= 0) -{ - # One or more tests failed, so return an error. - exit 1; -} -# End of main execution. - -sub run_test -{ - my ($test) = @_; - my ($okay) = 1; - my ($tutime, $tstime); - my ($utime, $stime, $cutime, $cstime); - my (@TSTATS, @TPATH); - my ($t_str); - my ($srcdir, $objdir); - - # Get the path component of $test, if any. - @TPATH = split(/\//, $test); - pop(@TPATH); - $srcdir = join('/', ($opt_srcdir, @TPATH)); - $objdir = join('/', ($opt_objdir, @TPATH)); - - @TSTATS = ("--------------------------------------------------------------------------\n"); - - $t_str = sprintf ("%s%s", $test, ' ' x (40 - length($test))); - @TSTATS = (@TSTATS, $t_str); - @STATS = (@STATS, @TSTATS); - if (!$opt_quiet) - { - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } - } - - ($utime, $stime, $cutime, $cstime) = times; - `$opt_objdir/$test $srcdir $objdir > $opt_objdir/$test.out 2>&1`; - ($utime, $stime, $tutime, $tstime) = times; - - # Subtract the before time from the after time. - $tutime -= $cutime; - $tstime -= $cstime; - - if ($opt_zero) - { - if ($?) - { - $okay = 0; - if ($opt_verbose) - { - print STDERR - "\"$opt_objdir/$test > $opt_objdir/$test.out 2>&1\" returned $?\n"; - } - } - } - - return ($okay, $tutime, $tstime); -} - -sub print_stats -{ - my ($test, $okay, $failed_subtests, $subtests, $utime, $stime) = @_; - my ($hutime, $hstime); -# my (TEST_PERF); - my (@TSTATS); - my ($t_str, $pass_str); - - $pass_str = $okay ? "passed" : "*** FAILED ***"; - if ((0 != $subtests) && (!$okay)) - { - $pass_str = $pass_str . " ($failed_subtests/$subtests failed)"; - } - $pass_str = $pass_str . ' ' x (39 - length($pass_str)); - - if (-r "$test.perf") - { - if (!open (TEST_PERF, "<$opt_objdir/$test.perf")) - { - print STDERR "Unable to open \"$opt_objdir/$test.perf\"\n"; - exit 1; - } - $_ = <TEST_PERF>; - - ($hutime, $hstime) = split; - close TEST_PERF; - - $t_str = sprintf (" %7.2f %7.2f %7.2f %7.2f\n" - . " %s %7.2f %7.2f %7.2f %7.2f%%%%\n", - $utime, $stime, $utime + $stime, - ($utime + $stime) - ($hutime + $hstime), - $pass_str, - $hutime, $hstime, $hutime + $hstime, - (($hutime + $hstime) == 0.0) ? 0.0 : - ((($utime + $stime) - ($hutime + $hstime)) - / ($hutime + $hstime) * 100)); - } - else - { - $hutime = 0.0; - $hstime = 0.0; - - $t_str = sprintf (" %7.2f %7.2f %7.2f \n" - . " %s\n", - $utime, $stime, $utime + $stime, - $pass_str); - } - @TSTATS = ($t_str); - if (!$opt_quiet) - { - foreach $line (@TSTATS) - { - printf STDOUT "$line"; - } - } - - if ($okay && $opt_ustats) - { - if (!open (TEST_PERF, ">$opt_objdir/$test.perf")) - { - if (!$opt_quiet) - { - print STDERR "Unable to update \"$opt_objdir/$test.perf\"\n"; - } - } - else - { - print TEST_PERF "$utime $stime\n"; - close TEST_PERF; - } - } - - return ($hutime, $hstime); -} - -sub usage -{ - print <<EOF; -$0 usage: - $0 [<options>] <test>+ - - Option | Description - --------------+------------------------------------------------------------- - -h --help | Print usage and exit. - -v --verbose | Verbose (incompatible with quiet). - -q --quiet | Quiet (incompatible with verbose). - -s --srcdir | Path to source tree (default is "."). - -o --objdir | Path to object tree (default is "."). - -u --ustats | Update historical statistics (stored in "<test>.perf". - -z --zero | Consider non-zero exit code to be an error. - --------------+------------------------------------------------------------- - - If <test>.exp exists, <test>'s output is diff'ed with <test>.exp. Any - difference is considered failure. - - If <test>.exp does not exist, output to stdout of the following form is - expected: - - 1..<n> - {not }ok[ 1] - {not }ok[ 2] - ... - {not }ok[ n] - - 1 <= <n> < 2^31 - - Lines which do not match the patterns shown above are ignored. -EOF -} |