Don't let protected variable access to be reordered after spinlock release.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 14 Oct 2014 07:01:00 +0000 (10:01 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 14 Oct 2014 07:05:17 +0000 (10:05 +0300)
LWLockAcquireWithVar needs to set the protected variable while holding
the spinlock. Need to use a volatile pointer to make sure it doesn't get
reordered by the compiler. The other functions that accessed the protected
variable already got this right.

9.4 only. Earlier releases didn't have this code, and in master, spinlock
release acts as a compiler barrier.

src/backend/storage/lmgr/lwlock.c

index 1607bc9e536d3f66cdecc61ed31389ebbb11cca4..cee3f082dea6af1180d1b14d3228777ee0301a29 100644 (file)
@@ -482,6 +482,7 @@ static inline bool
 LWLockAcquireCommon(LWLock *l, LWLockMode mode, uint64 *valptr, uint64 val)
 {
        volatile LWLock *lock = l;
+       volatile uint64 *valp = valptr;
        PGPROC     *proc = MyProc;
        bool            retry = false;
        bool            result = true;
@@ -637,8 +638,8 @@ LWLockAcquireCommon(LWLock *l, LWLockMode mode, uint64 *valptr, uint64 val)
        }
 
        /* If there's a variable associated with this lock, initialize it */
-       if (valptr)
-               *valptr = val;
+       if (valp)
+               *valp = val;
 
        /* We are done updating shared state of the lock itself. */
        SpinLockRelease(&lock->mutex);