You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OS开发:键盘中断处理程序中自旋锁引发死锁问题排查

问题分析与解决

核心死锁原因

单CPU环境下,自旋锁临界区未配合中断禁用是导致死锁的根本原因:
当主循环持有自旋锁时,若此时键盘中断触发,CPU会立即暂停主循环,转而执行中断处理程序。中断处理程序尝试获取同一把锁时,发现锁已被持有,便进入自旋等待;但被中断挂起的主循环无法继续执行,自然无法释放锁——双方陷入永久等待,最终导致系统卡死,键盘缓冲区因无法处理而溢出。

具体代码问题点

  1. 主循环持有自旋锁时未禁用中断,导致持有锁期间可能被键盘中断抢占;
  2. 中断处理程序手动执行__cli()/__sti(),但未解决主循环侧的中断抢占问题,反而可能导致中断状态混乱。

修复方案

1. 修改自旋锁实现,自动管理中断状态

修改汇编代码,让自旋锁在加锁时保存当前中断状态并禁用中断,解锁时恢复原状态,从根源避免持有锁时被中断抢占:

__spinlock_lock:
    pushfq                  ; 保存当前标志寄存器(包含中断使能位IF)
    cli                     ; 禁用中断,防止持有锁时被抢占
.lock_loop:
    lock bts word [rcx], 0  ; 原子尝试设置锁的第0位
    jnc .acquired           ; 若成功获取锁(CF=0),跳转到返回逻辑
.wait:
    test word [rcx], 0      ; 检查锁是否已释放
    jnz .wait               ; 未释放则继续自旋等待
    jmp .lock_loop          ; 锁已释放,再次尝试获取
.acquired:
    ret                     ; 返回,此时锁已持有,中断处于禁用状态

__spinlock_unlock:
    lock btr word [rcx], 0  ; 原子清除锁的第0位,释放锁
    popfq                   ; 恢复加锁前的中断状态
    ret

2. 移除中断处理程序中的手动中断控制

自旋锁现在会自动管理中断状态,无需手动执行__cli()/__sti(),修改后的中断处理函数:

_Use_decl_annotations_
bool
HandleKeyboard(
    _In_ const BYTE Index,
    _In_ const PINTERRUPT_STACK Stack,
    _In_ const BYTE HasError,
    _In_ const PINTERRUPT_CPU_STATE Cpu
)
{
    (void)Index;
    (void)Stack;
    (void)HasError;
    (void)Cpu;

    if (const auto key = Pic::PicManager::keyboard.GetKeyPress(); key.hasValue)
    {
        auto& [capitalize, keyLock, currentKey, wakeUp] = Pic::PicManager::keyboard;
        Sync::Guard guard(keyLock);

        currentKey = key.inner;
        wakeUp = true;
    }

    return true;
}

3. 优化主循环的等待逻辑(可选)

原主循环在锁内空转浪费CPU资源,可在无按键时释放锁并休眠,直到中断触发唤醒CPU:

while (true)
{
    auto& [capitalize, keyLock, currentKey, wakeUp] = Pic::PicManager::keyboard;
    Sync::Guard guard(keyLock);

    if (!wakeUp || currentKey == 0)
    {
        guard.~Guard(); // 手动提前释放锁,避免休眠时持有锁
        __hlt(); // 休眠,直到中断触发唤醒CPU
        continue;
    }
    
    // 此处添加按键处理逻辑
    
    currentKey = 0;
    wakeUp = false;
}

内容的提问来源于stack exchange,提问作者Toma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 22:47:08