From 1246355c4c2ed8cd81a6baed380685e32414133a Mon Sep 17 00:00:00 2001 From: torvald Date: Wed, 13 Jan 2016 12:40:34 +0000 Subject: 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 --- libitm/config/linux/rwlock.cc | 13 +++++++++++++ libitm/config/posix/rwlock.cc | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+) (limited to 'libitm/config') 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); -- cgit v1.2.1