From 4433eb1dff36707914081efeaff222f81412d60f Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Tue, 11 Dec 2001 02:58:49 +0000 Subject: [PATCH] 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. --- src/include/storage/s_lock.h | 11 ++++++++--- 1 file 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) -- GitLab