1312123Sngie/* $NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $ */ 2312123Sngie 3312123Sngie/*- 4312123Sngie * Copyright (c) 2016 The NetBSD Foundation, Inc. 5312123Sngie * All rights reserved. 6312123Sngie * 7312123Sngie * Redistribution and use in source and binary forms, with or without 8312123Sngie * modification, are permitted provided that the following conditions 9312123Sngie * are met: 10312123Sngie * 1. Redistributions of source code must retain the above copyright 11312123Sngie * notice, this list of conditions and the following disclaimer. 12312123Sngie * 2. Redistributions in binary form must reproduce the above copyright 13312123Sngie * notice, this list of conditions and the following disclaimer in the 14312123Sngie * documentation and/or other materials provided with the distribution. 15312123Sngie * 16312123Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17312123Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18312123Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19312123Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20312123Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21312123Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22312123Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23312123Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24312123Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25312123Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26312123Sngie * POSSIBILITY OF SUCH DAMAGE. 27312123Sngie */ 28312123Sngie 29312123Sngie 30312123Sngie#include <sys/cdefs.h> 31312123Sngie__RCSID("$NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $"); 32312123Sngie 33312123Sngie#include <dlfcn.h> 34312123Sngie#include <pthread.h> 35312123Sngie#include <pthread_dbg.h> 36312123Sngie#include <stdio.h> 37312123Sngie#include <string.h> 38312123Sngie#include <unistd.h> 39312123Sngie 40312123Sngie#include <atf-c.h> 41312123Sngie 42312123Sngie#include "h_common.h" 43312123Sngie 44312123Sngie#define MAX_THREADS (size_t)10 45312123Sngie 46312123SngieATF_TC(threads1); 47312123SngieATF_TC_HEAD(threads1, tc) 48312123Sngie{ 49312123Sngie 50312123Sngie atf_tc_set_md_var(tc, "descr", 51312123Sngie "Asserts that td_thr_iter() call without extra logic works"); 52312123Sngie} 53312123Sngie 54312123Sngiestatic volatile int exiting1; 55312123Sngie 56312123Sngiestatic void * 57312123SngiebusyFunction1(void *arg) 58312123Sngie{ 59312123Sngie 60312123Sngie while (exiting1 == 0) 61312123Sngie usleep(50000); 62312123Sngie 63312123Sngie return NULL; 64312123Sngie} 65312123Sngie 66312123Sngiestatic int 67312123SngieiterateThreads1(td_thread_t *thread, void *arg) 68312123Sngie{ 69312123Sngie 70312123Sngie return TD_ERR_OK; 71312123Sngie} 72312123Sngie 73312123SngieATF_TC_BODY(threads1, tc) 74312123Sngie{ 75312123Sngie struct td_proc_callbacks_t dummy_callbacks; 76312123Sngie td_proc_t *main_ta; 77312123Sngie size_t i; 78312123Sngie pthread_t threads[MAX_THREADS]; 79312123Sngie 80312123Sngie dummy_callbacks.proc_read = basic_proc_read; 81312123Sngie dummy_callbacks.proc_write = basic_proc_write; 82312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 83312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 84312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 85312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 86312123Sngie 87312123Sngie for (i = 0; i < MAX_THREADS; i++) { 88312123Sngie printf("Creating thread %zu\n", i); 89312123Sngie PTHREAD_REQUIRE 90312123Sngie (pthread_create(&threads[i], NULL, busyFunction1, NULL)); 91312123Sngie } 92312123Sngie 93312123Sngie printf("Calling td_open(3)\n"); 94312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 95312123Sngie 96312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads1, NULL) == TD_ERR_OK); 97312123Sngie 98312123Sngie exiting1 = 1; 99312123Sngie 100312123Sngie printf("Calling td_close(3)\n"); 101312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 102312123Sngie} 103312123Sngie 104312123SngieATF_TC(threads2); 105312123SngieATF_TC_HEAD(threads2, tc) 106312123Sngie{ 107312123Sngie 108312123Sngie atf_tc_set_md_var(tc, "descr", 109312123Sngie "Asserts that td_thr_iter() call is executed for each thread once"); 110312123Sngie} 111312123Sngie 112312123Sngiestatic volatile int exiting2; 113312123Sngie 114312123Sngiestatic void * 115312123SngiebusyFunction2(void *arg) 116312123Sngie{ 117312123Sngie 118312123Sngie while (exiting2 == 0) 119312123Sngie usleep(50000); 120312123Sngie 121312123Sngie return NULL; 122312123Sngie} 123312123Sngie 124312123Sngiestatic int 125312123SngieiterateThreads2(td_thread_t *thread, void *arg) 126312123Sngie{ 127312123Sngie int *counter = (int *)arg; 128312123Sngie 129312123Sngie ++(*counter); 130312123Sngie 131312123Sngie return TD_ERR_OK; 132312123Sngie} 133312123Sngie 134312123SngieATF_TC_BODY(threads2, tc) 135312123Sngie{ 136312123Sngie struct td_proc_callbacks_t dummy_callbacks; 137312123Sngie td_proc_t *main_ta; 138312123Sngie size_t i; 139312123Sngie pthread_t threads[MAX_THREADS]; 140312123Sngie int count = 0; 141312123Sngie 142312123Sngie dummy_callbacks.proc_read = basic_proc_read; 143312123Sngie dummy_callbacks.proc_write = basic_proc_write; 144312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 145312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 146312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 147312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 148312123Sngie 149312123Sngie 150312123Sngie for (i = 0; i < MAX_THREADS; i++) { 151312123Sngie printf("Creating thread %zu\n", i); 152312123Sngie PTHREAD_REQUIRE 153312123Sngie (pthread_create(&threads[i], NULL, busyFunction2, NULL)); 154312123Sngie } 155312123Sngie 156312123Sngie printf("Calling td_open(3)\n"); 157312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 158312123Sngie 159312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads2, &count) == TD_ERR_OK); 160312123Sngie 161312123Sngie exiting2 = 1; 162312123Sngie 163312123Sngie printf("Calling td_close(3)\n"); 164312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 165312123Sngie 166312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 167312123Sngie "counted threads (%d) != expected threads (%zu)", 168312123Sngie count, MAX_THREADS + 1); 169312123Sngie} 170312123Sngie 171312123SngieATF_TC(threads3); 172312123SngieATF_TC_HEAD(threads3, tc) 173312123Sngie{ 174312123Sngie 175312123Sngie atf_tc_set_md_var(tc, "descr", 176312123Sngie "Asserts that for each td_thr_iter() call td_thr_info() is valid"); 177312123Sngie} 178312123Sngie 179312123Sngiestatic volatile int exiting3; 180312123Sngie 181312123Sngiestatic void * 182312123SngiebusyFunction3(void *arg) 183312123Sngie{ 184312123Sngie 185312123Sngie while (exiting3 == 0) 186312123Sngie usleep(50000); 187312123Sngie 188312123Sngie return NULL; 189312123Sngie} 190312123Sngie 191312123Sngiestatic int 192312123SngieiterateThreads3(td_thread_t *thread, void *arg) 193312123Sngie{ 194312123Sngie int *counter = (int *)arg; 195312123Sngie td_thread_info_t info; 196312123Sngie 197312123Sngie ATF_REQUIRE(td_thr_info(thread, &info) == TD_ERR_OK); 198312123Sngie 199312123Sngie ++(*counter); 200312123Sngie 201312123Sngie return TD_ERR_OK; 202312123Sngie} 203312123Sngie 204312123SngieATF_TC_BODY(threads3, tc) 205312123Sngie{ 206312123Sngie struct td_proc_callbacks_t dummy_callbacks; 207312123Sngie td_proc_t *main_ta; 208312123Sngie size_t i; 209312123Sngie pthread_t threads[MAX_THREADS]; 210312123Sngie int count = 0; 211312123Sngie 212312123Sngie dummy_callbacks.proc_read = basic_proc_read; 213312123Sngie dummy_callbacks.proc_write = basic_proc_write; 214312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 215312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 216312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 217312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 218312123Sngie 219312123Sngie 220312123Sngie for (i = 0; i < MAX_THREADS; i++) { 221312123Sngie printf("Creating thread %zu\n", i); 222312123Sngie PTHREAD_REQUIRE 223312123Sngie (pthread_create(&threads[i], NULL, busyFunction3, NULL)); 224312123Sngie } 225312123Sngie 226312123Sngie printf("Calling td_open(3)\n"); 227312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 228312123Sngie 229312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads3, &count) == TD_ERR_OK); 230312123Sngie 231312123Sngie exiting3 = 1; 232312123Sngie 233312123Sngie printf("Calling td_close(3)\n"); 234312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 235312123Sngie 236312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 237312123Sngie "counted threads (%d) != expected threads (%zu)", 238312123Sngie count, MAX_THREADS + 1); 239312123Sngie} 240312123Sngie 241312123SngieATF_TC(threads4); 242312123SngieATF_TC_HEAD(threads4, tc) 243312123Sngie{ 244312123Sngie 245312123Sngie atf_tc_set_md_var(tc, "descr", 246312123Sngie "Asserts that for each td_thr_iter() call td_thr_getname() is " 247312123Sngie "valid"); 248312123Sngie} 249312123Sngie 250312123Sngiestatic volatile int exiting4; 251312123Sngie 252312123Sngiestatic void * 253312123SngiebusyFunction4(void *arg) 254312123Sngie{ 255312123Sngie 256312123Sngie while (exiting4 == 0) 257312123Sngie usleep(50000); 258312123Sngie 259312123Sngie return NULL; 260312123Sngie} 261312123Sngie 262312123Sngiestatic int 263312123SngieiterateThreads4(td_thread_t *thread, void *arg) 264312123Sngie{ 265312123Sngie int *counter = (int *)arg; 266312123Sngie char name[PTHREAD_MAX_NAMELEN_NP]; 267312123Sngie 268312123Sngie ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK); 269312123Sngie 270312123Sngie printf("Thread name: %s\n", name); 271312123Sngie 272312123Sngie ++(*counter); 273312123Sngie 274312123Sngie return TD_ERR_OK; 275312123Sngie} 276312123Sngie 277312123SngieATF_TC_BODY(threads4, tc) 278312123Sngie{ 279312123Sngie struct td_proc_callbacks_t dummy_callbacks; 280312123Sngie td_proc_t *main_ta; 281312123Sngie size_t i; 282312123Sngie pthread_t threads[MAX_THREADS]; 283312123Sngie int count = 0; 284312123Sngie 285312123Sngie dummy_callbacks.proc_read = basic_proc_read; 286312123Sngie dummy_callbacks.proc_write = basic_proc_write; 287312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 288312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 289312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 290312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 291312123Sngie 292312123Sngie for (i = 0; i < MAX_THREADS; i++) { 293312123Sngie printf("Creating thread %zu\n", i); 294312123Sngie PTHREAD_REQUIRE 295312123Sngie (pthread_create(&threads[i], NULL, busyFunction4, NULL)); 296312123Sngie } 297312123Sngie 298312123Sngie for (i = 0; i < MAX_THREADS; i++) { 299312123Sngie PTHREAD_REQUIRE 300312123Sngie (pthread_setname_np(threads[i], "test_%d", (void*)i)); 301312123Sngie } 302312123Sngie 303312123Sngie printf("Calling td_open(3)\n"); 304312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 305312123Sngie 306312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads4, &count) == TD_ERR_OK); 307312123Sngie 308312123Sngie exiting4 = 1; 309312123Sngie 310312123Sngie printf("Calling td_close(3)\n"); 311312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 312312123Sngie 313312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 314312123Sngie "counted threads (%d) != expected threads (%zu)", 315312123Sngie count, MAX_THREADS + 1); 316312123Sngie} 317312123Sngie 318312123SngieATF_TC(threads5); 319312123SngieATF_TC_HEAD(threads5, tc) 320312123Sngie{ 321312123Sngie 322312123Sngie atf_tc_set_md_var(tc, "descr", 323312123Sngie "Asserts that td_thr_getname() handles shorter buffer parameter " 324312123Sngie "and the result is properly truncated"); 325312123Sngie} 326312123Sngie 327312123Sngiestatic volatile int exiting5; 328312123Sngie 329312123Sngiestatic void * 330312123SngiebusyFunction5(void *arg) 331312123Sngie{ 332312123Sngie 333312123Sngie while (exiting5 == 0) 334312123Sngie usleep(50000); 335312123Sngie 336312123Sngie return NULL; 337312123Sngie} 338312123Sngie 339312123Sngiestatic int 340312123SngieiterateThreads5(td_thread_t *thread, void *arg) 341312123Sngie{ 342312123Sngie int *counter = (int *)arg; 343312123Sngie /* Arbitrarily short string buffer */ 344312123Sngie char name[3]; 345312123Sngie 346312123Sngie ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK); 347312123Sngie 348312123Sngie printf("Thread name: %s\n", name); 349312123Sngie 350312123Sngie /* strlen(3) does not count including a '\0' character */ 351312123Sngie ATF_REQUIRE(strlen(name) < sizeof(name)); 352312123Sngie 353312123Sngie ++(*counter); 354312123Sngie 355312123Sngie return TD_ERR_OK; 356312123Sngie} 357312123Sngie 358312123SngieATF_TC_BODY(threads5, tc) 359312123Sngie{ 360312123Sngie struct td_proc_callbacks_t dummy_callbacks; 361312123Sngie td_proc_t *main_ta; 362312123Sngie size_t i; 363312123Sngie pthread_t threads[MAX_THREADS]; 364312123Sngie int count = 0; 365312123Sngie 366312123Sngie dummy_callbacks.proc_read = basic_proc_read; 367312123Sngie dummy_callbacks.proc_write = basic_proc_write; 368312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 369312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 370312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 371312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 372312123Sngie 373312123Sngie for (i = 0; i < MAX_THREADS; i++) { 374312123Sngie printf("Creating thread %zu\n", i); 375312123Sngie PTHREAD_REQUIRE 376312123Sngie (pthread_create(&threads[i], NULL, busyFunction5, NULL)); 377312123Sngie } 378312123Sngie 379312123Sngie for (i = 0; i < MAX_THREADS; i++) { 380312123Sngie PTHREAD_REQUIRE 381312123Sngie (pthread_setname_np(threads[i], "test_%d", (void*)i)); 382312123Sngie } 383312123Sngie 384312123Sngie printf("Calling td_open(3)\n"); 385312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 386312123Sngie 387312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads5, &count) == TD_ERR_OK); 388312123Sngie 389312123Sngie exiting5 = 1; 390312123Sngie 391312123Sngie printf("Calling td_close(3)\n"); 392312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 393312123Sngie 394312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 395312123Sngie "counted threads (%d) != expected threads (%zu)", 396312123Sngie count, MAX_THREADS + 1); 397312123Sngie} 398312123Sngie 399312123SngieATF_TC(threads6); 400312123SngieATF_TC_HEAD(threads6, tc) 401312123Sngie{ 402312123Sngie 403312123Sngie atf_tc_set_md_var(tc, "descr", 404312123Sngie "Asserts that pthread_t can be translated with td_map_pth2thr() " 405312123Sngie "to td_thread_t -- and assert earlier that td_thr_iter() call is " 406312123Sngie "valid"); 407312123Sngie} 408312123Sngie 409312123Sngiestatic volatile int exiting6; 410312123Sngie 411312123Sngiestatic void * 412312123SngiebusyFunction6(void *arg) 413312123Sngie{ 414312123Sngie 415312123Sngie while (exiting6 == 0) 416312123Sngie usleep(50000); 417312123Sngie 418312123Sngie return NULL; 419312123Sngie} 420312123Sngie 421312123Sngiestatic int 422312123SngieiterateThreads6(td_thread_t *thread, void *arg) 423312123Sngie{ 424312123Sngie int *counter = (int *)arg; 425312123Sngie 426312123Sngie ++(*counter); 427312123Sngie 428312123Sngie return TD_ERR_OK; 429312123Sngie} 430312123Sngie 431312123SngieATF_TC_BODY(threads6, tc) 432312123Sngie{ 433312123Sngie struct td_proc_callbacks_t dummy_callbacks; 434312123Sngie td_proc_t *main_ta; 435312123Sngie size_t i; 436312123Sngie pthread_t threads[MAX_THREADS]; 437312123Sngie int count = 0; 438312123Sngie 439312123Sngie dummy_callbacks.proc_read = basic_proc_read; 440312123Sngie dummy_callbacks.proc_write = basic_proc_write; 441312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 442312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 443312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 444312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 445312123Sngie 446312123Sngie for (i = 0; i < MAX_THREADS; i++) { 447312123Sngie printf("Creating thread %zu\n", i); 448312123Sngie PTHREAD_REQUIRE 449312123Sngie (pthread_create(&threads[i], NULL, busyFunction6, NULL)); 450312123Sngie } 451312123Sngie 452312123Sngie printf("Calling td_open(3)\n"); 453312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 454312123Sngie 455312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads6, &count) == TD_ERR_OK); 456312123Sngie 457312123Sngie for (i = 0; i < MAX_THREADS; i++) { 458312123Sngie td_thread_t *td_thread; 459312123Sngie ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) 460312123Sngie == TD_ERR_OK); 461312123Sngie } 462312123Sngie 463312123Sngie exiting6 = 1; 464312123Sngie 465312123Sngie printf("Calling td_close(3)\n"); 466312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 467312123Sngie 468312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 469312123Sngie "counted threads (%d) != expected threads (%zu)", 470312123Sngie count, MAX_THREADS + 1); 471312123Sngie} 472312123Sngie 473312123SngieATF_TC(threads7); 474312123SngieATF_TC_HEAD(threads7, tc) 475312123Sngie{ 476312123Sngie 477312123Sngie atf_tc_set_md_var(tc, "descr", 478312123Sngie "Asserts that pthread_t can be translated with td_map_pth2thr() " 479312123Sngie "to td_thread_t -- and assert later that td_thr_iter() call is " 480312123Sngie "valid"); 481312123Sngie} 482312123Sngie 483312123Sngiestatic volatile int exiting7; 484312123Sngie 485312123Sngiestatic void * 486312123SngiebusyFunction7(void *arg) 487312123Sngie{ 488312123Sngie 489312123Sngie while (exiting7 == 0) 490312123Sngie usleep(50000); 491312123Sngie 492312123Sngie return NULL; 493312123Sngie} 494312123Sngie 495312123Sngiestatic int 496312123SngieiterateThreads7(td_thread_t *thread, void *arg) 497312123Sngie{ 498312123Sngie int *counter = (int *)arg; 499312123Sngie 500312123Sngie ++(*counter); 501312123Sngie 502312123Sngie return TD_ERR_OK; 503312123Sngie} 504312123Sngie 505312123SngieATF_TC_BODY(threads7, tc) 506312123Sngie{ 507312123Sngie struct td_proc_callbacks_t dummy_callbacks; 508312123Sngie td_proc_t *main_ta; 509312123Sngie size_t i; 510312123Sngie pthread_t threads[MAX_THREADS]; 511312123Sngie int count = 0; 512312123Sngie 513312123Sngie dummy_callbacks.proc_read = basic_proc_read; 514312123Sngie dummy_callbacks.proc_write = basic_proc_write; 515312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 516312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 517312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 518312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 519312123Sngie 520312123Sngie for (i = 0; i < MAX_THREADS; i++) { 521312123Sngie printf("Creating thread %zu\n", i); 522312123Sngie PTHREAD_REQUIRE 523312123Sngie (pthread_create(&threads[i], NULL, busyFunction7, NULL)); 524312123Sngie } 525312123Sngie 526312123Sngie printf("Calling td_open(3)\n"); 527312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 528312123Sngie 529312123Sngie for (i = 0; i < MAX_THREADS; i++) { 530312123Sngie td_thread_t *td_thread; 531312123Sngie ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) 532312123Sngie == TD_ERR_OK); 533312123Sngie } 534312123Sngie 535312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads7, &count) == TD_ERR_OK); 536312123Sngie 537312123Sngie exiting7 = 1; 538312123Sngie 539312123Sngie printf("Calling td_close(3)\n"); 540312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 541312123Sngie 542312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 543312123Sngie "counted threads (%d) != expected threads (%zu)", 544312123Sngie count, MAX_THREADS + 1); 545312123Sngie} 546312123Sngie 547312123SngieATF_TC(threads8); 548312123SngieATF_TC_HEAD(threads8, tc) 549312123Sngie{ 550312123Sngie 551312123Sngie atf_tc_set_md_var(tc, "descr", 552312123Sngie "Asserts that pthread_t can be translated with td_map_pth2thr() " 553312123Sngie "to td_thread_t -- compare thread's name of pthread_t and " 554312123Sngie "td_thread_t"); 555312123Sngie} 556312123Sngie 557312123Sngiestatic volatile int exiting8; 558312123Sngie 559312123Sngiestatic void * 560312123SngiebusyFunction8(void *arg) 561312123Sngie{ 562312123Sngie 563312123Sngie while (exiting8 == 0) 564312123Sngie usleep(50000); 565312123Sngie 566312123Sngie return NULL; 567312123Sngie} 568312123Sngie 569312123Sngiestatic int 570312123SngieiterateThreads8(td_thread_t *thread, void *arg) 571312123Sngie{ 572312123Sngie int *counter = (int *)arg; 573312123Sngie 574312123Sngie ++(*counter); 575312123Sngie 576312123Sngie return TD_ERR_OK; 577312123Sngie} 578312123Sngie 579312123SngieATF_TC_BODY(threads8, tc) 580312123Sngie{ 581312123Sngie struct td_proc_callbacks_t dummy_callbacks; 582312123Sngie td_proc_t *main_ta; 583312123Sngie size_t i; 584312123Sngie pthread_t threads[MAX_THREADS]; 585312123Sngie int count = 0; 586312123Sngie 587312123Sngie dummy_callbacks.proc_read = basic_proc_read; 588312123Sngie dummy_callbacks.proc_write = basic_proc_write; 589312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 590312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 591312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 592312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 593312123Sngie 594312123Sngie for (i = 0; i < MAX_THREADS; i++) { 595312123Sngie printf("Creating thread %zu\n", i); 596312123Sngie PTHREAD_REQUIRE 597312123Sngie (pthread_create(&threads[i], NULL, busyFunction8, NULL)); 598312123Sngie } 599312123Sngie 600312123Sngie printf("Calling td_open(3)\n"); 601312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 602312123Sngie 603312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads8, &count) == TD_ERR_OK); 604312123Sngie 605312123Sngie for (i = 0; i < MAX_THREADS; i++) { 606312123Sngie td_thread_t *td_thread; 607312123Sngie char td_threadname[PTHREAD_MAX_NAMELEN_NP]; 608312123Sngie char pth_threadname[PTHREAD_MAX_NAMELEN_NP]; 609312123Sngie ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) 610312123Sngie == TD_ERR_OK); 611312123Sngie ATF_REQUIRE(td_thr_getname(td_thread, td_threadname, 612312123Sngie sizeof(td_threadname)) == TD_ERR_OK); 613312123Sngie PTHREAD_REQUIRE(pthread_getname_np(threads[i], pth_threadname, 614312123Sngie sizeof(pth_threadname))); 615312123Sngie ATF_REQUIRE(strcmp(td_threadname, pth_threadname) == 0); 616312123Sngie } 617312123Sngie 618312123Sngie exiting8 = 1; 619312123Sngie 620312123Sngie printf("Calling td_close(3)\n"); 621312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 622312123Sngie 623312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 624312123Sngie "counted threads (%d) != expected threads (%zu)", 625312123Sngie count, MAX_THREADS + 1); 626312123Sngie} 627312123Sngie 628312123SngieATF_TC(threads9); 629312123SngieATF_TC_HEAD(threads9, tc) 630312123Sngie{ 631312123Sngie 632312123Sngie atf_tc_set_md_var(tc, "descr", 633312123Sngie "Asserts that pthread_t can be translated with td_map_pth2thr() " 634312123Sngie "to td_thread_t -- assert that thread is in the TD_STATE_RUNNING " 635312123Sngie "state"); 636312123Sngie} 637312123Sngie 638312123Sngiestatic volatile int exiting9; 639312123Sngie 640312123Sngiestatic void * 641312123SngiebusyFunction9(void *arg) 642312123Sngie{ 643312123Sngie 644312123Sngie while (exiting9 == 0) 645312123Sngie usleep(50000); 646312123Sngie 647312123Sngie return NULL; 648312123Sngie} 649312123Sngie 650312123Sngiestatic int 651312123SngieiterateThreads9(td_thread_t *thread, void *arg) 652312123Sngie{ 653312123Sngie int *counter = (int *)arg; 654312123Sngie 655312123Sngie ++(*counter); 656312123Sngie 657312123Sngie return TD_ERR_OK; 658312123Sngie} 659312123Sngie 660312123SngieATF_TC_BODY(threads9, tc) 661312123Sngie{ 662312123Sngie struct td_proc_callbacks_t dummy_callbacks; 663312123Sngie td_proc_t *main_ta; 664312123Sngie size_t i; 665312123Sngie pthread_t threads[MAX_THREADS]; 666312123Sngie int count = 0; 667312123Sngie 668312123Sngie dummy_callbacks.proc_read = basic_proc_read; 669312123Sngie dummy_callbacks.proc_write = basic_proc_write; 670312123Sngie dummy_callbacks.proc_lookup = basic_proc_lookup; 671312123Sngie dummy_callbacks.proc_regsize = dummy_proc_regsize; 672312123Sngie dummy_callbacks.proc_getregs = dummy_proc_getregs; 673312123Sngie dummy_callbacks.proc_setregs = dummy_proc_setregs; 674312123Sngie 675312123Sngie for (i = 0; i < MAX_THREADS; i++) { 676312123Sngie printf("Creating thread %zu\n", i); 677312123Sngie PTHREAD_REQUIRE 678312123Sngie (pthread_create(&threads[i], NULL, busyFunction9, NULL)); 679312123Sngie } 680312123Sngie 681312123Sngie printf("Calling td_open(3)\n"); 682312123Sngie ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); 683312123Sngie 684312123Sngie for (i = 0; i < MAX_THREADS; i++) { 685312123Sngie td_thread_t *td_thread; 686312123Sngie td_thread_info_t info; 687312123Sngie ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) 688312123Sngie == TD_ERR_OK); 689312123Sngie ATF_REQUIRE(td_thr_info(td_thread, &info) == TD_ERR_OK); 690312123Sngie ATF_REQUIRE_EQ(info.thread_state, TD_STATE_RUNNING); 691312123Sngie } 692312123Sngie 693312123Sngie ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads9, &count) == TD_ERR_OK); 694312123Sngie 695312123Sngie exiting9 = 1; 696312123Sngie 697312123Sngie printf("Calling td_close(3)\n"); 698312123Sngie ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); 699312123Sngie 700312123Sngie ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, 701312123Sngie "counted threads (%d) != expected threads (%zu)", 702312123Sngie count, MAX_THREADS + 1); 703312123Sngie} 704312123Sngie 705312123SngieATF_TP_ADD_TCS(tp) 706312123Sngie{ 707312123Sngie 708312123Sngie ATF_TP_ADD_TC(tp, threads1); 709312123Sngie ATF_TP_ADD_TC(tp, threads2); 710312123Sngie ATF_TP_ADD_TC(tp, threads3); 711312123Sngie ATF_TP_ADD_TC(tp, threads4); 712312123Sngie ATF_TP_ADD_TC(tp, threads5); 713312123Sngie ATF_TP_ADD_TC(tp, threads6); 714312123Sngie ATF_TP_ADD_TC(tp, threads7); 715312123Sngie ATF_TP_ADD_TC(tp, threads8); 716312123Sngie ATF_TP_ADD_TC(tp, threads9); 717312123Sngie 718312123Sngie return atf_no_error(); 719312123Sngie} 720