diff options
author | torvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-13 12:40:34 +0000 |
---|---|---|
committer | torvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-13 12:40:34 +0000 |
commit | 1246355c4c2ed8cd81a6baed380685e32414133a (patch) | |
tree | 0f4bfc83fa01d0a035d86c869e199905d89075cb /libitm/config | |
parent | 2e1cb7c04a9c5336615dfafdee1cb7fc1caf7559 (diff) | |
download | gcc-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.cc | 13 | ||||
-rw-r--r-- | libitm/config/posix/rwlock.cc | 20 |
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); |