1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===// 2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 3f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant// The LLVM Compiler Infrastructure 4bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 7bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===// 98d86b2e6867297fb2109824c67c50de67f3a31f2Jonathan Roelofs// 108d86b2e6867297fb2109824c67c50de67f3a31f2Jonathan Roelofs// UNSUPPORTED: libcpp-has-no-threads 11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// <thread> 13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// class thread 15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// template <class F, class ...Args> thread(F&& f, Args&&... args); 17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 1807a4bec1dd600078aa8ec64f5aaeae9a7cc5d7d8Eric Fiselier// UNSUPPORTED: sanitizer-new-delete 1969697c8506fb47fe160c0327caa2cd8bd8f6adedEric Fiselier 20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <thread> 21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <new> 22e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier#include <atomic> 23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <cstdlib> 24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <cassert> 25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 26286e0a491b5d3cfd73b2ae3b42cf16b9181904e7Eric Fiselier#include "test_macros.h" 27286e0a491b5d3cfd73b2ae3b42cf16b9181904e7Eric Fiselier 28e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselierstd::atomic<unsigned> throw_one(0xFFFF); 29e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselierstd::atomic<unsigned> outstanding_new(0); 30e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier 31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 3212a450ff3b05407eb5cd6a433edd5ab2f28c44feEric Fiseliervoid* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc) 33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (throw_one == 0) 35e3a71a295ed9412bb34ab125c98380498a608b1aAsiri Rathnayake TEST_THROW(std::bad_alloc()); 36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant --throw_one; 37e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier ++outstanding_new; 38f5b30213b6f14517baf4980ae696b4f37ba16575Eric Fiselier void* ret = std::malloc(s); 39f5b30213b6f14517baf4980ae696b4f37ba16575Eric Fiselier if (!ret) std::abort(); // placate MSVC's unchecked malloc warning 40f5b30213b6f14517baf4980ae696b4f37ba16575Eric Fiselier return ret; 41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 42bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 4312a450ff3b05407eb5cd6a433edd5ab2f28c44feEric Fiseliervoid operator delete(void* p) TEST_NOEXCEPT 44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 45e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier --outstanding_new; 46bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant std::free(p); 47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool f_run = false; 50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantvoid f() 52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant f_run = true; 54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass G 57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant int alive_; 59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic: 60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant static int n_alive; 61bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant static bool op_run; 62bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant G() : alive_(1) {++n_alive;} 64bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant G(const G& g) : alive_(g.alive_) {++n_alive;} 65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant ~G() {alive_ = 0; --n_alive;} 66bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 67bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant void operator()() 68bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 69bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(alive_ == 1); 70bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(n_alive >= 1); 71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant op_run = true; 72bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 73bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 74bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant void operator()(int i, double j) 75bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 76bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(alive_ == 1); 77bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(n_alive >= 1); 78bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(i == 5); 79bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(j == 5.5); 80bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant op_run = true; 81bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 82bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}; 83bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 84bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantint G::n_alive = 0; 85bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantbool G::op_run = false; 86bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 87286e0a491b5d3cfd73b2ae3b42cf16b9181904e7Eric Fiselier#if TEST_STD_VER >= 11 88656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant 89656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnantclass MoveOnly 90656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant{ 91656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant MoveOnly(const MoveOnly&); 92656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnantpublic: 93656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant MoveOnly() {} 94656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant MoveOnly(MoveOnly&&) {} 95656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant 96656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant void operator()(MoveOnly&&) 97656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant { 98656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant } 99656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant}; 100656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant 101656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant#endif 102656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant 103e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// Test throwing std::bad_alloc 104e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier//----------------------------- 105e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// Concerns: 106e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// A Each allocation performed during thread construction should be performed 107e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// in the parent thread so that std::terminate is not called if 108e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// std::bad_alloc is thrown by new. 10916e2ba19dfffdcf9bba202eb8a27fd79e3d15303Stephan T. Lavavej// B std::thread's constructor should properly handle exceptions and not leak 110e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// memory. 111e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// Plan: 112e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// 1 Create a thread and count the number of allocations, 'N', it performs. 113e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// 2 For each allocation performed run a test where that allocation throws. 114e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// 2.1 check that the exception can be caught in the parent thread. 115e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// 2.2 Check that the functor has not been called. 116e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// 2.3 Check that no memory allocated by the creation of the thread is leaked. 117e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// 3 Finally check that a thread runs successfully if we throw after 'N+1' 118e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier// allocations. 119e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiseliervoid test_throwing_new_during_thread_creation() { 120e3a71a295ed9412bb34ab125c98380498a608b1aAsiri Rathnayake#ifndef TEST_HAS_NO_EXCEPTIONS 121e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier throw_one = 0xFFF; 122bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 123bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant std::thread t(f); 124bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant t.join(); 125bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 126e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier const int numAllocs = 0xFFF - throw_one; 127e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier // i <= numAllocs means the last iteration is expected not to throw. 128e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier for (int i=0; i <= numAllocs; ++i) { 129e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier throw_one = i; 130e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier f_run = false; 131e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier unsigned old_outstanding = outstanding_new; 132e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier try { 133bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant std::thread t(f); 134e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier assert(i == numAllocs); // Only final iteration will not throw. 135e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier t.join(); 136e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier assert(f_run); 137e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier } catch (std::bad_alloc const&) { 138e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier assert(i < numAllocs); 139e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier assert(!f_run); // (2.2) 140bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 141e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier assert(old_outstanding == outstanding_new); // (2.3) 142e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier } 143e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier f_run = false; 144e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier throw_one = 0xFFF; 145e3a71a295ed9412bb34ab125c98380498a608b1aAsiri Rathnayake#endif 146e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier} 147e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier 148e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselierint main() 149e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier{ 150e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier test_throwing_new_during_thread_creation(); 151e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier { 152e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier std::thread t(f); 153e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier t.join(); 154e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier assert(f_run == true); 155bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 156e94c1aee2bef8ee8671d56160e2c27f9704646aeEric Fiselier 157bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 158bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::n_alive == 0); 159bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(!G::op_run); 160bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant std::thread t((G())); 161bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant t.join(); 162bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::n_alive == 0); 163bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::op_run); 164bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 165bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant G::op_run = false; 166e3a71a295ed9412bb34ab125c98380498a608b1aAsiri Rathnayake#ifndef TEST_HAS_NO_EXCEPTIONS 167bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 168bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant try 169bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 170bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant throw_one = 0; 171bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::n_alive == 0); 172bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(!G::op_run); 173bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant std::thread t((G())); 174bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(false); 175bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 176bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant catch (...) 177bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 178bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant throw_one = 0xFFFF; 179bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::n_alive == 0); 180bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(!G::op_run); 181bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 182bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 183e3a71a295ed9412bb34ab125c98380498a608b1aAsiri Rathnayake#endif 184286e0a491b5d3cfd73b2ae3b42cf16b9181904e7Eric Fiselier#if TEST_STD_VER >= 11 185bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant { 186bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::n_alive == 0); 187bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(!G::op_run); 188bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant std::thread t(G(), 5, 5.5); 189bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant t.join(); 190bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::n_alive == 0); 191bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant assert(G::op_run); 192bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant } 193656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant { 194656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant std::thread t = std::thread(MoveOnly(), MoveOnly()); 195656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant t.join(); 196656bdc3667f65f4d9c2bd2252c0d62122b97b5a0Howard Hinnant } 197286e0a491b5d3cfd73b2ae3b42cf16b9181904e7Eric Fiselier#endif 198bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 199