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 184b7533a1SEric 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 25*10967a6eSEric Fiselier #include "test_macros.h" 26*10967a6eSEric Fiselier 275a83710eSEric Fiselier unsigned throw_one = 0xFFFF; 285a83710eSEric Fiselier 295a83710eSEric Fiselier void* operator new(std::size_t s) throw(std::bad_alloc) 305a83710eSEric Fiselier { 315a83710eSEric Fiselier if (throw_one == 0) 325a83710eSEric Fiselier throw std::bad_alloc(); 335a83710eSEric Fiselier --throw_one; 345a83710eSEric Fiselier return std::malloc(s); 355a83710eSEric Fiselier } 365a83710eSEric Fiselier 375a83710eSEric Fiselier void operator delete(void* p) throw() 385a83710eSEric Fiselier { 395a83710eSEric Fiselier std::free(p); 405a83710eSEric Fiselier } 415a83710eSEric Fiselier 425a83710eSEric Fiselier bool f_run = false; 435a83710eSEric Fiselier 445a83710eSEric Fiselier void f() 455a83710eSEric Fiselier { 465a83710eSEric Fiselier f_run = true; 475a83710eSEric Fiselier } 485a83710eSEric Fiselier 495a83710eSEric Fiselier class G 505a83710eSEric Fiselier { 515a83710eSEric Fiselier int alive_; 525a83710eSEric Fiselier public: 535a83710eSEric Fiselier static int n_alive; 545a83710eSEric Fiselier static bool op_run; 555a83710eSEric Fiselier 565a83710eSEric Fiselier G() : alive_(1) {++n_alive;} 575a83710eSEric Fiselier G(const G& g) : alive_(g.alive_) {++n_alive;} 585a83710eSEric Fiselier ~G() {alive_ = 0; --n_alive;} 595a83710eSEric Fiselier 605a83710eSEric Fiselier void operator()() 615a83710eSEric Fiselier { 625a83710eSEric Fiselier assert(alive_ == 1); 635a83710eSEric Fiselier assert(n_alive >= 1); 645a83710eSEric Fiselier op_run = true; 655a83710eSEric Fiselier } 665a83710eSEric Fiselier 675a83710eSEric Fiselier void operator()(int i, double j) 685a83710eSEric Fiselier { 695a83710eSEric Fiselier assert(alive_ == 1); 705a83710eSEric Fiselier assert(n_alive >= 1); 715a83710eSEric Fiselier assert(i == 5); 725a83710eSEric Fiselier assert(j == 5.5); 735a83710eSEric Fiselier op_run = true; 745a83710eSEric Fiselier } 755a83710eSEric Fiselier }; 765a83710eSEric Fiselier 775a83710eSEric Fiselier int G::n_alive = 0; 785a83710eSEric Fiselier bool G::op_run = false; 795a83710eSEric Fiselier 80*10967a6eSEric Fiselier #if TEST_STD_VER >= 11 815a83710eSEric Fiselier 825a83710eSEric Fiselier class MoveOnly 835a83710eSEric Fiselier { 845a83710eSEric Fiselier MoveOnly(const MoveOnly&); 855a83710eSEric Fiselier public: 865a83710eSEric Fiselier MoveOnly() {} 875a83710eSEric Fiselier MoveOnly(MoveOnly&&) {} 885a83710eSEric Fiselier 895a83710eSEric Fiselier void operator()(MoveOnly&&) 905a83710eSEric Fiselier { 915a83710eSEric Fiselier } 925a83710eSEric Fiselier }; 935a83710eSEric Fiselier 945a83710eSEric Fiselier #endif 955a83710eSEric Fiselier 965a83710eSEric Fiselier int main() 975a83710eSEric Fiselier { 985a83710eSEric Fiselier { 995a83710eSEric Fiselier std::thread t(f); 1005a83710eSEric Fiselier t.join(); 1015a83710eSEric Fiselier assert(f_run == true); 1025a83710eSEric Fiselier } 1035a83710eSEric Fiselier f_run = false; 1045a83710eSEric Fiselier { 1055a83710eSEric Fiselier try 1065a83710eSEric Fiselier { 1075a83710eSEric Fiselier throw_one = 0; 1085a83710eSEric Fiselier std::thread t(f); 1095a83710eSEric Fiselier assert(false); 1105a83710eSEric Fiselier } 1115a83710eSEric Fiselier catch (...) 1125a83710eSEric Fiselier { 1135a83710eSEric Fiselier throw_one = 0xFFFF; 1145a83710eSEric Fiselier assert(!f_run); 1155a83710eSEric Fiselier } 1165a83710eSEric Fiselier } 1175a83710eSEric Fiselier { 1185a83710eSEric Fiselier assert(G::n_alive == 0); 1195a83710eSEric Fiselier assert(!G::op_run); 1205a83710eSEric Fiselier std::thread t((G())); 1215a83710eSEric Fiselier t.join(); 1225a83710eSEric Fiselier assert(G::n_alive == 0); 1235a83710eSEric Fiselier assert(G::op_run); 1245a83710eSEric Fiselier } 1255a83710eSEric Fiselier G::op_run = false; 1265a83710eSEric Fiselier { 1275a83710eSEric Fiselier try 1285a83710eSEric Fiselier { 1295a83710eSEric Fiselier throw_one = 0; 1305a83710eSEric Fiselier assert(G::n_alive == 0); 1315a83710eSEric Fiselier assert(!G::op_run); 1325a83710eSEric Fiselier std::thread t((G())); 1335a83710eSEric Fiselier assert(false); 1345a83710eSEric Fiselier } 1355a83710eSEric Fiselier catch (...) 1365a83710eSEric Fiselier { 1375a83710eSEric Fiselier throw_one = 0xFFFF; 1385a83710eSEric Fiselier assert(G::n_alive == 0); 1395a83710eSEric Fiselier assert(!G::op_run); 1405a83710eSEric Fiselier } 1415a83710eSEric Fiselier } 142*10967a6eSEric Fiselier #if TEST_STD_VER >= 11 1435a83710eSEric Fiselier { 1445a83710eSEric Fiselier assert(G::n_alive == 0); 1455a83710eSEric Fiselier assert(!G::op_run); 1465a83710eSEric Fiselier std::thread t(G(), 5, 5.5); 1475a83710eSEric Fiselier t.join(); 1485a83710eSEric Fiselier assert(G::n_alive == 0); 1495a83710eSEric Fiselier assert(G::op_run); 1505a83710eSEric Fiselier } 1515a83710eSEric Fiselier { 1525a83710eSEric Fiselier std::thread t = std::thread(MoveOnly(), MoveOnly()); 1535a83710eSEric Fiselier t.join(); 1545a83710eSEric Fiselier } 155*10967a6eSEric Fiselier #endif 1565a83710eSEric Fiselier } 157