mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
7d33bcb738
commit
5b9cf5d2bf
|
@ -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>
|
2012-02-14 Torvald Riegel <triegel@redhat.com>
|
||||||
|
|
||||||
* util.cc (GTM::xcalloc): New.
|
* util.cc (GTM::xcalloc): New.
|
||||||
|
|
|
@ -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:
|
||||||
// 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
// 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)
|
||||||
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue