summaryrefslogtreecommitdiff
path: root/libitm
diff options
context:
space:
mode:
authortorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-13 22:01:34 +0000
committertorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-13 22:01:34 +0000
commit8e4de83abc921c9bc22852bf52bc6c6fea162e99 (patch)
tree9bf6e180f1ef5968020eaafc59db2b5877e8e03f /libitm
parentf5774b88bb705ccb5229594875f95e86b05f014c (diff)
downloadgcc-8e4de83abc921c9bc22852bf52bc6c6fea162e99.tar.gz
libitm: Fix lost wake-up in serial lock.
PR libitm/52526 * config/linux/rwlock.cc (GTM::gtm_rwlock::read_lock): Fix lost wake-up. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185358 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libitm')
-rw-r--r--libitm/ChangeLog6
-rw-r--r--libitm/config/linux/rwlock.cc26
2 files changed, 32 insertions, 0 deletions
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index 5df1380f606..97c264522bb 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-13 Torvald Riegel <triegel@redhat.com>
+
+ PR libitm/52526
+ * config/linux/rwlock.cc (GTM::gtm_rwlock::read_lock): Fix lost
+ wake-up.
+
2012-03-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* configure.tgt (*-*-osf*): Remove.
diff --git a/libitm/config/linux/rwlock.cc b/libitm/config/linux/rwlock.cc
index ad1b042964a..cf1fdd55a91 100644
--- a/libitm/config/linux/rwlock.cc
+++ b/libitm/config/linux/rwlock.cc
@@ -74,6 +74,32 @@ gtm_rwlock::read_lock (gtm_thread *tx)
atomic_thread_fence (memory_order_seq_cst);
if (writers.load (memory_order_relaxed))
futex_wait(&readers, 1);
+ else
+ {
+ // There is no writer, actually. However, we can have enabled
+ // a futex_wait in other readers by previously setting readers
+ // to 1, so we have to wake them up because there is no writer
+ // that will do that. We don't know whether the wake-up is
+ // really necessary, but we can get lost wake-up situations
+ // otherwise.
+ // No additional barrier nor a nonrelaxed load is required due
+ // to coherency constraints. write_unlock() checks readers to
+ // see if any wake-up is necessary, but it is not possible that
+ // a reader's store prevents a required later writer wake-up;
+ // If the waking reader's store (value 0) is in modification
+ // order after the waiting readers store (value 1), then the
+ // latter will have to read 0 in the futex due to coherency
+ // constraints and the happens-before enforced by the futex
+ // (paragraph 6.10 in the standard, 6.19.4 in the Batty et al
+ // TR); second, the writer will be forced to read in
+ // modification order too due to Dekker-style synchronization
+ // with the waiting reader (see write_unlock()).
+ // ??? Can we avoid the wake-up if readers is zero (like in
+ // write_unlock())? Anyway, this might happen too infrequently
+ // to improve performance significantly.
+ readers.store (0, memory_order_relaxed);
+ futex_wake(&readers, INT_MAX);
+ }
}
// And we try again to acquire a read lock.