1/*	$OpenBSD: pthread_specific.c,v 1.4 2012/02/20 02:19:15 guenther Exp $	*/
2
3/*
4 * Copyright (c) 2002 CubeSoft Communications, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistribution of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Neither the name of CubeSoft Communications, nor the names of its
13 *    contributors may be used to endorse or promote products derived from
14 *    this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/types.h>
29#include <sys/resource.h>
30#include <pthread.h>
31#include <pthread_np.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <unistd.h>
35#include "test.h"
36
37#define NTHREADS	128
38
39pthread_key_t key;
40int destroy_run = 0;
41
42static void *
43run_thread(void *arg)
44{
45	int i;
46
47	CHECKe(write(STDOUT_FILENO, ".", 1));
48	for (i = 0; i < 32767; i++) {
49		void *p;
50
51		p = pthread_getspecific(key);
52		if (p == NULL) {
53			CHECKr(pthread_setspecific(key, pthread_self()));
54		} else {
55			ASSERT(p == pthread_self());
56		}
57		fflush(stderr);
58	}
59
60	return (NULL);
61}
62
63static void
64destroy_key(void *keyp)
65{
66	destroy_run++;
67}
68
69int
70main(int argc, char *argv[])
71{
72	pthread_t threads[NTHREADS];
73	struct rlimit nproc;
74	int i;
75
76	CHECKe(getrlimit(RLIMIT_NPROC, &nproc));
77	nproc.rlim_cur = nproc.rlim_max;
78	CHECKe(setrlimit(RLIMIT_NPROC, &nproc));
79
80	CHECKr(pthread_key_create(&key, destroy_key));
81	for (i = 0; i < NTHREADS; i++) {
82		CHECKr(pthread_create(&threads[i], NULL, run_thread, NULL));
83	}
84	for (i = 0; i < NTHREADS; i++) {
85		CHECKr(pthread_join(threads[i], NULL));
86	}
87	CHECKe(write(STDOUT_FILENO, "\n", 1));
88
89	CHECKr(pthread_key_delete(key));
90
91	ASSERT(destroy_run > 0);
92
93	SUCCEED;
94}
95