1 /* $NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $ */
4 * Copyright (c) 2016 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $");
35 #include <pthread_dbg.h>
44 #define MAX_THREADS (size_t)10
47 ATF_TC_HEAD(threads1, tc)
50 atf_tc_set_md_var(tc, "descr",
51 "Asserts that td_thr_iter() call without extra logic works");
54 static volatile int exiting1;
57 busyFunction1(void *arg)
67 iterateThreads1(td_thread_t *thread, void *arg)
73 ATF_TC_BODY(threads1, tc)
75 struct td_proc_callbacks_t dummy_callbacks;
78 pthread_t threads[MAX_THREADS];
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;
87 for (i = 0; i < MAX_THREADS; i++) {
88 printf("Creating thread %zu\n", i);
90 (pthread_create(&threads[i], NULL, busyFunction1, NULL));
93 printf("Calling td_open(3)\n");
94 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
96 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads1, NULL) == TD_ERR_OK);
100 printf("Calling td_close(3)\n");
101 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
105 ATF_TC_HEAD(threads2, tc)
108 atf_tc_set_md_var(tc, "descr",
109 "Asserts that td_thr_iter() call is executed for each thread once");
112 static volatile int exiting2;
115 busyFunction2(void *arg)
118 while (exiting2 == 0)
125 iterateThreads2(td_thread_t *thread, void *arg)
127 int *counter = (int *)arg;
134 ATF_TC_BODY(threads2, tc)
136 struct td_proc_callbacks_t dummy_callbacks;
139 pthread_t threads[MAX_THREADS];
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;
150 for (i = 0; i < MAX_THREADS; i++) {
151 printf("Creating thread %zu\n", i);
153 (pthread_create(&threads[i], NULL, busyFunction2, NULL));
156 printf("Calling td_open(3)\n");
157 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
159 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads2, &count) == TD_ERR_OK);
163 printf("Calling td_close(3)\n");
164 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
166 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
167 "counted threads (%d) != expected threads (%zu)",
168 count, MAX_THREADS + 1);
172 ATF_TC_HEAD(threads3, tc)
175 atf_tc_set_md_var(tc, "descr",
176 "Asserts that for each td_thr_iter() call td_thr_info() is valid");
179 static volatile int exiting3;
182 busyFunction3(void *arg)
185 while (exiting3 == 0)
192 iterateThreads3(td_thread_t *thread, void *arg)
194 int *counter = (int *)arg;
195 td_thread_info_t info;
197 ATF_REQUIRE(td_thr_info(thread, &info) == TD_ERR_OK);
204 ATF_TC_BODY(threads3, tc)
206 struct td_proc_callbacks_t dummy_callbacks;
209 pthread_t threads[MAX_THREADS];
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;
220 for (i = 0; i < MAX_THREADS; i++) {
221 printf("Creating thread %zu\n", i);
223 (pthread_create(&threads[i], NULL, busyFunction3, NULL));
226 printf("Calling td_open(3)\n");
227 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
229 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads3, &count) == TD_ERR_OK);
233 printf("Calling td_close(3)\n");
234 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
236 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
237 "counted threads (%d) != expected threads (%zu)",
238 count, MAX_THREADS + 1);
242 ATF_TC_HEAD(threads4, tc)
245 atf_tc_set_md_var(tc, "descr",
246 "Asserts that for each td_thr_iter() call td_thr_getname() is "
250 static volatile int exiting4;
253 busyFunction4(void *arg)
256 while (exiting4 == 0)
263 iterateThreads4(td_thread_t *thread, void *arg)
265 int *counter = (int *)arg;
266 char name[PTHREAD_MAX_NAMELEN_NP];
268 ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK);
270 printf("Thread name: %s\n", name);
277 ATF_TC_BODY(threads4, tc)
279 struct td_proc_callbacks_t dummy_callbacks;
282 pthread_t threads[MAX_THREADS];
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;
292 for (i = 0; i < MAX_THREADS; i++) {
293 printf("Creating thread %zu\n", i);
295 (pthread_create(&threads[i], NULL, busyFunction4, NULL));
298 for (i = 0; i < MAX_THREADS; i++) {
300 (pthread_setname_np(threads[i], "test_%d", (void*)i));
303 printf("Calling td_open(3)\n");
304 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
306 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads4, &count) == TD_ERR_OK);
310 printf("Calling td_close(3)\n");
311 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
313 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
314 "counted threads (%d) != expected threads (%zu)",
315 count, MAX_THREADS + 1);
319 ATF_TC_HEAD(threads5, tc)
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");
327 static volatile int exiting5;
330 busyFunction5(void *arg)
333 while (exiting5 == 0)
340 iterateThreads5(td_thread_t *thread, void *arg)
342 int *counter = (int *)arg;
343 /* Arbitrarily short string buffer */
346 ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK);
348 printf("Thread name: %s\n", name);
350 /* strlen(3) does not count including a '\0' character */
351 ATF_REQUIRE(strlen(name) < sizeof(name));
358 ATF_TC_BODY(threads5, tc)
360 struct td_proc_callbacks_t dummy_callbacks;
363 pthread_t threads[MAX_THREADS];
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;
373 for (i = 0; i < MAX_THREADS; i++) {
374 printf("Creating thread %zu\n", i);
376 (pthread_create(&threads[i], NULL, busyFunction5, NULL));
379 for (i = 0; i < MAX_THREADS; i++) {
381 (pthread_setname_np(threads[i], "test_%d", (void*)i));
384 printf("Calling td_open(3)\n");
385 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
387 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads5, &count) == TD_ERR_OK);
391 printf("Calling td_close(3)\n");
392 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
394 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
395 "counted threads (%d) != expected threads (%zu)",
396 count, MAX_THREADS + 1);
400 ATF_TC_HEAD(threads6, tc)
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 "
409 static volatile int exiting6;
412 busyFunction6(void *arg)
415 while (exiting6 == 0)
422 iterateThreads6(td_thread_t *thread, void *arg)
424 int *counter = (int *)arg;
431 ATF_TC_BODY(threads6, tc)
433 struct td_proc_callbacks_t dummy_callbacks;
436 pthread_t threads[MAX_THREADS];
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;
446 for (i = 0; i < MAX_THREADS; i++) {
447 printf("Creating thread %zu\n", i);
449 (pthread_create(&threads[i], NULL, busyFunction6, NULL));
452 printf("Calling td_open(3)\n");
453 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
455 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads6, &count) == TD_ERR_OK);
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)
465 printf("Calling td_close(3)\n");
466 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
468 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
469 "counted threads (%d) != expected threads (%zu)",
470 count, MAX_THREADS + 1);
474 ATF_TC_HEAD(threads7, tc)
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 "
483 static volatile int exiting7;
486 busyFunction7(void *arg)
489 while (exiting7 == 0)
496 iterateThreads7(td_thread_t *thread, void *arg)
498 int *counter = (int *)arg;
505 ATF_TC_BODY(threads7, tc)
507 struct td_proc_callbacks_t dummy_callbacks;
510 pthread_t threads[MAX_THREADS];
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;
520 for (i = 0; i < MAX_THREADS; i++) {
521 printf("Creating thread %zu\n", i);
523 (pthread_create(&threads[i], NULL, busyFunction7, NULL));
526 printf("Calling td_open(3)\n");
527 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
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)
535 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads7, &count) == TD_ERR_OK);
539 printf("Calling td_close(3)\n");
540 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
542 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
543 "counted threads (%d) != expected threads (%zu)",
544 count, MAX_THREADS + 1);
548 ATF_TC_HEAD(threads8, tc)
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 "
557 static volatile int exiting8;
560 busyFunction8(void *arg)
563 while (exiting8 == 0)
570 iterateThreads8(td_thread_t *thread, void *arg)
572 int *counter = (int *)arg;
579 ATF_TC_BODY(threads8, tc)
581 struct td_proc_callbacks_t dummy_callbacks;
584 pthread_t threads[MAX_THREADS];
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;
594 for (i = 0; i < MAX_THREADS; i++) {
595 printf("Creating thread %zu\n", i);
597 (pthread_create(&threads[i], NULL, busyFunction8, NULL));
600 printf("Calling td_open(3)\n");
601 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
603 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads8, &count) == TD_ERR_OK);
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)
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);
620 printf("Calling td_close(3)\n");
621 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
623 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
624 "counted threads (%d) != expected threads (%zu)",
625 count, MAX_THREADS + 1);
629 ATF_TC_HEAD(threads9, tc)
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 "
638 static volatile int exiting9;
641 busyFunction9(void *arg)
644 while (exiting9 == 0)
651 iterateThreads9(td_thread_t *thread, void *arg)
653 int *counter = (int *)arg;
660 ATF_TC_BODY(threads9, tc)
662 struct td_proc_callbacks_t dummy_callbacks;
665 pthread_t threads[MAX_THREADS];
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;
675 for (i = 0; i < MAX_THREADS; i++) {
676 printf("Creating thread %zu\n", i);
678 (pthread_create(&threads[i], NULL, busyFunction9, NULL));
681 printf("Calling td_open(3)\n");
682 ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);
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)
689 ATF_REQUIRE(td_thr_info(td_thread, &info) == TD_ERR_OK);
690 ATF_REQUIRE_EQ(info.thread_state, TD_STATE_RUNNING);
693 ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads9, &count) == TD_ERR_OK);
697 printf("Calling td_close(3)\n");
698 ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
700 ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1,
701 "counted threads (%d) != expected threads (%zu)",
702 count, MAX_THREADS + 1);
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);
718 return atf_no_error();