Commit 5b9cf5d2 by Torvald Riegel Committed by Torvald Riegel

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
parent 7d33bcb7
2012-02-14 Torvald Riegel <triegel@redhat.com> 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. * util.cc (GTM::xcalloc): New.
* common.h (GTM::xcalloc): Declare. * common.h (GTM::xcalloc): Declare.
......
...@@ -245,6 +245,12 @@ struct method_group ...@@ -245,6 +245,12 @@ struct method_group
// Stop using any method from this group for now. This can be used to // 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. // destruct meta data as soon as this method group is not used anymore.
virtual void fini() = 0; 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: ...@@ -290,6 +296,10 @@ public:
// method on begin of a nested transaction without committing or restarting // method on begin of a nested transaction without committing or restarting
// the parent method. // the parent method.
virtual abi_dispatch* closed_nesting_alternative() { return 0; } 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 read_only () const { return m_read_only; }
bool write_through() const { return m_write_through; } bool write_through() const { return m_write_through; }
......
...@@ -58,11 +58,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r) ...@@ -58,11 +58,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r)
serial_lock.read_unlock(this); serial_lock.read_unlock(this);
serial_lock.write_lock(); serial_lock.write_lock();
if (disp->get_method_group() == default_dispatch->get_method_group()) if (disp->get_method_group() == default_dispatch->get_method_group())
{ // Still the same method group.
// Still the same method group. disp->get_method_group()->reinit();
disp->get_method_group()->fini();
disp->get_method_group()->init();
}
serial_lock.write_unlock(); serial_lock.write_unlock();
serial_lock.read_lock(this); serial_lock.read_lock(this);
if (disp->get_method_group() != default_dispatch->get_method_group()) if (disp->get_method_group() != default_dispatch->get_method_group())
...@@ -72,11 +69,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r) ...@@ -72,11 +69,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r)
} }
} }
else else
{ // We are a serial transaction already, which makes things simple.
// We are a serial transaction already, which makes things simple. disp->get_method_group()->reinit();
disp->get_method_group()->fini();
disp->get_method_group()->init();
}
} }
bool retry_irr = (r == RESTART_SERIAL_IRR); bool retry_irr = (r == RESTART_SERIAL_IRR);
...@@ -249,7 +243,7 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now) ...@@ -249,7 +243,7 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now)
// Only one thread, so use a serializing method. // Only one thread, so use a serializing method.
// ??? If we don't have a fast serial mode implementation, it might be // ??? If we don't have a fast serial mode implementation, it might be
// better to use the global lock method set here. // 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); set_default_dispatch(default_dispatch_user);
else else
set_default_dispatch(dispatch_serialirr()); set_default_dispatch(dispatch_serialirr());
...@@ -257,9 +251,16 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now) ...@@ -257,9 +251,16 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now)
else if (now > 1 && previous <= 1) else if (now > 1 && previous <= 1)
{ {
// More than one thread, use the default method. // 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); set_default_dispatch(default_dispatch_user);
else 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());
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment