Make sure that inlined S_UNLOCK is marked as an update of a 'volatile'
authorTom Lane
Tue, 11 Dec 2001 02:58:49 +0000 (02:58 +0000)
committerTom Lane
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)