Adaptata la solutia de aici & aici.
#define FREE false
#define BUSY true
Lock::Lock(char* debugName) {
name=debugName;
value=FREE;
queue=new List;
}
void Lock::Acquire() {
IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts
// if lock not available...
if (value == BUSY) {
queue->Append (currentThread); // add to queue & go to sleep
currentThread->Sleep();
}
// here thread is waken up, the real acquire begins
value=BUSY;
held=currentThread; // save the thread which got the lock
interrupt->SetLevel(oldLevel); // re-enable interrupts
}
void Lock::Release() {
IntStatus oldLevel = interrupt->SetLevel(IntOff);
Thread* thread = (Thread *) queue->Remove();
if (held==currentThread) { // this is necessary to avoid a crazy thread releasing others
if (thread!=NULL) {
scheduler->ReadyToRun(thread); // add it to ready queue
}
else { // if queue is empty
value=FREE;
}
}
interrupt->SetLevel(oldLevel);
}
Meanings:
FREE : there is no other thread inside the Lock
BUSY: there is at least one thread either in the queue or in the process of acquiring
// there is a slightly equivalent solution
// however I think the previous one is more meaningful
// variable held is kind of useless here
void Lock::Acquire() {
IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts
// if lock not available...
while (value == BUSY) {
queue->Append (currentThread); // add to queue & go to sleep
currentThread->Sleep();
}
// here thread is waken up, the real acquire begins
value=BUSY;
held=currentThread;
interrupt->SetLevel(oldLevel); // re-enable interrupts
}
void Lock::Release() {
IntStatus oldLevel = interrupt->SetLevel(IntOff);
if (held==currentThread) {
Thread* thread = (Thread *) queue->Remove();
if (thread!=NULL) {
scheduler->ReadyToRun(thread); // add it to ready queue
}
value=FREE;
}
interrupt->SetLevel(oldLevel);
}
-------------------------
Some differences Lock vs. Semaphore
* Semaphore has a counter of resources whereas Lock is either busy or free. Lock is used for Mutual Exclusion only, i.e, only one thread can access the shared resources at any time.
* Lock has owner whereas Semaphore does not have any owner.
* Lock does not track number of resources/ number of waiting tasks, whereas Semaphore does.
* Only the thread which is the owner of the Lock can Release the lock on resource. Semaphore can be accessed by any thread.
* Semaphore is a shared object while Lock is not.
#define FREE false
#define BUSY true
Lock::Lock(char* debugName) {
name=debugName;
value=FREE;
queue=new List;
}
void Lock::Acquire() {
IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts
// if lock not available...
if (value == BUSY) {
queue->Append (currentThread); // add to queue & go to sleep
currentThread->Sleep();
}
// here thread is waken up, the real acquire begins
value=BUSY;
held=currentThread; // save the thread which got the lock
interrupt->SetLevel(oldLevel); // re-enable interrupts
}
void Lock::Release() {
IntStatus oldLevel = interrupt->SetLevel(IntOff);
Thread* thread = (Thread *) queue->Remove();
if (held==currentThread) { // this is necessary to avoid a crazy thread releasing others
if (thread!=NULL) {
scheduler->ReadyToRun(thread); // add it to ready queue
}
else { // if queue is empty
value=FREE;
}
}
interrupt->SetLevel(oldLevel);
}
Meanings:
FREE : there is no other thread inside the Lock
BUSY: there is at least one thread either in the queue or in the process of acquiring
// there is a slightly equivalent solution
// however I think the previous one is more meaningful
// variable held is kind of useless here
void Lock::Acquire() {
IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts
// if lock not available...
while (value == BUSY) {
queue->Append (currentThread); // add to queue & go to sleep
currentThread->Sleep();
}
// here thread is waken up, the real acquire begins
value=BUSY;
held=currentThread;
interrupt->SetLevel(oldLevel); // re-enable interrupts
}
void Lock::Release() {
IntStatus oldLevel = interrupt->SetLevel(IntOff);
if (held==currentThread) {
Thread* thread = (Thread *) queue->Remove();
if (thread!=NULL) {
scheduler->ReadyToRun(thread); // add it to ready queue
}
value=FREE;
}
interrupt->SetLevel(oldLevel);
}
-------------------------
Some differences Lock vs. Semaphore
* Semaphore has a counter of resources whereas Lock is either busy or free. Lock is used for Mutual Exclusion only, i.e, only one thread can access the shared resources at any time.
* Lock has owner whereas Semaphore does not have any owner.
* Lock does not track number of resources/ number of waiting tasks, whereas Semaphore does.
* Only the thread which is the owner of the Lock can Release the lock on resource. Semaphore can be accessed by any thread.
* Semaphore is a shared object while Lock is not.
Niciun comentariu:
Trimiteți un comentariu