summaryrefslogtreecommitdiff
path: root/libitm/config
diff options
context:
space:
mode:
authortorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-13 12:40:34 +0000
committertorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-13 12:40:34 +0000
commit1246355c4c2ed8cd81a6baed380685e32414133a (patch)
tree0f4bfc83fa01d0a035d86c869e199905d89075cb /libitm/config
parent2e1cb7c04a9c5336615dfafdee1cb7fc1caf7559 (diff)
downloadgcc-1246355c4c2ed8cd81a6baed380685e32414133a.tar.gz
libitm: Fix privatization safety interaction with serial mode.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232322 138bc75d-0d04-0410-961f-82ee72b054a4
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 46a775fd4e8..381a553171e 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 bf58ec051e6..1e1eea820f2 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);