当线程使内核禁用中断然后该线程进入休眠状态时会发生什么

时间:2012-09-25 21:46:03

标签: locking kernel interrupt thread-sleep

我有这个内核代码,我禁用中断使这个锁获取操作原子,但是如果你看到最后的其他条件,即当锁不可用时,线程进入休眠状态,只有在线程从睡眠状态恢复后才能启用中断。我的问题是,在整个操作系统中禁用中断,直到此线程退出睡眠状态?


void Lock::Acquire() 
{
    IntStatus oldLevel = interrupt->SetLevel(IntOff); // Disabling the interrups          to make the following statements atomic
    if(lockOwnerThread == currentThread)            //Checking if the requesting thread already owns lock
    {
        //printf("SM:error:%s already owns the lock\n",currentThread->getName());
        DEBUG('z', "SM:error:%s already owns the lock\n",currentThread->getName());
        (void) interrupt->SetLevel(oldLevel);
        return;
    }
    if(lockOwnerThread==NULL)
    {
       lockOwnerThread = currentThread;          // Lock owner ship is given to current  thread
       DEBUG('z', "SM:The ownership of the lock %s is given to %s \n",name,currentThread->getName());
    }
    else
    {
        DEBUG('z', "SM:Adding thread %s to request queue and putting it to sleep\n",currentThread->getName());
        queueForLock->Append((void *)currentThread);    // Lock is busy so add the thread to queue;
        currentThread->Sleep(); // And go to sleep
    }
       (void) interrupt->SetLevel(oldLevel); // Enable  the interrupts
 }

1 个答案:

答案 0 :(得分:1)

我不知道NACHOS,我不会自己做任何假设。所以你必须测试它。

这个想法很简单。如果此中断启用/禁用功能对于当前进程上下文是本地的,则在调用Sleep()时应执行以下操作: 该进程被标记为未运行,即它被排除在scheduler将考虑给CPU时间的进程列表中。然后Sleep()函数强制调度程序执行常规工作 - 找到要运行的进程。如果正在运行的进程列表不为空,则调度程序将选择下一个可用进程并将上下文切换到此进程。在此之后,从这个新的上下文恢复中断管理的状态。

如果没有要运行的进程,则调度程序进入Idle loop状态,通常启用中断。当调度程序在Idle loop时,它会继续轮询正在运行的进程的队列,直到它得到安排的内容。

当您的进程再次标记为正在运行时,它将获得控制权。如果某些其他进程调用WakeUp()(或类似内容,因为我提到API我不知道),就会发生这种情况。

当调度程序选择要切换到的进程时,执行通常(对于您的系统)上下文切换,将interrupts enabled标志设置为false,因此在{{1}之后的语句处继续执行调用中断禁用。

如果上述假设不正确并且Sleep()标志是全局的,那么有两种可能性:系统因为无法提供中断而挂起,或者它有一些interrupts enabled一种情况。

所以,你需要尝试。如果您有访问权限,最好的方法是阅读内核源代码。))