xref: /openbsd-src/regress/lib/libc/stdio_threading/include/local.h (revision ffb4dd050d1e35f39b1d6c1c600db7c6443475c2)
15054e3e7Sguenther /*
25054e3e7Sguenther  * Copyright (c) 2008 Bret S. Lambert <blambert@openbsd.org>
35054e3e7Sguenther  *
45054e3e7Sguenther  * Permission to use, copy, modify, and distribute this software for any
55054e3e7Sguenther  * purpose with or without fee is hereby granted, provided that the above
65054e3e7Sguenther  * copyright notice and this permission notice appear in all copies.
75054e3e7Sguenther  *
85054e3e7Sguenther  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
95054e3e7Sguenther  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
105054e3e7Sguenther  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
115054e3e7Sguenther  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
125054e3e7Sguenther  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
135054e3e7Sguenther  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
145054e3e7Sguenther  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
155054e3e7Sguenther  */
165054e3e7Sguenther 
17f1f3d9f4Sguenther #include <err.h>
18*ffb4dd05Sguenther #include <errno.h>
195054e3e7Sguenther #include <stdio.h>
20cd1eb269Snaddy #include <stdlib.h>
215054e3e7Sguenther #include <string.h>
225054e3e7Sguenther #include <unistd.h>
235054e3e7Sguenther #include <pthread.h>
245054e3e7Sguenther 
255054e3e7Sguenther #define THREAD_COUNT 64
265054e3e7Sguenther 
275054e3e7Sguenther #define TEXT	"barnacles"
285054e3e7Sguenther #define	TEXT_N	"barnacles\n"
295054e3e7Sguenther 
305054e3e7Sguenther void	run_threads(void (*)(void *), void *);
315054e3e7Sguenther 
325054e3e7Sguenther static pthread_rwlock_t	start;
335054e3e7Sguenther static void	(*real_func)(void *);
345054e3e7Sguenther 
355054e3e7Sguenther static void *
thread(void * arg)365054e3e7Sguenther thread(void *arg)
375054e3e7Sguenther {
385054e3e7Sguenther 	int	r;
395054e3e7Sguenther 
405054e3e7Sguenther 	if ((r = pthread_rwlock_rdlock(&start)))
415ad04d35Sguenther 		errc(1, r, "could not obtain lock in thread");
425054e3e7Sguenther 	real_func(arg);
435054e3e7Sguenther 	if ((r = pthread_rwlock_unlock(&start)))
445ad04d35Sguenther 		errc(1, r, "could not release lock in thread");
455054e3e7Sguenther 	return NULL;
465054e3e7Sguenther }
475054e3e7Sguenther 
485054e3e7Sguenther void
run_threads(void (* func)(void *),void * arg)495054e3e7Sguenther run_threads(void (*func)(void *), void *arg)
505054e3e7Sguenther {
515054e3e7Sguenther 	pthread_t	self, pthread[THREAD_COUNT];
525054e3e7Sguenther 	int	i, r;
535054e3e7Sguenther 
545054e3e7Sguenther 	self = pthread_self();
555054e3e7Sguenther 	real_func = func;
565054e3e7Sguenther 	if ((r = pthread_rwlock_init(&start, NULL)))
575ad04d35Sguenther 		errc(1, r, "could not initialize lock");
585054e3e7Sguenther 
595054e3e7Sguenther 	if ((r = pthread_rwlock_wrlock(&start)))		/* block */
605ad04d35Sguenther 		errc(1, r, "could not lock lock");
615054e3e7Sguenther 
625054e3e7Sguenther 	for (i = 0; i < THREAD_COUNT; i++)
635054e3e7Sguenther 		if ((r = pthread_create(&pthread[i], NULL, thread, arg))) {
645ad04d35Sguenther 			warnc(r, "could not create thread");
655054e3e7Sguenther 			pthread[i] = self;
665054e3e7Sguenther 		}
675054e3e7Sguenther 
685054e3e7Sguenther 
695054e3e7Sguenther 	if ((r = pthread_rwlock_unlock(&start)))		/* unleash */
705ad04d35Sguenther 		errc(1, r, "could not release lock");
715054e3e7Sguenther 
725054e3e7Sguenther 	sleep(1);
735054e3e7Sguenther 
745054e3e7Sguenther 	if ((r = pthread_rwlock_wrlock(&start)))		/* sync */
755054e3e7Sguenther 		errx(1, "parent could not sync with children: %s",
765054e3e7Sguenther 		    strerror(r));
775054e3e7Sguenther 
785054e3e7Sguenther 	for (i = 0; i < THREAD_COUNT; i++)
795054e3e7Sguenther 		if (! pthread_equal(pthread[i], self) &&
805054e3e7Sguenther 		    (r = pthread_join(pthread[i], NULL)))
815ad04d35Sguenther 			warnc(r, "could not join thread");
825054e3e7Sguenther }
835054e3e7Sguenther 
84