aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-12-11 02:58:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-12-11 02:58:49 +0000
commit4433eb1dff36707914081efeaff222f81412d60f (patch)
tree2e5d04e18ca0a271623ee4fa15210881a8e219ce /src
parent07009651ce4b2cc866171aed32bb67c8c65137ce (diff)
downloadpostgresql-4433eb1dff36707914081efeaff222f81412d60f.tar.gz
postgresql-4433eb1dff36707914081efeaff222f81412d60f.zip
Make sure that inlined S_UNLOCK is marked as an update of a 'volatile'
object. This should prevent the compiler from reordering loads and stores into or out of a critical section.
Diffstat (limited to 'src')
-rw-r--r--src/include/storage/s_lock.h11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 166019a6faf..721b488c087 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -43,6 +43,11 @@
* 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)