summaryrefslogtreecommitdiff
path: root/libitm
diff options
context:
space:
mode:
authortorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-20 20:57:23 +0000
committertorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-20 20:57:23 +0000
commit625ff7f1b91264c832b07100f8a48791255d9f1d (patch)
treedc864c9bb78042d05b370d6e2decbdc8ab5e601b /libitm
parentcebd4f00cfb0d8d1c836781cc9cb7198b3b53751 (diff)
downloadlinaro-gcc-625ff7f1b91264c832b07100f8a48791255d9f1d.tar.gz
linaro-gcc-625ff7f1b91264c832b07100f8a48791255d9f1d.tar.bz2
linaro-gcc-625ff7f1b91264c832b07100f8a48791255d9f1d.zip
libitm: Optimize synchronization in gl_wt rollback.
libitm/ * method-gl.cc (gl_wt_dispatch::rollback): Optimize memory orders. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184402 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libitm')
-rw-r--r--libitm/ChangeLog4
-rw-r--r--libitm/method-gl.cc28
2 files changed, 20 insertions, 12 deletions
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index 977613d05be..da94906bcd3 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,5 +1,9 @@
2012-02-20 Torvald Riegel <triegel@redhat.com>
+ * method-gl.cc (gl_wt_dispatch::rollback): Optimize memory orders.
+
+2012-02-20 Torvald Riegel <triegel@redhat.com>
+
* method-gl.cc (gl_wt_dispatch::trycommit): Remove handling of
serial mode corner cases made obsolete by prior gtm_rwlock changes.
(gl_wt_dispatch.rollback): Same.
diff --git a/libitm/method-gl.cc b/libitm/method-gl.cc
index 5bae22b90c1..4fd506ef154 100644
--- a/libitm/method-gl.cc
+++ b/libitm/method-gl.cc
@@ -314,22 +314,26 @@ public:
// value that is correct wrt. privatization safety.
if (gl_mg::is_locked(v))
{
- // Release the global orec, increasing its version number / timestamp.
- // See begin_or_restart() for why we need release memory order here.
+ // With our rollback, global time increases.
v = gl_mg::clear_locked(v) + 1;
- o_gl_mg.orec.store(v, memory_order_release);
- // Also reset the timestamp published via shared_state.
+ // First reset the timestamp published via shared_state. Release
+ // memory order will make this happen after undoing prior data writes.
+ // This must also happen before we actually release the global orec
+ // next, so that future update transactions in other threads observe
+ // a meaningful snapshot time for our transaction; otherwise, they
+ // could read a shared_store value with the LOCK_BIT set, which can
+ // break privatization safety because it's larger than the actual
+ // snapshot time. Note that we only need to consider other update
+ // transactions because only those will potentially privatize data.
tx->shared_state.store(v, memory_order_release);
- // We need a store-load barrier after this store to prevent it
- // from becoming visible after later data loads because the
- // previous value of shared_state has been higher than the actual
- // snapshot time (the lock bit had been set), which could break
- // privatization safety. We do not need a barrier before this
- // store (see pre_write() for an explanation).
- // ??? What is the precise reasoning in the C++11 model?
- atomic_thread_fence(memory_order_seq_cst);
+ // Release the global orec, increasing its version number / timestamp.
+ // See begin_or_restart() for why we need release memory order here,
+ // and we also need it to make future update transactions read the
+ // prior update to shared_state too (update transactions acquire the
+ // global orec with acquire memory order).
+ o_gl_mg.orec.store(v, memory_order_release);
}
}