15a83710eSEric Fiselier //===----------------------------------------------------------------------===// 25a83710eSEric Fiselier // 35a83710eSEric Fiselier // The LLVM Compiler Infrastructure 45a83710eSEric Fiselier // 55a83710eSEric Fiselier // This file is dual licensed under the MIT and the University of Illinois Open 65a83710eSEric Fiselier // Source Licenses. See LICENSE.TXT for details. 75a83710eSEric Fiselier // 85a83710eSEric Fiselier //===----------------------------------------------------------------------===// 95a83710eSEric Fiselier // 105a83710eSEric Fiselier // UNSUPPORTED: libcpp-has-no-threads 115a83710eSEric Fiselier 125a83710eSEric Fiselier // <thread> 135a83710eSEric Fiselier 145a83710eSEric Fiselier // class thread 155a83710eSEric Fiselier 165a83710eSEric Fiselier // template <class F, class ...Args> thread(F&& f, Args&&... args); 175a83710eSEric Fiselier 18*4b7533a1SEric Fiselier // UNSUPPORTED: sanitizer-new-delete 195a83710eSEric Fiselier 205a83710eSEric Fiselier #include <thread> 215a83710eSEric Fiselier #include <new> 225a83710eSEric Fiselier #include <cstdlib> 235a83710eSEric Fiselier #include <cassert> 245a83710eSEric Fiselier 255a83710eSEric Fiselier unsigned throw_one = 0xFFFF; 265a83710eSEric Fiselier 275a83710eSEric Fiselier void* operator new(std::size_t s) throw(std::bad_alloc) 285a83710eSEric Fiselier { 295a83710eSEric Fiselier if (throw_one == 0) 305a83710eSEric Fiselier throw std::bad_alloc(); 315a83710eSEric Fiselier --throw_one; 325a83710eSEric Fiselier return std::malloc(s); 335a83710eSEric Fiselier } 345a83710eSEric Fiselier 355a83710eSEric Fiselier void operator delete(void* p) throw() 365a83710eSEric Fiselier { 375a83710eSEric Fiselier std::free(p); 385a83710eSEric Fiselier } 395a83710eSEric Fiselier 405a83710eSEric Fiselier bool f_run = false; 415a83710eSEric Fiselier 425a83710eSEric Fiselier void f() 435a83710eSEric Fiselier { 445a83710eSEric Fiselier f_run = true; 455a83710eSEric Fiselier } 465a83710eSEric Fiselier 475a83710eSEric Fiselier class G 485a83710eSEric Fiselier { 495a83710eSEric Fiselier int alive_; 505a83710eSEric Fiselier public: 515a83710eSEric Fiselier static int n_alive; 525a83710eSEric Fiselier static bool op_run; 535a83710eSEric Fiselier 545a83710eSEric Fiselier G() : alive_(1) {++n_alive;} 555a83710eSEric Fiselier G(const G& g) : alive_(g.alive_) {++n_alive;} 565a83710eSEric Fiselier ~G() {alive_ = 0; --n_alive;} 575a83710eSEric Fiselier 585a83710eSEric Fiselier void operator()() 595a83710eSEric Fiselier { 605a83710eSEric Fiselier assert(alive_ == 1); 615a83710eSEric Fiselier assert(n_alive >= 1); 625a83710eSEric Fiselier op_run = true; 635a83710eSEric Fiselier } 645a83710eSEric Fiselier 655a83710eSEric Fiselier void operator()(int i, double j) 665a83710eSEric Fiselier { 675a83710eSEric Fiselier assert(alive_ == 1); 685a83710eSEric Fiselier assert(n_alive >= 1); 695a83710eSEric Fiselier assert(i == 5); 705a83710eSEric Fiselier assert(j == 5.5); 715a83710eSEric Fiselier op_run = true; 725a83710eSEric Fiselier } 735a83710eSEric Fiselier }; 745a83710eSEric Fiselier 755a83710eSEric Fiselier int G::n_alive = 0; 765a83710eSEric Fiselier bool G::op_run = false; 775a83710eSEric Fiselier 785a83710eSEric Fiselier #ifndef _LIBCPP_HAS_NO_VARIADICS 795a83710eSEric Fiselier 805a83710eSEric Fiselier class MoveOnly 815a83710eSEric Fiselier { 825a83710eSEric Fiselier MoveOnly(const MoveOnly&); 835a83710eSEric Fiselier public: 845a83710eSEric Fiselier MoveOnly() {} 855a83710eSEric Fiselier MoveOnly(MoveOnly&&) {} 865a83710eSEric Fiselier 875a83710eSEric Fiselier void operator()(MoveOnly&&) 885a83710eSEric Fiselier { 895a83710eSEric Fiselier } 905a83710eSEric Fiselier }; 915a83710eSEric Fiselier 925a83710eSEric Fiselier #endif 935a83710eSEric Fiselier 945a83710eSEric Fiselier int main() 955a83710eSEric Fiselier { 965a83710eSEric Fiselier { 975a83710eSEric Fiselier std::thread t(f); 985a83710eSEric Fiselier t.join(); 995a83710eSEric Fiselier assert(f_run == true); 1005a83710eSEric Fiselier } 1015a83710eSEric Fiselier f_run = false; 1025a83710eSEric Fiselier { 1035a83710eSEric Fiselier try 1045a83710eSEric Fiselier { 1055a83710eSEric Fiselier throw_one = 0; 1065a83710eSEric Fiselier std::thread t(f); 1075a83710eSEric Fiselier assert(false); 1085a83710eSEric Fiselier } 1095a83710eSEric Fiselier catch (...) 1105a83710eSEric Fiselier { 1115a83710eSEric Fiselier throw_one = 0xFFFF; 1125a83710eSEric Fiselier assert(!f_run); 1135a83710eSEric Fiselier } 1145a83710eSEric Fiselier } 1155a83710eSEric Fiselier { 1165a83710eSEric Fiselier assert(G::n_alive == 0); 1175a83710eSEric Fiselier assert(!G::op_run); 1185a83710eSEric Fiselier std::thread t((G())); 1195a83710eSEric Fiselier t.join(); 1205a83710eSEric Fiselier assert(G::n_alive == 0); 1215a83710eSEric Fiselier assert(G::op_run); 1225a83710eSEric Fiselier } 1235a83710eSEric Fiselier G::op_run = false; 1245a83710eSEric Fiselier { 1255a83710eSEric Fiselier try 1265a83710eSEric Fiselier { 1275a83710eSEric Fiselier throw_one = 0; 1285a83710eSEric Fiselier assert(G::n_alive == 0); 1295a83710eSEric Fiselier assert(!G::op_run); 1305a83710eSEric Fiselier std::thread t((G())); 1315a83710eSEric Fiselier assert(false); 1325a83710eSEric Fiselier } 1335a83710eSEric Fiselier catch (...) 1345a83710eSEric Fiselier { 1355a83710eSEric Fiselier throw_one = 0xFFFF; 1365a83710eSEric Fiselier assert(G::n_alive == 0); 1375a83710eSEric Fiselier assert(!G::op_run); 1385a83710eSEric Fiselier } 1395a83710eSEric Fiselier } 1405a83710eSEric Fiselier #ifndef _LIBCPP_HAS_NO_VARIADICS 1415a83710eSEric Fiselier { 1425a83710eSEric Fiselier assert(G::n_alive == 0); 1435a83710eSEric Fiselier assert(!G::op_run); 1445a83710eSEric Fiselier std::thread t(G(), 5, 5.5); 1455a83710eSEric Fiselier t.join(); 1465a83710eSEric Fiselier assert(G::n_alive == 0); 1475a83710eSEric Fiselier assert(G::op_run); 1485a83710eSEric Fiselier } 1495a83710eSEric Fiselier { 1505a83710eSEric Fiselier std::thread t = std::thread(MoveOnly(), MoveOnly()); 1515a83710eSEric Fiselier t.join(); 1525a83710eSEric Fiselier } 1535a83710eSEric Fiselier #endif // _LIBCPP_HAS_NO_VARIADICS 1545a83710eSEric Fiselier } 155