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 / OSProject / p3 / Synch.c < prev    next >
Text File  |  2009-04-09  |  9KB  |  271 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.     --    Up()  ...also known as "V" or "Signal"...
  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.     --    Down()   ...also known as "P" or "Wait"...
  16.     --         Decrement the semaphore count.  If the count would go
  17.     --         negative, wait for some other thread to do an Up()
  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 Down()
  23.     --         operation before any Up() will wait for the first
  24.     --         Up().  If initialized with i, then it is as if i Up()
  25.     --         operations have been performed already.
  26.     --
  27.     -- NOTE: The user should never look at a semaphore's count since the value
  28.     -- retrieved may be out-of-date, due to other threads performing Up() or
  29.     -- Down() 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 . Up  ----------
  42.  
  43.       method Up ()
  44.           var
  45.             oldIntStat: int
  46.             t: ptr to Thread
  47.           oldIntStat = SetInterruptsTo (DISABLED)
  48.           if count == 0x7fffffff
  49.             FatalError ("Semaphore count overflowed during 'Up' 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 . Down  ----------
  61.  
  62.       method Down ()
  63.           var
  64.             oldIntStat: int
  65.           oldIntStat = SetInterruptsTo (DISABLED)
  66.           if count == 0x80000000
  67.             FatalError ("Semaphore count underflowed during 'Down' 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 the oldest one and give it the lock.
  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.        -----------  Mutex . Init  -----------
  96.  
  97.        method Init ()
  98.            waitingThreads = new List [Thread]
  99.          endMethod
  100.  
  101.        -----------  Mutex . Lock  -----------
  102.  
  103.        method Lock ()
  104.            var
  105.              oldIntStat: int
  106.            if heldBy == currentThread
  107.              FatalError ("Attempt to lock a mutex by a thread already holding it")
  108.            endIf
  109.            oldIntStat = SetInterruptsTo (DISABLED)
  110.            if !heldBy
  111.              heldBy = currentThread
  112.            else
  113.              waitingThreads.AddToEnd (currentThread)
  114.              currentThread.Sleep ()
  115.            endIf
  116.            oldIntStat = SetInterruptsTo (oldIntStat)
  117.          endMethod
  118.  
  119.        -----------  Mutex . Unlock  -----------
  120.  
  121.        method Unlock ()
  122.            var
  123.              oldIntStat: int
  124.              t: ptr to Thread
  125.            if heldBy != currentThread
  126.              FatalError ("Attempt to unlock a mutex by a thread not holding it")
  127.            endIf
  128.            oldIntStat = SetInterruptsTo (DISABLED)
  129.            t = waitingThreads.Remove ()
  130.            if t
  131.              t.status = READY
  132.              readyList.AddToEnd (t)
  133.              heldBy = t
  134.            else
  135.              heldBy = null
  136.            endIf
  137.            oldIntStat = SetInterruptsTo (oldIntStat)
  138.          endMethod
  139.  
  140.        -----------  Mutex . IsHeldByCurrentThread  -----------
  141.  
  142.        method IsHeldByCurrentThread () returns bool
  143.            return heldBy == currentThread
  144.          endMethod
  145.  
  146.   endBehavior
  147.  
  148. -----------------------------  Mutex2  ---------------------------------
  149.  
  150.   behavior Mutex2
  151.     -- This is a second implementation of Mutexs, using Semaphores.
  152.  
  153.     method Init ()
  154.         sem = new Semaphore
  155.         sem.Init (1)
  156.       endMethod
  157.  
  158.     method Lock ()
  159.         sem.Down ()
  160.         heldBy = currentThread
  161.       endMethod
  162.  
  163.     method Unlock ()
  164.         heldBy = null
  165.         sem.Up ()
  166.       endMethod
  167.  
  168.     method IsHeldByCurrentThread () returns bool
  169.         return heldBy == currentThread
  170.       endMethod
  171.  
  172.   endBehavior
  173.  
  174. -----------------------------  Condition  ---------------------------------
  175.  
  176.   behavior Condition
  177.     -- This class is used to implement monitors.  Each monitor will have a
  178.     -- mutex lock and one or more condition variables.  The lock ensures that
  179.     -- only one process at a time may execute code in the monitor.  Within the
  180.     -- monitor code, a thread can execute Wait() and Signal() operations
  181.     -- on the condition variables to make sure certain condions are met.
  182.     --
  183.     -- The condition variables here implement "Mesa-style" semantics, which
  184.     -- means that in the time between a Signal() operation and the awakening
  185.     -- and execution of the corrsponding waiting thread, other threads may
  186.     -- have snuck in and run.  The waiting thread should always re-check the
  187.     -- data to ensure that the condition which was signalled is still true.
  188.     --
  189.     -- This class provides the following methods:
  190.     --    Wait(mutex)
  191.     --         This method assumes the mutex has alreasy been locked.
  192.     --         It unlocks it, and goes to sleep waiting for a signal on
  193.     --         this condition.  When the signal is received, this method
  194.     --         re-awakens, re-locks the mutex, and returns.
  195.     --    Signal(mutex)
  196.     --         If there are any threads waiting on this condition, this
  197.     --         method will wake up the oldest and schedule it to run.
  198.     --         However, since this thread holds the mutex and never unlocks
  199.     --         it, the newly awakened thread will be forced to wait before
  200.     --         it can re-acquire the mutex and resume execution.
  201.     --    Broadcast(mutex)
  202.     --         This method is like Signal() except that it wakes up all
  203.     --         threads waiting on this condition, not just the next one.
  204.     --    Init()
  205.     --         Each condition must be initialized.
  206.  
  207.       ----------  Condition . Init  ----------
  208.  
  209.       method Init ()
  210.           waitingThreads = new List [Thread]
  211.         endMethod
  212.  
  213.       ----------  Condition . Wait  ----------
  214.  
  215.       method Wait (mutex: ptr to Mutex)
  216.           var
  217.             oldIntStat: int
  218.           if ! mutex.IsHeldByCurrentThread ()
  219.             FatalError ("Attempt to wait on condition when mutex is not held")
  220.           endIf
  221.           oldIntStat = SetInterruptsTo (DISABLED)
  222.           mutex.Unlock ()
  223.           waitingThreads.AddToEnd (currentThread)
  224.           currentThread.Sleep ()
  225.           mutex.Lock ()
  226.           oldIntStat = SetInterruptsTo (oldIntStat)
  227.         endMethod
  228.  
  229.       ----------  Condition . Signal  ----------
  230.  
  231.       method Signal (mutex: ptr to Mutex)
  232.           var
  233.             oldIntStat: int
  234.             t: ptr to Thread
  235.           if ! mutex.IsHeldByCurrentThread ()
  236.             FatalError ("Attempt to signal a condition when mutex is not held")
  237.           endIf
  238.           oldIntStat = SetInterruptsTo (DISABLED)
  239.           t = waitingThreads.Remove ()
  240.           if t
  241.             t.status = READY
  242.             readyList.AddToEnd (t)
  243.           endIf
  244.           oldIntStat = SetInterruptsTo (oldIntStat)
  245.         endMethod
  246.  
  247.       ----------  Condition . Broadcast  ----------
  248.  
  249.       method Broadcast (mutex: ptr to Mutex)
  250.           var
  251.             oldIntStat: int
  252.             t: ptr to Thread
  253.           if ! mutex.IsHeldByCurrentThread ()
  254.             FatalError ("Attempt to broadcast a condition when lock is not held")
  255.           endIf
  256.           oldIntStat = SetInterruptsTo (DISABLED)
  257.           while true
  258.             t = waitingThreads.Remove ()
  259.             if t == null
  260.               break
  261.             endIf
  262.             t.status = READY
  263.             readyList.AddToEnd (t)
  264.           endWhile
  265.           oldIntStat = SetInterruptsTo (oldIntStat)
  266.         endMethod
  267.  
  268.   endBehavior
  269.  
  270. endCode
  271.