| 11 | #include "task_messages.hpp" |
| 12 | |
| 13 | auto TaskManager::SendSignal(Pid pid, int signum) -> Expected<void> { |
| 14 | if (!SignalState::IsValid(signum)) { |
| 15 | return std::unexpected(Error{ErrorCode::kSignalInvalidNumber}); |
| 16 | } |
| 17 | |
| 18 | // 查找目标任务 |
| 19 | TaskControlBlock* target = nullptr; |
| 20 | { |
| 21 | LockGuard<SpinLock> lock_guard(task_table_lock_); |
| 22 | auto it = task_table_.find(pid); |
| 23 | if (it == task_table_.end()) { |
| 24 | return std::unexpected(Error{ErrorCode::kSignalTaskNotFound}); |
| 25 | } |
| 26 | target = it->second.get(); |
| 27 | } |
| 28 | |
| 29 | if (!target || !target->aux) { |
| 30 | return std::unexpected(Error{ErrorCode::kSignalTaskNotFound}); |
| 31 | } |
| 32 | |
| 33 | target->aux->signals.SetPending(signum); |
| 34 | |
| 35 | klog::Debug("SendSignal: signal {} ({}) sent to pid={}", |
| 36 | SignalState::GetSignalName(signum), signum, pid); |
| 37 | |
| 38 | // SIGKILL 和 SIGCONT 需要立即唤醒阻塞/睡眠的任务 |
| 39 | bool needs_wake = |
| 40 | (signum == signal_number::kSigKill || signum == signal_number::kSigCont); |
| 41 | |
| 42 | // 如果信号未被屏蔽,也需要唤醒 |
| 43 | if (!needs_wake && |
| 44 | !(target->aux->signals.blocked.load(std::memory_order_acquire) & |
| 45 | (1U << signum))) { |
| 46 | auto status = target->GetStatus(); |
| 47 | if (status == TaskStatus::kBlocked || status == TaskStatus::kSleeping) { |
| 48 | needs_wake = true; |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | if (needs_wake) { |
| 53 | auto status = target->GetStatus(); |
| 54 | |
| 55 | if (status == TaskStatus::kBlocked) { |
| 56 | auto resource_id = target->aux->blocked_on; |
| 57 | if (static_cast<bool>(resource_id)) { |
| 58 | Wakeup(resource_id); |
| 59 | klog::Debug("SendSignal: woke blocked task pid={} for signal {}", pid, |
| 60 | SignalState::GetSignalName(signum)); |
| 61 | } |
| 62 | } else if (status == TaskStatus::kSleeping) { |
| 63 | // Expedite wake: set wake_tick to 0 so next TickUpdate wakes it. |
| 64 | // Note: single aligned 64-bit store is atomic on 64-bit platforms. |
| 65 | target->sched_info.wake_tick = 0; |
| 66 | klog::Debug("SendSignal: expedited sleep wakeup for pid={}", pid); |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | return {}; |
no test coverage detected