xref: /freebsd/contrib/netbsd-tests/lib/libpthread_dbg/t_threads.c (revision 1a36faad54665288ed4eb839d2a4699ae2ead45e)
1*63d1fd59SEnji Cooper /*	$NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $	*/
2*63d1fd59SEnji Cooper 
3*63d1fd59SEnji Cooper /*-
4*63d1fd59SEnji Cooper  * Copyright (c) 2016 The NetBSD Foundation, Inc.
5*63d1fd59SEnji Cooper  * All rights reserved.
6*63d1fd59SEnji Cooper  *
7*63d1fd59SEnji Cooper  * Redistribution and use in source and binary forms, with or without
8*63d1fd59SEnji Cooper  * modification, are permitted provided that the following conditions
9*63d1fd59SEnji Cooper  * are met:
10*63d1fd59SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
11*63d1fd59SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
12*63d1fd59SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
13*63d1fd59SEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
14*63d1fd59SEnji Cooper  *    documentation and/or other materials provided with the distribution.
15*63d1fd59SEnji Cooper  *
16*63d1fd59SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17*63d1fd59SEnji Cooper  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18*63d1fd59SEnji Cooper  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*63d1fd59SEnji Cooper  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20*63d1fd59SEnji Cooper  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*63d1fd59SEnji Cooper  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*63d1fd59SEnji Cooper  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*63d1fd59SEnji Cooper  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*63d1fd59SEnji Cooper  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*63d1fd59SEnji Cooper  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*63d1fd59SEnji Cooper  * POSSIBILITY OF SUCH DAMAGE.
27*63d1fd59SEnji Cooper  */
28*63d1fd59SEnji Cooper 
29*63d1fd59SEnji Cooper 
30*63d1fd59SEnji Cooper #include <sys/cdefs.h>
31*63d1fd59SEnji Cooper __RCSID("$NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $");
32*63d1fd59SEnji Cooper 
33*63d1fd59SEnji Cooper #include <dlfcn.h>
34*63d1fd59SEnji Cooper #include <pthread.h>
35*63d1fd59SEnji Cooper #include <pthread_dbg.h>
36*63d1fd59SEnji Cooper #include <stdio.h>
37*63d1fd59SEnji Cooper #include <string.h>
38*63d1fd59SEnji Cooper #include <unistd.h>
39*63d1fd59SEnji Cooper 
40*63d1fd59SEnji Cooper #include <atf-c.h>
41*63d1fd59SEnji Cooper 
42*63d1fd59SEnji Cooper #include "h_common.h"
43*63d1fd59SEnji Cooper 
44*63d1fd59SEnji Cooper #define MAX_THREADS (size_t)10
45*63d1fd59SEnji Cooper 
46*63d1fd59SEnji Cooper ATF_TC(threads1);
ATF_TC_HEAD(threads1,tc)47*63d1fd59SEnji Cooper ATF_TC_HEAD(threads1, tc)
48*63d1fd59SEnji Cooper {
49*63d1fd59SEnji Cooper 
50*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
51*63d1fd59SEnji Cooper 	    "Asserts that td_thr_iter() call without extra logic works");
52*63d1fd59SEnji Cooper }
53*63d1fd59SEnji Cooper 
54*63d1fd59SEnji Cooper static volatile int exiting1;
55*63d1fd59SEnji Cooper 
56*63d1fd59SEnji Cooper static void *
busyFunction1(void * arg)57*63d1fd59SEnji Cooper busyFunction1(void *arg)
58*63d1fd59SEnji Cooper {
59*63d1fd59SEnji Cooper 
60*63d1fd59SEnji Cooper 	while (exiting1 == 0)
61*63d1fd59SEnji Cooper 		usleep(50000);
62*63d1fd59SEnji Cooper 
63*63d1fd59SEnji Cooper 	return NULL;
64*63d1fd59SEnji Cooper }
65*63d1fd59SEnji Cooper 
66*63d1fd59SEnji Cooper static int
iterateThreads1(td_thread_t * thread,void * arg)67*63d1fd59SEnji Cooper iterateThreads1(td_thread_t *thread, void *arg)
68*63d1fd59SEnji Cooper {
69*63d1fd59SEnji Cooper 
70*63d1fd59SEnji Cooper 	return TD_ERR_OK;
71*63d1fd59SEnji Cooper }
72*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads1,tc)73*63d1fd59SEnji Cooper ATF_TC_BODY(threads1, tc)
74*63d1fd59SEnji Cooper {
75*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
76*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
77*63d1fd59SEnji Cooper 	size_t i;
78*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
79*63d1fd59SEnji Cooper 
80*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
81*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
82*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
83*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
84*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
85*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
86*63d1fd59SEnji Cooper 
87*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
88*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
89*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
90*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction1, NULL));
91*63d1fd59SEnji Cooper 	}
92*63d1fd59SEnji Cooper 
93*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
94*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
95*63d1fd59SEnji Cooper 
96*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads1, NULL) == TD_ERR_OK);
97*63d1fd59SEnji Cooper 
98*63d1fd59SEnji Cooper 	exiting1 = 1;
99*63d1fd59SEnji Cooper 
100*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
101*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
102*63d1fd59SEnji Cooper }
103*63d1fd59SEnji Cooper 
104*63d1fd59SEnji Cooper ATF_TC(threads2);
ATF_TC_HEAD(threads2,tc)105*63d1fd59SEnji Cooper ATF_TC_HEAD(threads2, tc)
106*63d1fd59SEnji Cooper {
107*63d1fd59SEnji Cooper 
108*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
109*63d1fd59SEnji Cooper 	    "Asserts that td_thr_iter() call is executed for each thread once");
110*63d1fd59SEnji Cooper }
111*63d1fd59SEnji Cooper 
112*63d1fd59SEnji Cooper static volatile int exiting2;
113*63d1fd59SEnji Cooper 
114*63d1fd59SEnji Cooper static void *
busyFunction2(void * arg)115*63d1fd59SEnji Cooper busyFunction2(void *arg)
116*63d1fd59SEnji Cooper {
117*63d1fd59SEnji Cooper 
118*63d1fd59SEnji Cooper 	while (exiting2 == 0)
119*63d1fd59SEnji Cooper 		usleep(50000);
120*63d1fd59SEnji Cooper 
121*63d1fd59SEnji Cooper 	return NULL;
122*63d1fd59SEnji Cooper }
123*63d1fd59SEnji Cooper 
124*63d1fd59SEnji Cooper static int
iterateThreads2(td_thread_t * thread,void * arg)125*63d1fd59SEnji Cooper iterateThreads2(td_thread_t *thread, void *arg)
126*63d1fd59SEnji Cooper {
127*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
128*63d1fd59SEnji Cooper 
129*63d1fd59SEnji Cooper 	++(*counter);
130*63d1fd59SEnji Cooper 
131*63d1fd59SEnji Cooper 	return TD_ERR_OK;
132*63d1fd59SEnji Cooper }
133*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads2,tc)134*63d1fd59SEnji Cooper ATF_TC_BODY(threads2, tc)
135*63d1fd59SEnji Cooper {
136*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
137*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
138*63d1fd59SEnji Cooper 	size_t i;
139*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
140*63d1fd59SEnji Cooper 	int count = 0;
141*63d1fd59SEnji Cooper 
142*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
143*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
144*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
145*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
146*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
147*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
148*63d1fd59SEnji Cooper 
149*63d1fd59SEnji Cooper 
150*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
151*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
152*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
153*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction2, NULL));
154*63d1fd59SEnji Cooper 	}
155*63d1fd59SEnji Cooper 
156*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
157*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
158*63d1fd59SEnji Cooper 
159*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads2, &count) == TD_ERR_OK);
160*63d1fd59SEnji Cooper 
161*63d1fd59SEnji Cooper 	exiting2 = 1;
162*63d1fd59SEnji Cooper 
163*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
164*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
165*63d1fd59SEnji Cooper 
166*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
167*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
168*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
169*63d1fd59SEnji Cooper }
170*63d1fd59SEnji Cooper 
171*63d1fd59SEnji Cooper ATF_TC(threads3);
ATF_TC_HEAD(threads3,tc)172*63d1fd59SEnji Cooper ATF_TC_HEAD(threads3, tc)
173*63d1fd59SEnji Cooper {
174*63d1fd59SEnji Cooper 
175*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
176*63d1fd59SEnji Cooper 	    "Asserts that for each td_thr_iter() call td_thr_info() is valid");
177*63d1fd59SEnji Cooper }
178*63d1fd59SEnji Cooper 
179*63d1fd59SEnji Cooper static volatile int exiting3;
180*63d1fd59SEnji Cooper 
181*63d1fd59SEnji Cooper static void *
busyFunction3(void * arg)182*63d1fd59SEnji Cooper busyFunction3(void *arg)
183*63d1fd59SEnji Cooper {
184*63d1fd59SEnji Cooper 
185*63d1fd59SEnji Cooper 	while (exiting3 == 0)
186*63d1fd59SEnji Cooper 		usleep(50000);
187*63d1fd59SEnji Cooper 
188*63d1fd59SEnji Cooper 	return NULL;
189*63d1fd59SEnji Cooper }
190*63d1fd59SEnji Cooper 
191*63d1fd59SEnji Cooper static int
iterateThreads3(td_thread_t * thread,void * arg)192*63d1fd59SEnji Cooper iterateThreads3(td_thread_t *thread, void *arg)
193*63d1fd59SEnji Cooper {
194*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
195*63d1fd59SEnji Cooper 	td_thread_info_t info;
196*63d1fd59SEnji Cooper 
197*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_info(thread, &info) == TD_ERR_OK);
198*63d1fd59SEnji Cooper 
199*63d1fd59SEnji Cooper 	++(*counter);
200*63d1fd59SEnji Cooper 
201*63d1fd59SEnji Cooper 	return TD_ERR_OK;
202*63d1fd59SEnji Cooper }
203*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads3,tc)204*63d1fd59SEnji Cooper ATF_TC_BODY(threads3, tc)
205*63d1fd59SEnji Cooper {
206*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
207*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
208*63d1fd59SEnji Cooper 	size_t i;
209*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
210*63d1fd59SEnji Cooper 	int count = 0;
211*63d1fd59SEnji Cooper 
212*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
213*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
214*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
215*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
216*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
217*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
218*63d1fd59SEnji Cooper 
219*63d1fd59SEnji Cooper 
220*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
221*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
222*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
223*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction3, NULL));
224*63d1fd59SEnji Cooper 	}
225*63d1fd59SEnji Cooper 
226*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
227*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
228*63d1fd59SEnji Cooper 
229*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads3, &count) == TD_ERR_OK);
230*63d1fd59SEnji Cooper 
231*63d1fd59SEnji Cooper 	exiting3 = 1;
232*63d1fd59SEnji Cooper 
233*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
234*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
235*63d1fd59SEnji Cooper 
236*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
237*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
238*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
239*63d1fd59SEnji Cooper }
240*63d1fd59SEnji Cooper 
241*63d1fd59SEnji Cooper ATF_TC(threads4);
ATF_TC_HEAD(threads4,tc)242*63d1fd59SEnji Cooper ATF_TC_HEAD(threads4, tc)
243*63d1fd59SEnji Cooper {
244*63d1fd59SEnji Cooper 
245*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
246*63d1fd59SEnji Cooper 	    "Asserts that for each td_thr_iter() call td_thr_getname() is "
247*63d1fd59SEnji Cooper 	    "valid");
248*63d1fd59SEnji Cooper }
249*63d1fd59SEnji Cooper 
250*63d1fd59SEnji Cooper static volatile int exiting4;
251*63d1fd59SEnji Cooper 
252*63d1fd59SEnji Cooper static void *
busyFunction4(void * arg)253*63d1fd59SEnji Cooper busyFunction4(void *arg)
254*63d1fd59SEnji Cooper {
255*63d1fd59SEnji Cooper 
256*63d1fd59SEnji Cooper 	while (exiting4 == 0)
257*63d1fd59SEnji Cooper 		usleep(50000);
258*63d1fd59SEnji Cooper 
259*63d1fd59SEnji Cooper 	return NULL;
260*63d1fd59SEnji Cooper }
261*63d1fd59SEnji Cooper 
262*63d1fd59SEnji Cooper static int
iterateThreads4(td_thread_t * thread,void * arg)263*63d1fd59SEnji Cooper iterateThreads4(td_thread_t *thread, void *arg)
264*63d1fd59SEnji Cooper {
265*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
266*63d1fd59SEnji Cooper 	char name[PTHREAD_MAX_NAMELEN_NP];
267*63d1fd59SEnji Cooper 
268*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK);
269*63d1fd59SEnji Cooper 
270*63d1fd59SEnji Cooper 	printf("Thread name: %s\n", name);
271*63d1fd59SEnji Cooper 
272*63d1fd59SEnji Cooper 	++(*counter);
273*63d1fd59SEnji Cooper 
274*63d1fd59SEnji Cooper 	return TD_ERR_OK;
275*63d1fd59SEnji Cooper }
276*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads4,tc)277*63d1fd59SEnji Cooper ATF_TC_BODY(threads4, tc)
278*63d1fd59SEnji Cooper {
279*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
280*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
281*63d1fd59SEnji Cooper 	size_t i;
282*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
283*63d1fd59SEnji Cooper 	int count = 0;
284*63d1fd59SEnji Cooper 
285*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
286*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
287*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
288*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
289*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
290*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
291*63d1fd59SEnji Cooper 
292*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
293*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
294*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
295*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction4, NULL));
296*63d1fd59SEnji Cooper 	}
297*63d1fd59SEnji Cooper 
298*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
299*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
300*63d1fd59SEnji Cooper 		    (pthread_setname_np(threads[i], "test_%d", (void*)i));
301*63d1fd59SEnji Cooper 	}
302*63d1fd59SEnji Cooper 
303*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
304*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
305*63d1fd59SEnji Cooper 
306*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads4, &count) == TD_ERR_OK);
307*63d1fd59SEnji Cooper 
308*63d1fd59SEnji Cooper 	exiting4 = 1;
309*63d1fd59SEnji Cooper 
310*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
311*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
312*63d1fd59SEnji Cooper 
313*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
314*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
315*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
316*63d1fd59SEnji Cooper }
317*63d1fd59SEnji Cooper 
318*63d1fd59SEnji Cooper ATF_TC(threads5);
ATF_TC_HEAD(threads5,tc)319*63d1fd59SEnji Cooper ATF_TC_HEAD(threads5, tc)
320*63d1fd59SEnji Cooper {
321*63d1fd59SEnji Cooper 
322*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
323*63d1fd59SEnji Cooper 	    "Asserts that td_thr_getname() handles shorter buffer parameter "
324*63d1fd59SEnji Cooper 	    "and the result is properly truncated");
325*63d1fd59SEnji Cooper }
326*63d1fd59SEnji Cooper 
327*63d1fd59SEnji Cooper static volatile int exiting5;
328*63d1fd59SEnji Cooper 
329*63d1fd59SEnji Cooper static void *
busyFunction5(void * arg)330*63d1fd59SEnji Cooper busyFunction5(void *arg)
331*63d1fd59SEnji Cooper {
332*63d1fd59SEnji Cooper 
333*63d1fd59SEnji Cooper 	while (exiting5 == 0)
334*63d1fd59SEnji Cooper 		usleep(50000);
335*63d1fd59SEnji Cooper 
336*63d1fd59SEnji Cooper 	return NULL;
337*63d1fd59SEnji Cooper }
338*63d1fd59SEnji Cooper 
339*63d1fd59SEnji Cooper static int
iterateThreads5(td_thread_t * thread,void * arg)340*63d1fd59SEnji Cooper iterateThreads5(td_thread_t *thread, void *arg)
341*63d1fd59SEnji Cooper {
342*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
343*63d1fd59SEnji Cooper 	/* Arbitrarily short string buffer */
344*63d1fd59SEnji Cooper 	char name[3];
345*63d1fd59SEnji Cooper 
346*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK);
347*63d1fd59SEnji Cooper 
348*63d1fd59SEnji Cooper 	printf("Thread name: %s\n", name);
349*63d1fd59SEnji Cooper 
350*63d1fd59SEnji Cooper 	/* strlen(3) does not count including a '\0' character */
351*63d1fd59SEnji Cooper 	ATF_REQUIRE(strlen(name) < sizeof(name));
352*63d1fd59SEnji Cooper 
353*63d1fd59SEnji Cooper 	++(*counter);
354*63d1fd59SEnji Cooper 
355*63d1fd59SEnji Cooper 	return TD_ERR_OK;
356*63d1fd59SEnji Cooper }
357*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads5,tc)358*63d1fd59SEnji Cooper ATF_TC_BODY(threads5, tc)
359*63d1fd59SEnji Cooper {
360*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
361*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
362*63d1fd59SEnji Cooper 	size_t i;
363*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
364*63d1fd59SEnji Cooper 	int count = 0;
365*63d1fd59SEnji Cooper 
366*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
367*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
368*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
369*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
370*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
371*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
372*63d1fd59SEnji Cooper 
373*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
374*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
375*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
376*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction5, NULL));
377*63d1fd59SEnji Cooper 	}
378*63d1fd59SEnji Cooper 
379*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
380*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
381*63d1fd59SEnji Cooper 		    (pthread_setname_np(threads[i], "test_%d", (void*)i));
382*63d1fd59SEnji Cooper 	}
383*63d1fd59SEnji Cooper 
384*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
385*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
386*63d1fd59SEnji Cooper 
387*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads5, &count) == TD_ERR_OK);
388*63d1fd59SEnji Cooper 
389*63d1fd59SEnji Cooper 	exiting5 = 1;
390*63d1fd59SEnji Cooper 
391*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
392*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
393*63d1fd59SEnji Cooper 
394*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
395*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
396*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
397*63d1fd59SEnji Cooper }
398*63d1fd59SEnji Cooper 
399*63d1fd59SEnji Cooper ATF_TC(threads6);
ATF_TC_HEAD(threads6,tc)400*63d1fd59SEnji Cooper ATF_TC_HEAD(threads6, tc)
401*63d1fd59SEnji Cooper {
402*63d1fd59SEnji Cooper 
403*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
404*63d1fd59SEnji Cooper 	    "Asserts that pthread_t can be translated with td_map_pth2thr() "
405*63d1fd59SEnji Cooper 	    "to td_thread_t -- and assert earlier that td_thr_iter() call is "
406*63d1fd59SEnji Cooper 	    "valid");
407*63d1fd59SEnji Cooper }
408*63d1fd59SEnji Cooper 
409*63d1fd59SEnji Cooper static volatile int exiting6;
410*63d1fd59SEnji Cooper 
411*63d1fd59SEnji Cooper static void *
busyFunction6(void * arg)412*63d1fd59SEnji Cooper busyFunction6(void *arg)
413*63d1fd59SEnji Cooper {
414*63d1fd59SEnji Cooper 
415*63d1fd59SEnji Cooper 	while (exiting6 == 0)
416*63d1fd59SEnji Cooper 		usleep(50000);
417*63d1fd59SEnji Cooper 
418*63d1fd59SEnji Cooper 	return NULL;
419*63d1fd59SEnji Cooper }
420*63d1fd59SEnji Cooper 
421*63d1fd59SEnji Cooper static int
iterateThreads6(td_thread_t * thread,void * arg)422*63d1fd59SEnji Cooper iterateThreads6(td_thread_t *thread, void *arg)
423*63d1fd59SEnji Cooper {
424*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
425*63d1fd59SEnji Cooper 
426*63d1fd59SEnji Cooper 	++(*counter);
427*63d1fd59SEnji Cooper 
428*63d1fd59SEnji Cooper 	return TD_ERR_OK;
429*63d1fd59SEnji Cooper }
430*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads6,tc)431*63d1fd59SEnji Cooper ATF_TC_BODY(threads6, tc)
432*63d1fd59SEnji Cooper {
433*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
434*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
435*63d1fd59SEnji Cooper 	size_t i;
436*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
437*63d1fd59SEnji Cooper 	int count = 0;
438*63d1fd59SEnji Cooper 
439*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
440*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
441*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
442*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
443*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
444*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
445*63d1fd59SEnji Cooper 
446*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
447*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
448*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
449*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction6, NULL));
450*63d1fd59SEnji Cooper 	}
451*63d1fd59SEnji Cooper 
452*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
453*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
454*63d1fd59SEnji Cooper 
455*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads6, &count) == TD_ERR_OK);
456*63d1fd59SEnji Cooper 
457*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
458*63d1fd59SEnji Cooper 		td_thread_t *td_thread;
459*63d1fd59SEnji Cooper 		ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread)
460*63d1fd59SEnji Cooper 		    == TD_ERR_OK);
461*63d1fd59SEnji Cooper 	}
462*63d1fd59SEnji Cooper 
463*63d1fd59SEnji Cooper 	exiting6 = 1;
464*63d1fd59SEnji Cooper 
465*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
466*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
467*63d1fd59SEnji Cooper 
468*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
469*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
470*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
471*63d1fd59SEnji Cooper }
472*63d1fd59SEnji Cooper 
473*63d1fd59SEnji Cooper ATF_TC(threads7);
ATF_TC_HEAD(threads7,tc)474*63d1fd59SEnji Cooper ATF_TC_HEAD(threads7, tc)
475*63d1fd59SEnji Cooper {
476*63d1fd59SEnji Cooper 
477*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
478*63d1fd59SEnji Cooper 	    "Asserts that pthread_t can be translated with td_map_pth2thr() "
479*63d1fd59SEnji Cooper 	    "to td_thread_t -- and assert later that td_thr_iter() call is "
480*63d1fd59SEnji Cooper 	    "valid");
481*63d1fd59SEnji Cooper }
482*63d1fd59SEnji Cooper 
483*63d1fd59SEnji Cooper static volatile int exiting7;
484*63d1fd59SEnji Cooper 
485*63d1fd59SEnji Cooper static void *
busyFunction7(void * arg)486*63d1fd59SEnji Cooper busyFunction7(void *arg)
487*63d1fd59SEnji Cooper {
488*63d1fd59SEnji Cooper 
489*63d1fd59SEnji Cooper 	while (exiting7 == 0)
490*63d1fd59SEnji Cooper 		usleep(50000);
491*63d1fd59SEnji Cooper 
492*63d1fd59SEnji Cooper 	return NULL;
493*63d1fd59SEnji Cooper }
494*63d1fd59SEnji Cooper 
495*63d1fd59SEnji Cooper static int
iterateThreads7(td_thread_t * thread,void * arg)496*63d1fd59SEnji Cooper iterateThreads7(td_thread_t *thread, void *arg)
497*63d1fd59SEnji Cooper {
498*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
499*63d1fd59SEnji Cooper 
500*63d1fd59SEnji Cooper 	++(*counter);
501*63d1fd59SEnji Cooper 
502*63d1fd59SEnji Cooper 	return TD_ERR_OK;
503*63d1fd59SEnji Cooper }
504*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads7,tc)505*63d1fd59SEnji Cooper ATF_TC_BODY(threads7, tc)
506*63d1fd59SEnji Cooper {
507*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
508*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
509*63d1fd59SEnji Cooper 	size_t i;
510*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
511*63d1fd59SEnji Cooper 	int count = 0;
512*63d1fd59SEnji Cooper 
513*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
514*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
515*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
516*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
517*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
518*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
519*63d1fd59SEnji Cooper 
520*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
521*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
522*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
523*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction7, NULL));
524*63d1fd59SEnji Cooper 	}
525*63d1fd59SEnji Cooper 
526*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
527*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
528*63d1fd59SEnji Cooper 
529*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
530*63d1fd59SEnji Cooper 		td_thread_t *td_thread;
531*63d1fd59SEnji Cooper 		ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread)
532*63d1fd59SEnji Cooper 		    == TD_ERR_OK);
533*63d1fd59SEnji Cooper 	}
534*63d1fd59SEnji Cooper 
535*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads7, &count) == TD_ERR_OK);
536*63d1fd59SEnji Cooper 
537*63d1fd59SEnji Cooper 	exiting7 = 1;
538*63d1fd59SEnji Cooper 
539*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
540*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
541*63d1fd59SEnji Cooper 
542*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
543*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
544*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
545*63d1fd59SEnji Cooper }
546*63d1fd59SEnji Cooper 
547*63d1fd59SEnji Cooper ATF_TC(threads8);
ATF_TC_HEAD(threads8,tc)548*63d1fd59SEnji Cooper ATF_TC_HEAD(threads8, tc)
549*63d1fd59SEnji Cooper {
550*63d1fd59SEnji Cooper 
551*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
552*63d1fd59SEnji Cooper 	    "Asserts that pthread_t can be translated with td_map_pth2thr() "
553*63d1fd59SEnji Cooper 	    "to td_thread_t -- compare thread's name of pthread_t and "
554*63d1fd59SEnji Cooper 	    "td_thread_t");
555*63d1fd59SEnji Cooper }
556*63d1fd59SEnji Cooper 
557*63d1fd59SEnji Cooper static volatile int exiting8;
558*63d1fd59SEnji Cooper 
559*63d1fd59SEnji Cooper static void *
busyFunction8(void * arg)560*63d1fd59SEnji Cooper busyFunction8(void *arg)
561*63d1fd59SEnji Cooper {
562*63d1fd59SEnji Cooper 
563*63d1fd59SEnji Cooper 	while (exiting8 == 0)
564*63d1fd59SEnji Cooper 		usleep(50000);
565*63d1fd59SEnji Cooper 
566*63d1fd59SEnji Cooper 	return NULL;
567*63d1fd59SEnji Cooper }
568*63d1fd59SEnji Cooper 
569*63d1fd59SEnji Cooper static int
iterateThreads8(td_thread_t * thread,void * arg)570*63d1fd59SEnji Cooper iterateThreads8(td_thread_t *thread, void *arg)
571*63d1fd59SEnji Cooper {
572*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
573*63d1fd59SEnji Cooper 
574*63d1fd59SEnji Cooper 	++(*counter);
575*63d1fd59SEnji Cooper 
576*63d1fd59SEnji Cooper 	return TD_ERR_OK;
577*63d1fd59SEnji Cooper }
578*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads8,tc)579*63d1fd59SEnji Cooper ATF_TC_BODY(threads8, tc)
580*63d1fd59SEnji Cooper {
581*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
582*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
583*63d1fd59SEnji Cooper 	size_t i;
584*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
585*63d1fd59SEnji Cooper 	int count = 0;
586*63d1fd59SEnji Cooper 
587*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
588*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
589*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
590*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
591*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
592*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
593*63d1fd59SEnji Cooper 
594*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
595*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
596*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
597*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction8, NULL));
598*63d1fd59SEnji Cooper 	}
599*63d1fd59SEnji Cooper 
600*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
601*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
602*63d1fd59SEnji Cooper 
603*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads8, &count) == TD_ERR_OK);
604*63d1fd59SEnji Cooper 
605*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
606*63d1fd59SEnji Cooper 		td_thread_t *td_thread;
607*63d1fd59SEnji Cooper 		char td_threadname[PTHREAD_MAX_NAMELEN_NP];
608*63d1fd59SEnji Cooper 		char pth_threadname[PTHREAD_MAX_NAMELEN_NP];
609*63d1fd59SEnji Cooper 		ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread)
610*63d1fd59SEnji Cooper 		    == TD_ERR_OK);
611*63d1fd59SEnji Cooper 		ATF_REQUIRE(td_thr_getname(td_thread, td_threadname,
612*63d1fd59SEnji Cooper 		    sizeof(td_threadname)) == TD_ERR_OK);
613*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE(pthread_getname_np(threads[i], pth_threadname,
614*63d1fd59SEnji Cooper 		    sizeof(pth_threadname)));
615*63d1fd59SEnji Cooper 		ATF_REQUIRE(strcmp(td_threadname, pth_threadname) == 0);
616*63d1fd59SEnji Cooper 	}
617*63d1fd59SEnji Cooper 
618*63d1fd59SEnji Cooper 	exiting8 = 1;
619*63d1fd59SEnji Cooper 
620*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
621*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
622*63d1fd59SEnji Cooper 
623*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
624*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
625*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
626*63d1fd59SEnji Cooper }
627*63d1fd59SEnji Cooper 
628*63d1fd59SEnji Cooper ATF_TC(threads9);
ATF_TC_HEAD(threads9,tc)629*63d1fd59SEnji Cooper ATF_TC_HEAD(threads9, tc)
630*63d1fd59SEnji Cooper {
631*63d1fd59SEnji Cooper 
632*63d1fd59SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
633*63d1fd59SEnji Cooper 	    "Asserts that pthread_t can be translated with td_map_pth2thr() "
634*63d1fd59SEnji Cooper 	    "to td_thread_t -- assert that thread is in the TD_STATE_RUNNING "
635*63d1fd59SEnji Cooper             "state");
636*63d1fd59SEnji Cooper }
637*63d1fd59SEnji Cooper 
638*63d1fd59SEnji Cooper static volatile int exiting9;
639*63d1fd59SEnji Cooper 
640*63d1fd59SEnji Cooper static void *
busyFunction9(void * arg)641*63d1fd59SEnji Cooper busyFunction9(void *arg)
642*63d1fd59SEnji Cooper {
643*63d1fd59SEnji Cooper 
644*63d1fd59SEnji Cooper 	while (exiting9 == 0)
645*63d1fd59SEnji Cooper 		usleep(50000);
646*63d1fd59SEnji Cooper 
647*63d1fd59SEnji Cooper 	return NULL;
648*63d1fd59SEnji Cooper }
649*63d1fd59SEnji Cooper 
650*63d1fd59SEnji Cooper static int
iterateThreads9(td_thread_t * thread,void * arg)651*63d1fd59SEnji Cooper iterateThreads9(td_thread_t *thread, void *arg)
652*63d1fd59SEnji Cooper {
653*63d1fd59SEnji Cooper 	int *counter = (int *)arg;
654*63d1fd59SEnji Cooper 
655*63d1fd59SEnji Cooper 	++(*counter);
656*63d1fd59SEnji Cooper 
657*63d1fd59SEnji Cooper 	return TD_ERR_OK;
658*63d1fd59SEnji Cooper }
659*63d1fd59SEnji Cooper 
ATF_TC_BODY(threads9,tc)660*63d1fd59SEnji Cooper ATF_TC_BODY(threads9, tc)
661*63d1fd59SEnji Cooper {
662*63d1fd59SEnji Cooper 	struct td_proc_callbacks_t dummy_callbacks;
663*63d1fd59SEnji Cooper 	td_proc_t *main_ta;
664*63d1fd59SEnji Cooper 	size_t i;
665*63d1fd59SEnji Cooper 	pthread_t threads[MAX_THREADS];
666*63d1fd59SEnji Cooper 	int count = 0;
667*63d1fd59SEnji Cooper 
668*63d1fd59SEnji Cooper 	dummy_callbacks.proc_read	= basic_proc_read;
669*63d1fd59SEnji Cooper 	dummy_callbacks.proc_write	= basic_proc_write;
670*63d1fd59SEnji Cooper 	dummy_callbacks.proc_lookup	= basic_proc_lookup;
671*63d1fd59SEnji Cooper 	dummy_callbacks.proc_regsize	= dummy_proc_regsize;
672*63d1fd59SEnji Cooper 	dummy_callbacks.proc_getregs	= dummy_proc_getregs;
673*63d1fd59SEnji Cooper 	dummy_callbacks.proc_setregs	= dummy_proc_setregs;
674*63d1fd59SEnji Cooper 
675*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
676*63d1fd59SEnji Cooper 		printf("Creating thread %zu\n", i);
677*63d1fd59SEnji Cooper 		PTHREAD_REQUIRE
678*63d1fd59SEnji Cooper 		    (pthread_create(&threads[i], NULL, busyFunction9, NULL));
679*63d1fd59SEnji Cooper 	}
680*63d1fd59SEnji Cooper 
681*63d1fd59SEnji Cooper 	printf("Calling td_open(3)\n");
682*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
683*63d1fd59SEnji Cooper 
684*63d1fd59SEnji Cooper 	for (i = 0; i < MAX_THREADS; i++) {
685*63d1fd59SEnji Cooper 		td_thread_t *td_thread;
686*63d1fd59SEnji Cooper 		td_thread_info_t info;
687*63d1fd59SEnji Cooper 		ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread)
688*63d1fd59SEnji Cooper 		    == TD_ERR_OK);
689*63d1fd59SEnji Cooper 		ATF_REQUIRE(td_thr_info(td_thread, &info) == TD_ERR_OK);
690*63d1fd59SEnji Cooper 		ATF_REQUIRE_EQ(info.thread_state, TD_STATE_RUNNING);
691*63d1fd59SEnji Cooper 	}
692*63d1fd59SEnji Cooper 
693*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads9, &count) == TD_ERR_OK);
694*63d1fd59SEnji Cooper 
695*63d1fd59SEnji Cooper 	exiting9 = 1;
696*63d1fd59SEnji Cooper 
697*63d1fd59SEnji Cooper 	printf("Calling td_close(3)\n");
698*63d1fd59SEnji Cooper 	ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
699*63d1fd59SEnji Cooper 
700*63d1fd59SEnji Cooper 	ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
701*63d1fd59SEnji Cooper 	    "counted threads (%d) != expected threads (%zu)",
702*63d1fd59SEnji Cooper 	    count, MAX_THREADS + 1);
703*63d1fd59SEnji Cooper }
704*63d1fd59SEnji Cooper 
ATF_TP_ADD_TCS(tp)705*63d1fd59SEnji Cooper ATF_TP_ADD_TCS(tp)
706*63d1fd59SEnji Cooper {
707*63d1fd59SEnji Cooper 
708*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads1);
709*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads2);
710*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads3);
711*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads4);
712*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads5);
713*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads6);
714*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads7);
715*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads8);
716*63d1fd59SEnji Cooper 	ATF_TP_ADD_TC(tp, threads9);
717*63d1fd59SEnji Cooper 
718*63d1fd59SEnji Cooper 	return atf_no_error();
719*63d1fd59SEnji Cooper }
720