1695138caSHui //===----------------------------------------------------------------------===// 2695138caSHui // 3695138caSHui // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4695138caSHui // See https://llvm.org/LICENSE.txt for license information. 5695138caSHui // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6695138caSHui // 7695138caSHui //===----------------------------------------------------------------------===// 8695138caSHui // 9695138caSHui // UNSUPPORTED: no-threads 10695138caSHui // UNSUPPORTED: c++03, c++11, c++14, c++17 11695138caSHui // XFAIL: availability-synchronization_library-missing 12695138caSHui 13695138caSHui // ~jthread(); 14695138caSHui 15695138caSHui #include <atomic> 16695138caSHui #include <cassert> 17695138caSHui #include <optional> 18695138caSHui #include <stop_token> 19695138caSHui #include <thread> 20695138caSHui #include <type_traits> 21695138caSHui #include <vector> 22*475e1543SLouis Dionne 23*475e1543SLouis Dionne #include "make_test_thread.h" 24695138caSHui #include "test_macros.h" 25695138caSHui 26695138caSHui int main(int, char**) { 27695138caSHui // !joinable() 28695138caSHui { 29695138caSHui std::jthread jt; 30695138caSHui assert(!jt.joinable()); 31695138caSHui } 32695138caSHui 33695138caSHui // If joinable() is true, calls request_stop() and then join(). 34695138caSHui // request_stop is called 35695138caSHui { 36*475e1543SLouis Dionne std::optional<std::jthread> jt = support::make_test_jthread([] {}); 37695138caSHui bool called = false; 38695138caSHui std::stop_callback cb(jt->get_stop_token(), [&called] { called = true; }); 39695138caSHui jt.reset(); 40695138caSHui assert(called); 41695138caSHui } 42695138caSHui 43695138caSHui // If joinable() is true, calls request_stop() and then join(). 44695138caSHui // join is called 45695138caSHui { 46695138caSHui std::atomic_int calledTimes = 0; 47695138caSHui std::vector<std::jthread> jts; 48695138caSHui 49695138caSHui constexpr auto numberOfThreads = 10u; 50695138caSHui jts.reserve(numberOfThreads); 51695138caSHui for (auto i = 0u; i < numberOfThreads; ++i) { 52*475e1543SLouis Dionne jts.emplace_back(support::make_test_jthread([&calledTimes] { 53695138caSHui std::this_thread::sleep_for(std::chrono::milliseconds{2}); 54695138caSHui calledTimes.fetch_add(1, std::memory_order_relaxed); 55*475e1543SLouis Dionne })); 56695138caSHui } 57695138caSHui jts.clear(); 58695138caSHui 59695138caSHui // If join was called as expected, calledTimes must equal to numberOfThreads 60695138caSHui // If join was not called, there is a chance that the check below happened 61695138caSHui // before test threads incrementing the counter, thus calledTimed would 62695138caSHui // be less than numberOfThreads. 63695138caSHui // This is not going to catch issues 100%. Creating more threads would increase 64695138caSHui // the probability of catching the issue 65695138caSHui assert(calledTimes.load(std::memory_order_relaxed) == numberOfThreads); 66695138caSHui } 67695138caSHui 68695138caSHui return 0; 69695138caSHui } 70