diff options
Diffstat (limited to 'libitm/method-serial.cc')
-rw-r--r-- | libitm/method-serial.cc | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/libitm/method-serial.cc b/libitm/method-serial.cc index 09cfdd4a175..38857dcc80d 100644 --- a/libitm/method-serial.cc +++ b/libitm/method-serial.cc @@ -212,11 +212,46 @@ class serialirr_onwrite_dispatch : public serialirr_dispatch } }; +// This group is pure HTM with serial mode as a fallback. There is no +// difference to serial_mg except that we need to enable or disable the HTM +// fastpath. See gtm_thread::begin_transaction. +struct htm_mg : public method_group +{ + virtual void init() + { + // Enable the HTM fastpath if the HW is available. The fastpath is + // initially disabled. +#ifdef USE_HTM_FASTPATH + htm_fastpath = htm_init(); +#endif + } + virtual void fini() + { + // Disable the HTM fastpath. + htm_fastpath = 0; + } +}; + +static htm_mg o_htm_mg; + +// We just need the subclass to associate it with the HTM method group that +// sets up the HTM fast path. This will use serial_dispatch as fallback for +// transactions that might get canceled; it has a different method group, but +// this is harmless for serial dispatchs because they never abort. +class htm_dispatch : public serialirr_dispatch +{ + public: + htm_dispatch() : serialirr_dispatch(false, true, false, false, + gtm_thread::STATE_SERIAL | gtm_thread::STATE_IRREVOCABLE, &o_htm_mg) + { } +}; + } // anon namespace static const serialirr_dispatch o_serialirr_dispatch; static const serial_dispatch o_serial_dispatch; static const serialirr_onwrite_dispatch o_serialirr_onwrite_dispatch; +static const htm_dispatch o_htm_dispatch; abi_dispatch * GTM::dispatch_serialirr () @@ -237,6 +272,12 @@ GTM::dispatch_serialirr_onwrite () const_cast<serialirr_onwrite_dispatch *>(&o_serialirr_onwrite_dispatch); } +abi_dispatch * +GTM::dispatch_htm () +{ + return const_cast<htm_dispatch *>(&o_htm_dispatch); +} + // Put the transaction into serial-irrevocable mode. void @@ -244,6 +285,13 @@ GTM::gtm_thread::serialirr_mode () { struct abi_dispatch *disp = abi_disp (); +#if defined(USE_HTM_FASTPATH) + // HTM fastpath. If we are executing a HW transaction, don't go serial but + // continue. See gtm_thread::begin_transaction. + if (likely(htm_fastpath && !gtm_thread::serial_lock.is_write_locked())) + return; +#endif + if (this->state & STATE_SERIAL) { if (this->state & STATE_IRREVOCABLE) |