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 // 10*f520c144SAsiri Rathnayake // XFAIL: libcpp-no-exceptions 115a83710eSEric Fiselier // UNSUPPORTED: libcpp-has-no-threads 125a83710eSEric Fiselier 135a83710eSEric Fiselier // <thread> 145a83710eSEric Fiselier 155a83710eSEric Fiselier // class thread 165a83710eSEric Fiselier 175a83710eSEric Fiselier // template <class F, class ...Args> thread(F&& f, Args&&... args); 185a83710eSEric Fiselier 194b7533a1SEric Fiselier // UNSUPPORTED: sanitizer-new-delete 205a83710eSEric Fiselier 215a83710eSEric Fiselier #include <thread> 225a83710eSEric Fiselier #include <new> 235a83710eSEric Fiselier #include <cstdlib> 245a83710eSEric Fiselier #include <cassert> 255a83710eSEric Fiselier 2610967a6eSEric Fiselier #include "test_macros.h" 2710967a6eSEric Fiselier 285a83710eSEric Fiselier unsigned throw_one = 0xFFFF; 295a83710eSEric Fiselier 305a83710eSEric Fiselier void* operator new(std::size_t s) throw(std::bad_alloc) 315a83710eSEric Fiselier { 325a83710eSEric Fiselier if (throw_one == 0) 335a83710eSEric Fiselier throw std::bad_alloc(); 345a83710eSEric Fiselier --throw_one; 355a83710eSEric Fiselier return std::malloc(s); 365a83710eSEric Fiselier } 375a83710eSEric Fiselier 385a83710eSEric Fiselier void operator delete(void* p) throw() 395a83710eSEric Fiselier { 405a83710eSEric Fiselier std::free(p); 415a83710eSEric Fiselier } 425a83710eSEric Fiselier 435a83710eSEric Fiselier bool f_run = false; 445a83710eSEric Fiselier 455a83710eSEric Fiselier void f() 465a83710eSEric Fiselier { 475a83710eSEric Fiselier f_run = true; 485a83710eSEric Fiselier } 495a83710eSEric Fiselier 505a83710eSEric Fiselier class G 515a83710eSEric Fiselier { 525a83710eSEric Fiselier int alive_; 535a83710eSEric Fiselier public: 545a83710eSEric Fiselier static int n_alive; 555a83710eSEric Fiselier static bool op_run; 565a83710eSEric Fiselier 575a83710eSEric Fiselier G() : alive_(1) {++n_alive;} 585a83710eSEric Fiselier G(const G& g) : alive_(g.alive_) {++n_alive;} 595a83710eSEric Fiselier ~G() {alive_ = 0; --n_alive;} 605a83710eSEric Fiselier 615a83710eSEric Fiselier void operator()() 625a83710eSEric Fiselier { 635a83710eSEric Fiselier assert(alive_ == 1); 645a83710eSEric Fiselier assert(n_alive >= 1); 655a83710eSEric Fiselier op_run = true; 665a83710eSEric Fiselier } 675a83710eSEric Fiselier 685a83710eSEric Fiselier void operator()(int i, double j) 695a83710eSEric Fiselier { 705a83710eSEric Fiselier assert(alive_ == 1); 715a83710eSEric Fiselier assert(n_alive >= 1); 725a83710eSEric Fiselier assert(i == 5); 735a83710eSEric Fiselier assert(j == 5.5); 745a83710eSEric Fiselier op_run = true; 755a83710eSEric Fiselier } 765a83710eSEric Fiselier }; 775a83710eSEric Fiselier 785a83710eSEric Fiselier int G::n_alive = 0; 795a83710eSEric Fiselier bool G::op_run = false; 805a83710eSEric Fiselier 8110967a6eSEric Fiselier #if TEST_STD_VER >= 11 825a83710eSEric Fiselier 835a83710eSEric Fiselier class MoveOnly 845a83710eSEric Fiselier { 855a83710eSEric Fiselier MoveOnly(const MoveOnly&); 865a83710eSEric Fiselier public: 875a83710eSEric Fiselier MoveOnly() {} 885a83710eSEric Fiselier MoveOnly(MoveOnly&&) {} 895a83710eSEric Fiselier 905a83710eSEric Fiselier void operator()(MoveOnly&&) 915a83710eSEric Fiselier { 925a83710eSEric Fiselier } 935a83710eSEric Fiselier }; 945a83710eSEric Fiselier 955a83710eSEric Fiselier #endif 965a83710eSEric Fiselier 975a83710eSEric Fiselier int main() 985a83710eSEric Fiselier { 995a83710eSEric Fiselier { 1005a83710eSEric Fiselier std::thread t(f); 1015a83710eSEric Fiselier t.join(); 1025a83710eSEric Fiselier assert(f_run == true); 1035a83710eSEric Fiselier } 1045a83710eSEric Fiselier f_run = false; 1055a83710eSEric Fiselier { 1065a83710eSEric Fiselier try 1075a83710eSEric Fiselier { 1085a83710eSEric Fiselier throw_one = 0; 1095a83710eSEric Fiselier std::thread t(f); 1105a83710eSEric Fiselier assert(false); 1115a83710eSEric Fiselier } 1125a83710eSEric Fiselier catch (...) 1135a83710eSEric Fiselier { 1145a83710eSEric Fiselier throw_one = 0xFFFF; 1155a83710eSEric Fiselier assert(!f_run); 1165a83710eSEric Fiselier } 1175a83710eSEric Fiselier } 1185a83710eSEric Fiselier { 1195a83710eSEric Fiselier assert(G::n_alive == 0); 1205a83710eSEric Fiselier assert(!G::op_run); 1215a83710eSEric Fiselier std::thread t((G())); 1225a83710eSEric Fiselier t.join(); 1235a83710eSEric Fiselier assert(G::n_alive == 0); 1245a83710eSEric Fiselier assert(G::op_run); 1255a83710eSEric Fiselier } 1265a83710eSEric Fiselier G::op_run = false; 1275a83710eSEric Fiselier { 1285a83710eSEric Fiselier try 1295a83710eSEric Fiselier { 1305a83710eSEric Fiselier throw_one = 0; 1315a83710eSEric Fiselier assert(G::n_alive == 0); 1325a83710eSEric Fiselier assert(!G::op_run); 1335a83710eSEric Fiselier std::thread t((G())); 1345a83710eSEric Fiselier assert(false); 1355a83710eSEric Fiselier } 1365a83710eSEric Fiselier catch (...) 1375a83710eSEric Fiselier { 1385a83710eSEric Fiselier throw_one = 0xFFFF; 1395a83710eSEric Fiselier assert(G::n_alive == 0); 1405a83710eSEric Fiselier assert(!G::op_run); 1415a83710eSEric Fiselier } 1425a83710eSEric Fiselier } 14310967a6eSEric Fiselier #if TEST_STD_VER >= 11 1445a83710eSEric Fiselier { 1455a83710eSEric Fiselier assert(G::n_alive == 0); 1465a83710eSEric Fiselier assert(!G::op_run); 1475a83710eSEric Fiselier std::thread t(G(), 5, 5.5); 1485a83710eSEric Fiselier t.join(); 1495a83710eSEric Fiselier assert(G::n_alive == 0); 1505a83710eSEric Fiselier assert(G::op_run); 1515a83710eSEric Fiselier } 1525a83710eSEric Fiselier { 1535a83710eSEric Fiselier std::thread t = std::thread(MoveOnly(), MoveOnly()); 1545a83710eSEric Fiselier t.join(); 1555a83710eSEric Fiselier } 15610967a6eSEric Fiselier #endif 1575a83710eSEric Fiselier } 158