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 / p3 / Synch.c < prev    next >
Text File  |  2006-04-17  |  9KB  |  260 lines

  1. code Synch
  2.  
  3.   -- OS Class: Project 2 -- SOLUTION CODE
  4.   --
  5.   -- Harry Porter  --  December 12, 2003
  6.  
  7. -----------------------------  Semaphore  ---------------------------------
  8.  
  9.   behavior Semaphore
  10.     -- This class provides the following methods:
  11.     --    Signal()  ...also known as "Up" or "V"...
  12.     --         Increment the semaphore count.  Wake up a thread if
  13.     --         there are any waiting.  This operation always executes
  14.     --         quickly and will not suspend the thread.
  15.     --    Wait()   ...also known as "Down" or "P"...
  16.     --         Decrement the semaphore count.  If the count would go
  17.     --         negative, wait for some other thread to do a Signal()
  18.     --         first.  Conceptually, the count will never go negative.
  19.     --    Init(initialCount)
  20.     --         Each semaphore must be initialized.  Normally, you should
  21.     --         invoke this method, providing an 'initialCount' of zero.
  22.     --         If the semaphore is initialized with 0, then a Wait()
  23.     --         operation before any Signal() will wait for the first
  24.     --         Signal().  If initialized with i, then it is as if i Signal()
  25.     --         operations have been performed already.
  26.     --
  27.     -- NOTE: You should never look at a semaphore's count since the value you
  28.     -- retrieve may be out-of-date, due to other threads performing Wait and/or
  29.     -- Signal operations since the retrieval of the count.
  30.  
  31.       ----------  Semaphore . Init  ----------
  32.  
  33.       method Init (initialCount: int)
  34.           if initialCount < 0
  35.             FatalError ("Semaphore created with initialCount < 0")
  36.           endIf
  37.           count = initialCount
  38.           waitingThreads = new List [Thread]
  39.         endMethod
  40.  
  41.       ----------  Semaphore . Signal  ----------
  42.  
  43.       method Signal ()
  44.           var
  45.             oldIntStat: int
  46.             t: ptr to Thread
  47.           oldIntStat = SetInterruptsTo (DISABLED)
  48.           if count == 0x7fffffff
  49.             FatalError ("Semaphore count overflowed during 'Signal' operation")
  50.           endIf
  51.           count = count + 1
  52.           if count <= 0
  53.             t = waitingThreads.Remove ()
  54.             t.status = READY
  55.             readyList.AddToEnd (t)
  56.           endIf
  57.           oldIntStat = SetInterruptsTo (oldIntStat)
  58.         endMethod
  59.  
  60.       ----------  Semaphore . Wait  ----------
  61.  
  62.       method Wait ()
  63.           var
  64.             oldIntStat: int
  65.           oldIntStat = SetInterruptsTo (DISABLED)
  66.           if count == 0x80000000
  67.             FatalError ("Semaphore count underflowed during 'Wait' operation")
  68.           endIf
  69.           count = count - 1
  70.           if count < 0
  71.             waitingThreads.AddToEnd (currentThread)
  72.             currentThread.Sleep ()
  73.           endIf
  74.           oldIntStat = SetInterruptsTo (oldIntStat)
  75.         endMethod
  76.  
  77.   endBehavior
  78.  
  79. -----------------------------  Mutex  ---------------------------------
  80.  
  81.   behavior Mutex
  82.     -- This class provides the following methods:
  83.     --    Lock()
  84.     --         Acquire the mutex if free, otherwise wait until the mutex is
  85.     --         free and then get it.
  86.     --    Unlock()
  87.     --         Release the mutex.  If other threads are waiting, then
  88.     --         wake up one so it can then lock the mutex next.
  89.     --    Init()
  90.     --         Each mutex must be initialized.
  91.     --    IsHeldByCurrentThread()
  92.     --         Return TRUE iff the current (invoking) thread holds a lock
  93.     --         on the mutex.
  94.  
  95.     method Init ()
  96.         waitingThreads = new List [Thread]
  97.       endMethod
  98.  
  99.     method Lock ()
  100.         var
  101.           oldIntStat: int
  102.         if heldBy == currentThread
  103.           FatalError ("Attempt to lock a mutex by a thread already holding it")
  104.         endIf
  105.         oldIntStat = SetInterruptsTo (DISABLED)
  106.         while heldBy
  107.           waitingThreads.AddToEnd (currentThread)
  108.           currentThread.Sleep ()
  109.         endWhile
  110.         heldBy = currentThread
  111.         oldIntStat = SetInterruptsTo (oldIntStat)
  112.       endMethod
  113.  
  114.     method Unlock ()
  115.         var
  116.           oldIntStat: int
  117.           t: ptr to Thread
  118.         if heldBy != currentThread
  119.           FatalError ("Attempt to unlock a mutex by a thread not holding it")
  120.         endIf
  121.         oldIntStat = SetInterruptsTo (DISABLED)
  122.         t = waitingThreads.Remove ()
  123.         if t
  124.           t.status = READY
  125.           readyList.AddToEnd (t)
  126.         endIf
  127.         heldBy = null
  128.         oldIntStat = SetInterruptsTo (oldIntStat)
  129.       endMethod
  130.  
  131.     method IsHeldByCurrentThread () returns bool
  132.         return heldBy == currentThread
  133.       endMethod
  134.  
  135.   endBehavior
  136.  
  137. -----------------------------  Mutex2  ---------------------------------
  138.  
  139.   behavior Mutex2
  140.     -- This is a second implementation of Mutexs, using Semaphores.
  141.  
  142.     method Init ()
  143.         sem = new Semaphore
  144.         sem.Init (1)
  145.       endMethod
  146.  
  147.     method Lock ()
  148.         sem.Wait ()
  149.         heldBy = currentThread
  150.       endMethod
  151.  
  152.     method Unlock ()
  153.         heldBy = null
  154.         sem.Signal ()
  155.       endMethod
  156.  
  157.     method IsHeldByCurrentThread () returns bool
  158.         return heldBy == currentThread
  159.       endMethod
  160.  
  161.   endBehavior
  162.  
  163. -----------------------------  Condition  ---------------------------------
  164.  
  165.   behavior Condition
  166.     -- This class is used to implement monitors.  Each monitor will have a
  167.     -- mutex lock and one or more condition variables.  The lock ensures that
  168.     -- only one process at a time may execute code in the monitor.  Within the
  169.     -- monitor code, a thread can execute Wait() and Signal() operations
  170.     -- on the condition variables to make sure certain condions are met.
  171.     --
  172.     -- The condition variables here implement "Mesa-style" semantics, which
  173.     -- means that in the time between a Signal() operation and the awakening
  174.     -- and execution of the corrsponding waiting thread, other threads may
  175.     -- have snuck in and run.  The waiting thread should always re-check the
  176.     -- data to ensure that the condition which was signalled is still true.
  177.     --
  178.     -- This class provides the following methods:
  179.     --    Wait(mutex)
  180.     --         This method assumes the mutex has alreasy been locked.
  181.     --         It unlocks it, and goes to sleep waiting for a signal on
  182.     --         this condition.  When the signal is received, this method
  183.     --         re-awakens, re-locks the mutex, and returns.
  184.     --    Signal(mutex)
  185.     --         If there are any threads waiting on this condition, this
  186.     --         method will wake up the oldest and schedule it to run.
  187.     --         However, since this thread holds the mutex and never unlocks
  188.     --         it, the newly awakened thread will be forced to wait before
  189.     --         it can re-acquire the mutex and resume execution.
  190.     --    Broadcast(mutex)
  191.     --         This method is like Signal() except that it wakes up all
  192.     --         threads waiting on this condition, not just the next one.
  193.     --    Init()
  194.     --         Each condition must be initialized.
  195.  
  196.       ----------  Condition . Init  ----------
  197.  
  198.       method Init ()
  199.           waitingThreads = new List [Thread]
  200.         endMethod
  201.  
  202.       ----------  Condition . Wait  ----------
  203.  
  204.       method Wait (mutex: ptr to Mutex)
  205.           var
  206.             oldIntStat: int
  207.           if ! mutex.IsHeldByCurrentThread ()
  208.             FatalError ("Attempt to wait on condition when mutex is not held")
  209.           endIf
  210.           oldIntStat = SetInterruptsTo (DISABLED)
  211.           mutex.Unlock ()
  212.           waitingThreads.AddToEnd (currentThread)
  213.           currentThread.Sleep ()
  214.           mutex.Lock ()
  215.           oldIntStat = SetInterruptsTo (oldIntStat)
  216.         endMethod
  217.  
  218.       ----------  Condition . Signal  ----------
  219.  
  220.       method Signal (mutex: ptr to Mutex)
  221.           var
  222.             oldIntStat: int
  223.             t: ptr to Thread
  224.           if ! mutex.IsHeldByCurrentThread ()
  225.             FatalError ("Attempt to signal a condition when mutex is not held")
  226.           endIf
  227.           oldIntStat = SetInterruptsTo (DISABLED)
  228.           t = waitingThreads.Remove ()
  229.           if t
  230.             t.status = READY
  231.             readyList.AddToEnd (t)
  232.           endIf
  233.           oldIntStat = SetInterruptsTo (oldIntStat)
  234.         endMethod
  235.  
  236.       ----------  Condition . Broadcast  ----------
  237.  
  238.       method Broadcast (mutex: ptr to Mutex)
  239.           var
  240.             oldIntStat: int
  241.             t: ptr to Thread
  242.           if ! mutex.IsHeldByCurrentThread ()
  243.             FatalError ("Attempt to broadcast a condition when lock is not held")
  244.           endIf
  245.           oldIntStat = SetInterruptsTo (DISABLED)
  246.           while true
  247.             t = waitingThreads.Remove ()
  248.             if t == null
  249.               break
  250.             endIf
  251.             t.status = READY
  252.             readyList.AddToEnd (t)
  253.           endWhile
  254.           oldIntStat = SetInterruptsTo (oldIntStat)
  255.         endMethod
  256.  
  257.   endBehavior
  258.  
  259. endCode
  260.