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