Skip to content

[Bug] 关于smp环境下内核中信号处理部分锁相关问题 #10547

@eatvector

Description

@eatvector

RT-Thread Version

master

Hardware Type/Architectures

all

Develop Toolchain

Other

Describe the bug

  1. _signal_deliver 部分代码
  //获取信号自旋锁
   level = rt_spin_lock_irqsave(&_thread_signal_lock);

    /* thread is not interested in pended signals */
    if (!(tid->sig_pending & tid->sig_mask))
    {
        rt_spin_unlock_irqrestore(&_thread_signal_lock, level);
        return;
    }

 //没有获取调度器自旋锁 _mp_scheduler_lock的情况下读取调度相关状态位
// 其他核心可能同时修改这个字段

    if ((RT_SCHED_CTX(tid).stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK)
    {
        /* resume thread to handle signal */
#ifdef RT_USING_SMART
        rt_thread_wakeup(tid);
#else
        rt_thread_resume(tid);
#endif
        /* add signal state */
        RT_SCHED_CTX(tid).stat |= (RT_THREAD_STAT_SIGNAL | RT_THREAD_STAT_SIGNAL_PENDING);

        rt_spin_unlock_irqrestore(&_thread_signal_lock, level);

        /* re-schedule */
        rt_schedule();
    }

对于上面的代码,我存在两点疑惑,如果有大佬能解答,十分感激:

  1. 能通过两个不同自旋锁保护状态字的不同位域吗?如使用 _mp_scheduler_lock保护调度相关的状态位域,通过 _thread_signal_lock保护信号相关位域。

  2. 为什么上面代码在读取调度相关位域时没有加 _mp_scheduler_lock 进行保护,而是直接读取判断 if ((RT_SCHED_CTX(tid).stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK),我注意到另外一个函数的实现是要求持有 _mp_scheduler_lock 的:

rt_uint8_t rt_sched_thread_is_suspended(struct rt_thread *thread)
{
    RT_SCHED_DEBUG_IS_LOCKED;// 检测是否持有  _mp_scheduler_lock
    return (RT_SCHED_CTX(thread).stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK;
}

Other additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions