Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc++] Introduce make_test_jthread for jthread tests #68837

Merged
merged 2 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions libcxx/test/std/thread/thread.jthread/assign.move.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,31 @@
#include <utility>
#include <vector>

#include "make_test_thread.h"
#include "test_macros.h"

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

int main(int, char**) {
// If &x == this is true, there are no effects.
{
std::jthread j([] {});
auto id = j.get_id();
auto ssource = j.get_stop_source();
j = std::move(j);
std::jthread j = support::make_test_jthread([] {});
auto id = j.get_id();
auto ssource = j.get_stop_source();
j = std::move(j);
assert(j.get_id() == id);
assert(j.get_stop_source() == ssource);
}

// if joinable() is true, calls request_stop() and then join()
// request_stop is called
{
std::jthread j1([] {});
bool called = false;
std::jthread j1 = support::make_test_jthread([] {});
bool called = false;
std::stop_callback cb(j1.get_stop_token(), [&called] { called = true; });

std::jthread j2([] {});
j1 = std::move(j2);
std::jthread j2 = support::make_test_jthread([] {});
j1 = std::move(j2);
assert(called);
}

Expand All @@ -58,10 +59,10 @@ int main(int, char**) {
constexpr auto numberOfThreads = 10u;
jts.reserve(numberOfThreads);
for (auto i = 0u; i < numberOfThreads; ++i) {
jts.emplace_back([&] {
jts.emplace_back(support::make_test_jthread([&] {
std::this_thread::sleep_for(std::chrono::milliseconds(2));
calledTimes.fetch_add(1, std::memory_order_relaxed);
});
}));
}

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

// then assigns the state of x to *this
{
std::jthread j1([] {});
std::jthread j2([] {});
auto id2 = j2.get_id();
auto ssource2 = j2.get_stop_source();
std::jthread j1 = support::make_test_jthread([] {});
std::jthread j2 = support::make_test_jthread([] {});
auto id2 = j2.get_id();
auto ssource2 = j2.get_stop_source();

j1 = std::move(j2);

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

// sets x to a default constructed state
{
std::jthread j1([] {});
std::jthread j2([] {});
j1 = std::move(j2);
std::jthread j1 = support::make_test_jthread([] {});
std::jthread j2 = support::make_test_jthread([] {});
j1 = std::move(j2);

assert(j2.get_id() == std::jthread::id());
assert(!j2.get_stop_source().stop_possible());
Expand All @@ -103,7 +104,7 @@ int main(int, char**) {
// joinable is false
{
std::jthread j1;
std::jthread j2([] {});
std::jthread j2 = support::make_test_jthread([] {});

auto j2Id = j2.get_id();

Expand Down
9 changes: 5 additions & 4 deletions libcxx/test/std/thread/thread.jthread/cons.move.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <type_traits>
#include <utility>

#include "make_test_thread.h"
#include "test_macros.h"

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

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

std::jthread j2(std::move(j1));
assert(ss1 == j2.get_stop_source());
Expand Down
7 changes: 4 additions & 3 deletions libcxx/test/std/thread/thread.jthread/detach.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@
#include <thread>
#include <type_traits>

#include "make_test_thread.h"
#include "test_macros.h"

int main(int, char**) {
// Effects: The thread represented by *this continues execution without the calling thread blocking.
{
std::atomic_bool start{false};
std::atomic_bool done{false};
std::optional<std::jthread> jt{[&start, &done] {
std::optional<std::jthread> jt = support::make_test_jthread([&start, &done] {
start.wait(false);
done = true;
}};
});

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

// Postconditions: get_id() == id().
{
std::jthread jt{[] {}};
std::jthread jt = support::make_test_jthread([] {});
assert(jt.get_id() != std::jthread::id());
jt.detach();
assert(jt.get_id() == std::jthread::id());
Expand Down
10 changes: 6 additions & 4 deletions libcxx/test/std/thread/thread.jthread/dtor.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <thread>
#include <type_traits>
#include <vector>

#include "make_test_thread.h"
#include "test_macros.h"

int main(int, char**) {
Expand All @@ -32,8 +34,8 @@ int main(int, char**) {
// If joinable() is true, calls request_stop() and then join().
// request_stop is called
{
std::optional<std::jthread> jt([] {});
bool called = false;
std::optional<std::jthread> jt = support::make_test_jthread([] {});
bool called = false;
std::stop_callback cb(jt->get_stop_token(), [&called] { called = true; });
jt.reset();
assert(called);
Expand All @@ -48,10 +50,10 @@ int main(int, char**) {
constexpr auto numberOfThreads = 10u;
jts.reserve(numberOfThreads);
for (auto i = 0u; i < numberOfThreads; ++i) {
jts.emplace_back([&calledTimes] {
jts.emplace_back(support::make_test_jthread([&calledTimes] {
std::this_thread::sleep_for(std::chrono::milliseconds{2});
calledTimes.fetch_add(1, std::memory_order_relaxed);
});
}));
}
jts.clear();

Expand Down
3 changes: 2 additions & 1 deletion libcxx/test/std/thread/thread.jthread/get_id.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <thread>
#include <type_traits>

#include "make_test_thread.h"
#include "test_macros.h"

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

// Represents a thread
{
const std::jthread jt{[] {}};
const std::jthread jt = support::make_test_jthread([] {});
std::same_as<std::jthread::id> decltype(auto) result = jt.get_id();
assert(result != std::jthread::id());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@
#include <thread>
#include <type_traits>

#include "make_test_thread.h"
#include "test_macros.h"

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

int main(int, char**) {
// Represents a thread
{
std::jthread jt{[] {}};
std::jthread jt = support::make_test_jthread([] {});
std::same_as<std::stop_source> decltype(auto) result = jt.get_stop_source();
assert(result.stop_possible());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
#include <type_traits>
#include <utility>

#include "make_test_thread.h"
#include "test_macros.h"

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

int main(int, char**) {
// Represents a thread
{
std::jthread jt{[] {}};
std::jthread jt = support::make_test_jthread([] {});
auto ss = jt.get_stop_source();
std::same_as<std::stop_token> decltype(auto) st = std::as_const(jt).get_stop_token();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <type_traits>
#include <vector>

#include "make_test_thread.h"
#include "test_macros.h"

int main(int, char**) {
Expand All @@ -40,12 +41,12 @@ int main(int, char**) {
std::atomic_bool start = false;
std::atomic_bool done = false;

std::jthread jt{[&] {
std::jthread jt = support::make_test_jthread([&] {
start.wait(false);
f();
done = true;
done.notify_all();
}};
});

f = [&] {
try {
Expand Down
11 changes: 6 additions & 5 deletions libcxx/test/std/thread/thread.jthread/join.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <type_traits>
#include <vector>

#include "make_test_thread.h"
#include "test_macros.h"

int main(int, char**) {
Expand All @@ -33,10 +34,10 @@ int main(int, char**) {
constexpr auto numberOfThreads = 10u;
jts.reserve(numberOfThreads);
for (auto i = 0u; i < numberOfThreads; ++i) {
jts.emplace_back([&] {
jts.emplace_back(support::make_test_jthread([&] {
std::this_thread::sleep_for(std::chrono::milliseconds(2));
calledTimes.fetch_add(1, std::memory_order_relaxed);
});
}));
}

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

// Postconditions: The thread represented by *this has completed. get_id() == id().
{
std::jthread jt{[] {}};
std::jthread jt = support::make_test_jthread([] {});
assert(jt.get_id() != std::jthread::id());
jt.join();
assert(jt.get_id() == std::jthread::id());
Expand Down
7 changes: 4 additions & 3 deletions libcxx/test/std/thread/thread.jthread/joinable.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <thread>
#include <type_traits>

#include "make_test_thread.h"
#include "test_macros.h"

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

// Non-default constructed
{
const std::jthread jt{[] {}};
const std::jthread jt = support::make_test_jthread([] {});
std::same_as<bool> decltype(auto) result = jt.joinable();
assert(result);
}

// Non-default constructed
// the thread of execution has not finished
{
std::atomic_bool done = false;
const std::jthread jt{[&done] { done.wait(false); }};
std::atomic_bool done = false;
const std::jthread jt = support::make_test_jthread([&done] { done.wait(false); });
std::same_as<bool> decltype(auto) result = jt.joinable();
done = true;
done.notify_all();
Expand Down
5 changes: 3 additions & 2 deletions libcxx/test/std/thread/thread.jthread/request_stop.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@
#include <thread>
#include <type_traits>

#include "make_test_thread.h"
#include "test_macros.h"

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

int main(int, char**) {
// Represents a thread
{
std::jthread jt{[] {}};
auto st = jt.get_stop_token();
std::jthread jt = support::make_test_jthread([] {});
auto st = jt.get_stop_token();
assert(!st.stop_requested());
std::same_as<bool> decltype(auto) result = jt.request_stop();
assert(result);
Expand Down
9 changes: 5 additions & 4 deletions libcxx/test/std/thread/thread.jthread/swap.free.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <thread>
#include <type_traits>

#include "make_test_thread.h"
#include "test_macros.h"

template <class T>
Expand All @@ -30,7 +31,7 @@ int main(int, char**) {
// x is default constructed
{
std::jthread t1;
std::jthread t2{[] {}};
std::jthread t2 = support::make_test_jthread([] {});
const auto originalId2 = t2.get_id();
swap(t1, t2);

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

// y is default constructed
{
std::jthread t1([] {});
std::jthread t1 = support::make_test_jthread([] {});
std::jthread t2{};
const auto originalId1 = t1.get_id();
swap(t1, t2);
Expand All @@ -51,8 +52,8 @@ int main(int, char**) {

// both not default constructed
{
std::jthread t1([] {});
std::jthread t2{[] {}};
std::jthread t1 = support::make_test_jthread([] {});
std::jthread t2 = support::make_test_jthread([] {});
const auto originalId1 = t1.get_id();
const auto originalId2 = t2.get_id();
swap(t1, t2);
Expand Down
Loading