14#include "kstd_cstring"
25std::atomic<int> g_thread_counter{0};
26std::atomic<int> g_thread_completed{0};
28std::atomic<int> g_tests_completed{0};
29std::atomic<int> g_tests_failed{0};
33void thread_increment(
void* arg) {
34 uint64_t thread_id =
reinterpret_cast<uint64_t
>(arg);
36 for (
int i = 0; i < 10; ++i) {
38 klog::Debug(
"Thread {}: counter={}, iter={}", thread_id,
39 g_thread_counter.load(), i);
51void test_thread_group_basic(
void* ) {
55 g_thread_completed = 0;
57 auto leader_holder = kstd::make_unique<TaskControlBlock>(
58 "ThreadGroupLeader", 10,
nullptr,
nullptr);
59 auto* leader = leader_holder.get();
61 leader->aux->tgid = 90000;
64 auto thread1 = kstd::make_unique<TaskControlBlock>(
65 "Thread1", 10, thread_increment,
reinterpret_cast<void*
>(1));
67 thread1->JoinThreadGroup(leader);
69 auto thread2 = kstd::make_unique<TaskControlBlock>(
70 "Thread2", 10, thread_increment,
reinterpret_cast<void*
>(2));
72 thread2->JoinThreadGroup(leader);
74 auto thread3 = kstd::make_unique<TaskControlBlock>(
75 "Thread3", 10, thread_increment,
reinterpret_cast<void*
>(3));
77 thread3->JoinThreadGroup(leader);
80 size_t group_size = leader->GetThreadGroupSize();
81 klog::Info(
"Thread group size: {} (expected 4)", group_size);
84 if (leader->InSameThreadGroup(thread1.get()) &&
85 leader->InSameThreadGroup(thread2.get()) &&
86 leader->InSameThreadGroup(thread3.get())) {
87 klog::Info(
"All threads are in the same thread group: PASS");
89 klog::Err(
"Thread group membership check failed: FAIL");
93 auto& task_mgr = TaskManagerSingleton::instance();
94 task_mgr.AddTask(std::move(thread1));
95 task_mgr.AddTask(std::move(thread2));
96 task_mgr.AddTask(std::move(thread3));
99 for (
int i = 0; i < 200 && g_thread_completed < 3; ++i) {
103 klog::Info(
"Thread completed count: {} (expected 3)",
104 g_thread_completed.load());
105 klog::Info(
"Final counter value: {} (expected 30)", g_thread_counter.load());
107 bool passed = (g_thread_completed == 3 && g_thread_counter >= 30);
111 klog::Err(
"Thread Group Basic Test: FAIL");
122void test_thread_group_dynamic(
void* ) {
123 klog::Info(
"=== Thread Group Dynamic Test ===");
125 auto leader_holder = kstd::make_unique<TaskControlBlock>(
"DynamicLeader", 10,
127 auto* leader = leader_holder.get();
129 leader->aux->tgid = 91000;
131 constexpr int kThreadCount = 5;
132 etl::unique_ptr<TaskControlBlock> thread_holders[kThreadCount];
135 for (
int i = 0; i < kThreadCount; ++i) {
136 thread_holders[i] = kstd::make_unique<TaskControlBlock>(
"DynamicThread", 10,
138 threads[i] = thread_holders[i].get();
139 threads[i]->
pid = 91001 + i;
144 for (
int i = 0; i < kThreadCount; ++i) {
146 size_t size = leader->GetThreadGroupSize();
147 klog::Debug(
"After join {}: group size={}", i, size);
150 size_t final_size = leader->GetThreadGroupSize();
151 klog::Info(
"Final group size: {} (expected {})", final_size,
155 for (
int i = 0; i < kThreadCount; ++i) {
157 size_t size = leader->GetThreadGroupSize();
158 klog::Debug(
"After leave {}: group size={}", i, size);
161 size_t remaining_size = leader->GetThreadGroupSize();
162 klog::Info(
"Remaining group size: {} (expected 1)", remaining_size);
164 bool passed = (final_size ==
static_cast<size_t>(kThreadCount + 1) &&
165 remaining_size == 1);
167 klog::Info(
"Thread Group Dynamic Test: PASS");
169 klog::Err(
"Thread Group Dynamic Test: FAIL");
180void concurrent_exit_worker(
void* arg) {
181 uint64_t thread_id =
reinterpret_cast<uint64_t
>(arg);
184 for (
int i = 0; i < 5; ++i) {
185 klog::Debug(
"ConcurrentExitWorker {}: iter={}", thread_id, i);
189 klog::Info(
"ConcurrentExitWorker {}: exiting", thread_id);
190 g_thread_completed++;
194void test_thread_group_concurrent_exit(
void* ) {
195 klog::Info(
"=== Thread Group Concurrent Exit Test ===");
197 g_thread_completed = 0;
199 auto leader_holder = kstd::make_unique<TaskControlBlock>(
200 "ConcurrentLeader", 10,
nullptr,
nullptr);
201 auto* leader = leader_holder.get();
203 leader->aux->tgid = 92000;
206 constexpr int kWorkerCount = 4;
207 for (
int i = 0; i < kWorkerCount; ++i) {
208 auto worker = kstd::make_unique<TaskControlBlock>(
209 "ConcurrentWorker", 10, concurrent_exit_worker,
210 reinterpret_cast<void*
>(i));
211 worker->pid = 92001 + i;
212 worker->JoinThreadGroup(leader);
213 TaskManagerSingleton::instance().AddTask(std::move(worker));
216 klog::Info(
"Started {} worker threads", kWorkerCount);
219 for (
int i = 0; i < 100 && g_thread_completed < kWorkerCount; ++i) {
223 klog::Info(
"Completed threads: {} (expected {})", g_thread_completed.load(),
226 bool passed = (g_thread_completed == kWorkerCount);
228 klog::Info(
"Thread Group Concurrent Exit Test: PASS");
230 klog::Err(
"Thread Group Concurrent Exit Test: FAIL");
244 klog::Info(
"=== Thread Group System Test Suite ===");
246 g_tests_completed = 0;
250 auto test1 = kstd::make_unique<TaskControlBlock>(
251 "TestThreadGroupBasic", 10, test_thread_group_basic,
nullptr);
252 TaskManagerSingleton::instance().AddTask(std::move(test1));
255 auto test2 = kstd::make_unique<TaskControlBlock>(
256 "TestThreadGroupDynamic", 10, test_thread_group_dynamic,
nullptr);
257 TaskManagerSingleton::instance().AddTask(std::move(test2));
260 auto test3 = kstd::make_unique<TaskControlBlock>(
261 "TestThreadGroupConcurrentExit", 10, test_thread_group_concurrent_exit,
263 TaskManagerSingleton::instance().AddTask(std::move(test3));
266 constexpr int kExpectedTests = 3;
268 while (timeout > 0) {
270 if (g_tests_completed >= kExpectedTests) {
276 EXPECT_EQ(g_tests_completed.load(), kExpectedTests,
277 "All thread group tests should complete");
278 EXPECT_EQ(g_tests_failed.load(), 0,
"No thread group tests should fail");
280 klog::Info(
"Thread Group System Test Suite: COMPLETED");
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
auto Debug(etl::format_string< Args... > fmt, Args &&... args) -> void
以 DEBUG 级别记录日志(SIMPLEKERNEL_MIN_LOG_LEVEL > 0 时编译期消除)
auto JoinThreadGroup(TaskControlBlock *leader) -> void
将线程添加到线程组
auto LeaveThreadGroup() -> void
从线程组中移除自己
auto sys_sleep(uint64_t ms) -> int
休眠指定毫秒数
auto sys_exit(int code) -> int
退出当前进程或线程
#define EXPECT_EQ(val1, val2, msg)
auto thread_group_system_test() -> bool
线程组系统测试入口