home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / runtime / sync.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-09  |  3.4 KB  |  155 lines

  1. /* sync.c
  2.  *
  3.  * COPYRIGHT (c) 1990 by AT&T Bell Laboratories.
  4.  *
  5.  * Provides synchronization primitves for processors.  The try_spin_lock
  6.  * and spin_unlock routines are intended to work on runtime spin locks
  7.  * only.  
  8.  *
  9.  * ml_spin_locks can "share" in the sense that calls to ml_spin_lock
  10.  * can return the same lock (currently happens only on SGI where we
  11.  * have a limited number of hardware locks.)  Runtime spin locks never
  12.  * share.
  13.  */
  14. #include "ml_state.h"
  15. #include "ml_types.h"
  16. #include "tags.h"
  17.  
  18. #if (MAX_PROCS > 1)
  19. #ifdef SGI
  20. /*******************************************************************/
  21. /* SGI spin locks -- we use the SGI's hardware locks.              */
  22. /*******************************************************************/
  23. #include <sys/types.h>
  24. #include <ulocks.h>
  25. #define MAX_LOCKS 4000
  26.  
  27. usptr_t *sync_arena;
  28. typedef ulock_t spin_lock_t;
  29.  
  30. int           max_locks = MAX_LOCKS;
  31. spin_lock_t   locks[MAX_LOCKS];
  32.  
  33.  
  34. #define syscall(x,f,v)    if (((x) = (f)) == (v)) { \
  35.                 error = oserror(); \
  36.                             chatting("f failed with error %d\n",error); \
  37.                             die("%s\n",strerror(error)); } else
  38.  
  39. void sync_init(restarted)
  40.     int restarted;
  41. {
  42.   int error;
  43.   int ret;
  44.   int i, done = FALSE;
  45.   int proc_share, k;
  46.   extern MLState_t *MLProc;
  47.   MLState_ptr p;
  48.  
  49.   if (!restarted) { 
  50.     syscall(ret, usconfig(CONF_LOCKTYPE, US_NODEBUG), -1);
  51.     syscall(ret, usconfig(CONF_ARENATYPE, US_SHAREDONLY), -1);
  52.   } 
  53.   syscall(sync_arena,usinit(tmpnam(0)),0);
  54.   max_locks = 0;
  55.   for (max_locks = 0; (max_locks < MAX_LOCKS) && (!done); max_locks++) {
  56.     if ((locks[max_locks] = usnewlock(sync_arena)) == 0)
  57.       done = TRUE;
  58.   }
  59.   proc_share = max_locks / MAX_PROCS;
  60.   for (i=0, k=0; i < MAX_PROCS; i++) {
  61.     p = &(MLproc[i]);
  62.     p->lock_base = k;
  63.     p->lock_ptr = k;
  64.     k += proc_share;
  65.     p->lock_top = k - 1;
  66.   }
  67. }
  68.  
  69. spin_lock_t runtime_spin_lock()
  70. {
  71.   int error;
  72.   spin_lock_t ret;
  73.   syscall(ret,usnewlock(sync_arena),0);
  74.   return ret;
  75. }
  76.  
  77. void ml_spin_lock (msp)
  78.     MLState_ptr msp;
  79. {
  80.   ML_val_t l = (ML_val_t)&(locks[msp->lock_ptr]);
  81.   msp->lock_ptr++;
  82.   if (msp->lock_ptr > msp->lock_top) {
  83.     msp->lock_ptr = msp->lock_base;
  84.   }
  85.   msp->ml_arg = l;
  86.   return;
  87. }
  88.   
  89. int try_spin_lock(lock)
  90.      spin_lock_t lock;
  91. {
  92.   int error, ret;
  93.   syscall(ret, uscsetlock(lock, 1), -1);
  94.   return(ret);
  95. }
  96.  
  97. void spin_unlock(lock)
  98.      spin_lock_t lock;
  99. {
  100.   int error, ret;
  101.   syscall(ret, usunsetlock(lock), -1);
  102. }
  103.  
  104. #endif SGI
  105. #else /* (MAX_PROCS == 1) */
  106. /*******************************************************************/
  107. /* Default case (i.e. MAX_PROCS == 1)                              */
  108. /*******************************************************************/
  109. typedef int *spin_lock_t;
  110.  
  111. void sync_init (restarted)
  112.     int restarted;
  113. {
  114.     /* nothing */
  115. }
  116.  
  117. /* These are spin locks to be used by the runtime -- just an int pointer,
  118.    initialized to TRUE.
  119. */
  120. static int runtime_lock;
  121.  
  122. spin_lock_t runtime_spin_lock()
  123. {
  124.   spin_lock_t lock;
  125.  
  126.   runtime_lock = TRUE;
  127.   return (&runtime_lock);
  128. }
  129.  
  130. /* Allocate a 1-element bool array on the heap. */
  131. void ml_spin_lock(msp)
  132.      MLState_ptr msp;
  133. {
  134.     ML_alloc_write (msp, 0, MAKE_DESC(4, TAG_bytearray));
  135.     ML_alloc_write (msp, 1, ML_true);
  136.     msp->ml_arg = ML_alloc(msp, 1);
  137.     return;
  138. }
  139.  
  140. int try_spin_lock(lock)
  141.      spin_lock_t lock;
  142. {
  143.   int old = *lock;
  144.   *lock = FALSE;
  145.   return old;
  146. }
  147.  
  148. void spin_unlock(lock)
  149.      spin_lock_t lock;
  150.   *lock = TRUE;
  151. }
  152.  
  153. #endif /* (MAX_PROCS > 1) */
  154.