Compare commits

...

1 Commits

Author SHA1 Message Date
Michael Cahill
eaa7b5f0fc Merge pull request #2670 from wiredtiger/wt-2566
WT-2566 Lock/unlock operations should imply memory barriers.
(cherry picked from commit 05cfbc26c2)
2016-04-20 17:14:06 +10:00
2 changed files with 38 additions and 11 deletions

View File

@@ -306,6 +306,12 @@ __wt_fair_lock(WT_SESSION_IMPL *session, WT_FAIR_LOCK *lock)
__wt_sleep(0, 10);
}
/*
* Applications depend on a barrier here so that operations holding the
* lock see consistent data.
*/
WT_READ_BARRIER();
return (0);
}
@@ -318,6 +324,12 @@ __wt_fair_unlock(WT_SESSION_IMPL *session, WT_FAIR_LOCK *lock)
{
WT_UNUSED(session);
/*
* Ensure that all updates made while the lock was held are visible to
* the next thread to acquire the lock.
*/
WT_WRITE_BARRIER();
/*
* We have exclusive access - the update does not need to be atomic.
*/

View File

@@ -183,6 +183,8 @@ __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
session, WT_VERB_MUTEX, "rwlock: readlock %s", rwlock->name));
WT_STAT_FAST_CONN_INCR(session, rwlock_read);
WT_DIAGNOSTIC_YIELD;
l = &rwlock->rwlock;
/*
@@ -213,6 +215,12 @@ __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
*/
++l->s.readers;
/*
* Applications depend on a barrier here so that operations holding the
* lock see consistent data.
*/
WT_READ_BARRIER();
return (0);
}
@@ -306,6 +314,12 @@ __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
__wt_sleep(0, 10);
}
/*
* Applications depend on a barrier here so that operations holding the
* lock see consistent data.
*/
WT_READ_BARRIER();
return (0);
}
@@ -316,31 +330,32 @@ __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
int
__wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
{
wt_rwlock_t *l, copy;
wt_rwlock_t *l, new;
WT_RET(__wt_verbose(
session, WT_VERB_MUTEX, "rwlock: writeunlock %s", rwlock->name));
/*
* Ensure that all updates made while the lock was held are visible to
* the next thread to acquire the lock.
*/
WT_WRITE_BARRIER();
l = &rwlock->rwlock;
copy = *l;
new = *l;
/*
* We're the only writer of the writers/readers fields, so the update
* does not need to be atomic; we have to update both values at the
* same time though, otherwise we'd potentially race with the thread
* next granted the lock.
*
* Use a memory barrier to ensure the compiler doesn't mess with these
* instructions and rework the code in a way that avoids the update as
* a unit.
*/
WT_BARRIER();
++new.s.writers;
++new.s.readers;
l->i.wr = new.i.wr;
++copy.s.writers;
++copy.s.readers;
l->i.wr = copy.i.wr;
WT_DIAGNOSTIC_YIELD;
return (0);
}