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.

From-SVN: r184211
This commit is contained in:
Torvald Riegel 2012-02-14 13:14:12 +00:00 committed by Torvald Riegel
parent 7d33bcb738
commit 5b9cf5d2bf
3 changed files with 32 additions and 13 deletions

View file

@ -1,3 +1,11 @@
2012-02-14 Torvald Riegel <triegel@redhat.com>
* 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 <triegel@redhat.com>
* util.cc (GTM::xcalloc): New.

View file

@ -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; }

View file

@ -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());
}
}
}