Skip to content

Commit cf1a8c0

Browse files
author
Yui Kwan Calvin Leung
committed
update to current commit
1 parent 9101c5f commit cf1a8c0

File tree

3 files changed

+536
-15
lines changed

3 files changed

+536
-15
lines changed

synch.cc

Lines changed: 162 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,165 @@ Semaphore::V()
100100
// Dummy functions -- so we can compile our later assignments
101101
// Note -- without a correct implementation of Condition::Wait(),
102102
// the test case in the network assignment won't work!
103-
Lock::Lock(char* debugName) {}
104-
Lock::~Lock() {}
105-
void Lock::Acquire() {}
106-
void Lock::Release() {}
107-
108-
Condition::Condition(char* debugName) { }
109-
Condition::~Condition() { }
110-
void Condition::Wait(Lock* conditionLock) { ASSERT(FALSE); }
111-
void Condition::Signal(Lock* conditionLock) { }
112-
void Condition::Broadcast(Lock* conditionLock) { }
103+
Lock::Lock(char* debugName)
104+
{
105+
name = debugName;
106+
lockStatus = FREE;
107+
lockOwner = NULL;
108+
waitQueue = new List;
109+
}
110+
111+
Lock::~Lock()
112+
{
113+
delete waitQueue;
114+
}
115+
116+
void Lock::Acquire()
117+
{
118+
IntStatus oldLevel = interrupt->SetLevel(IntOff); //disable interrupts
119+
if(currentThread == lockOwner) //current thread is lock owner
120+
{
121+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
122+
return;
123+
}
124+
125+
if(lockStatus == FREE) //lock is available
126+
{
127+
//I can have the lock
128+
lockStatus = BUSY; //make state BUSY
129+
lockOwner = currentThread; //make myself the owner
130+
}
131+
else //lock is busy
132+
{
133+
waitQueue->Append(currentThread); //Put current thread on the lock’s waitQueue
134+
currentThread->Sleep();
135+
}
136+
137+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
138+
}
139+
140+
void Lock::Release()
141+
{
142+
IntStatus oldLevel = interrupt->SetLevel(IntOff); //disable interrupts
143+
if(currentThread != lockOwner) //current thread is not lock owner
144+
{
145+
printf("Lock::Release::(currentThread != lockOwner)::Current thread is not lock owner\n");
146+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
147+
return;
148+
}
149+
150+
if(!waitQueue->IsEmpty()) //lock waitQueue is not empty
151+
{
152+
Thread* thread = (Thread*)waitQueue->Remove(); //remove 1 waiting thread
153+
lockOwner = thread; //make them lock owner
154+
scheduler->ReadyToRun(thread); //puts a thread at the back of the
155+
//readyQueue in the ready state
156+
}
157+
else
158+
{
159+
lockStatus = FREE; //make lock available
160+
lockOwner = NULL; //unset ownership
161+
}
162+
163+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
164+
}
165+
166+
void Lock::Print()
167+
{
168+
printf("Lock waitQueue contents:\n");
169+
waitQueue->Mapcar((VoidFunctionPtr) ThreadPrint);
170+
}
171+
172+
Condition::Condition(char* debugName)
173+
{
174+
name = debugName;
175+
waitingLock = NULL;
176+
waitQueue = new List;
177+
}
178+
179+
Condition::~Condition()
180+
{
181+
delete waitQueue;
182+
}
183+
184+
void Condition::Wait(Lock* conditionLock)
185+
{
186+
//ASSERT(FALSE);
187+
188+
IntStatus oldLevel = interrupt->SetLevel(IntOff); //disable interrupts
189+
if(conditionLock == NULL)
190+
{
191+
printf("Condition::Wait::(conditionLock == NULL)::There is no lock to be acquired\n");
192+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
193+
return;
194+
}
195+
if(waitingLock == NULL)
196+
{
197+
//no one waiting
198+
waitingLock = conditionLock;
199+
}
200+
if(waitingLock != conditionLock)
201+
{
202+
printf("Condition::Wait::(waitingLock != conditionLock)::waitingLock and the lock passed in don't match\n");
203+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
204+
return;
205+
}
206+
//OK to wait
207+
waitQueue->Append(currentThread);//Hung: add myself to Condition Variable waitQueue
208+
conditionLock->Release();
209+
currentThread->Sleep(); //currentThread is put on the waitQueue
210+
conditionLock->Acquire();
211+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
212+
}
213+
214+
void Condition::Signal(Lock* conditionLock)
215+
{
216+
IntStatus oldLevel = interrupt->SetLevel(IntOff); //disable interrupts
217+
if(waitQueue->IsEmpty()) //no thread waiting
218+
{
219+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
220+
return;
221+
}
222+
223+
if(waitingLock != conditionLock)
224+
{
225+
printf("Condition::Signal::(waitingLock != lock)::Incorrect lock passed in\n");
226+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
227+
return;
228+
}
229+
230+
//Wake up one waiting thread
231+
Thread* thread = (Thread*)waitQueue->Remove();//Remove one thread from waitQueue
232+
scheduler->ReadyToRun(thread); //Put on readyQueue
233+
234+
if(waitQueue->IsEmpty()) //waitQueue is empty
235+
{
236+
waitingLock = NULL;
237+
}
238+
239+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
240+
}
241+
242+
void Condition::Broadcast(Lock* conditionLock)
243+
{
244+
IntStatus oldLevel = interrupt->SetLevel(IntOff); //disable interrupts
245+
if(conditionLock == NULL)
246+
{
247+
printf("Condition::Broadcast::(conditionLock == NULL)::No lock passed in. Reenable interrupts and return.\n");
248+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
249+
return;
250+
}
251+
252+
if(conditionLock != waitingLock)
253+
{
254+
printf("Condition::Broadcast::(conditionLock != waitingLock)::Waiting lock is not the same as the condition lock.\n");
255+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
256+
return;
257+
}
258+
259+
(void) interrupt->SetLevel(oldLevel); //restore interrupts
260+
while(!waitQueue->IsEmpty()) //waitQueue is not empty
261+
{
262+
Signal(conditionLock);
263+
}
264+
}

synch.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class Semaphore {
4141
Semaphore(char* debugName, int initialValue); // set initial value
4242
~Semaphore(); // de-allocate semaphore
4343
char* getName() { return name;} // debugging assist
44-
4544
void P(); // these are the only operations on a semaphore
4645
void V(); // they are both *atomic*
4746

@@ -76,10 +75,15 @@ class Lock {
7675
// holds this lock. Useful for
7776
// checking in Release, and in
7877
// Condition variable ops below.
79-
78+
Thread* getLockOwner() {return lockOwner;}
79+
void Print();
8080
private:
8181
char* name; // for debugging
8282
// plus some other stuff you'll need to define
83+
enum LockStatus {FREE, BUSY};
84+
LockStatus lockStatus;
85+
Thread* lockOwner;
86+
List* waitQueue;
8387
};
8488

8589
// The following class defines a "condition variable". A condition
@@ -132,5 +136,7 @@ class Condition {
132136
private:
133137
char* name;
134138
// plus some other stuff you'll need to define
139+
Lock* waitingLock;
140+
List *waitQueue;
135141
};
136142
#endif // SYNCH_H

0 commit comments

Comments
 (0)