home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / kaffe-0.5p4-src.tgz / tar.out / contrib / kaffe / kaffevm / locks.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  3KB  |  191 lines

  1. /*
  2.  * locks.c
  3.  * Manage locking system
  4.  * This include the mutex's and cv's.
  5.  *
  6.  * Copyright (c) 1996 Systems Architecture Research Centre,
  7.  *           City University, London, UK.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  *
  12.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
  13.  */
  14.  
  15. #include <assert.h>
  16. #include "object.h"
  17. #include "baseClasses.h"
  18. #include "thread.h"
  19. #include "locks.h"
  20. #include "errors.h"
  21. #include "exception.h"
  22. #include "md.h"
  23.  
  24. extern thread* currentThread;
  25.  
  26. #if defined(HAVE_NATIVE_INT64)
  27. jlong    waitforever = -1;
  28. #else
  29. jlong    waitforever = { -1, -1 };
  30. #endif
  31.  
  32. #if defined(USE_INTERNAL_THREADS)
  33.  
  34. /*
  35.  * Lock a mutex.
  36.  */
  37. void
  38. internalLockMutex(iMux* mux)
  39. {
  40.     intsDisable();
  41.  
  42.     if (mux->holder == 0) {
  43.         mux->holder = currentThread;
  44.         mux->count = 1;
  45.     }
  46.     else if (mux->holder == currentThread) {
  47.         mux->count++;
  48.     }
  49.     else {
  50.         while (mux->holder != 0) {
  51.             suspendOnQThread(currentThread, &mux->muxWaiters);
  52.         }
  53.         mux->holder = currentThread;
  54.         mux->count = 1;
  55.     }
  56.  
  57.     intsRestore();
  58. }
  59.  
  60. /*
  61.  * Release a mutex.
  62.  */
  63. void
  64. internalUnlockMutex(iMux* mux)
  65. {
  66.     thread* tid;
  67.  
  68.     intsDisable();
  69.  
  70.     assert(mux->holder == currentThread);
  71.  
  72.     mux->count--;
  73.     if (mux->count == 0) {
  74.         mux->holder = 0;
  75.         if (mux->muxWaiters != 0) {
  76.             tid = mux->muxWaiters;
  77.             mux->muxWaiters = tid->next;
  78.             resumeThread(tid);
  79.         }
  80.     }
  81.  
  82.     intsRestore();
  83. }
  84.  
  85. /*
  86.  * Wait on a conditional variable.
  87.  *  (timeout currently ignored)
  88.  */
  89. void
  90. internalWaitCond(iMux* mux, iCv* cv, jlong timeout)
  91. {
  92.     int count;
  93.     thread* tid;
  94.  
  95.     if (mux->holder != currentThread) {
  96.         throwException(IllegalMonitorStateException);
  97.     }
  98.  
  99.     intsDisable();
  100.  
  101.     count = mux->count;
  102.     mux->holder = 0;
  103.     mux->count = 0;
  104.     cv->mux = mux;
  105.  
  106.     /* If there's anyone waiting here, wake them up */
  107.     if (mux->muxWaiters != 0) {
  108.         tid = mux->muxWaiters;
  109.         mux->muxWaiters = tid->next;
  110.         resumeThread(tid);
  111.     }
  112.  
  113.     /* Suspend, and keep suspended until I re-get the lock */
  114.     suspendOnQThread(currentThread, &cv->cvWaiters);
  115.     while (mux->holder != 0) {
  116.         suspendOnQThread(currentThread, &mux->muxWaiters);
  117.     }
  118.  
  119.     mux->holder = currentThread;
  120.     mux->count = count;
  121.  
  122.     intsRestore();
  123. }
  124.  
  125. /*
  126.  * Wake one thread on a conditional variable.
  127.  */
  128. void
  129. internalSignalCond(iCv* cv)
  130. {
  131.     thread* tid;
  132.  
  133.     /* If 'mux' isn't set then we've never waited on this object. */
  134.     if (cv->mux == 0) {
  135.         return;
  136.     }
  137.  
  138.     if (cv->mux->holder != currentThread) {
  139.         throwException(IllegalMonitorStateException);
  140.     }
  141.  
  142.     intsDisable();
  143.  
  144.     /* Remove one thread from cv list */
  145.     if (cv->cvWaiters != 0) {
  146.         tid = cv->cvWaiters;
  147.         cv->cvWaiters = tid->next;
  148.  
  149.         /* Place it on mux list */
  150.         tid->next = cv->mux->muxWaiters;
  151.         cv->mux->muxWaiters = tid;
  152.     }
  153.  
  154.     intsRestore();
  155. }
  156.  
  157. /*
  158.  * Wake all threads on a conditional variable.
  159.  */
  160. void
  161. internalBroadcastCond(iCv* cv)
  162. {
  163.     thread** tidp;
  164.  
  165.     /* If 'mux' isn't set then we've never waited on this object. */
  166.     if (cv->mux == 0) {
  167.         return;
  168.     }
  169.  
  170.     if (cv->mux->holder != currentThread) {
  171.         throwException(IllegalMonitorStateException);
  172.     }
  173.  
  174.     intsDisable();
  175.  
  176.     /* Find the end of the cv list */
  177.     if (cv->cvWaiters) {
  178.         for (tidp = &cv->cvWaiters; *tidp != 0; tidp = &(*tidp)->next)
  179.             ;
  180.  
  181.         /* Place entire cv list on mux list */
  182.         (*tidp) = cv->mux->muxWaiters;
  183.         cv->mux->muxWaiters = cv->cvWaiters;
  184.         cv->cvWaiters = 0;
  185.     }
  186.  
  187.     intsRestore();
  188. }
  189.  
  190. #endif
  191.