mirror of git://gcc.gnu.org/git/gcc.git
libitm: Optimize synchronization in gl_wt rollback.
libitm/ * method-gl.cc (gl_wt_dispatch::rollback): Optimize memory orders. From-SVN: r184402
This commit is contained in:
parent
651ff4152e
commit
4c9bd6acb0
|
@ -1,3 +1,7 @@
|
||||||
|
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>
|
2012-02-20 Torvald Riegel <triegel@redhat.com>
|
||||||
|
|
||||||
* method-gl.cc (gl_wt_dispatch::trycommit): Remove handling of
|
* method-gl.cc (gl_wt_dispatch::trycommit): Remove handling of
|
||||||
|
|
|
@ -314,22 +314,26 @@ public:
|
||||||
// value that is correct wrt. privatization safety.
|
// value that is correct wrt. privatization safety.
|
||||||
if (gl_mg::is_locked(v))
|
if (gl_mg::is_locked(v))
|
||||||
{
|
{
|
||||||
// Release the global orec, increasing its version number / timestamp.
|
// With our rollback, global time increases.
|
||||||
// See begin_or_restart() for why we need release memory order here.
|
|
||||||
v = gl_mg::clear_locked(v) + 1;
|
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);
|
tx->shared_state.store(v, memory_order_release);
|
||||||
|
|
||||||
// We need a store-load barrier after this store to prevent it
|
// Release the global orec, increasing its version number / timestamp.
|
||||||
// from becoming visible after later data loads because the
|
// See begin_or_restart() for why we need release memory order here,
|
||||||
// previous value of shared_state has been higher than the actual
|
// and we also need it to make future update transactions read the
|
||||||
// snapshot time (the lock bit had been set), which could break
|
// prior update to shared_state too (update transactions acquire the
|
||||||
// privatization safety. We do not need a barrier before this
|
// global orec with acquire memory order).
|
||||||
// store (see pre_write() for an explanation).
|
o_gl_mg.orec.store(v, memory_order_release);
|
||||||
// ??? What is the precise reasoning in the C++11 model?
|
|
||||||
atomic_thread_fence(memory_order_seq_cst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue