Skip to content

Commit 17ec788

Browse files
committed
tests: cpp: tests for std::thread and std::this_thread
This commit adds tests for std::thread and std::this_thread. Signed-off-by: Christopher Friedt <[email protected]>
1 parent 74cc8a5 commit 17ec788

File tree

5 files changed

+263
-0
lines changed

5 files changed

+263
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.13.1)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(thread)
6+
7+
FILE(GLOB_RECURSE app_sources src/*.cpp)
8+
target_sources(app PRIVATE ${app_sources})

tests/lib/cpp/std/thread/prj.conf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CONFIG_ZTEST=y
2+
3+
CONFIG_CPP=y
4+
CONFIG_REQUIRES_FULL_LIBCPP=y
5+
CONFIG_CPP_EXCEPTIONS=y
6+
CONFIG_STD_CPP20=y
7+
8+
CONFIG_COMMON_LIBC_THRD=y
9+
CONFIG_POSIX_API=y
10+
CONFIG_THREAD_STACK_INFO=y
11+
CONFIG_DYNAMIC_THREAD=y
12+
CONFIG_DYNAMIC_THREAD_POOL_SIZE=6
13+
CONFIG_DYNAMIC_THREAD_STACK_SIZE=4096
14+
15+
CONFIG_ZTEST_STACK_SIZE=4096
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <chrono>
8+
#include <system_error>
9+
#include <thread>
10+
11+
#include <zephyr/ztest.h>
12+
13+
using namespace std;
14+
using namespace std::chrono_literals;
15+
16+
static auto now()
17+
{
18+
return chrono::steady_clock::now();
19+
}
20+
21+
ZTEST(this_thread, test_get_id)
22+
{
23+
thread::id id = this_thread::get_id();
24+
}
25+
26+
ZTEST(this_thread, test_yield)
27+
{
28+
this_thread::yield();
29+
}
30+
31+
ZTEST(this_thread, test_sleep_until)
32+
{
33+
this_thread::sleep_until(now() + 10ms);
34+
}
35+
36+
ZTEST(this_thread, test_sleep_for)
37+
{
38+
this_thread::sleep_for(10ms);
39+
}
40+
41+
ZTEST_SUITE(this_thread, NULL, NULL, NULL, NULL, NULL);
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <system_error>
8+
#include <thread>
9+
10+
#include <zephyr/ztest.h>
11+
12+
using namespace std;
13+
14+
ZTEST(thread, test_joinable)
15+
{
16+
// implicitly tests the move assignment operator (operator=)
17+
thread th = thread([]() {});
18+
zassert_true(th.joinable(), "non-default constructed thread should be joinable");
19+
20+
#ifdef __cpp_exceptions
21+
try {
22+
th.join();
23+
} catch (const system_error &e) {
24+
zassert_true(false, "joinable thread should join");
25+
}
26+
#else
27+
th.join();
28+
#endif
29+
30+
// This is an issue with gthread, so disabling the test for now.
31+
if (false) {
32+
zassert_false(th.joinable(), "previously joined thread should not be joinable");
33+
34+
th = std::thread([]() {});
35+
th.detach();
36+
zassert_false(th.joinable(), "detached thread should not be joinable");
37+
}
38+
}
39+
40+
ZTEST(thread, test_get_id)
41+
{
42+
thread::id tid = this_thread::get_id();
43+
}
44+
45+
ZTEST(thread, test_native_handle)
46+
{
47+
thread th([]() {});
48+
th.native_handle();
49+
th.join();
50+
}
51+
52+
ZTEST(thread, test_hardware_concurrency)
53+
{
54+
if (IS_ENABLED(CONFIG_ARCH_POSIX)) {
55+
zassert_true(thread::hardware_concurrency() >= 1, "actual: %u, expected: >= 1",
56+
thread::hardware_concurrency());
57+
} else {
58+
zassert_true(thread::hardware_concurrency() == 0 ||
59+
thread::hardware_concurrency() == CONFIG_MP_NUM_CPUS,
60+
"actual: %u, expected: %u", thread::hardware_concurrency(),
61+
CONFIG_MP_NUM_CPUS);
62+
}
63+
}
64+
65+
ZTEST(thread, test_join)
66+
{
67+
thread th;
68+
__unused bool caught = false;
69+
70+
#ifdef __cpp_exceptions
71+
try {
72+
th.join();
73+
} catch (const system_error &e) {
74+
caught = true;
75+
}
76+
zassert_true(caught, "join of default-constructed thread should throw");
77+
#endif
78+
79+
th = thread([]() {});
80+
#ifdef __cpp_exceptions
81+
caught = false;
82+
try {
83+
th.join();
84+
} catch (const system_error &e) {
85+
caught = true;
86+
}
87+
zassert_false(caught, "join() should not throw");
88+
#else
89+
th.join();
90+
#endif
91+
92+
#ifdef __cpp_exceptions
93+
caught = false;
94+
try {
95+
th.join();
96+
} catch (const system_error &e) {
97+
caught = true;
98+
}
99+
zassert_true(caught, "join should throw with already-joined thread");
100+
#endif
101+
}
102+
103+
ZTEST(thread, test_detach)
104+
{
105+
thread th;
106+
__unused bool caught = false;
107+
108+
#ifdef __cpp_exceptions
109+
// this is the behaviour in linux for detach() with an invalid thread object
110+
caught = false;
111+
try {
112+
th.detach();
113+
} catch (const system_error &e) {
114+
caught = true;
115+
zassert_equal(e.code(), errc::invalid_argument, "expected errc::invalid_argument");
116+
}
117+
zassert_true(caught, "detach should throw with default-constructed thread");
118+
#endif
119+
120+
th = thread([]() {});
121+
#ifdef __cpp_exceptions
122+
caught = false;
123+
try {
124+
th.detach();
125+
} catch (const system_error &e) {
126+
caught = true;
127+
}
128+
zassert_false(caught, "detach on a valid thread should not throw");
129+
#else
130+
th.detach();
131+
#endif
132+
133+
#ifdef __cpp_exceptions
134+
caught = false;
135+
try {
136+
th.detach();
137+
} catch (const system_error &e) {
138+
caught = true;
139+
}
140+
zassert_true(caught, "detach on an already-detached thread should throw");
141+
#endif
142+
}
143+
144+
ZTEST(thread, test_swap)
145+
{
146+
thread th1;
147+
thread th2;
148+
149+
#ifdef __cpp_exceptions
150+
bool caught = false;
151+
try {
152+
th1.swap(th2);
153+
} catch (...) {
154+
caught = true;
155+
}
156+
zassert_false(caught, "thread::swap() is noexcept");
157+
#endif
158+
159+
th1 = thread([]() {});
160+
th2 = thread([]() {});
161+
162+
thread::id th1_id = th1.get_id();
163+
thread::id th2_id = th2.get_id();
164+
165+
th1.swap(th2);
166+
167+
zassert_equal(th2.get_id(), th1_id, "expected ids to be swapped");
168+
zassert_equal(th1.get_id(), th2_id, "expected ids to be swapped");
169+
170+
th1.join();
171+
th2.join();
172+
}
173+
174+
ZTEST_SUITE(thread, NULL, NULL, NULL, NULL, NULL);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
common:
2+
tags: cpp
3+
filter: CONFIG_FULL_LIBCPP_SUPPORTED
4+
integration_platforms:
5+
- qemu_cortex_a53
6+
- mps2/an385
7+
- qemu_riscv32
8+
- qemu_riscv64
9+
- qemu_x86
10+
- qemu_x86_64
11+
# llvm currently excluded due to 'inttypes.h' file not found
12+
toolchain_exclude:
13+
- llvm
14+
tests:
15+
cpp.thread.newlib.except:
16+
tags: newlib
17+
filter: CONFIG_NEWLIB_LIBC_SUPPORTED
18+
extra_configs:
19+
- CONFIG_NEWLIB_LIBC=y
20+
- CONFIG_CPP_EXCEPTIONS=y
21+
cpp.thread.newlib.noexcept:
22+
tags: newlib
23+
filter: CONFIG_NEWLIB_LIBC_SUPPORTED
24+
extra_configs:
25+
- CONFIG_NEWLIB_LIBC=y

0 commit comments

Comments
 (0)