SimpleKernel 1.17.0
Loading...
Searching...
No Matches
Mutex Class Reference

互斥锁(Mutex) More...

#include <mutex.hpp>

Collaboration diagram for Mutex:
Collaboration graph

Public Member Functions

auto Lock () -> Expected< void >
 获取锁(阻塞)
 
auto UnLock () -> Expected< void >
 释放锁
 
auto TryLock () -> Expected< void >
 尝试获取锁(非阻塞)
 
auto IsLockedByCurrentTask () const -> bool
 检查锁是否被当前线程持有
 
构造/析构函数
 Mutex (const char *_name)
 
 Mutex ()=default
 
 Mutex (const Mutex &)=delete
 
 Mutex (Mutex &&)=delete
 
auto operator= (const Mutex &) -> Mutex &=delete
 
auto operator= (Mutex &&) -> Mutex &=delete
 
 ~Mutex ()=default
 

Public Attributes

const char * name {"unnamed_mutex"}
 锁的名称
 

Protected Attributes

std::atomic< bool > locked_ {false}
 锁状态
 
std::atomic< Pidowner_ {std::numeric_limits<Pid>::max()}
 持有锁的任务 ID,max() 表示未被持有
 
ResourceId resource_id_ {}
 资源 ID,用于任务阻塞队列
 

Detailed Description

互斥锁(Mutex)

实现基于任务调度的互斥锁:

  • 当锁被占用时,请求线程会被阻塞并进入等待队列
  • 当锁释放时,会唤醒一个等待线程
  • 支持所有者跟踪和递归检测
Note
使用限制:
  1. 不可重入:同一线程不能递归获取同一锁
  2. 所有权:必须由获取锁的线程释放锁
  3. 阻塞语义:获取锁失败时会阻塞当前任务
  4. 必须在任务上下文中使用:不能在中断处理程序中使用

Definition at line 30 of file mutex.hpp.

Constructor & Destructor Documentation

◆ Mutex() [1/4]

Mutex::Mutex ( const char *  _name)
inlineexplicit

Definition at line 73 of file mutex.hpp.

74 : name(_name),
75 resource_id_(ResourceType::kMutex, reinterpret_cast<uint64_t>(this)) {}
const char * name
锁的名称
Definition mutex.hpp:33
ResourceId resource_id_
资源 ID,用于任务阻塞队列
Definition mutex.hpp:93
@ kMutex
互斥锁

◆ Mutex() [2/4]

Mutex::Mutex ( )
default

◆ Mutex() [3/4]

Mutex::Mutex ( const Mutex )
delete

◆ Mutex() [4/4]

Mutex::Mutex ( Mutex &&  )
delete

◆ ~Mutex()

Mutex::~Mutex ( )
default

Member Function Documentation

◆ IsLockedByCurrentTask()

auto Mutex::IsLockedByCurrentTask ( ) const -> bool

检查锁是否被当前线程持有

Returns
true 当前线程持有锁
false 当前线程未持有锁

Definition at line 99 of file mutex.cpp.

99 {
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
std::atomic< bool > locked_
锁状态
Definition mutex.hpp:87

◆ Lock()

auto Mutex::Lock ( ) -> Expected<void>

获取锁(阻塞)

如果锁已被其他线程持有,当前线程将被阻塞直到锁可用。 如果当前线程已持有锁,返回错误(不支持递归)。

Returns
Expected<void> 成功返回空值,失败返回错误

Definition at line 11 of file mutex.cpp.

11 {
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
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}
auto IsLockedByCurrentTask() const -> bool
检查锁是否被当前线程持有
Definition mutex.cpp:99
@ kMutexNoTaskContext
@ kMutexRecursiveLock
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 类型
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=() [1/2]

auto Mutex::operator= ( const Mutex ) -> Mutex &=delete
delete

◆ operator=() [2/2]

auto Mutex::operator= ( Mutex &&  ) -> Mutex &=delete
delete

◆ TryLock()

auto Mutex::TryLock ( ) -> Expected<void>

尝试获取锁(非阻塞)

尝试获取锁,如果锁不可用则立即返回。

Returns
Expected<void> 成功返回空值,失败返回错误

Definition at line 68 of file mutex.cpp.

68 {
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
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}
Here is the call graph for this function:

◆ UnLock()

auto Mutex::UnLock ( ) -> Expected<void>

释放锁

释放锁并唤醒一个等待线程(如果有)。 只能由持有锁的线程调用。

Returns
Expected<void> 成功返回空值,失败返回错误

Definition at line 41 of file mutex.cpp.

41 {
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}
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ locked_

std::atomic<bool> Mutex::locked_ {false}
protected

锁状态

Definition at line 87 of file mutex.hpp.

87{false};

◆ name

const char* Mutex::name {"unnamed_mutex"}

锁的名称

Definition at line 33 of file mutex.hpp.

33{"unnamed_mutex"};

◆ owner_

std::atomic<Pid> Mutex::owner_ {std::numeric_limits<Pid>::max()}
protected

持有锁的任务 ID,max() 表示未被持有

Definition at line 90 of file mutex.hpp.

90{std::numeric_limits<Pid>::max()};

◆ resource_id_

ResourceId Mutex::resource_id_ {}
protected

资源 ID,用于任务阻塞队列

Definition at line 93 of file mutex.hpp.

93{};

The documentation for this class was generated from the following files: