diff options
author | Torvald Riegel <triegel@redhat.com> | 2016-01-13 12:40:34 +0000 |
---|---|---|
committer | Torvald Riegel <torvald@gcc.gnu.org> | 2016-01-13 12:40:34 +0000 |
commit | 629e47295b44d9adf01b66061dd891a25e567474 (patch) | |
tree | 0f4bfc83fa01d0a035d86c869e199905d89075cb /libitm/config | |
parent | 8bc47ae2a784685f79dca8d7d04135c939a49452 (diff) | |
download | gcc-629e47295b44d9adf01b66061dd891a25e567474.tar.gz |
libitm: Fix privatization safety interaction with serial mode.
From-SVN: r232322
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); |