summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorguenther <>2009-11-19 08:06:06 +0000
committerguenther <>2009-11-19 08:06:06 +0000
commit3bf8c221bc859ae3254fe6b11fb60750f0bae04e (patch)
treed068826e9af472b7f9584e32bdc17e83472df8f4
parente9648d2ce662fb0d79072496682efb0718c01e66 (diff)
downloadopenbsd-3bf8c221bc859ae3254fe6b11fb60750f0bae04e.tar.gz
openbsd-3bf8c221bc859ae3254fe6b11fb60750f0bae04e.tar.bz2
openbsd-3bf8c221bc859ae3254fe6b11fb60750f0bae04e.zip
Add regression tests for stdio threading. Originally by blambert with
some further hacking by me
-rw-r--r--src/regress/lib/libc/Makefile3
-rw-r--r--src/regress/lib/libc/stdio_threading/Makefile3
-rw-r--r--src/regress/lib/libc/stdio_threading/fgetln/Makefile6
-rwxr-xr-xsrc/regress/lib/libc/stdio_threading/fgetln/fgetln_test.c70
-rw-r--r--src/regress/lib/libc/stdio_threading/fgets/Makefile6
-rwxr-xr-xsrc/regress/lib/libc/stdio_threading/fgets/fgets_test.c69
-rw-r--r--src/regress/lib/libc/stdio_threading/fopen/Makefile6
-rwxr-xr-xsrc/regress/lib/libc/stdio_threading/fopen/fopen_test.c48
-rw-r--r--src/regress/lib/libc/stdio_threading/fputs/Makefile6
-rwxr-xr-xsrc/regress/lib/libc/stdio_threading/fputs/fputs_test.c66
-rw-r--r--src/regress/lib/libc/stdio_threading/fread/Makefile6
-rwxr-xr-xsrc/regress/lib/libc/stdio_threading/fread/fread_test.c71
-rw-r--r--src/regress/lib/libc/stdio_threading/fwrite/Makefile6
-rwxr-xr-xsrc/regress/lib/libc/stdio_threading/fwrite/fwrite_test.c66
-rw-r--r--src/regress/lib/libc/stdio_threading/include/local.h80
15 files changed, 511 insertions, 1 deletions
diff --git a/src/regress/lib/libc/Makefile b/src/regress/lib/libc/Makefile
index cca83b0a86..b210b7df71 100644
--- a/src/regress/lib/libc/Makefile
+++ b/src/regress/lib/libc/Makefile
@@ -1,9 +1,10 @@
1# $OpenBSD: Makefile,v 1.28 2008/10/02 12:26:45 millert Exp $ 1# $OpenBSD: Makefile,v 1.29 2009/11/19 08:06:06 guenther Exp $
2 2
3SUBDIR+= _setjmp alloca atexit basename cxa-atexit db dirname fnmatch 3SUBDIR+= _setjmp alloca atexit basename cxa-atexit db dirname fnmatch
4SUBDIR+= fpclassify getaddrinfo getcap getopt_long glob hsearch longjmp 4SUBDIR+= fpclassify getaddrinfo getcap getopt_long glob hsearch longjmp
5SUBDIR+= locale malloc netdb popen printf regex setjmp setjmp-signal 5SUBDIR+= locale malloc netdb popen printf regex setjmp setjmp-signal
6SUBDIR+= sigreturn sigsetjmp sprintf strerror strtod strtonum telldir time vis 6SUBDIR+= sigreturn sigsetjmp sprintf strerror strtod strtonum telldir time vis
7SUBDIR+= stdio_threading
7 8
8.if (${MACHINE_ARCH} != "vax") 9.if (${MACHINE_ARCH} != "vax")
9SUBDIR+= ieeefp 10SUBDIR+= ieeefp
diff --git a/src/regress/lib/libc/stdio_threading/Makefile b/src/regress/lib/libc/stdio_threading/Makefile
new file mode 100644
index 0000000000..e42481afc2
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/Makefile
@@ -0,0 +1,3 @@
1SUBDIR += fopen fread fwrite fgetln fgets fputs
2
3.include <bsd.subdir.mk>
diff --git a/src/regress/lib/libc/stdio_threading/fgetln/Makefile b/src/regress/lib/libc/stdio_threading/fgetln/Makefile
new file mode 100644
index 0000000000..216db188ef
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fgetln/Makefile
@@ -0,0 +1,6 @@
1TOPDIR=${.CURDIR}
2PROG=fgetln_test
3CFLAGS+=-I ${TOPDIR}/../include/
4LDFLAGS+=-lpthread
5
6.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/stdio_threading/fgetln/fgetln_test.c b/src/regress/lib/libc/stdio_threading/fgetln/fgetln_test.c
new file mode 100755
index 0000000000..d5c4db2edf
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fgetln/fgetln_test.c
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "local.h"
18
19void
20fgetln_thread(void *v)
21{
22 FILE *file = v;
23 size_t len;
24 char *buf;
25 int i;
26
27 for (i = 0; i < 4096; i++) {
28 if ((buf = fgetln(file, &len)) == NULL) {
29
30 if (feof(file))
31 break;
32
33 printf("OMG!!!\n");
34 fflush(stdout);
35 break;
36 }
37 if (strncmp(buf, TEXT_N, sizeof(TEXT_N)))
38 err(1, "fgetln not atomic!!!");
39 }
40}
41
42int
43main(void)
44{
45 char sfn[24];
46 char buf[sizeof(TEXT_N)];
47 FILE *sfp;
48 int fd, i;
49
50 strlcpy(sfn, "/tmp/barnacles.XXXXXXXX", sizeof(sfn));
51 if ((fd = mkstemp(sfn)) == -1 ||
52 (sfp = fdopen(fd, "w+")) == NULL) {
53 if (fd != -1) {
54 unlink(sfn);
55 close(fd);
56 }
57 err(1, "could not open temporary file");
58 }
59
60 for (i = 0; i < 4096 * THREAD_COUNT; i++)
61 if (fwrite(TEXT_N, sizeof(char), strlen(TEXT_N), sfp) == 0)
62 err(1, "Could not populate test file");
63
64 run_threads(fgetln_thread, sfp);
65
66 unlink(sfn);
67 close(fd);
68
69 exit(0);
70}
diff --git a/src/regress/lib/libc/stdio_threading/fgets/Makefile b/src/regress/lib/libc/stdio_threading/fgets/Makefile
new file mode 100644
index 0000000000..dfd210cbf4
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fgets/Makefile
@@ -0,0 +1,6 @@
1TOPDIR=${.CURDIR}
2PROG=fgets_test
3CFLAGS+=-I ${TOPDIR}/../include/
4LDFLAGS+=-lpthread
5
6.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/stdio_threading/fgets/fgets_test.c b/src/regress/lib/libc/stdio_threading/fgets/fgets_test.c
new file mode 100755
index 0000000000..685d4c8257
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fgets/fgets_test.c
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "local.h"
18
19void
20fgets_thread(void *v)
21{
22 char buf[sizeof(TEXT_N) + 1];
23 FILE *file = v;
24 int i;
25
26 for (i = 0; i < 4096; i++) {
27 if (fgets(buf, sizeof(buf), file) == NULL) {
28
29 if (feof(file))
30 break;
31
32 printf("OMG!!!\n");
33 fflush(stdout);
34 break;
35 }
36 if (strncmp(buf, TEXT, sizeof(TEXT)))
37 err(1, "Read not atomic!!!");
38 }
39}
40
41int
42main(void)
43{
44 char sfn[24];
45 char buf[sizeof(TEXT)];
46 FILE *sfp;
47 int fd, i;
48
49 strlcpy(sfn, "/tmp/barnacles.XXXXXXXX", sizeof(sfn));
50 if ((fd = mkstemp(sfn)) == -1 ||
51 (sfp = fdopen(fd, "w+")) == NULL) {
52 if (fd != -1) {
53 unlink(sfn);
54 close(fd);
55 }
56 err(1, "could not open temporary file");
57 }
58
59 for (i = 0; i < 4096 * THREAD_COUNT; i++)
60 if (fwrite(TEXT_N, sizeof(char), strlen(TEXT_N), sfp) == 0)
61 err(1, "Could not populate test file");
62
63 run_threads(fgets_thread, sfp);
64
65 unlink(sfn);
66 close(fd);
67
68 exit(0);
69}
diff --git a/src/regress/lib/libc/stdio_threading/fopen/Makefile b/src/regress/lib/libc/stdio_threading/fopen/Makefile
new file mode 100644
index 0000000000..4301a83978
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fopen/Makefile
@@ -0,0 +1,6 @@
1TOPDIR=${.CURDIR}
2PROG=fopen_test
3CFLAGS+=-I ${TOPDIR}/../include/
4LDFLAGS+=-lpthread
5
6.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/stdio_threading/fopen/fopen_test.c b/src/regress/lib/libc/stdio_threading/fopen/fopen_test.c
new file mode 100755
index 0000000000..72359bb323
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fopen/fopen_test.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <stdio.h>
18#include <pthread.h>
19#include "local.h"
20
21int
22writefn(void *cookie, const char *buf, int size)
23{
24 return 0;
25}
26
27void
28fopen_thread(void *v)
29{
30 FILE *file;
31 int i;
32
33 for (i = 0; i < 4096; i++) {
34 file = fwopen(&i, writefn);
35 if (file != NULL) {
36 fputc('0', file);
37 pthread_yield();
38 fclose(file);
39 }
40 }
41}
42
43int
44main(void)
45{
46 run_threads(fopen_thread, NULL);
47 exit(0);
48}
diff --git a/src/regress/lib/libc/stdio_threading/fputs/Makefile b/src/regress/lib/libc/stdio_threading/fputs/Makefile
new file mode 100644
index 0000000000..5542dd3979
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fputs/Makefile
@@ -0,0 +1,6 @@
1TOPDIR=${.CURDIR}
2PROG=fputs_test
3CFLAGS+=-I ${TOPDIR}/../include/
4LDFLAGS+=-lpthread
5
6.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/stdio_threading/fputs/fputs_test.c b/src/regress/lib/libc/stdio_threading/fputs/fputs_test.c
new file mode 100755
index 0000000000..c0a617510e
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fputs/fputs_test.c
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "local.h"
18
19void
20fputs_thread(void *v)
21{
22 FILE *file = v;
23 int i;
24
25 for (i = 0; i < 4096; i++) {
26 if (fputs(TEXT, file) != 0) {
27
28 if (feof(file))
29 break;
30
31 printf("OMG!!!\n");
32 fflush(stdout);
33 break;
34 }
35 }
36}
37
38int
39main(void)
40{
41 char sfn[24];
42 char buf[sizeof(TEXT)];
43 FILE *sfp;
44 int fd, i;
45
46 strlcpy(sfn, "/tmp/barnacles.XXXXXXXX", sizeof(sfn));
47 if ((fd = mkstemp(sfn)) == -1 ||
48 (sfp = fdopen(fd, "w+")) == NULL) {
49 if (fd != -1) {
50 unlink(sfn);
51 close(fd);
52 }
53 err(1, "could not open temporary file");
54 }
55
56 run_threads(fputs_thread, sfp);
57
58 while (fgets(buf, sizeof(buf), sfp) != NULL) /* verify */
59 if (strcmp(buf, TEXT))
60 err(1, "Thread writes were not atomic!!!");
61
62 unlink(sfn);
63 close(fd);
64
65 exit(0);
66}
diff --git a/src/regress/lib/libc/stdio_threading/fread/Makefile b/src/regress/lib/libc/stdio_threading/fread/Makefile
new file mode 100644
index 0000000000..97c8816652
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fread/Makefile
@@ -0,0 +1,6 @@
1TOPDIR=${.CURDIR}
2PROG=fread_test
3CFLAGS+=-I ${TOPDIR}/../include/
4LDFLAGS+=-lpthread
5
6.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/stdio_threading/fread/fread_test.c b/src/regress/lib/libc/stdio_threading/fread/fread_test.c
new file mode 100755
index 0000000000..b2372f5ab6
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fread/fread_test.c
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <stdio.h>
18#include <pthread.h>
19#include "local.h"
20
21void
22fread_thread(void *v)
23{
24 char buf[sizeof(TEXT)];
25 FILE *file = v;
26 int i;
27
28 for (i = 0; i < 4096; i++) {
29 if (fread(buf, sizeof(char), strlen(TEXT), file) == 0) {
30
31 if (feof(file))
32 break;
33
34 printf("OMG!!!\n");
35 fflush(stdout);
36 break;
37 }
38 if (strncmp(buf, TEXT, sizeof(TEXT)))
39 err(1, "Read not atomic!!!");
40 }
41}
42
43int
44main(void)
45{
46 char sfn[24];
47 char buf[sizeof(TEXT)];
48 FILE *sfp;
49 int fd, i;
50
51 strlcpy(sfn, "/tmp/barnacles.XXXXXXXX", sizeof(sfn));
52 if ((fd = mkstemp(sfn)) == -1 ||
53 (sfp = fdopen(fd, "w+")) == NULL) {
54 if (fd != -1) {
55 unlink(sfn);
56 close(fd);
57 }
58 err(1, "could not open temporary file");
59 }
60
61 for (i = 0; i < 4096 * THREAD_COUNT; i++)
62 if (fwrite(TEXT, sizeof(char), strlen(TEXT), sfp) == 0)
63 err(1, "Could not populate test file");
64
65 run_threads(fread_thread, sfp);
66
67 unlink(sfn);
68 close(fd);
69
70 exit(0);
71}
diff --git a/src/regress/lib/libc/stdio_threading/fwrite/Makefile b/src/regress/lib/libc/stdio_threading/fwrite/Makefile
new file mode 100644
index 0000000000..5952a1f48a
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fwrite/Makefile
@@ -0,0 +1,6 @@
1TOPDIR=${.CURDIR}
2PROG=fwrite_test
3CFLAGS+=-I ${TOPDIR}/../include/
4LDFLAGS+=-lpthread
5
6.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/stdio_threading/fwrite/fwrite_test.c b/src/regress/lib/libc/stdio_threading/fwrite/fwrite_test.c
new file mode 100755
index 0000000000..39bfb51ef0
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/fwrite/fwrite_test.c
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "local.h"
18
19void
20fwrite_thread(void *v)
21{
22 FILE *file = v;
23 int i;
24
25 for (i = 0; i < 4096; i++) {
26 if (fwrite(TEXT, sizeof(char), strlen(TEXT), file) == 0) {
27
28 if (feof(file))
29 break;
30
31 printf("OMG!!!\n");
32 fflush(stdout);
33 break;
34 }
35 }
36}
37
38int
39main(void)
40{
41 char sfn[24];
42 char buf[sizeof(TEXT)];
43 FILE *sfp;
44 int fd, i;
45
46 strlcpy(sfn, "/tmp/barnacles.XXXXXXXX", sizeof(sfn));
47 if ((fd = mkstemp(sfn)) == -1 ||
48 (sfp = fdopen(fd, "w+")) == NULL) {
49 if (fd != -1) {
50 unlink(sfn);
51 close(fd);
52 }
53 err(1, "could not open temporary file");
54 }
55
56 run_threads(fwrite_thread, sfp);
57
58 while (fread(buf, sizeof(char), strlen(TEXT), sfp)) /* verify */
59 if (strncmp(buf, TEXT, sizeof(TEXT)))
60 err(1, "Thread writes were not atomic!!!");
61
62 unlink(sfn);
63 close(fd);
64
65 exit(0);
66}
diff --git a/src/regress/lib/libc/stdio_threading/include/local.h b/src/regress/lib/libc/stdio_threading/include/local.h
new file mode 100644
index 0000000000..794d868071
--- /dev/null
+++ b/src/regress/lib/libc/stdio_threading/include/local.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <stdio.h>
18#include <string.h>
19#include <unistd.h>
20#include <pthread.h>
21
22#define THREAD_COUNT 64
23
24#define TEXT "barnacles"
25#define TEXT_N "barnacles\n"
26
27void run_threads(void (*)(void *), void *);
28
29static pthread_rwlock_t start;
30static void (*real_func)(void *);
31
32static void *
33thread(void *arg)
34{
35 int r;
36
37 if ((r = pthread_rwlock_rdlock(&start)))
38 errx(1, "could not obtain lock in thread: %s", strerror(r));
39 real_func(arg);
40 if ((r = pthread_rwlock_unlock(&start)))
41 errx(1, "could not release lock in thread: %s", strerror(r));
42 return NULL;
43}
44
45void
46run_threads(void (*func)(void *), void *arg)
47{
48 pthread_t self, pthread[THREAD_COUNT];
49 int i, r;
50
51 self = pthread_self();
52 real_func = func;
53 if ((r = pthread_rwlock_init(&start, NULL)))
54 errx(1, "could not initialize lock: %s", strerror(r));
55
56 if ((r = pthread_rwlock_wrlock(&start))) /* block */
57 errx(1, "could not lock lock: %s", strerror(r));
58
59 for (i = 0; i < THREAD_COUNT; i++)
60 if ((r = pthread_create(&pthread[i], NULL, thread, arg))) {
61 warnx("could not create thread: %s", strerror(r));
62 pthread[i] = self;
63 }
64
65
66 if ((r = pthread_rwlock_unlock(&start))) /* unleash */
67 errx(1, "could not release lock: %s", strerror(r));
68
69 sleep(1);
70
71 if ((r = pthread_rwlock_wrlock(&start))) /* sync */
72 errx(1, "parent could not sync with children: %s",
73 strerror(r));
74
75 for (i = 0; i < THREAD_COUNT; i++)
76 if (! pthread_equal(pthread[i], self) &&
77 (r = pthread_join(pthread[i], NULL)))
78 warnx("could not join thread: %s", strerror(r));
79}
80