SimpleKernel 1.17.0
Loading...
Searching...
No Matches
spinlock_test.cpp
Go to the documentation of this file.
1
6#include "spinlock.hpp"
7
8#include <gmock/gmock.h>
9#include <gtest/gtest.h>
10
11#include <array>
12#include <format>
13#include <thread>
14#include <vector>
15
17
18namespace {
19
20// 测试用的全局变量
21static std::atomic<int> shared_counter{0};
22static std::atomic<int> thread_counter{0};
23
24// 测试辅助类:暴露 protected 成员用于测试验证
25class SpinLockTestable : public SpinLock {
26 public:
28 explicit SpinLockTestable(const char* name) : SpinLock(name) {}
29 SpinLockTestable() = default;
30};
31
32class SpinLockTest : public ::testing::Test {
33 protected:
34 void SetUp() override {
35 shared_counter = 0;
36 thread_counter = 0;
37
38 // 初始化环境层
39 env_state_.InitializeCores(8); // 支持多核测试(最多 8 核)
40 env_state_.SetCurrentThreadEnvironment();
41 env_state_.BindThreadToCore(std::this_thread::get_id(), 0);
42 }
43
44 void TearDown() override {
45 // 清理环境
46 env_state_.ClearCurrentThreadEnvironment();
47 }
48
50};
51
52// 测试基本的 lock/UnLock 功能
53TEST_F(SpinLockTest, BasicLockUnlock) {
54 SpinLockTestable lock("basic_test");
55
56 // 初始状态应该是未锁定的
57 EXPECT_TRUE(lock.Lock());
58
59 // 解锁应该成功
60 EXPECT_TRUE(lock.UnLock());
61}
62
63// 测试中断控制
64TEST_F(SpinLockTest, InterruptControl) {
65 SpinLockTestable lock("interrupt_test");
66
67 // 初始状态中断是开启的
69
70 (void)lock.Lock();
71 // 加锁后中断应该被禁用
73
74 (void)lock.UnLock();
75 // 解锁后中断应该被恢复
77}
78
79// 测试中断状态恢复
80TEST_F(SpinLockTest, InterruptRestore) {
81 SpinLockTestable lock("intr_restore_test");
82
83 // 模拟中断原本就是关闭的情况
86
87 (void)lock.Lock();
89
90 (void)lock.UnLock();
91 // 解锁后中断应该保持关闭(恢复原状)
93
94 // 清理:恢复中断
96}
97
98// 测试多线程并发安全性
99TEST_F(SpinLockTest, ConcurrentAccess) {
100 SpinLockTestable lock("concurrent_test");
101 const int num_threads = 4;
102 const int increments_per_thread = 1000;
103
104 std::vector<std::thread> threads;
105
106 for (int i = 0; i < num_threads; ++i) {
107 threads.emplace_back([this, &lock, increments_per_thread, i]() {
108 env_state_.SetCurrentThreadEnvironment();
109 env_state_.BindThreadToCore(std::this_thread::get_id(),
110 i % env_state_.GetCoreCount());
111 for (int j = 0; j < increments_per_thread; ++j) {
112 (void)lock.Lock();
113 int temp = shared_counter.load();
114 std::this_thread::sleep_for(std::chrono::microseconds(1));
115 shared_counter.store(temp + 1);
116 (void)lock.UnLock();
117 }
118 });
119 }
120
121 for (auto& thread : threads) {
122 thread.join();
123 }
124
125 // 如果锁工作正常,最终结果应该是精确的
126 EXPECT_EQ(shared_counter.load(), num_threads * increments_per_thread);
127}
128
129// 测试无锁的并发访问(验证锁确实有效)
130TEST_F(SpinLockTest, ConcurrentAccessWithoutLock) {
131 const int num_threads = 4;
132 const int increments_per_thread = 1000;
133
134 std::vector<std::thread> threads;
135
136 for (int i = 0; i < num_threads; ++i) {
137 threads.emplace_back([this, increments_per_thread, i]() {
138 env_state_.SetCurrentThreadEnvironment();
139 env_state_.BindThreadToCore(std::this_thread::get_id(),
140 i % env_state_.GetCoreCount());
141 for (int j = 0; j < increments_per_thread; ++j) {
142 // 不使用锁的并发访问
143 int temp = thread_counter.load();
144 std::this_thread::sleep_for(std::chrono::microseconds(1));
145 thread_counter.store(temp + 1);
146 }
147 });
148 }
149
150 for (auto& thread : threads) {
151 thread.join();
152 }
153
154 // 没有锁的情况下,结果通常不会是精确的(由于竞态条件)
155 // 这个测试可能会失败,这证明了锁的必要性
156 EXPECT_LE(thread_counter.load(), num_threads * increments_per_thread);
157}
158
159// 测试嵌套中断控制
160TEST_F(SpinLockTest, NestedInterruptControl) {
161 SpinLockTestable lock1("nested_test1");
162 SpinLockTestable lock2("nested_test2");
163
165
166 (void)lock1.Lock();
168
169 // 嵌套加锁
170 (void)lock2.Lock();
172
173 (void)lock2.UnLock();
174 EXPECT_FALSE(cpu_io::GetInterruptStatus()); // 仍然禁用
175
176 (void)lock1.UnLock();
178}
179
180// 测试递归加锁检测
181TEST_F(SpinLockTest, RecursiveLockDetection) {
182 SpinLockTestable lock("recursive_test");
183
184 // 第一次加锁应该成功
185 EXPECT_TRUE(lock.Lock());
186 EXPECT_TRUE(lock.IsLockedByCurrentCore());
187
188 // 在同一线程(模拟同一核心)再次加锁应该失败
189 EXPECT_FALSE(lock.Lock());
190
191 // 解锁
192 EXPECT_TRUE(lock.UnLock());
193 EXPECT_FALSE(lock.IsLockedByCurrentCore());
194}
195
196// 测试多个锁的独立性
197TEST_F(SpinLockTest, MultipleLockIndependence) {
198 SpinLockTestable lock1("independent_test1");
199 SpinLockTestable lock2("independent_test2");
200
201 // 锁1和锁2应该是独立的
202 (void)lock1.Lock();
203 EXPECT_TRUE(lock2.Lock());
204
205 (void)lock1.UnLock();
206 EXPECT_TRUE(lock2.UnLock());
207}
208
209// 性能测试:测试锁的获取和释放速度
210TEST_F(SpinLockTest, PerformanceTest) {
211 SpinLockTestable lock("performance_test");
212 const int iterations = 100000;
213
214 auto start = std::chrono::high_resolution_clock::now();
215
216 for (int i = 0; i < iterations; ++i) {
217 (void)lock.Lock();
218 (void)lock.UnLock();
219 }
220
221 auto end = std::chrono::high_resolution_clock::now();
222 auto duration =
223 std::chrono::duration_cast<std::chrono::microseconds>(end - start);
224
225 // 输出性能信息
226 std::cout << std::format(
227 "SpinLock performance: {} lock/UnLock pairs in {} microseconds\n",
228 iterations, duration.count());
229
230 // 基本的性能断言:应该能在合理时间内完成
231 EXPECT_LT(duration.count(), 1000000); // 少于1秒
232}
233
234// 测试异常情况
235TEST_F(SpinLockTest, EdgeCases) {
236 SpinLockTestable lock("edge_case_test");
237
238 // 测试快速连续的 lock/UnLock
239 for (int i = 0; i < 1000; ++i) {
240 (void)lock.Lock();
241 (void)lock.UnLock();
242 }
243
244 EXPECT_TRUE(cpu_io::GetInterruptStatus()); // 中断状态应该正确恢复
245}
246
247// 测试中断状态在锁持有期间保持关闭
248TEST_F(SpinLockTest, InterruptDisabledDuringLock) {
249 SpinLockTestable lock("interrupt_disabled_test");
250
252
253 (void)lock.Lock();
254
255 // 锁持有期间中断应该被禁用
257 EXPECT_TRUE(lock.IsLockedByCurrentCore());
258
259 (void)lock.UnLock();
260
261 // 解锁后中断应该恢复
263}
264
265// 测试锁的公平性(FIFO 顺序)
266TEST_F(SpinLockTest, FairnessTest) {
267 SpinLockTestable lock("fairness_test");
268 std::vector<int> execution_order;
269 std::mutex order_mutex;
270 const int num_threads = 5;
271
272 std::vector<std::thread> threads;
273
274 for (int i = 0; i < num_threads; ++i) {
275 threads.emplace_back([this, &lock, &execution_order, &order_mutex, i]() {
276 env_state_.SetCurrentThreadEnvironment();
277 env_state_.BindThreadToCore(std::this_thread::get_id(),
278 i % env_state_.GetCoreCount());
279 std::this_thread::sleep_for(std::chrono::milliseconds(i * 10));
280
281 (void)lock.Lock();
282 {
283 std::lock_guard<std::mutex> guard(order_mutex);
284 execution_order.push_back(i);
285 }
286 std::this_thread::sleep_for(std::chrono::milliseconds(10));
287 (void)lock.UnLock();
288 });
289 }
290
291 for (auto& thread : threads) {
292 thread.join();
293 }
294
295 // 验证所有线程都执行了
296 EXPECT_EQ(execution_order.size(), num_threads);
297}
298
299// 测试高负载下的锁性能
300TEST_F(SpinLockTest, HighLoadPerformance) {
301 SpinLockTestable lock("high_load_test");
302 const int num_threads = 8;
303 const int operations_per_thread = 1000;
304 std::atomic<int> total_operations{0};
305
306 std::vector<std::thread> threads;
307
308 for (int i = 0; i < num_threads; ++i) {
309 threads.emplace_back(
310 [this, &lock, operations_per_thread, &total_operations, i]() {
311 env_state_.SetCurrentThreadEnvironment();
312 env_state_.BindThreadToCore(std::this_thread::get_id(),
313 i % env_state_.GetCoreCount());
314 for (int j = 0; j < operations_per_thread; ++j) {
315 (void)lock.Lock();
316 total_operations.fetch_add(1);
317 (void)lock.UnLock();
318 }
319 });
320 }
321
322 for (auto& thread : threads) {
323 thread.join();
324 }
325
326 EXPECT_EQ(total_operations.load(), num_threads * operations_per_thread);
327}
328
329// 测试中断状态的嵌套保存和恢复
330TEST_F(SpinLockTest, NestedInterruptSaveRestore) {
331 SpinLockTestable lock1("nested1");
332 SpinLockTestable lock2("nested2");
333 SpinLockTestable lock3("nested3");
334
335 // 初始状态:中断开启
337
338 (void)lock1.Lock();
340
341 (void)lock2.Lock();
343
344 (void)lock3.Lock();
346
347 // 按相反顺序解锁
348 (void)lock3.UnLock();
350
351 (void)lock2.UnLock();
353
354 (void)lock1.UnLock();
355 EXPECT_TRUE(cpu_io::GetInterruptStatus()); // 恢复原始状态
356}
357
358// 测试零竞争情况
359TEST_F(SpinLockTest, NoContentionSingleThread) {
360 SpinLockTestable lock("no_contention");
361 const int iterations = 10000;
362
363 auto start = std::chrono::high_resolution_clock::now();
364
365 for (int i = 0; i < iterations; ++i) {
366 (void)lock.Lock();
367 shared_counter++;
368 (void)lock.UnLock();
369 }
370
371 auto end = std::chrono::high_resolution_clock::now();
372 auto duration =
373 std::chrono::duration_cast<std::chrono::microseconds>(end - start);
374
375 EXPECT_EQ(shared_counter.load(), iterations);
376
377 std::cout << std::format(
378 "Single thread (no contention): {} operations in {} microseconds\n",
379 iterations, duration.count());
380}
381
382// 测试锁持有时间过长的情况
383TEST_F(SpinLockTest, LongHoldTime) {
384 SpinLockTestable lock("long_hold");
385 std::atomic<bool> lock_held{false};
386 std::atomic<bool> waiter_started{false};
387 std::atomic<int> spin_count{0};
388
389 std::thread holder([this, &lock, &lock_held, &waiter_started]() {
390 env_state_.SetCurrentThreadEnvironment();
391 env_state_.BindThreadToCore(std::this_thread::get_id(),
392 1 % env_state_.GetCoreCount());
393 (void)lock.Lock();
394 lock_held = true;
395
396 // 等待 waiter 线程开始尝试获取锁
397 while (!waiter_started.load()) {
398 std::this_thread::yield();
399 }
400
401 // 持有锁一段时间
402 std::this_thread::sleep_for(std::chrono::milliseconds(50));
403 (void)lock.UnLock();
404 });
405
406 std::thread waiter([this, &lock, &lock_held, &spin_count, &waiter_started]() {
407 env_state_.SetCurrentThreadEnvironment();
408 env_state_.BindThreadToCore(std::this_thread::get_id(),
409 2 % env_state_.GetCoreCount());
410 // 等待直到第一个线程持有锁
411 while (!lock_held.load()) {
412 std::this_thread::yield();
413 }
414
415 waiter_started = true;
416
417 // 在尝试获取锁之前,开始计数自旋次数
418 auto start_time = std::chrono::steady_clock::now();
419
420 // 尝试获取锁(会自旋等待)
421 (void)lock.Lock();
422
423 auto end_time = std::chrono::steady_clock::now();
424 auto wait_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
425 end_time - start_time);
426
427 // 如果等待时间大于 10ms,说明确实等待了
428 if (wait_duration.count() > 10) {
429 spin_count.fetch_add(1);
430 }
431
432 (void)lock.UnLock();
433 });
434
435 holder.join();
436 waiter.join();
437
438 // 验证等待者确实等待了(等待时间应该大于 10ms)
439 EXPECT_GT(spin_count.load(), 0);
440}
441
442// 测试多线程的独立性
443TEST_F(SpinLockTest, MultipleThreads) {
444 SpinLockTestable lock("multi_thread");
445 std::vector<int> thread_results(4, 0);
446 std::vector<std::thread> threads;
447
448 for (int i = 0; i < 4; ++i) {
449 threads.emplace_back([this, &lock, &thread_results, i]() {
450 env_state_.SetCurrentThreadEnvironment();
451 env_state_.BindThreadToCore(std::this_thread::get_id(),
452 i % env_state_.GetCoreCount());
453 for (int j = 0; j < 100; ++j) {
454 (void)lock.Lock();
455 thread_results[i]++;
456 std::this_thread::sleep_for(std::chrono::microseconds(10));
457 (void)lock.UnLock();
458 }
459 });
460 }
461
462 for (auto& thread : threads) {
463 thread.join();
464 }
465
466 // 验证每个线程都完成了预期的操作
467 for (int i = 0; i < 4; ++i) {
468 EXPECT_EQ(thread_results[i], 100);
469 }
470}
471
472// 测试锁的状态一致性
473TEST_F(SpinLockTest, StateConsistency) {
474 SpinLockTestable lock("consistency");
475
476 // 初始状态
478
479 // 加锁
480 (void)lock.Lock();
482
483 // 解锁
484 (void)lock.UnLock();
486
487 // 多次循环验证状态一致性
488 for (int i = 0; i < 100; ++i) {
489 (void)lock.Lock();
491 (void)lock.UnLock();
493 }
494}
495
496} // namespace
void * end[]
内核结束
自旋锁
Definition spinlock.hpp:27
__always_inline auto IsLockedByCurrentCore() -> bool
检查当前 core 是否获得此锁
Definition spinlock.hpp:115
TEST_F(KernelFdtTest, ConstructorTest)
void DisableInterrupt()
Definition cpu_io.h:41
bool GetInterruptStatus()
Definition cpu_io.h:48
void EnableInterrupt()
Definition cpu_io.h:34
#define EXPECT_TRUE(cond, msg)
#define EXPECT_LE(val1, val2, msg)
#define EXPECT_LT(val1, val2, msg)
#define EXPECT_FALSE(cond, msg)
#define EXPECT_GT(val1, val2, msg)
#define EXPECT_EQ(val1, val2, msg)