| 9 | #include "task_manager.hpp" |
| 10 | |
| 11 | auto Mutex::Lock() -> Expected<void> { |
| 12 | auto& tm = TaskManagerSingleton::instance(); |
| 13 | auto* current_task = tm.GetCurrentTask(); |
| 14 | if (current_task == nullptr) { |
| 15 | klog::Err("Mutex::Lock: Cannot lock mutex '{}' outside task context", name); |
| 16 | return std::unexpected(Error{ErrorCode::kMutexNoTaskContext}); |
| 17 | } |
| 18 | |
| 19 | Pid current_pid = current_task->pid; |
| 20 | |
| 21 | if (IsLockedByCurrentTask()) { |
| 22 | klog::Warn("Mutex::Lock: Task {} tried to recursively lock mutex '{}'", |
| 23 | current_pid, name); |
| 24 | return std::unexpected(Error{ErrorCode::kMutexRecursiveLock}); |
| 25 | } |
| 26 | |
| 27 | // 快速路径:尝试立即获取 |
| 28 | bool expected = false; |
| 29 | if (locked_.compare_exchange_strong(expected, true, std::memory_order_acquire, |
| 30 | std::memory_order_relaxed)) { |
| 31 | owner_.store(current_pid, std::memory_order_release); |
| 32 | klog::Debug("Mutex::Lock: Task {} acquired mutex '{}'", current_pid, name); |
| 33 | return {}; |
| 34 | } |
| 35 | |
| 36 | // 慢路径:在调度器锁保护下进行 re-check + block,防止丢失唤醒 |
| 37 | // @todo: 当前实现在高竞争下可能不公平——被唤醒的任务的 CAS 可能被快速路径 |
| 38 | // 的新到达者抢占,导致被唤醒任务重新 Block。考虑实现 handoff 模式: |
| 39 | // UnLock 直接将 owner_ 转移给被唤醒任务,避免竞争。 |
| 40 | while (true) { |
| 41 | { |
| 42 | auto& cpu_sched = tm.GetCurrentCpuSched(); |
| 43 | LockGuard<SpinLock> lock_guard(cpu_sched.lock); |
| 44 | |
| 45 | expected = false; |
| 46 | if (locked_.compare_exchange_strong(expected, true, |
| 47 | std::memory_order_acquire, |
| 48 | std::memory_order_relaxed)) { |
| 49 | owner_.store(current_pid, std::memory_order_release); |
| 50 | klog::Debug("Mutex::Lock: Task {} acquired mutex '{}' (re-check)", |
| 51 | current_pid, name); |
| 52 | return {}; |
| 53 | } |
| 54 | |
| 55 | klog::Debug("Mutex::Lock: Task {} blocking on mutex '{}'", current_pid, |
| 56 | name); |
| 57 | tm.Block(cpu_sched, resource_id_); |
| 58 | } |
| 59 | |
| 60 | tm.Schedule(); |
| 61 | |
| 62 | expected = false; |
| 63 | if (locked_.compare_exchange_strong(expected, true, |
| 64 | std::memory_order_acquire, |
| 65 | std::memory_order_relaxed)) { |
| 66 | owner_.store(current_pid, std::memory_order_release); |
| 67 | klog::Debug("Mutex::Lock: Task {} acquired mutex '{}' (after wake)", |
| 68 | current_pid, name); |