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 } 720