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