diff options
Diffstat (limited to 'src/base/atomicops-internals-x86.cc')
-rw-r--r-- | src/base/atomicops-internals-x86.cc | 17 |
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); |