我有这个内核代码,我禁用中断使这个锁获取操作原子,但是如果你看到最后的其他条件,即当锁不可用时,线程进入休眠状态,只有在线程从睡眠状态恢复后才能启用中断。我的问题是,在整个操作系统中禁用中断,直到此线程退出睡眠状态?
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 }
答案 0 :(得分:1)
我不知道NACHOS,我不会自己做任何假设。所以你必须测试它。
这个想法很简单。如果此中断启用/禁用功能对于当前进程上下文是本地的,则在调用Sleep()
时应执行以下操作:
该进程被标记为未运行,即它被排除在scheduler
将考虑给CPU时间的进程列表中。然后Sleep()函数强制调度程序执行常规工作 - 找到要运行的进程。如果正在运行的进程列表不为空,则调度程序将选择下一个可用进程并将上下文切换到此进程。在此之后,从这个新的上下文恢复中断管理的状态。
如果没有要运行的进程,则调度程序进入Idle loop
状态,通常启用中断。当调度程序在Idle loop
时,它会继续轮询正在运行的进程的队列,直到它得到安排的内容。
当您的进程再次标记为正在运行时,它将获得控制权。如果某些其他进程调用WakeUp()
(或类似内容,因为我提到API我不知道),就会发生这种情况。
当调度程序选择要切换到的进程时,执行通常(对于您的系统)上下文切换,将interrupts enabled
标志设置为false,因此在{{1}之后的语句处继续执行调用中断禁用。
如果上述假设不正确并且Sleep()
标志是全局的,那么有两种可能性:系统因为无法提供中断而挂起,或者它有一些interrupts enabled
一种情况。
所以,你需要尝试。如果您有访问权限,最好的方法是阅读内核源代码。))