home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / storage / ipc / spin.c < prev   
Encoding:
C/C++ Source or Header  |  1993-04-15  |  6.2 KB  |  266 lines

  1. /*
  2.  * spin.c -- routines for managing spin locks
  3.  *
  4.  * Identification:
  5.  *    $Header: /private/postgres/src/storage/ipc/RCS/spin.c,v 1.13 1992/04/13 21:33:36 mer Exp $
  6.  *
  7.  * POSTGRES has two kinds of locks: semaphores (which put the
  8.  * process to sleep) and spinlocks (which are supposed to be
  9.  * short term locks).  Currently both are implemented as SysV
  10.  * semaphores, but presumably this can change if we move to
  11.  * a machine with a test-and-set (TAS) instruction.  Its probably
  12.  * a good idea to think about (and allocate) short term and long
  13.  * term semaphores separately anyway.
  14.  *
  15.  * NOTE: These routines are not supposed to be widely used in Postgres.
  16.  *     They are preserved solely for the purpose of porting Mark Sullivan's
  17.  *     buffer manager to Postgres.
  18.  */
  19. #include <errno.h>
  20. #include "tmp/postgres.h"
  21. #include "storage/ipc.h"
  22. #include "storage/ipci.h"
  23. #include "storage/shmem.h"
  24. #include "storage/spin.h"
  25. #include "storage/proc.h"
  26. #include "utils/log.h"
  27.  
  28. /* globals used in this file */
  29. IpcSemaphoreId    SpinLockId;
  30.  
  31. #ifdef HAS_TEST_AND_SET
  32. /* real spin lock implementations */
  33.  
  34. CreateSpinlocks(key)
  35. IPCKey key;
  36.    /* the spin lock shared memory must have been created by now */
  37.    return(TRUE); 
  38. }
  39.  
  40. AttachSpinLocks(key)
  41. {
  42.     /* the spin lock shared memory must have been attached by now */
  43.     return(TRUE);
  44. }
  45.  
  46. InitSpinLocks(init, key)
  47. int init;
  48. IPCKey key;
  49. {
  50.   extern SPINLOCK ShmemLock;
  51.   extern SPINLOCK BindingLock;
  52.   extern SPINLOCK BufMgrLock;
  53.   extern SPINLOCK LockMgrLock;
  54.   extern SPINLOCK ProcStructLock;
  55.   extern SPINLOCK SInvalLock;
  56.   extern SPINLOCK OidGenLockId;
  57.  
  58. #ifdef SONY_JUKEBOX
  59.   extern SPINLOCK SJCacheLock;
  60.   extern SPINLOCK JBSpinLock;
  61. #endif /* SONY_JUKEBOX */
  62.  
  63. #ifdef MAIN_MEMORY
  64.   extern SPINLOCK MMCacheLock;
  65. #endif /* SONY_JUKEBOX */
  66.  
  67.   /* These six spinlocks have fixed location is shmem */
  68.   ShmemLock = (SPINLOCK) SHMEMLOCKID;
  69.   BindingLock = (SPINLOCK) BINDINGLOCKID;
  70.   BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
  71.   LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
  72.   ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
  73.   SInvalLock = (SPINLOCK) SINVALLOCKID;
  74.   OidGenLockId = (SPINLOCK) OIDGENLOCKID;
  75.  
  76. #ifdef SONY_JUKEBOX
  77.   SJCacheLock = (SPINLOCK) SJCACHELOCKID;
  78.   JBSpinLock = (SPINLOCK) JBSPINLOCKID;
  79. #endif /* SONY_JUKEBOX */
  80.  
  81. #ifdef MAIN_MEMORY
  82.   MMCacheLock = (SPINLOCK) MMCACHELOCKID;
  83. #endif /* MAIN_MEMORY */
  84.  
  85.   return(TRUE);
  86. }
  87.  
  88. SpinAcquire(lock)
  89. SPINLOCK lock;
  90. {
  91.     ExclusiveLock(lock);
  92.     PROC_INCR_SLOCK(lock);
  93. }
  94.  
  95. SpinRelease(lock)
  96. SPINLOCK lock;
  97. {
  98.     PROC_DECR_SLOCK(lock);
  99.     ExclusiveUnlock(lock);
  100. }
  101.  
  102. SpinIsLocked(lock)
  103. SPINLOCK lock;
  104. {
  105.     return(!LockIsFree(lock));
  106. }
  107. #else /* HAS_TEST_AND_SET */
  108. /* Spinlocks are implemented using SysV semaphores */
  109.  
  110.  
  111. /*
  112.  * SpinAcquire -- try to grab a spinlock
  113.  *
  114.  * FAILS if the semaphore is corrupted.
  115.  */
  116. SpinAcquire(lock) 
  117. SPINLOCK    lock;
  118. {
  119.   IpcSemaphoreLock(SpinLockId, lock, IpcExclusiveLock);
  120.   PROC_INCR_SLOCK(lock);
  121. }
  122.  
  123. /*
  124.  * SpinRelease -- release a spin lock
  125.  * 
  126.  * FAILS if the semaphore is corrupted
  127.  */
  128. SpinRelease(lock) 
  129. SPINLOCK    lock;
  130. {
  131.   Assert(SpinIsLocked(lock))
  132.   PROC_DECR_SLOCK(lock);
  133.   IpcSemaphoreUnlock(SpinLockId, lock, IpcExclusiveLock);
  134. }
  135.  
  136. int
  137. SpinIsLocked(lock)
  138. SPINLOCK    lock;
  139. {
  140.    int semval;
  141.  
  142.    semval = IpcSemaphoreGetValue(SpinLockId, lock);
  143.    return(semval < IpcSemaphoreDefaultStartValue);
  144. }
  145.  
  146. /*
  147.  * CreateSpinlocks -- Create a sysV semaphore array for
  148.  *    the spinlocks
  149.  *
  150.  */
  151. CreateSpinlocks(key)
  152. IPCKey key;
  153. {
  154.  
  155.   int status;
  156.   IpcSemaphoreId semid;
  157.   semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection, 
  158.                  IpcSemaphoreDefaultStartValue, &status);
  159.   if (status == IpcSemIdExist) {
  160.     IpcSemaphoreKill(key);
  161.     elog(NOTICE,"Destroying old spinlock semaphore");
  162.     semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection, 
  163.                    IpcSemaphoreDefaultStartValue, &status);
  164.     }
  165.  
  166.   if (semid >= 0) {
  167.     SpinLockId = semid;
  168.     return(TRUE);
  169.   }
  170.   /* cannot create spinlocks */
  171.   elog(FATAL,"CreateSpinlocks: cannot create spin locks");
  172.   return(FALSE);
  173. }
  174.  
  175. /*
  176.  * Attach to existing spinlock set
  177.  */
  178. AttachSpinLocks(key)
  179. IPCKey key;
  180. {
  181.   IpcSemaphoreId id;
  182.  
  183. #ifdef linux
  184.   id = semget (key, MAX_SPINS, 0600);
  185. #else
  186.   id = semget (key, MAX_SPINS, 0);
  187. #endif
  188.   if (id < 0) {
  189.     if (errno == EEXIST) {
  190.       /* key is the name of someone else's semaphore */
  191.       elog (FATAL,"AttachSpinlocks: SPIN_KEY belongs to someone else");
  192.     }
  193.     /* cannot create spinlocks */
  194.     elog(FATAL,"AttachSpinlocks: cannot create spin locks");
  195.     return(FALSE);
  196.   }
  197.   SpinLockId = id;
  198.   return(TRUE);
  199. }
  200.  
  201. /*
  202.  * InitSpinLocks -- Spinlock bootstrapping
  203.  * 
  204.  * We need several spinlocks for bootstrapping:
  205.  * BindingLock (for the shmem binding table) and
  206.  * ShmemLock (for the shmem allocator), BufMgrLock (for buffer
  207.  * pool exclusive access), LockMgrLock (for the lock table), and
  208.  * ProcStructLock (a spin lock for the shared process structure).
  209.  * If there's a Sony WORM drive attached, we also have a spinlock
  210.  * (SJCacheLock) for it.  Same story for the main memory storage mgr.
  211.  *
  212.  */
  213. InitSpinLocks(init, key)
  214. int init;
  215. IPCKey key;
  216. {
  217.   extern SPINLOCK ShmemLock;
  218.   extern SPINLOCK BindingLock;
  219.   extern SPINLOCK BufMgrLock;
  220.   extern SPINLOCK LockMgrLock;
  221.   extern SPINLOCK ProcStructLock;
  222.   extern SPINLOCK SInvalLock;
  223.   extern SPINLOCK OidGenLockId;
  224.  
  225. #ifdef SONY_JUKEBOX
  226.   extern SPINLOCK SJCacheLock;
  227.   extern SPINLOCK JBSpinLock;
  228. #endif /* SONY_JUKEBOX */
  229.  
  230. #ifdef MAIN_MEMORY
  231.   extern SPINLOCK MMCacheLock;
  232. #endif /* MAIN_MEMORY */
  233.  
  234.   if (!init || key != IPC_PRIVATE) {
  235.       /* if bootstrap and key is IPC_PRIVATE, it means that we are running
  236.        * backend by itself.  no need to attach spinlocks
  237.        */
  238.       if (! AttachSpinLocks(key)) {
  239.         elog(FATAL,"InitSpinLocks: couldnt attach spin locks");
  240.         return(FALSE);
  241.       }
  242.     }
  243.  
  244.   /* These five (or six) spinlocks have fixed location is shmem */
  245.   ShmemLock = (SPINLOCK) SHMEMLOCKID;
  246.   BindingLock = (SPINLOCK) BINDINGLOCKID;
  247.   BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
  248.   LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
  249.   ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
  250.   SInvalLock = (SPINLOCK) SINVALLOCKID;
  251.   OidGenLockId = (SPINLOCK) OIDGENLOCKID;
  252.  
  253. #ifdef SONY_JUKEBOX
  254.   SJCacheLock = (SPINLOCK) SJCACHELOCKID;
  255.   JBSpinLock = (SPINLOCK) JBSPINLOCKID;
  256. #endif /* SONY_JUKEBOX */
  257.  
  258. #ifdef MAIN_MEMORY
  259.   MMCacheLock = (SPINLOCK) MMCACHELOCKID;
  260. #endif /* MAIN_MEMORY */
  261.   
  262.   return(TRUE);
  263. }
  264. #endif /* HAS_TEST_AND_SET */
  265.