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