From ef3a70c39560b819a3731adc4079c643aa75c20b Mon Sep 17 00:00:00 2001 From: torvald Date: Tue, 14 Feb 2012 13:14:12 +0000 Subject: [PATCH] libitm: Improve method reinit and choice. libitm/ * dispatch.h (GTM::abi_dispatch::supports): New. (GTM::method_group::reinit): New. * retry.cc (GTM::gtm_thread::decide_retry_strategy): Use reinit(). (GTM::gtm_thread::number_of_threads_changed): Check that the method supports the current situation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184211 138bc75d-0d04-0410-961f-82ee72b054a4 --- libitm/ChangeLog | 8 ++++++++ libitm/dispatch.h | 10 ++++++++++ libitm/retry.cc | 27 ++++++++++++++------------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/libitm/ChangeLog b/libitm/ChangeLog index 130c9efbd85..e44057d38d3 100644 --- a/libitm/ChangeLog +++ b/libitm/ChangeLog @@ -1,5 +1,13 @@ 2012-02-14 Torvald Riegel + * dispatch.h (GTM::abi_dispatch::supports): New. + (GTM::method_group::reinit): New. + * retry.cc (GTM::gtm_thread::decide_retry_strategy): Use reinit(). + (GTM::gtm_thread::number_of_threads_changed): Check that the method + supports the current situation. + +2012-02-14 Torvald Riegel + * util.cc (GTM::xcalloc): New. * common.h (GTM::xcalloc): Declare. diff --git a/libitm/dispatch.h b/libitm/dispatch.h index dbf05e4da37..d059c493507 100644 --- a/libitm/dispatch.h +++ b/libitm/dispatch.h @@ -245,6 +245,12 @@ struct method_group // Stop using any method from this group for now. This can be used to // destruct meta data as soon as this method group is not used anymore. virtual void fini() = 0; + // This can be overriden to implement more light-weight re-initialization. + virtual void reinit() + { + fini(); + init(); + } }; @@ -290,6 +296,10 @@ public: // method on begin of a nested transaction without committing or restarting // the parent method. virtual abi_dispatch* closed_nesting_alternative() { return 0; } + // Returns true iff this method group supports the current situation. + // NUMBER_OF_THREADS is the current number of threads that might execute + // transactions. + virtual bool supports(unsigned number_of_threads) { return true; } bool read_only () const { return m_read_only; } bool write_through() const { return m_write_through; } diff --git a/libitm/retry.cc b/libitm/retry.cc index decd7731b46..761a066e834 100644 --- a/libitm/retry.cc +++ b/libitm/retry.cc @@ -58,11 +58,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r) serial_lock.read_unlock(this); serial_lock.write_lock(); if (disp->get_method_group() == default_dispatch->get_method_group()) - { - // Still the same method group. - disp->get_method_group()->fini(); - disp->get_method_group()->init(); - } + // Still the same method group. + disp->get_method_group()->reinit(); serial_lock.write_unlock(); serial_lock.read_lock(this); if (disp->get_method_group() != default_dispatch->get_method_group()) @@ -72,11 +69,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r) } } else - { - // We are a serial transaction already, which makes things simple. - disp->get_method_group()->fini(); - disp->get_method_group()->init(); - } + // We are a serial transaction already, which makes things simple. + disp->get_method_group()->reinit(); } bool retry_irr = (r == RESTART_SERIAL_IRR); @@ -249,7 +243,7 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now) // Only one thread, so use a serializing method. // ??? If we don't have a fast serial mode implementation, it might be // better to use the global lock method set here. - if (default_dispatch_user) + if (default_dispatch_user && default_dispatch_user->supports(now)) set_default_dispatch(default_dispatch_user); else set_default_dispatch(dispatch_serialirr()); @@ -257,9 +251,16 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now) else if (now > 1 && previous <= 1) { // More than one thread, use the default method. - if (default_dispatch_user) + if (default_dispatch_user && default_dispatch_user->supports(now)) set_default_dispatch(default_dispatch_user); else - set_default_dispatch(dispatch_serialirr_onwrite()); + { + abi_dispatch* a = dispatch_serialirr_onwrite(); + if (a->supports(now)) + set_default_dispatch(a); + else + // Serial-irrevocable mode always works. + set_default_dispatch(dispatch_serialirr()); + } } } -- 2.11.0