Skip to content

Commit 475e154

Browse files
authored
[libc++] Introduce make_test_jthread for jthread tests (#68837)
This patch introduces the support::make_test_jthread utility which is basically the same as support::make_test_thread but for std::jthread. It allows vendors to maintain a downstream way to create threads for use within the test suite, which is especially useful for embedded platforms.
1 parent 158c052 commit 475e154

14 files changed

+93
-52
lines changed

libcxx/test/std/thread/thread.jthread/assign.move.pass.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,31 @@
2323
#include <utility>
2424
#include <vector>
2525

26+
#include "make_test_thread.h"
2627
#include "test_macros.h"
2728

2829
static_assert(std::is_nothrow_move_assignable_v<std::jthread>);
2930

3031
int main(int, char**) {
3132
// If &x == this is true, there are no effects.
3233
{
33-
std::jthread j([] {});
34-
auto id = j.get_id();
35-
auto ssource = j.get_stop_source();
36-
j = std::move(j);
34+
std::jthread j = support::make_test_jthread([] {});
35+
auto id = j.get_id();
36+
auto ssource = j.get_stop_source();
37+
j = std::move(j);
3738
assert(j.get_id() == id);
3839
assert(j.get_stop_source() == ssource);
3940
}
4041

4142
// if joinable() is true, calls request_stop() and then join()
4243
// request_stop is called
4344
{
44-
std::jthread j1([] {});
45-
bool called = false;
45+
std::jthread j1 = support::make_test_jthread([] {});
46+
bool called = false;
4647
std::stop_callback cb(j1.get_stop_token(), [&called] { called = true; });
4748

48-
std::jthread j2([] {});
49-
j1 = std::move(j2);
49+
std::jthread j2 = support::make_test_jthread([] {});
50+
j1 = std::move(j2);
5051
assert(called);
5152
}
5253

@@ -58,10 +59,10 @@ int main(int, char**) {
5859
constexpr auto numberOfThreads = 10u;
5960
jts.reserve(numberOfThreads);
6061
for (auto i = 0u; i < numberOfThreads; ++i) {
61-
jts.emplace_back([&] {
62+
jts.emplace_back(support::make_test_jthread([&] {
6263
std::this_thread::sleep_for(std::chrono::milliseconds(2));
6364
calledTimes.fetch_add(1, std::memory_order_relaxed);
64-
});
65+
}));
6566
}
6667

6768
for (auto i = 0u; i < numberOfThreads; ++i) {
@@ -79,10 +80,10 @@ int main(int, char**) {
7980

8081
// then assigns the state of x to *this
8182
{
82-
std::jthread j1([] {});
83-
std::jthread j2([] {});
84-
auto id2 = j2.get_id();
85-
auto ssource2 = j2.get_stop_source();
83+
std::jthread j1 = support::make_test_jthread([] {});
84+
std::jthread j2 = support::make_test_jthread([] {});
85+
auto id2 = j2.get_id();
86+
auto ssource2 = j2.get_stop_source();
8687

8788
j1 = std::move(j2);
8889

@@ -92,9 +93,9 @@ int main(int, char**) {
9293

9394
// sets x to a default constructed state
9495
{
95-
std::jthread j1([] {});
96-
std::jthread j2([] {});
97-
j1 = std::move(j2);
96+
std::jthread j1 = support::make_test_jthread([] {});
97+
std::jthread j2 = support::make_test_jthread([] {});
98+
j1 = std::move(j2);
9899

99100
assert(j2.get_id() == std::jthread::id());
100101
assert(!j2.get_stop_source().stop_possible());
@@ -103,7 +104,7 @@ int main(int, char**) {
103104
// joinable is false
104105
{
105106
std::jthread j1;
106-
std::jthread j2([] {});
107+
std::jthread j2 = support::make_test_jthread([] {});
107108

108109
auto j2Id = j2.get_id();
109110

libcxx/test/std/thread/thread.jthread/cons.move.pass.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <type_traits>
2020
#include <utility>
2121

22+
#include "make_test_thread.h"
2223
#include "test_macros.h"
2324

2425
static_assert(std::is_nothrow_move_constructible_v<std::jthread>);
@@ -27,8 +28,8 @@ int main(int, char**) {
2728
{
2829
// x.get_id() == id() and get_id() returns the value of x.get_id() prior
2930
// to the start of construction.
30-
std::jthread j1{[] {}};
31-
auto id1 = j1.get_id();
31+
std::jthread j1 = support::make_test_jthread([] {});
32+
auto id1 = j1.get_id();
3233

3334
std::jthread j2(std::move(j1));
3435
assert(j1.get_id() == std::jthread::id());
@@ -38,8 +39,8 @@ int main(int, char**) {
3839
{
3940
// ssource has the value of x.ssource prior to the start of construction
4041
// and x.ssource.stop_possible() is false.
41-
std::jthread j1{[] {}};
42-
auto ss1 = j1.get_stop_source();
42+
std::jthread j1 = support::make_test_jthread([] {});
43+
auto ss1 = j1.get_stop_source();
4344

4445
std::jthread j2(std::move(j1));
4546
assert(ss1 == j2.get_stop_source());

libcxx/test/std/thread/thread.jthread/detach.pass.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,18 @@
2323
#include <thread>
2424
#include <type_traits>
2525

26+
#include "make_test_thread.h"
2627
#include "test_macros.h"
2728

2829
int main(int, char**) {
2930
// Effects: The thread represented by *this continues execution without the calling thread blocking.
3031
{
3132
std::atomic_bool start{false};
3233
std::atomic_bool done{false};
33-
std::optional<std::jthread> jt{[&start, &done] {
34+
std::optional<std::jthread> jt = support::make_test_jthread([&start, &done] {
3435
start.wait(false);
3536
done = true;
36-
}};
37+
});
3738

3839
// If it blocks, it will deadlock here
3940
jt->detach();
@@ -49,7 +50,7 @@ int main(int, char**) {
4950

5051
// Postconditions: get_id() == id().
5152
{
52-
std::jthread jt{[] {}};
53+
std::jthread jt = support::make_test_jthread([] {});
5354
assert(jt.get_id() != std::jthread::id());
5455
jt.detach();
5556
assert(jt.get_id() == std::jthread::id());

libcxx/test/std/thread/thread.jthread/dtor.pass.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <thread>
2121
#include <type_traits>
2222
#include <vector>
23+
24+
#include "make_test_thread.h"
2325
#include "test_macros.h"
2426

2527
int main(int, char**) {
@@ -32,8 +34,8 @@ int main(int, char**) {
3234
// If joinable() is true, calls request_stop() and then join().
3335
// request_stop is called
3436
{
35-
std::optional<std::jthread> jt([] {});
36-
bool called = false;
37+
std::optional<std::jthread> jt = support::make_test_jthread([] {});
38+
bool called = false;
3739
std::stop_callback cb(jt->get_stop_token(), [&called] { called = true; });
3840
jt.reset();
3941
assert(called);
@@ -48,10 +50,10 @@ int main(int, char**) {
4850
constexpr auto numberOfThreads = 10u;
4951
jts.reserve(numberOfThreads);
5052
for (auto i = 0u; i < numberOfThreads; ++i) {
51-
jts.emplace_back([&calledTimes] {
53+
jts.emplace_back(support::make_test_jthread([&calledTimes] {
5254
std::this_thread::sleep_for(std::chrono::milliseconds{2});
5355
calledTimes.fetch_add(1, std::memory_order_relaxed);
54-
});
56+
}));
5557
}
5658
jts.clear();
5759

libcxx/test/std/thread/thread.jthread/get_id.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <thread>
1919
#include <type_traits>
2020

21+
#include "make_test_thread.h"
2122
#include "test_macros.h"
2223

2324
static_assert(noexcept(std::declval<const std::jthread&>().get_id()));
@@ -32,7 +33,7 @@ int main(int, char**) {
3233

3334
// Represents a thread
3435
{
35-
const std::jthread jt{[] {}};
36+
const std::jthread jt = support::make_test_jthread([] {});
3637
std::same_as<std::jthread::id> decltype(auto) result = jt.get_id();
3738
assert(result != std::jthread::id());
3839
}

libcxx/test/std/thread/thread.jthread/get_stop_source.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919
#include <thread>
2020
#include <type_traits>
2121

22+
#include "make_test_thread.h"
2223
#include "test_macros.h"
2324

2425
static_assert(noexcept(std::declval<std::jthread&>().get_stop_source()));
2526

2627
int main(int, char**) {
2728
// Represents a thread
2829
{
29-
std::jthread jt{[] {}};
30+
std::jthread jt = support::make_test_jthread([] {});
3031
std::same_as<std::stop_source> decltype(auto) result = jt.get_stop_source();
3132
assert(result.stop_possible());
3233
}

libcxx/test/std/thread/thread.jthread/get_stop_token.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
#include <type_traits>
2121
#include <utility>
2222

23+
#include "make_test_thread.h"
2324
#include "test_macros.h"
2425

2526
static_assert(noexcept(std::declval<const std::jthread&>().get_stop_token()));
2627

2728
int main(int, char**) {
2829
// Represents a thread
2930
{
30-
std::jthread jt{[] {}};
31+
std::jthread jt = support::make_test_jthread([] {});
3132
auto ss = jt.get_stop_source();
3233
std::same_as<std::stop_token> decltype(auto) st = std::as_const(jt).get_stop_token();
3334

libcxx/test/std/thread/thread.jthread/join.deadlock.pass.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <type_traits>
3232
#include <vector>
3333

34+
#include "make_test_thread.h"
3435
#include "test_macros.h"
3536

3637
int main(int, char**) {
@@ -40,12 +41,12 @@ int main(int, char**) {
4041
std::atomic_bool start = false;
4142
std::atomic_bool done = false;
4243

43-
std::jthread jt{[&] {
44+
std::jthread jt = support::make_test_jthread([&] {
4445
start.wait(false);
4546
f();
4647
done = true;
4748
done.notify_all();
48-
}};
49+
});
4950

5051
f = [&] {
5152
try {

libcxx/test/std/thread/thread.jthread/join.pass.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <type_traits>
2424
#include <vector>
2525

26+
#include "make_test_thread.h"
2627
#include "test_macros.h"
2728

2829
int main(int, char**) {
@@ -33,10 +34,10 @@ int main(int, char**) {
3334
constexpr auto numberOfThreads = 10u;
3435
jts.reserve(numberOfThreads);
3536
for (auto i = 0u; i < numberOfThreads; ++i) {
36-
jts.emplace_back([&] {
37+
jts.emplace_back(support::make_test_jthread([&] {
3738
std::this_thread::sleep_for(std::chrono::milliseconds(2));
3839
calledTimes.fetch_add(1, std::memory_order_relaxed);
39-
});
40+
}));
4041
}
4142

4243
for (auto i = 0u; i < numberOfThreads; ++i) {
@@ -55,15 +56,15 @@ int main(int, char**) {
5556
// Synchronization: The completion of the thread represented by *this synchronizes with
5657
// ([intro.multithread]) the corresponding successful join() return.
5758
{
58-
bool flag = false;
59-
std::jthread jt{[&] { flag = true; }};
59+
bool flag = false;
60+
std::jthread jt = support::make_test_jthread([&] { flag = true; });
6061
jt.join();
6162
assert(flag); // non atomic write is visible to the current thread
6263
}
6364

6465
// Postconditions: The thread represented by *this has completed. get_id() == id().
6566
{
66-
std::jthread jt{[] {}};
67+
std::jthread jt = support::make_test_jthread([] {});
6768
assert(jt.get_id() != std::jthread::id());
6869
jt.join();
6970
assert(jt.get_id() == std::jthread::id());

libcxx/test/std/thread/thread.jthread/joinable.pass.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <thread>
2020
#include <type_traits>
2121

22+
#include "make_test_thread.h"
2223
#include "test_macros.h"
2324

2425
static_assert(noexcept(std::declval<const std::jthread&>().joinable()));
@@ -33,16 +34,16 @@ int main(int, char**) {
3334

3435
// Non-default constructed
3536
{
36-
const std::jthread jt{[] {}};
37+
const std::jthread jt = support::make_test_jthread([] {});
3738
std::same_as<bool> decltype(auto) result = jt.joinable();
3839
assert(result);
3940
}
4041

4142
// Non-default constructed
4243
// the thread of execution has not finished
4344
{
44-
std::atomic_bool done = false;
45-
const std::jthread jt{[&done] { done.wait(false); }};
45+
std::atomic_bool done = false;
46+
const std::jthread jt = support::make_test_jthread([&done] { done.wait(false); });
4647
std::same_as<bool> decltype(auto) result = jt.joinable();
4748
done = true;
4849
done.notify_all();

libcxx/test/std/thread/thread.jthread/request_stop.pass.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@
1919
#include <thread>
2020
#include <type_traits>
2121

22+
#include "make_test_thread.h"
2223
#include "test_macros.h"
2324

2425
static_assert(noexcept(std::declval<std::jthread&>().request_stop()));
2526

2627
int main(int, char**) {
2728
// Represents a thread
2829
{
29-
std::jthread jt{[] {}};
30-
auto st = jt.get_stop_token();
30+
std::jthread jt = support::make_test_jthread([] {});
31+
auto st = jt.get_stop_token();
3132
assert(!st.stop_requested());
3233
std::same_as<bool> decltype(auto) result = jt.request_stop();
3334
assert(result);

libcxx/test/std/thread/thread.jthread/swap.free.pass.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <thread>
1818
#include <type_traits>
1919

20+
#include "make_test_thread.h"
2021
#include "test_macros.h"
2122

2223
template <class T>
@@ -30,7 +31,7 @@ int main(int, char**) {
3031
// x is default constructed
3132
{
3233
std::jthread t1;
33-
std::jthread t2{[] {}};
34+
std::jthread t2 = support::make_test_jthread([] {});
3435
const auto originalId2 = t2.get_id();
3536
swap(t1, t2);
3637

@@ -40,7 +41,7 @@ int main(int, char**) {
4041

4142
// y is default constructed
4243
{
43-
std::jthread t1([] {});
44+
std::jthread t1 = support::make_test_jthread([] {});
4445
std::jthread t2{};
4546
const auto originalId1 = t1.get_id();
4647
swap(t1, t2);
@@ -51,8 +52,8 @@ int main(int, char**) {
5152

5253
// both not default constructed
5354
{
54-
std::jthread t1([] {});
55-
std::jthread t2{[] {}};
55+
std::jthread t1 = support::make_test_jthread([] {});
56+
std::jthread t2 = support::make_test_jthread([] {});
5657
const auto originalId1 = t1.get_id();
5758
const auto originalId2 = t2.get_id();
5859
swap(t1, t2);

0 commit comments

Comments
 (0)