SimpleKernel 1.17.0
Loading...
Searching...
No Matches
thread_group_system_test.cpp
Go to the documentation of this file.
1
5#include <cpu_io.h>
6
7#include <atomic>
8#include <cstddef>
9#include <cstdint>
10
11#include "arch.h"
12#include "basic_info.hpp"
13#include "kernel.h"
14#include "kstd_cstring"
15#include "kstd_libcxx.h"
16#include "kstd_memory"
17#include "sk_stdlib.h"
18#include "syscall.hpp"
19#include "system_test.h"
21#include "task_manager.hpp"
22
23namespace {
24
25std::atomic<int> g_thread_counter{0};
26std::atomic<int> g_thread_completed{0};
27
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);
35
36 for (int i = 0; i < 10; ++i) {
37 g_thread_counter++;
38 klog::Debug("Thread {}: counter={}, iter={}", thread_id,
39 g_thread_counter.load(), i);
40 (void)sys_sleep(10);
41 }
42
43 g_thread_completed++;
44 klog::Info("Thread {}: completed", thread_id);
45 sys_exit(0);
46}
47
51void test_thread_group_basic(void* /*arg*/) {
52 klog::Info("=== Thread Group Basic Test ===");
53
54 g_thread_counter = 0;
55 g_thread_completed = 0;
56
57 auto leader_holder = kstd::make_unique<TaskControlBlock>(
58 "ThreadGroupLeader", 10, nullptr, nullptr);
59 auto* leader = leader_holder.get();
60 leader->pid = 90000;
61 leader->aux->tgid = 90000;
62
63 // 创建并加入线程组的线程
64 auto thread1 = kstd::make_unique<TaskControlBlock>(
65 "Thread1", 10, thread_increment, reinterpret_cast<void*>(1));
66 thread1->pid = 90001;
67 thread1->JoinThreadGroup(leader);
68
69 auto thread2 = kstd::make_unique<TaskControlBlock>(
70 "Thread2", 10, thread_increment, reinterpret_cast<void*>(2));
71 thread2->pid = 90002;
72 thread2->JoinThreadGroup(leader);
73
74 auto thread3 = kstd::make_unique<TaskControlBlock>(
75 "Thread3", 10, thread_increment, reinterpret_cast<void*>(3));
76 thread3->pid = 90003;
77 thread3->JoinThreadGroup(leader);
78
79 // 验证线程组大小
80 size_t group_size = leader->GetThreadGroupSize();
81 klog::Info("Thread group size: {} (expected 4)", group_size);
82
83 // 验证所有线程在同一线程组
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");
88 } else {
89 klog::Err("Thread group membership check failed: FAIL");
90 }
91
92 // 添加到调度器
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));
97
98 // 等待线程完成
99 for (int i = 0; i < 200 && g_thread_completed < 3; ++i) {
100 (void)sys_sleep(50);
101 }
102
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());
106
107 bool passed = (g_thread_completed == 3 && g_thread_counter >= 30);
108 if (passed) {
109 klog::Info("Thread Group Basic Test: PASS");
110 } else {
111 klog::Err("Thread Group Basic Test: FAIL");
112 g_tests_failed++;
113 }
114
115 g_tests_completed++;
116 sys_exit(0);
117}
118
122void test_thread_group_dynamic(void* /*arg*/) {
123 klog::Info("=== Thread Group Dynamic Test ===");
124
125 auto leader_holder = kstd::make_unique<TaskControlBlock>("DynamicLeader", 10,
126 nullptr, nullptr);
127 auto* leader = leader_holder.get();
128 leader->pid = 91000;
129 leader->aux->tgid = 91000;
130
131 constexpr int kThreadCount = 5;
132 etl::unique_ptr<TaskControlBlock> thread_holders[kThreadCount];
133 TaskControlBlock* threads[kThreadCount];
134
135 for (int i = 0; i < kThreadCount; ++i) {
136 thread_holders[i] = kstd::make_unique<TaskControlBlock>("DynamicThread", 10,
137 nullptr, nullptr);
138 threads[i] = thread_holders[i].get();
139 threads[i]->pid = 91001 + i;
140 }
141
142 // 动态加入
143 klog::Info("Joining threads...");
144 for (int i = 0; i < kThreadCount; ++i) {
145 threads[i]->JoinThreadGroup(leader);
146 size_t size = leader->GetThreadGroupSize();
147 klog::Debug("After join {}: group size={}", i, size);
148 }
149
150 size_t final_size = leader->GetThreadGroupSize();
151 klog::Info("Final group size: {} (expected {})", final_size,
152 kThreadCount + 1);
153
154 klog::Info("Leaving threads...");
155 for (int i = 0; i < kThreadCount; ++i) {
156 threads[i]->LeaveThreadGroup();
157 size_t size = leader->GetThreadGroupSize();
158 klog::Debug("After leave {}: group size={}", i, size);
159 }
160
161 size_t remaining_size = leader->GetThreadGroupSize();
162 klog::Info("Remaining group size: {} (expected 1)", remaining_size);
163
164 bool passed = (final_size == static_cast<size_t>(kThreadCount + 1) &&
165 remaining_size == 1);
166 if (passed) {
167 klog::Info("Thread Group Dynamic Test: PASS");
168 } else {
169 klog::Err("Thread Group Dynamic Test: FAIL");
170 g_tests_failed++;
171 }
172
173 g_tests_completed++;
174 sys_exit(0);
175}
176
180void concurrent_exit_worker(void* arg) {
181 uint64_t thread_id = reinterpret_cast<uint64_t>(arg);
182
183 // 执行一些工作
184 for (int i = 0; i < 5; ++i) {
185 klog::Debug("ConcurrentExitWorker {}: iter={}", thread_id, i);
186 (void)sys_sleep(20);
187 }
188
189 klog::Info("ConcurrentExitWorker {}: exiting", thread_id);
190 g_thread_completed++;
191 sys_exit(0);
192}
193
194void test_thread_group_concurrent_exit(void* /*arg*/) {
195 klog::Info("=== Thread Group Concurrent Exit Test ===");
196
197 g_thread_completed = 0;
198
199 auto leader_holder = kstd::make_unique<TaskControlBlock>(
200 "ConcurrentLeader", 10, nullptr, nullptr);
201 auto* leader = leader_holder.get();
202 leader->pid = 92000;
203 leader->aux->tgid = 92000;
204
205 // 创建多个工作线程
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));
214 }
215
216 klog::Info("Started {} worker threads", kWorkerCount);
217
218 // 等待所有线程完成
219 for (int i = 0; i < 100 && g_thread_completed < kWorkerCount; ++i) {
220 (void)sys_sleep(50);
221 }
222
223 klog::Info("Completed threads: {} (expected {})", g_thread_completed.load(),
224 kWorkerCount);
225
226 bool passed = (g_thread_completed == kWorkerCount);
227 if (passed) {
228 klog::Info("Thread Group Concurrent Exit Test: PASS");
229 } else {
230 klog::Err("Thread Group Concurrent Exit Test: FAIL");
231 g_tests_failed++;
232 }
233
234 g_tests_completed++;
235 sys_exit(0);
236}
237
238} // namespace
239
244 klog::Info("=== Thread Group System Test Suite ===");
245
246 g_tests_completed = 0;
247 g_tests_failed = 0;
248
249 // 测试 1: 基本线程组功能
250 auto test1 = kstd::make_unique<TaskControlBlock>(
251 "TestThreadGroupBasic", 10, test_thread_group_basic, nullptr);
252 TaskManagerSingleton::instance().AddTask(std::move(test1));
253
254 // 测试 2: 动态加入和离开
255 auto test2 = kstd::make_unique<TaskControlBlock>(
256 "TestThreadGroupDynamic", 10, test_thread_group_dynamic, nullptr);
257 TaskManagerSingleton::instance().AddTask(std::move(test2));
258
259 // 测试 3: 并发退出
260 auto test3 = kstd::make_unique<TaskControlBlock>(
261 "TestThreadGroupConcurrentExit", 10, test_thread_group_concurrent_exit,
262 nullptr);
263 TaskManagerSingleton::instance().AddTask(std::move(test3));
264
265 // 同步等待所有测试完成
266 constexpr int kExpectedTests = 3;
267 int timeout = 400;
268 while (timeout > 0) {
269 (void)sys_sleep(50);
270 if (g_tests_completed >= kExpectedTests) {
271 break;
272 }
273 timeout--;
274 }
275
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");
279
280 klog::Info("Thread Group System Test Suite: COMPLETED");
281 return true;
282}
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
从线程组中移除自己
Pid pid
线程 ID (Task ID)
auto sys_sleep(uint64_t ms) -> int
休眠指定毫秒数
Definition syscall.cpp:90
auto sys_exit(int code) -> int
退出当前进程或线程
Definition syscall.cpp:75
#define EXPECT_EQ(val1, val2, msg)
auto thread_group_system_test() -> bool
线程组系统测试入口