13bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor//===-- main.cpp ------------------------------------------------*- C++ -*-===// 23bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// 33bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// The LLVM Compiler Infrastructure 43bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// 53bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// This file is distributed under the University of Illinois Open Source 63bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// License. See LICENSE.TXT for details. 73bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// 83bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor//===----------------------------------------------------------------------===// 93bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 103bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// This test verifies the correct handling of child thread exits. 113bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 123bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor#include <pthread.h> 133bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor#include <atomic> 143bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 153bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// Note that although hogging the CPU while waiting for a variable to change 163bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// would be terrible in production code, it's great for testing since it 173bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// avoids a lot of messy context switching to get multiple threads synchronized. 183bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor#define do_nothing() 193bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 203bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor#define pseudo_barrier_wait(bar) \ 213bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor --bar; \ 223bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor while (bar > 0) \ 233bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor do_nothing(); 243bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 253bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor#define pseudo_barrier_init(bar, count) (bar = count) 263bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 273bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorstd::atomic_int g_barrier1; 283bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorstd::atomic_int g_barrier2; 293bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorstd::atomic_int g_barrier3; 303bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 313bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorvoid * 323bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorthread1 (void *input) 333bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor{ 343bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Synchronize with the main thread. 353bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_wait(g_barrier1); 363bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 373bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Synchronize with the main thread and thread2. 383bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_wait(g_barrier2); 393bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 403bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Return 413bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor return NULL; // Set second breakpoint here 423bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor} 433bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 443bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorvoid * 453bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorthread2 (void *input) 463bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor{ 473bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Synchronize with thread1 and the main thread. 483bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_wait(g_barrier2); 493bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 503bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Synchronize with the main thread. 513bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_wait(g_barrier3); 523bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 533bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Return 543bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor return NULL; 553bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor} 563bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 573bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorint main () 583bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor{ 593bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pthread_t thread_1; 603bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pthread_t thread_2; 613bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pthread_t thread_3; 623bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 633bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_init(g_barrier1, 2); 643bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_init(g_barrier2, 3); 653bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_init(g_barrier3, 2); 663bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 673bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Create a thread. 683bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pthread_create (&thread_1, NULL, thread1, NULL); 693bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 703bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Wait for thread1 to start. 713bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_wait(g_barrier1); 723bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 733bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Create another thread. 743bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pthread_create (&thread_2, NULL, thread2, NULL); // Set first breakpoint here 753bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 763bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Wait for thread2 to start. 773bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_wait(g_barrier2); 783bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 793bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Wait for the first thread to finish 803bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pthread_join(thread_1, NULL); 813bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 823bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Synchronize with the remaining thread 833bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pseudo_barrier_wait(g_barrier3); // Set third breakpoint here 843bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 853bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor // Wait for the second thread to finish 863bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor pthread_join(thread_2, NULL); 873bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor 883bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor return 0; // Set fourth breakpoint here 893bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor} 90