⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 synch-sem.cc

📁 nachos下线程与同步的实验
💻 CC
字号:
#include "copyright.h"
#include "synch.h"
#include "system.h"

//----------------------------------------------------------------------
// Semaphore::Semaphore
// 	Initialize a semaphore, so that it can be used for synchronization.
//
//	"debugName" is an arbitrary name, useful for debugging.
//	"initialValue" is the initial value of the semaphore.
//----------------------------------------------------------------------

Semaphore::Semaphore(char* debugName, int initialValue)
{
    name = debugName;
    value = initialValue;
    queue = new List;
}

//----------------------------------------------------------------------
// Semaphore::Semaphore
// 	De-allocate semaphore, when no longer needed.  Assume no one
//	is still waiting on the semaphore!
//----------------------------------------------------------------------

Semaphore::~Semaphore()
{
    delete queue;
}

//----------------------------------------------------------------------
// Semaphore::P
// 	Wait until semaphore value > 0, then decrement.  Checking the
//	value and decrementing must be done atomically, so we
//	need to disable interrupts before checking the value.
//
//	Note that Thread::Sleep assumes that interrupts are disabled
//	when it is called.
//----------------------------------------------------------------------

void
Semaphore::P()
{
    IntStatus oldLevel = interrupt->SetLevel(IntOff);	//禁用中断 
    
    while (value == 0) { 			// semaphore not available
	queue->Append((void *)currentThread);	// so go to sleep
	currentThread->Sleep();
    } 
    value--; 					// semaphore available, 
						// consume its value
    
    (void) interrupt->SetLevel(oldLevel);	//恢复中断 
}

//----------------------------------------------------------------------
// Semaphore::V
// 	Increment semaphore value, waking up a waiter if necessary.
//	As with P(), this operation must be atomic, so we need to disable
//	interrupts.  Scheduler::ReadyToRun() assumes that threads
//	are disabled when it is called.
//----------------------------------------------------------------------

void
Semaphore::V()
{
    Thread *thread;
    IntStatus oldLevel = interrupt->SetLevel(IntOff); //禁用中断 

    thread = (Thread *)queue->Remove();
    if (thread != NULL)	   // make thread ready, consuming the V immediately
	scheduler->ReadyToRun(thread);
    value++;
    (void) interrupt->SetLevel(oldLevel); //恢复中断 
}

Lock::Lock(char* debugName)  //initialize lock to be FREE
{
    name = debugName;
    HoldThread = new Thread("HoldThread");
    Hold = 0;
    threadnum = 0;
    semaphore = new Semaphore("locksem",0);
}

Lock::~Lock() //析构函数 
{
    delete HoldThreak;
    delete semaphore;
}

void 
Lock::Acquire()  //wait until the lock is FREE, then set it to BUSY
{
     ASSERT( !isHeldByCurrentThread );  //check the lock if FREE
     IntStatus oldL = interrupt->SetLevel(IntOff);  //禁用中断
     
     while ( Hold )
           semaphore->P();
     HoldThread = currentThread;
     Hold = 1;
     (void) interrupt->SetLevel(oldL); //恢复中断 
}

void 
Lock::Release()  //set lock to be FREE, waking up a thread waiting
{
     ASSERT( isHeldByCurrentThread());  //check the lock if BUSY
     IntStatus oldL = interrupt->SetLevel(IntOff);  //禁用中断
     
     HoldThread = NULL;
     Hold = 0;
     semaphore->V();
     (void) interrupt->SetLevel(oldL);  //恢复中断 
}

bool 
isHeldByCurrentThread()
{
     if ( HoldThread == currentThread && Hold )
          return true;
     else 
          return false;
}

Condition::Condition(char* debugName) //initialize condition to "no one waiting"
{
     name = debugName;
     semaphore = new Semaphore("Conditionsem",0);
}

Condition::~Condition()
{
     delete semaphore;
}

void 
Condition::Wait(Lock* conditionLock) 
//release the lock, relinquish the CPU until signaled,then re-acquire the lock
{
     ASSERT( conditionLock->isHeldByCurrentThread()); //check the lock if held
     IntStatus oldL = interrupt->SetLevel(IntOff); //禁用中断
     
     conditionLock->Release();
     semaphore->P();
     threadnum++;
     conditionLock->Acquire();
     (void) interrupt->SetLever(oldL); //恢复中断 
}

void 
Condition::Signal() //wake up a thread,if there are any waiting on the condition
{
    ASSERT( conditionLock->isHeldByCurrentThread());
    IntStatus oldLeve = interrupt->SetLevel(IntOff);
    if ( threadnum > 0 )
    {
         semaphore->V();
         threadnum--;
    }
    (void) interrupt->SetLevel(oldLeve);
}

void 
Condition::Broadcast()  //wake up all threads waiting on the condition
{
     ASSERT( conditionLock->isHeldByCurrentThread());
     IntStatus odlLeve = interrupt->SetLevel(IntOff);
     while ( threadnum > 0 )
     {
           semaphore->V();
           threadnum--;
     }
     (void) interrupt->SetLevel(oldLeve);
}
           

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -