home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.ee.pdx.edu
/
2014.02.ftp.ee.pdx.edu.tar
/
ftp.ee.pdx.edu
/
pub
/
users
/
Harry
/
Blitz
/
version-1-0
/
OSProject
/
p2
/
Synch.c
< prev
next >
Wrap
Text File
|
2006-04-05
|
8KB
|
211 lines
code Synch
-- OS Class: Project 2
--
-- <PUT YOUR NAME HERE>
----------------------------- Semaphore ---------------------------------
behavior Semaphore
-- This class provides the following methods:
-- Signal() ...also known as "Up" or "V"...
-- Increment the semaphore count. Wake up a thread if
-- there are any waiting. This operation always executes
-- quickly and will not suspend the thread.
-- Wait() ...also known as "Down" or "P"...
-- Decrement the semaphore count. If the count would go
-- negative, wait for some other thread to do a Signal()
-- first. Conceptually, the count will never go negative.
-- Init(initialCount)
-- Each semaphore must be initialized. Normally, you should
-- invoke this method, providing an 'initialCount' of zero.
-- If the semaphore is initialized with 0, then a Wait()
-- operation before any Signal() will wait for the first
-- Signal(). If initialized with i, then it is as if i Signal()
-- operations have been performed already.
--
-- NOTE: You should never look at a semaphore's count since the value you
-- retrieve may be out-of-date, due to other threads performing Wait and/or
-- Signal operations since the retrieval of the count.
---------- Semaphore . Init ----------
method Init (initialCount: int)
if initialCount < 0
FatalError ("Semaphore created with initialCount < 0")
endIf
count = initialCount
waitingThreads = new List [Thread]
endMethod
---------- Semaphore . Signal ----------
method Signal ()
var
oldIntStat: int
t: ptr to Thread
oldIntStat = SetInterruptsTo (DISABLED)
if count == 0x7fffffff
FatalError ("Semaphore count overflowed during 'Signal' operation")
endIf
count = count + 1
if count <= 0
t = waitingThreads.Remove ()
t.status = READY
readyList.AddToEnd (t)
endIf
oldIntStat = SetInterruptsTo (oldIntStat)
endMethod
---------- Semaphore . Wait ----------
method Wait ()
var
oldIntStat: int
oldIntStat = SetInterruptsTo (DISABLED)
if count == 0x80000000
FatalError ("Semaphore count underflowed during 'Wait' operation")
endIf
count = count - 1
if count < 0
waitingThreads.AddToEnd (currentThread)
currentThread.Sleep ()
endIf
oldIntStat = SetInterruptsTo (oldIntStat)
endMethod
endBehavior
----------------------------- Mutex ---------------------------------
behavior Mutex
-- This class provides the following methods:
-- Lock()
-- Acquire the mutex if free, otherwise wait until the mutex is
-- free and then get it.
-- Unlock()
-- Release the mutex. If other threads are waiting, then
-- wake up one so it can then lock the mutex next.
-- Init()
-- Each mutex must be initialized.
-- IsHeldByCurrentThread()
-- Return TRUE iff the current (invoking) thread holds a lock
-- on the mutex.
method Init ()
FatalError ("Unimplemented method")
endMethod
method Lock ()
FatalError ("Unimplemented method")
endMethod
method Unlock ()
FatalError ("Unimplemented method")
endMethod
method IsHeldByCurrentThread () returns bool
FatalError ("Unimplemented method")
return false
endMethod
endBehavior
----------------------------- Condition ---------------------------------
behavior Condition
-- This class is used to implement monitors. Each monitor will have a
-- mutex lock and one or more condition variables. The lock ensures that
-- only one process at a time may execute code in the monitor. Within the
-- monitor code, a thread can execute Wait() and Signal() operations
-- on the condition variables to make sure certain condions are met.
--
-- The condition variables here implement "Mesa-style" semantics, which
-- means that in the time between a Signal() operation and the awakening
-- and execution of the corrsponding waiting thread, other threads may
-- have snuck in and run. The waiting thread should always re-check the
-- data to ensure that the condition which was signalled is still true.
--
-- This class provides the following methods:
-- Wait(mutex)
-- This method assumes the mutex has alreasy been locked.
-- It unlocks it, and goes to sleep waiting for a signal on
-- this condition. When the signal is received, this method
-- re-awakens, re-locks the mutex, and returns.
-- Signal(mutex)
-- If there are any threads waiting on this condition, this
-- method will wake up the oldest and schedule it to run.
-- However, since this thread holds the mutex and never unlocks
-- it, the newly awakened thread will be forced to wait before
-- it can re-acquire the mutex and resume execution.
-- Broadcast(mutex)
-- This method is like Signal() except that it wakes up all
-- threads waiting on this condition, not just the next one.
-- Init()
-- Each condition must be initialized.
---------- Condition . Init ----------
method Init ()
waitingThreads = new List [Thread]
endMethod
---------- Condition . Wait ----------
method Wait (mutex: ptr to Mutex)
var
oldIntStat: int
if ! mutex.IsHeldByCurrentThread ()
FatalError ("Attempt to wait on condition when mutex is not held")
endIf
oldIntStat = SetInterruptsTo (DISABLED)
mutex.Unlock ()
waitingThreads.AddToEnd (currentThread)
currentThread.Sleep ()
mutex.Lock ()
oldIntStat = SetInterruptsTo (oldIntStat)
endMethod
---------- Condition . Signal ----------
method Signal (mutex: ptr to Mutex)
var
oldIntStat: int
t: ptr to Thread
if ! mutex.IsHeldByCurrentThread ()
FatalError ("Attempt to signal a condition when mutex is not held")
endIf
oldIntStat = SetInterruptsTo (DISABLED)
t = waitingThreads.Remove ()
if t
t.status = READY
readyList.AddToEnd (t)
endIf
oldIntStat = SetInterruptsTo (oldIntStat)
endMethod
---------- Condition . Broadcast ----------
method Broadcast (mutex: ptr to Mutex)
var
oldIntStat: int
t: ptr to Thread
if ! mutex.IsHeldByCurrentThread ()
FatalError ("Attempt to broadcast a condition when lock is not held")
endIf
oldIntStat = SetInterruptsTo (DISABLED)
while true
t = waitingThreads.Remove ()
if t == null
break
endIf
t.status = READY
readyList.AddToEnd (t)
endWhile
oldIntStat = SetInterruptsTo (oldIntStat)
endMethod
endBehavior
endCode