summaryrefslogtreecommitdiff
path: root/libitm
diff options
context:
space:
mode:
authortorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-14 13:14:12 +0000
committertorvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-14 13:14:12 +0000
commitef3a70c39560b819a3731adc4079c643aa75c20b (patch)
tree0c010bcc192851eb16058d7cb732414acc193075 /libitm
parentc625f5685bcb1609fbfde7535e90de262fedd91f (diff)
downloadgcc-ef3a70c39560b819a3731adc4079c643aa75c20b.tar.gz
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
Diffstat (limited to 'libitm')
-rw-r--r--libitm/ChangeLog8
-rw-r--r--libitm/dispatch.h10
-rw-r--r--libitm/retry.cc27
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 <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.
* 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());
+ }
}
}