Make sure that inlined S_UNLOCK is marked as an update of a 'volatile'
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 11 Dec 2001 02:58:49 +0000 (02:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 11 Dec 2001 02:58:49 +0000 (02:58 +0000)
object.  This should prevent the compiler from reordering loads and stores
into or out of a critical section.

src/include/storage/s_lock.h

index 166019a6fafc4427c653d80beaa2a024e83c36e7..721b488c0874a6a0bbb4f2a152e522d9a5fedb35 100644 (file)
  *     will "fail" if interrupted.  Therefore TAS() should always be invoked
  *     in a retry loop, even if you are certain the lock is free.
  *
+ *     ANOTHER CAUTION: be sure that TAS() and S_UNLOCK() represent sequence
+ *     points, ie, loads and stores of other values must not be moved across
+ *     a lock or unlock.  In most cases it suffices to make the operation be
+ *     done through a "volatile" pointer.
+ *
  *     On most supported platforms, TAS() uses a tas() function written
  *     in assembly language to execute a hardware atomic-test-and-set
  *     instruction.  Equivalent OS-supplied mutex routines could be used too.
@@ -58,7 +63,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *       $Id: s_lock.h,v 1.95 2001/09/29 04:02:26 tgl Exp $
+ *       $Id: s_lock.h,v 1.96 2001/12/11 02:58:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -306,7 +311,7 @@ tas(volatile slock_t *s_lock)
 do \
 {\
        __asm__ __volatile__ (" mb \n"); \
-       *(lock) = 0; \
+       *((volatile slock_t *) (lock)) = 0; \
 } while (0)
 
 static __inline__ int
@@ -500,7 +505,7 @@ extern int  tas_sema(volatile slock_t *lock);
 #endif  /* S_LOCK_FREE */
 
 #if !defined(S_UNLOCK)
-#define S_UNLOCK(lock)         (*(lock) = 0)
+#define S_UNLOCK(lock)         (*((volatile slock_t *) (lock)) = 0)
 #endif  /* S_UNLOCK */
 
 #if !defined(S_INIT_LOCK)