aboutsummaryrefslogtreecommitdiff
path: root/libitm/config
diff options
context:
space:
mode:
authorTorvald Riegel <triegel@redhat.com>2016-01-13 12:40:34 +0000
committerTorvald Riegel <torvald@gcc.gnu.org>2016-01-13 12:40:34 +0000
commit629e47295b44d9adf01b66061dd891a25e567474 (patch)
tree0f4bfc83fa01d0a035d86c869e199905d89075cb /libitm/config
parent8bc47ae2a784685f79dca8d7d04135c939a49452 (diff)
downloadgcc-629e47295b44d9adf01b66061dd891a25e567474.zip
gcc-629e47295b44d9adf01b66061dd891a25e567474.tar.gz
gcc-629e47295b44d9adf01b66061dd891a25e567474.tar.bz2
libitm: Fix privatization safety interaction with serial mode.
From-SVN: r232322
Diffstat (limited to 'libitm/config')
-rw-r--r--libitm/config/linux/rwlock.cc13
-rw-r--r--libitm/config/posix/rwlock.cc20
2 files changed, 33 insertions, 0 deletions
diff --git a/libitm/config/linux/rwlock.cc b/libitm/config/linux/rwlock.cc
index 46a775f..381a553 100644
--- a/libitm/config/linux/rwlock.cc
+++ b/libitm/config/linux/rwlock.cc
@@ -158,6 +158,19 @@ gtm_rwlock::write_lock_generic (gtm_thread *tx)
while (it->shared_state.load (memory_order_relaxed)
!= ~(typeof it->shared_state)0)
{
+ // If this is an upgrade, we have to break deadlocks with
+ // privatization safety. This may fail on our side, in which
+ // case we need to cancel our attempt to upgrade. Also, we do not
+ // block but just spin so that we never have to be woken.
+ if (tx != 0)
+ {
+ if (!abi_disp()->snapshot_most_recent ())
+ {
+ write_unlock ();
+ return false;
+ }
+ continue;
+ }
// An active reader. Wait until it has finished. To avoid lost
// wake-ups, we need to use Dekker-like synchronization.
// Note that we can reset writer_readers to zero when we see after
diff --git a/libitm/config/posix/rwlock.cc b/libitm/config/posix/rwlock.cc
index bf58ec0..1e1eea8 100644
--- a/libitm/config/posix/rwlock.cc
+++ b/libitm/config/posix/rwlock.cc
@@ -200,6 +200,26 @@ gtm_rwlock::write_lock_generic (gtm_thread *tx)
if (readers == 0)
break;
+ // If this is an upgrade, we have to break deadlocks with
+ // privatization safety. This may fail on our side, in which
+ // case we need to cancel our attempt to upgrade. Also, we do not
+ // block using the convdar but just spin so that we never have to be
+ // woken.
+ // FIXME This is horribly inefficient -- but so is not being able
+ // to use futexes in this case.
+ if (tx != 0)
+ {
+ pthread_mutex_unlock (&this->mutex);
+ if (!abi_disp ()->snapshot_most_recent ())
+ {
+ write_unlock ();
+ return false;
+ }
+ pthread_mutex_lock (&this->mutex);
+ continue;
+ }
+
+
// We've seen a number of readers, so we publish this number and wait.
this->a_readers = readers;
pthread_cond_wait (&this->c_confirmed_writers, &this->mutex);