1*5a83710eSEric Fiselier //===----------------------------------------------------------------------===// 2*5a83710eSEric Fiselier // 3*5a83710eSEric Fiselier // The LLVM Compiler Infrastructure 4*5a83710eSEric Fiselier // 5*5a83710eSEric Fiselier // This file is dual licensed under the MIT and the University of Illinois Open 6*5a83710eSEric Fiselier // Source Licenses. See LICENSE.TXT for details. 7*5a83710eSEric Fiselier // 8*5a83710eSEric Fiselier //===----------------------------------------------------------------------===// 9*5a83710eSEric Fiselier // 10*5a83710eSEric Fiselier // UNSUPPORTED: libcpp-has-no-threads 11*5a83710eSEric Fiselier 12*5a83710eSEric Fiselier // <thread> 13*5a83710eSEric Fiselier 14*5a83710eSEric Fiselier // class thread 15*5a83710eSEric Fiselier 16*5a83710eSEric Fiselier // template <class F, class ...Args> thread(F&& f, Args&&... args); 17*5a83710eSEric Fiselier 18*5a83710eSEric Fiselier // UNSUPPORTED: asan, msan 19*5a83710eSEric Fiselier 20*5a83710eSEric Fiselier #include <thread> 21*5a83710eSEric Fiselier #include <new> 22*5a83710eSEric Fiselier #include <cstdlib> 23*5a83710eSEric Fiselier #include <cassert> 24*5a83710eSEric Fiselier 25*5a83710eSEric Fiselier unsigned throw_one = 0xFFFF; 26*5a83710eSEric Fiselier 27*5a83710eSEric Fiselier void* operator new(std::size_t s) throw(std::bad_alloc) 28*5a83710eSEric Fiselier { 29*5a83710eSEric Fiselier if (throw_one == 0) 30*5a83710eSEric Fiselier throw std::bad_alloc(); 31*5a83710eSEric Fiselier --throw_one; 32*5a83710eSEric Fiselier return std::malloc(s); 33*5a83710eSEric Fiselier } 34*5a83710eSEric Fiselier 35*5a83710eSEric Fiselier void operator delete(void* p) throw() 36*5a83710eSEric Fiselier { 37*5a83710eSEric Fiselier std::free(p); 38*5a83710eSEric Fiselier } 39*5a83710eSEric Fiselier 40*5a83710eSEric Fiselier bool f_run = false; 41*5a83710eSEric Fiselier 42*5a83710eSEric Fiselier void f() 43*5a83710eSEric Fiselier { 44*5a83710eSEric Fiselier f_run = true; 45*5a83710eSEric Fiselier } 46*5a83710eSEric Fiselier 47*5a83710eSEric Fiselier class G 48*5a83710eSEric Fiselier { 49*5a83710eSEric Fiselier int alive_; 50*5a83710eSEric Fiselier public: 51*5a83710eSEric Fiselier static int n_alive; 52*5a83710eSEric Fiselier static bool op_run; 53*5a83710eSEric Fiselier 54*5a83710eSEric Fiselier G() : alive_(1) {++n_alive;} 55*5a83710eSEric Fiselier G(const G& g) : alive_(g.alive_) {++n_alive;} 56*5a83710eSEric Fiselier ~G() {alive_ = 0; --n_alive;} 57*5a83710eSEric Fiselier 58*5a83710eSEric Fiselier void operator()() 59*5a83710eSEric Fiselier { 60*5a83710eSEric Fiselier assert(alive_ == 1); 61*5a83710eSEric Fiselier assert(n_alive >= 1); 62*5a83710eSEric Fiselier op_run = true; 63*5a83710eSEric Fiselier } 64*5a83710eSEric Fiselier 65*5a83710eSEric Fiselier void operator()(int i, double j) 66*5a83710eSEric Fiselier { 67*5a83710eSEric Fiselier assert(alive_ == 1); 68*5a83710eSEric Fiselier assert(n_alive >= 1); 69*5a83710eSEric Fiselier assert(i == 5); 70*5a83710eSEric Fiselier assert(j == 5.5); 71*5a83710eSEric Fiselier op_run = true; 72*5a83710eSEric Fiselier } 73*5a83710eSEric Fiselier }; 74*5a83710eSEric Fiselier 75*5a83710eSEric Fiselier int G::n_alive = 0; 76*5a83710eSEric Fiselier bool G::op_run = false; 77*5a83710eSEric Fiselier 78*5a83710eSEric Fiselier #ifndef _LIBCPP_HAS_NO_VARIADICS 79*5a83710eSEric Fiselier 80*5a83710eSEric Fiselier class MoveOnly 81*5a83710eSEric Fiselier { 82*5a83710eSEric Fiselier MoveOnly(const MoveOnly&); 83*5a83710eSEric Fiselier public: 84*5a83710eSEric Fiselier MoveOnly() {} 85*5a83710eSEric Fiselier MoveOnly(MoveOnly&&) {} 86*5a83710eSEric Fiselier 87*5a83710eSEric Fiselier void operator()(MoveOnly&&) 88*5a83710eSEric Fiselier { 89*5a83710eSEric Fiselier } 90*5a83710eSEric Fiselier }; 91*5a83710eSEric Fiselier 92*5a83710eSEric Fiselier #endif 93*5a83710eSEric Fiselier 94*5a83710eSEric Fiselier int main() 95*5a83710eSEric Fiselier { 96*5a83710eSEric Fiselier { 97*5a83710eSEric Fiselier std::thread t(f); 98*5a83710eSEric Fiselier t.join(); 99*5a83710eSEric Fiselier assert(f_run == true); 100*5a83710eSEric Fiselier } 101*5a83710eSEric Fiselier f_run = false; 102*5a83710eSEric Fiselier { 103*5a83710eSEric Fiselier try 104*5a83710eSEric Fiselier { 105*5a83710eSEric Fiselier throw_one = 0; 106*5a83710eSEric Fiselier std::thread t(f); 107*5a83710eSEric Fiselier assert(false); 108*5a83710eSEric Fiselier } 109*5a83710eSEric Fiselier catch (...) 110*5a83710eSEric Fiselier { 111*5a83710eSEric Fiselier throw_one = 0xFFFF; 112*5a83710eSEric Fiselier assert(!f_run); 113*5a83710eSEric Fiselier } 114*5a83710eSEric Fiselier } 115*5a83710eSEric Fiselier { 116*5a83710eSEric Fiselier assert(G::n_alive == 0); 117*5a83710eSEric Fiselier assert(!G::op_run); 118*5a83710eSEric Fiselier std::thread t((G())); 119*5a83710eSEric Fiselier t.join(); 120*5a83710eSEric Fiselier assert(G::n_alive == 0); 121*5a83710eSEric Fiselier assert(G::op_run); 122*5a83710eSEric Fiselier } 123*5a83710eSEric Fiselier G::op_run = false; 124*5a83710eSEric Fiselier { 125*5a83710eSEric Fiselier try 126*5a83710eSEric Fiselier { 127*5a83710eSEric Fiselier throw_one = 0; 128*5a83710eSEric Fiselier assert(G::n_alive == 0); 129*5a83710eSEric Fiselier assert(!G::op_run); 130*5a83710eSEric Fiselier std::thread t((G())); 131*5a83710eSEric Fiselier assert(false); 132*5a83710eSEric Fiselier } 133*5a83710eSEric Fiselier catch (...) 134*5a83710eSEric Fiselier { 135*5a83710eSEric Fiselier throw_one = 0xFFFF; 136*5a83710eSEric Fiselier assert(G::n_alive == 0); 137*5a83710eSEric Fiselier assert(!G::op_run); 138*5a83710eSEric Fiselier } 139*5a83710eSEric Fiselier } 140*5a83710eSEric Fiselier #ifndef _LIBCPP_HAS_NO_VARIADICS 141*5a83710eSEric Fiselier { 142*5a83710eSEric Fiselier assert(G::n_alive == 0); 143*5a83710eSEric Fiselier assert(!G::op_run); 144*5a83710eSEric Fiselier std::thread t(G(), 5, 5.5); 145*5a83710eSEric Fiselier t.join(); 146*5a83710eSEric Fiselier assert(G::n_alive == 0); 147*5a83710eSEric Fiselier assert(G::op_run); 148*5a83710eSEric Fiselier } 149*5a83710eSEric Fiselier { 150*5a83710eSEric Fiselier std::thread t = std::thread(MoveOnly(), MoveOnly()); 151*5a83710eSEric Fiselier t.join(); 152*5a83710eSEric Fiselier } 153*5a83710eSEric Fiselier #endif // _LIBCPP_HAS_NO_VARIADICS 154*5a83710eSEric Fiselier } 155