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

📄 synch-sleep.cc

📁 nachos test nachos 有关实验
💻 CC
字号:
// synch.cc //	Routines for synchronizing threads.  Three kinds of//	synchronization routines are defined here: semaphores, locks //   	and condition variables (the implementation of the last two//	are left to the reader).//// Any implementation of a synchronization routine needs some// primitive atomic operation.  We assume Nachos is running on// a uniprocessor, and thus atomicity can be provided by// turning off interrupts.  While interrupts are disabled, no// context switch can occur, and thus the current thread is guaranteed// to hold the CPU throughout, until interrupts are reenabled.//// Because some of these routines might be called with interrupts// already disabled (Semaphore::V for one), instead of turning// on interrupts at the end of the atomic operation, we always simply// re-set the interrupt state back to its original value (whether// that be disabled or enabled).//// Copyright (c) 1992-1993 The Regents of the University of California.// All rights reserved.  See copyright.h for copyright notice and limitation // of liability and disclaimer of warranty provisions.#include "copyright.h"#include "synch-sleep.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.//----------------------------------------------------------------------voidSemaphore::P(){    IntStatus oldLevel = interrupt->SetLevel(IntOff);	// disable interrupts        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);	// re-enable interrupts}//----------------------------------------------------------------------// 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.//----------------------------------------------------------------------voidSemaphore::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);}// Dummy functions -- so we can compile our later assignments // Note -- without a correct implementation of Condition::Wait(), // the test case in the network assignment won't work!*///--------------------------------------------------------------------------Lock::Lock(char* debugName) {     name = debugName;    now = Free;    lockqueue = new List;    holdthread = NULL;}//-------------------------------------------------------------------------Lock::~Lock() {    delete lockqueue;}//-------------------------------------------------------------------------void Lock::Acquire() {   IntStatus oldLevel = interrupt->SetLevel(IntOff);	// disable interrupts       while (now == Busy) { 			// semaphore not available	lockqueue->Append((void *)currentThread);	// so go to sleep	currentThread->Sleep();      }    DEBUG('t', "thread \"%s\" acquire the lock\n", currentThread->getName());    now = Busy; 					// lock is available,     holdthread = currentThread;	            					// consume its status    (void) interrupt->SetLevel(oldLevel);	// re-enable interrupts}//-------------------------------------------------------------------------void Lock::Release() {             if(isHeldByCurrentThread()){    Thread *thread;    IntStatus oldLevel = interrupt->SetLevel(IntOff);    thread = (Thread *)lockqueue->Remove();    if (thread != NULL)	   // make thread ready, consuming the V immediately	 scheduler->ReadyToRun(thread);    DEBUG('t', "thread \"%s\" release the lock\n", currentThread->getName());    now = Free;    holdthread = NULL;    (void) interrupt->SetLevel(oldLevel);           }    else return;}//--------------------------------------------------------------------------bool Lock::isHeldByCurrentThread(){   if (holdthread == currentThread)
        return TRUE;
    else
	return FALSE;}//----------------------------------------------------------------------------Condition::Condition(char* debugName) {    name = debugName;    blockqueue = new List;}//-----------------------------------------------------------------------------Condition::~Condition() {    delete blockqueue;}//-----------------------------------------------------------------------------void Condition::Wait(Lock* conditionLock) {    //ASSERT(FALSE);    IntStatus oldLevel = interrupt->SetLevel(IntOff);     conditionLock->Release();    DEBUG('t', "thread \"%s\" wait on the condition\n", currentThread->getName());    blockqueue->Append((void *)currentThread);	// so go to sleep	 currentThread->Sleep();    conditionLock->Acquire();    (void) interrupt->SetLevel(oldLevel);}//-----------------------------------------------------------------------------void Condition::Signal(Lock* conditionLock) {    Thread *thread;    IntStatus oldLevel = interrupt->SetLevel(IntOff);    thread = (Thread *)blockqueue->Remove();    if (thread != NULL)	   // make thread ready	 {DEBUG('t', "thread \"%s\" signal on the condition\n", currentThread->getName());    conditionLock->lockqueue->Append((void *)thread);}    (void) interrupt->SetLevel(oldLevel);}//------------------------------------------------------------------------------void Condition::Broadcast(Lock* conditionLock) {   Thread *thread;    IntStatus oldLevel = interrupt->SetLevel(IntOff);    while((thread = (Thread *)blockqueue->Remove())!=NULL)    {DEBUG('t', "thread \"%s\" signal on the condition\n", currentThread->getName());	 conditionLock->lockqueue->Append((void *)thread);}    (void) interrupt->SetLevel(oldLevel);}//------------------------------------------------------------------------------

⌨️ 快捷键说明

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