summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-06 20:31:08 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-06 20:31:08 +0000
commit67518851535a5303a126201b2c68508c369f96ef (patch)
treefc46d4517215160085224e179732892943443922 /libstdc++-v3
parentf819bb7398c28c88bd12f95589ebae74d837cad4 (diff)
downloadgcc-67518851535a5303a126201b2c68508c369f96ef.tar.gz
2012-09-06 Thiago Macieira <thiago.macieira@intel.com>
PR libstdc++/54172 * libsupc++/guard.cc (__cxa_guard_acquire): Exit the loop earlier if we detect that another thread has had success. Don't compare_exchange from a finished state back to a waiting state. Comment. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191042 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/libsupc++/guard.cc19
2 files changed, 23 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 707e474b899..f3a5852dd21 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2012-09-06 Thiago Macieira <thiago.macieira@intel.com>
+
+ PR libstdc++/54172
+ * libsupc++/guard.cc (__cxa_guard_acquire): Exit the loop earlier if
+ we detect that another thread has had success. Don't compare_exchange
+ from a finished state back to a waiting state. Comment.
+
2012-09-05 François Dumont <fdumont@gcc.gnu.org>
PR libstdc++/54296
diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc
index adc96086108..60165cdecb4 100644
--- a/libstdc++-v3/libsupc++/guard.cc
+++ b/libstdc++-v3/libsupc++/guard.cc
@@ -244,13 +244,13 @@ namespace __cxxabiv1
if (__gthread_active_p ())
{
int *gi = (int *) (void *) g;
- int expected(0);
const int guard_bit = _GLIBCXX_GUARD_BIT;
const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT;
const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
while (1)
{
+ int expected(0);
if (__atomic_compare_exchange_n(gi, &expected, pending_bit, false,
__ATOMIC_ACQ_REL,
__ATOMIC_RELAXED))
@@ -264,13 +264,26 @@ namespace __cxxabiv1
// Already initialized.
return 0;
}
+
if (expected == pending_bit)
{
+ // Use acquire here.
int newv = expected | waiting_bit;
if (!__atomic_compare_exchange_n(gi, &expected, newv, false,
__ATOMIC_ACQ_REL,
- __ATOMIC_RELAXED))
- continue;
+ __ATOMIC_ACQUIRE))
+ {
+ if (expected == guard_bit)
+ {
+ // Make a thread that failed to set the
+ // waiting bit exit the function earlier,
+ // if it detects that another thread has
+ // successfully finished initialising.
+ return 0;
+ }
+ if (expected == 0)
+ continue;
+ }
expected = newv;
}