aboutsummaryrefslogtreecommitdiff
path: root/src/base/atomicops-internals-x86.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/atomicops-internals-x86.cc')
-rw-r--r--src/base/atomicops-internals-x86.cc17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/base/atomicops-internals-x86.cc b/src/base/atomicops-internals-x86.cc
index c3391e7..4f75d47 100644
--- a/src/base/atomicops-internals-x86.cc
+++ b/src/base/atomicops-internals-x86.cc
@@ -1,4 +1,3 @@
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
@@ -67,8 +66,9 @@
// Set the flags so that code will run correctly and conservatively
// until InitGoogle() is called.
struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
+ false, // bug can't exist before process spawns multiple threads
false, // no SSE2
- false // no cmpxchg16b
+ false, // no cmpxchg16b
};
// Initialize the AtomicOps_Internalx86CPUFeatures struct.
@@ -96,6 +96,19 @@ static void AtomicOps_Internalx86CPUFeaturesInit() {
model += ((eax >> 16) & 0xf) << 4;
}
+ // Opteron Rev E has a bug in which on very rare occasions a locked
+ // instruction doesn't act as a read-acquire barrier if followed by a
+ // non-locked read-modify-write instruction. Rev F has this bug in
+ // pre-release versions, but not in versions released to customers,
+ // so we test only for Rev E, which is family 15, model 32..63 inclusive.
+ if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD
+ family == 15 &&
+ 32 <= model && model <= 63) {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
+ } else {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
+ }
+
// edx bit 26 is SSE2 which we use to tell use whether we can use mfence
AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);