SimpleKernel 1.17.0
Loading...
Searching...
No Matches
mutex.cpp
Go to the documentation of this file.
1
5#include "mutex.hpp"
6
7#include "kernel.h"
8#include "kernel_log.hpp"
9#include "task_manager.hpp"
10
12 auto current_task = TaskManagerSingleton::instance().GetCurrentTask();
13 if (current_task == nullptr) {
14 klog::Err("Mutex::Lock: Cannot lock mutex '{}' outside task context", name);
15 return std::unexpected(Error{ErrorCode::kMutexNoTaskContext});
16 }
17
18 Pid current_pid = current_task->pid;
19
20 if (IsLockedByCurrentTask()) {
21 klog::Warn("Mutex::Lock: Task {} tried to recursively lock mutex '{}'",
22 current_pid, name);
23 return std::unexpected(Error{ErrorCode::kMutexRecursiveLock});
24 }
25
26 bool expected = false;
27 while (!locked_.compare_exchange_weak(
28 expected, true, std::memory_order_acquire, std::memory_order_relaxed)) {
29 klog::Debug("Mutex::Lock: Task {} blocking on mutex '{}'", current_pid,
30 name);
31 TaskManagerSingleton::instance().Block(resource_id_);
32
33 expected = false;
34 }
35
36 owner_.store(current_pid, std::memory_order_release);
37 klog::Debug("Mutex::Lock: Task {} acquired mutex '{}'", current_pid, name);
38 return {};
39}
40
42 auto current_task = TaskManagerSingleton::instance().GetCurrentTask();
43 if (current_task == nullptr) {
44 klog::Err("Mutex::UnLock: Cannot unlock mutex '{}' outside task context",
45 name);
46 return std::unexpected(Error{ErrorCode::kMutexNoTaskContext});
47 }
48
49 Pid current_pid = current_task->pid;
50
51 if (!IsLockedByCurrentTask()) {
53 "Mutex::UnLock: Task {} tried to unlock mutex '{}' it doesn't own",
54 current_pid, name);
55 return std::unexpected(Error{ErrorCode::kMutexNotOwned});
56 }
57
58 owner_.store(std::numeric_limits<Pid>::max(), std::memory_order_release);
59 locked_.store(false, std::memory_order_release);
60
61 klog::Debug("Mutex::UnLock: Task {} released mutex '{}'", current_pid, name);
62
63 TaskManagerSingleton::instance().Wakeup(resource_id_);
64
65 return {};
66}
67
69 auto current_task = TaskManagerSingleton::instance().GetCurrentTask();
70 if (current_task == nullptr) {
71 klog::Err("Mutex::TryLock: Cannot trylock mutex '{}' outside task context",
72 name);
73 return std::unexpected(Error{ErrorCode::kMutexNoTaskContext});
74 }
75
76 Pid current_pid = current_task->pid;
77
78 if (IsLockedByCurrentTask()) {
80 "Mutex::TryLock: Task {} tried to recursively trylock mutex '{}'",
81 current_pid, name);
82 return std::unexpected(Error{ErrorCode::kMutexRecursiveLock});
83 }
84
85 bool expected = false;
86 if (locked_.compare_exchange_strong(expected, true, std::memory_order_acquire,
87 std::memory_order_relaxed)) {
88 owner_.store(current_pid, std::memory_order_release);
89 klog::Debug("Mutex::TryLock: Task {} acquired mutex '{}'", current_pid,
90 name);
91 return {};
92 }
93
94 klog::Debug("Mutex::TryLock: Task {} failed to acquire mutex '{}'",
95 current_pid, name);
96 return std::unexpected(Error{ErrorCode::kMutexNotLocked});
97}
98
99auto Mutex::IsLockedByCurrentTask() const -> bool {
100 auto current_task = TaskManagerSingleton::instance().GetCurrentTask();
101 if (current_task == nullptr) {
102 return false;
103 }
104
105 return locked_.load(std::memory_order_acquire) &&
106 owner_.load(std::memory_order_acquire) == current_task->pid;
107}
std::atomic< Pid > owner_
持有锁的任务 ID,max() 表示未被持有
Definition mutex.hpp:90
auto Lock() -> Expected< void >
获取锁(阻塞)
Definition mutex.cpp:11
auto IsLockedByCurrentTask() const -> bool
检查锁是否被当前线程持有
Definition mutex.cpp:99
auto UnLock() -> Expected< void >
释放锁
Definition mutex.cpp:41
std::atomic< bool > locked_
锁状态
Definition mutex.hpp:87
auto TryLock() -> Expected< void >
尝试获取锁(非阻塞)
Definition mutex.cpp:68
@ kMutexNoTaskContext
@ kMutexRecursiveLock
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
auto Debug(etl::format_string< Args... > fmt, Args &&... args) -> void
以 DEBUG 级别记录日志(SIMPLEKERNEL_MIN_LOG_LEVEL > 0 时编译期消除)
auto Warn(etl::format_string< Args... > fmt, Args &&... args) -> void
以 WARN 级别记录日志
错误类型,用于 std::expected
Definition expected.hpp:343
size_t Pid
进程 ID 类型