mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 04:27:37 +00:00
e351d68da5
--HG-- rename : security/sandbox/base/at_exit.cc => security/sandbox/chromium/base/at_exit.cc rename : security/sandbox/base/at_exit.h => security/sandbox/chromium/base/at_exit.h rename : security/sandbox/base/atomic_ref_count.h => security/sandbox/chromium/base/atomic_ref_count.h rename : security/sandbox/base/atomic_sequence_num.h => security/sandbox/chromium/base/atomic_sequence_num.h rename : security/sandbox/base/atomicops.h => security/sandbox/chromium/base/atomicops.h rename : security/sandbox/base/atomicops_internals_tsan.h => security/sandbox/chromium/base/atomicops_internals_tsan.h rename : security/sandbox/base/atomicops_internals_x86_gcc.h => security/sandbox/chromium/base/atomicops_internals_x86_gcc.h rename : security/sandbox/base/atomicops_internals_x86_msvc.h => security/sandbox/chromium/base/atomicops_internals_x86_msvc.h rename : security/sandbox/base/base_export.h => security/sandbox/chromium/base/base_export.h rename : security/sandbox/base/base_paths.cc => security/sandbox/chromium/base/base_paths.cc rename : security/sandbox/base/base_paths.h => security/sandbox/chromium/base/base_paths.h rename : security/sandbox/base/base_paths_win.cc => security/sandbox/chromium/base/base_paths_win.cc rename : security/sandbox/base/base_paths_win.h => security/sandbox/chromium/base/base_paths_win.h rename : security/sandbox/base/base_switches.cc => security/sandbox/chromium/base/base_switches.cc rename : security/sandbox/base/base_switches.h => security/sandbox/chromium/base/base_switches.h rename : security/sandbox/base/basictypes.h => security/sandbox/chromium/base/basictypes.h rename : security/sandbox/base/bind.h => security/sandbox/chromium/base/bind.h rename : security/sandbox/base/bind_helpers.h => security/sandbox/chromium/base/bind_helpers.h rename : security/sandbox/base/bind_internal.h => security/sandbox/chromium/base/bind_internal.h rename : security/sandbox/base/bind_internal_win.h => security/sandbox/chromium/base/bind_internal_win.h rename : security/sandbox/base/callback.h => security/sandbox/chromium/base/callback.h rename : security/sandbox/base/callback_forward.h => security/sandbox/chromium/base/callback_forward.h rename : security/sandbox/base/callback_internal.cc => security/sandbox/chromium/base/callback_internal.cc rename : security/sandbox/base/callback_internal.h => security/sandbox/chromium/base/callback_internal.h rename : security/sandbox/base/command_line.cc => security/sandbox/chromium/base/command_line.cc rename : security/sandbox/base/command_line.h => security/sandbox/chromium/base/command_line.h rename : security/sandbox/base/compiler_specific.h => security/sandbox/chromium/base/compiler_specific.h rename : security/sandbox/base/containers/hash_tables.h => security/sandbox/chromium/base/containers/hash_tables.h rename : security/sandbox/base/cpu.cc => security/sandbox/chromium/base/cpu.cc rename : security/sandbox/base/cpu.h => security/sandbox/chromium/base/cpu.h rename : security/sandbox/base/critical_closure.h => security/sandbox/chromium/base/critical_closure.h rename : security/sandbox/base/debug/alias.cc => security/sandbox/chromium/base/debug/alias.cc rename : security/sandbox/base/debug/alias.h => security/sandbox/chromium/base/debug/alias.h rename : security/sandbox/base/debug/debugger.h => security/sandbox/chromium/base/debug/debugger.h rename : security/sandbox/base/debug/leak_annotations.h => security/sandbox/chromium/base/debug/leak_annotations.h rename : security/sandbox/base/debug/profiler.cc => security/sandbox/chromium/base/debug/profiler.cc rename : security/sandbox/base/debug/profiler.h => security/sandbox/chromium/base/debug/profiler.h rename : security/sandbox/base/environment.h => security/sandbox/chromium/base/environment.h rename : security/sandbox/base/file_descriptor_posix.h => security/sandbox/chromium/base/file_descriptor_posix.h rename : security/sandbox/base/file_util.cc => security/sandbox/chromium/base/file_util.cc rename : security/sandbox/base/file_util.h => security/sandbox/chromium/base/file_util.h rename : security/sandbox/base/file_util_win.cc => security/sandbox/chromium/base/file_util_win.cc rename : security/sandbox/base/file_version_info.h => security/sandbox/chromium/base/file_version_info.h rename : security/sandbox/base/file_version_info_win.h => security/sandbox/chromium/base/file_version_info_win.h rename : security/sandbox/base/files/file_path.h => security/sandbox/chromium/base/files/file_path.h rename : security/sandbox/base/float_util.h => security/sandbox/chromium/base/float_util.h rename : security/sandbox/base/format_macros.h => security/sandbox/chromium/base/format_macros.h rename : security/sandbox/base/guid.h => security/sandbox/chromium/base/guid.h rename : security/sandbox/base/lazy_instance.cc => security/sandbox/chromium/base/lazy_instance.cc rename : security/sandbox/base/lazy_instance.h => security/sandbox/chromium/base/lazy_instance.h rename : security/sandbox/base/location.cc => security/sandbox/chromium/base/location.cc rename : security/sandbox/base/location.h => security/sandbox/chromium/base/location.h rename : security/sandbox/base/logging.cc => security/sandbox/chromium/base/logging.cc rename : security/sandbox/base/logging.h => security/sandbox/chromium/base/logging.h rename : security/sandbox/base/logging_win.cc => security/sandbox/chromium/base/logging_win.cc rename : security/sandbox/base/logging_win.h => security/sandbox/chromium/base/logging_win.h rename : security/sandbox/base/memory/aligned_memory.h => security/sandbox/chromium/base/memory/aligned_memory.h rename : security/sandbox/base/memory/raw_scoped_refptr_mismatch_checker.h => security/sandbox/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h rename : security/sandbox/base/memory/ref_counted.cc => security/sandbox/chromium/base/memory/ref_counted.cc rename : security/sandbox/base/memory/ref_counted.h => security/sandbox/chromium/base/memory/ref_counted.h rename : security/sandbox/base/memory/scoped_ptr.h => security/sandbox/chromium/base/memory/scoped_ptr.h rename : security/sandbox/base/memory/singleton.cc => security/sandbox/chromium/base/memory/singleton.cc rename : security/sandbox/base/memory/singleton.h => security/sandbox/chromium/base/memory/singleton.h rename : security/sandbox/base/memory/weak_ptr.h => security/sandbox/chromium/base/memory/weak_ptr.h rename : security/sandbox/base/move.h => security/sandbox/chromium/base/move.h rename : security/sandbox/base/observer_list.h => security/sandbox/chromium/base/observer_list.h rename : security/sandbox/base/observer_list_threadsafe.h => security/sandbox/chromium/base/observer_list_threadsafe.h rename : security/sandbox/base/os_compat_nacl.h => security/sandbox/chromium/base/os_compat_nacl.h rename : security/sandbox/base/path_service.cc => security/sandbox/chromium/base/path_service.cc rename : security/sandbox/base/path_service.h => security/sandbox/chromium/base/path_service.h rename : security/sandbox/base/pending_task.h => security/sandbox/chromium/base/pending_task.h rename : security/sandbox/base/platform_file.cc => security/sandbox/chromium/base/platform_file.cc rename : security/sandbox/base/platform_file.h => security/sandbox/chromium/base/platform_file.h rename : security/sandbox/base/port.h => security/sandbox/chromium/base/port.h rename : security/sandbox/base/process/process_handle.h => security/sandbox/chromium/base/process/process_handle.h rename : security/sandbox/base/profiler/alternate_timer.h => security/sandbox/chromium/base/profiler/alternate_timer.h rename : security/sandbox/base/profiler/tracked_time.h => security/sandbox/chromium/base/profiler/tracked_time.h rename : security/sandbox/base/rand_util.h => security/sandbox/chromium/base/rand_util.h rename : security/sandbox/base/run_loop.h => security/sandbox/chromium/base/run_loop.h rename : security/sandbox/base/scoped_clear_errno.h => security/sandbox/chromium/base/scoped_clear_errno.h rename : security/sandbox/base/sequence_checker.h => security/sandbox/chromium/base/sequence_checker.h rename : security/sandbox/base/sequence_checker_impl.h => security/sandbox/chromium/base/sequence_checker_impl.h rename : security/sandbox/base/sequenced_task_runner.h => security/sandbox/chromium/base/sequenced_task_runner.h rename : security/sandbox/base/sequenced_task_runner_helpers.h => security/sandbox/chromium/base/sequenced_task_runner_helpers.h rename : security/sandbox/base/shim/base/gtest_prod_util.h => security/sandbox/chromium/base/shim/base/gtest_prod_util.h rename : security/sandbox/base/shim/base/logging.cpp => security/sandbox/chromium/base/shim/base/logging.cpp rename : security/sandbox/base/shim/base/strings/string_piece.h => security/sandbox/chromium/base/shim/base/strings/string_piece.h rename : security/sandbox/base/shim/base/third_party/nspr/prtime.h => security/sandbox/chromium/base/shim/base/third_party/nspr/prtime.h rename : security/sandbox/base/shim/base/third_party/nspr/prtypes.h => security/sandbox/chromium/base/shim/base/third_party/nspr/prtypes.h rename : security/sandbox/base/shim/base/tracked_objects.h => security/sandbox/chromium/base/shim/base/tracked_objects.h rename : security/sandbox/base/shim/sdkdecls.h => security/sandbox/chromium/base/shim/sdkdecls.h rename : security/sandbox/base/single_thread_task_runner.h => security/sandbox/chromium/base/single_thread_task_runner.h rename : security/sandbox/base/stl_util.h => security/sandbox/chromium/base/stl_util.h rename : security/sandbox/base/strings/nullable_string16.cc => security/sandbox/chromium/base/strings/nullable_string16.cc rename : security/sandbox/base/strings/nullable_string16.h => security/sandbox/chromium/base/strings/nullable_string16.h rename : security/sandbox/base/strings/string16.h => security/sandbox/chromium/base/strings/string16.h rename : security/sandbox/base/strings/string_number_conversions.cc => security/sandbox/chromium/base/strings/string_number_conversions.cc rename : security/sandbox/base/strings/string_number_conversions.h => security/sandbox/chromium/base/strings/string_number_conversions.h rename : security/sandbox/base/strings/string_piece.cc => security/sandbox/chromium/base/strings/string_piece.cc rename : security/sandbox/base/strings/string_piece.h => security/sandbox/chromium/base/strings/string_piece.h rename : security/sandbox/base/strings/string_util.h => security/sandbox/chromium/base/strings/string_util.h rename : security/sandbox/base/strings/string_util_constants.cc => security/sandbox/chromium/base/strings/string_util_constants.cc rename : security/sandbox/base/strings/string_util_stripped.cc => security/sandbox/chromium/base/strings/string_util_stripped.cc rename : security/sandbox/base/strings/string_util_win.h => security/sandbox/chromium/base/strings/string_util_win.h rename : security/sandbox/base/strings/stringprintf.cc => security/sandbox/chromium/base/strings/stringprintf.cc rename : security/sandbox/base/strings/stringprintf.h => security/sandbox/chromium/base/strings/stringprintf.h rename : security/sandbox/base/strings/utf_string_conversion_utils.cc => security/sandbox/chromium/base/strings/utf_string_conversion_utils.cc rename : security/sandbox/base/strings/utf_string_conversion_utils.h => security/sandbox/chromium/base/strings/utf_string_conversion_utils.h rename : security/sandbox/base/strings/utf_string_conversions.cc => security/sandbox/chromium/base/strings/utf_string_conversions.cc rename : security/sandbox/base/strings/utf_string_conversions.h => security/sandbox/chromium/base/strings/utf_string_conversions.h rename : security/sandbox/base/synchronization/lock.cc => security/sandbox/chromium/base/synchronization/lock.cc rename : security/sandbox/base/synchronization/lock.h => security/sandbox/chromium/base/synchronization/lock.h rename : security/sandbox/base/synchronization/lock_impl.h => security/sandbox/chromium/base/synchronization/lock_impl.h rename : security/sandbox/base/synchronization/lock_impl_win.cc => security/sandbox/chromium/base/synchronization/lock_impl_win.cc rename : security/sandbox/base/sys_info.h => security/sandbox/chromium/base/sys_info.h rename : security/sandbox/base/task_runner.h => security/sandbox/chromium/base/task_runner.h rename : security/sandbox/base/template_util.h => security/sandbox/chromium/base/template_util.h rename : security/sandbox/base/third_party/dmg_fp/LICENSE => security/sandbox/chromium/base/third_party/dmg_fp/LICENSE rename : security/sandbox/base/third_party/dmg_fp/dmg_fp.h => security/sandbox/chromium/base/third_party/dmg_fp/dmg_fp.h rename : security/sandbox/base/third_party/dmg_fp/dtoa.cc => security/sandbox/chromium/base/third_party/dmg_fp/dtoa.cc rename : security/sandbox/base/third_party/dmg_fp/g_fmt.cc => security/sandbox/chromium/base/third_party/dmg_fp/g_fmt.cc rename : security/sandbox/base/third_party/dynamic_annotations/LICENSE => security/sandbox/chromium/base/third_party/dynamic_annotations/LICENSE rename : security/sandbox/base/third_party/dynamic_annotations/dynamic_annotations.h => security/sandbox/chromium/base/third_party/dynamic_annotations/dynamic_annotations.h rename : security/sandbox/base/third_party/icu/LICENSE => security/sandbox/chromium/base/third_party/icu/LICENSE rename : security/sandbox/base/third_party/icu/icu_utf.cc => security/sandbox/chromium/base/third_party/icu/icu_utf.cc rename : security/sandbox/base/third_party/icu/icu_utf.h => security/sandbox/chromium/base/third_party/icu/icu_utf.h rename : security/sandbox/base/thread_task_runner_handle.h => security/sandbox/chromium/base/thread_task_runner_handle.h rename : security/sandbox/base/threading/platform_thread.h => security/sandbox/chromium/base/threading/platform_thread.h rename : security/sandbox/base/threading/platform_thread_win.cc => security/sandbox/chromium/base/threading/platform_thread_win.cc rename : security/sandbox/base/threading/sequenced_worker_pool.h => security/sandbox/chromium/base/threading/sequenced_worker_pool.h rename : security/sandbox/base/threading/thread_checker_impl.h => security/sandbox/chromium/base/threading/thread_checker_impl.h rename : security/sandbox/base/threading/thread_collision_warner.cc => security/sandbox/chromium/base/threading/thread_collision_warner.cc rename : security/sandbox/base/threading/thread_collision_warner.h => security/sandbox/chromium/base/threading/thread_collision_warner.h rename : security/sandbox/base/threading/thread_id_name_manager.cc => security/sandbox/chromium/base/threading/thread_id_name_manager.cc rename : security/sandbox/base/threading/thread_id_name_manager.h => security/sandbox/chromium/base/threading/thread_id_name_manager.h rename : security/sandbox/base/threading/thread_local.h => security/sandbox/chromium/base/threading/thread_local.h rename : security/sandbox/base/threading/thread_local_storage.h => security/sandbox/chromium/base/threading/thread_local_storage.h rename : security/sandbox/base/threading/thread_local_win.cc => security/sandbox/chromium/base/threading/thread_local_win.cc rename : security/sandbox/base/threading/thread_restrictions.cc => security/sandbox/chromium/base/threading/thread_restrictions.cc rename : security/sandbox/base/threading/thread_restrictions.h => security/sandbox/chromium/base/threading/thread_restrictions.h rename : security/sandbox/base/time/time.cc => security/sandbox/chromium/base/time/time.cc rename : security/sandbox/base/time/time.h => security/sandbox/chromium/base/time/time.h rename : security/sandbox/base/time/time_win.cc => security/sandbox/chromium/base/time/time_win.cc rename : security/sandbox/base/tracking_info.h => security/sandbox/chromium/base/tracking_info.h rename : security/sandbox/base/tuple.h => security/sandbox/chromium/base/tuple.h rename : security/sandbox/base/values.h => security/sandbox/chromium/base/values.h rename : security/sandbox/base/version.h => security/sandbox/chromium/base/version.h rename : security/sandbox/base/win/event_trace_provider.cc => security/sandbox/chromium/base/win/event_trace_provider.cc rename : security/sandbox/base/win/event_trace_provider.h => security/sandbox/chromium/base/win/event_trace_provider.h rename : security/sandbox/base/win/pe_image.cc => security/sandbox/chromium/base/win/pe_image.cc rename : security/sandbox/base/win/pe_image.h => security/sandbox/chromium/base/win/pe_image.h rename : security/sandbox/base/win/registry.cc => security/sandbox/chromium/base/win/registry.cc rename : security/sandbox/base/win/registry.h => security/sandbox/chromium/base/win/registry.h rename : security/sandbox/base/win/scoped_handle.cc => security/sandbox/chromium/base/win/scoped_handle.cc rename : security/sandbox/base/win/scoped_handle.h => security/sandbox/chromium/base/win/scoped_handle.h rename : security/sandbox/base/win/scoped_process_information.cc => security/sandbox/chromium/base/win/scoped_process_information.cc rename : security/sandbox/base/win/scoped_process_information.h => security/sandbox/chromium/base/win/scoped_process_information.h rename : security/sandbox/base/win/startup_information.cc => security/sandbox/chromium/base/win/startup_information.cc rename : security/sandbox/base/win/startup_information.h => security/sandbox/chromium/base/win/startup_information.h rename : security/sandbox/base/win/windows_version.cc => security/sandbox/chromium/base/win/windows_version.cc rename : security/sandbox/base/win/windows_version.h => security/sandbox/chromium/base/win/windows_version.h
270 lines
9.1 KiB
C++
270 lines
9.1 KiB
C++
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// This file is an internal atomic implementation, use base/atomicops.h instead.
|
|
|
|
#ifndef BASE_ATOMICOPS_INTERNALS_X86_GCC_H_
|
|
#define BASE_ATOMICOPS_INTERNALS_X86_GCC_H_
|
|
|
|
#include "base/base_export.h"
|
|
|
|
// This struct is not part of the public API of this module; clients may not
|
|
// use it. (However, it's exported via BASE_EXPORT because clients implicitly
|
|
// do use it at link time by inlining these functions.)
|
|
// Features of this x86. Values may not be correct before main() is run,
|
|
// but are set conservatively.
|
|
struct AtomicOps_x86CPUFeatureStruct {
|
|
bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence
|
|
// after acquire compare-and-swap.
|
|
bool has_sse2; // Processor has SSE2.
|
|
};
|
|
BASE_EXPORT extern struct AtomicOps_x86CPUFeatureStruct
|
|
AtomicOps_Internalx86CPUFeatures;
|
|
|
|
#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
|
|
|
|
namespace base {
|
|
namespace subtle {
|
|
|
|
// 32-bit low-level operations on any platform.
|
|
|
|
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
|
|
Atomic32 old_value,
|
|
Atomic32 new_value) {
|
|
Atomic32 prev;
|
|
__asm__ __volatile__("lock; cmpxchgl %1,%2"
|
|
: "=a" (prev)
|
|
: "q" (new_value), "m" (*ptr), "0" (old_value)
|
|
: "memory");
|
|
return prev;
|
|
}
|
|
|
|
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
|
|
Atomic32 new_value) {
|
|
__asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg.
|
|
: "=r" (new_value)
|
|
: "m" (*ptr), "0" (new_value)
|
|
: "memory");
|
|
return new_value; // Now it's the previous value.
|
|
}
|
|
|
|
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
|
|
Atomic32 increment) {
|
|
Atomic32 temp = increment;
|
|
__asm__ __volatile__("lock; xaddl %0,%1"
|
|
: "+r" (temp), "+m" (*ptr)
|
|
: : "memory");
|
|
// temp now holds the old value of *ptr
|
|
return temp + increment;
|
|
}
|
|
|
|
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
|
|
Atomic32 increment) {
|
|
Atomic32 temp = increment;
|
|
__asm__ __volatile__("lock; xaddl %0,%1"
|
|
: "+r" (temp), "+m" (*ptr)
|
|
: : "memory");
|
|
// temp now holds the old value of *ptr
|
|
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
|
|
__asm__ __volatile__("lfence" : : : "memory");
|
|
}
|
|
return temp + increment;
|
|
}
|
|
|
|
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
|
|
Atomic32 old_value,
|
|
Atomic32 new_value) {
|
|
Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
|
|
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
|
|
__asm__ __volatile__("lfence" : : : "memory");
|
|
}
|
|
return x;
|
|
}
|
|
|
|
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
|
|
Atomic32 old_value,
|
|
Atomic32 new_value) {
|
|
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
|
|
}
|
|
|
|
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
|
|
*ptr = value;
|
|
}
|
|
|
|
#if defined(__x86_64__)
|
|
|
|
// 64-bit implementations of memory barrier can be simpler, because it
|
|
// "mfence" is guaranteed to exist.
|
|
inline void MemoryBarrier() {
|
|
__asm__ __volatile__("mfence" : : : "memory");
|
|
}
|
|
|
|
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
|
|
*ptr = value;
|
|
MemoryBarrier();
|
|
}
|
|
|
|
#else
|
|
|
|
inline void MemoryBarrier() {
|
|
if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
|
|
__asm__ __volatile__("mfence" : : : "memory");
|
|
} else { // mfence is faster but not present on PIII
|
|
Atomic32 x = 0;
|
|
NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII
|
|
}
|
|
}
|
|
|
|
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
|
|
if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
|
|
*ptr = value;
|
|
__asm__ __volatile__("mfence" : : : "memory");
|
|
} else {
|
|
NoBarrier_AtomicExchange(ptr, value);
|
|
// acts as a barrier on PIII
|
|
}
|
|
}
|
|
#endif
|
|
|
|
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
|
|
ATOMICOPS_COMPILER_BARRIER();
|
|
*ptr = value; // An x86 store acts as a release barrier.
|
|
// See comments in Atomic64 version of Release_Store(), below.
|
|
}
|
|
|
|
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
|
|
return *ptr;
|
|
}
|
|
|
|
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
|
|
Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.
|
|
// See comments in Atomic64 version of Release_Store(), below.
|
|
ATOMICOPS_COMPILER_BARRIER();
|
|
return value;
|
|
}
|
|
|
|
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
|
|
MemoryBarrier();
|
|
return *ptr;
|
|
}
|
|
|
|
#if defined(__x86_64__)
|
|
|
|
// 64-bit low-level operations on 64-bit platform.
|
|
|
|
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
|
|
Atomic64 old_value,
|
|
Atomic64 new_value) {
|
|
Atomic64 prev;
|
|
__asm__ __volatile__("lock; cmpxchgq %1,%2"
|
|
: "=a" (prev)
|
|
: "q" (new_value), "m" (*ptr), "0" (old_value)
|
|
: "memory");
|
|
return prev;
|
|
}
|
|
|
|
inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
|
|
Atomic64 new_value) {
|
|
__asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg.
|
|
: "=r" (new_value)
|
|
: "m" (*ptr), "0" (new_value)
|
|
: "memory");
|
|
return new_value; // Now it's the previous value.
|
|
}
|
|
|
|
inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
|
|
Atomic64 increment) {
|
|
Atomic64 temp = increment;
|
|
__asm__ __volatile__("lock; xaddq %0,%1"
|
|
: "+r" (temp), "+m" (*ptr)
|
|
: : "memory");
|
|
// temp now contains the previous value of *ptr
|
|
return temp + increment;
|
|
}
|
|
|
|
inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
|
|
Atomic64 increment) {
|
|
Atomic64 temp = increment;
|
|
__asm__ __volatile__("lock; xaddq %0,%1"
|
|
: "+r" (temp), "+m" (*ptr)
|
|
: : "memory");
|
|
// temp now contains the previous value of *ptr
|
|
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
|
|
__asm__ __volatile__("lfence" : : : "memory");
|
|
}
|
|
return temp + increment;
|
|
}
|
|
|
|
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
|
|
*ptr = value;
|
|
}
|
|
|
|
inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
|
|
*ptr = value;
|
|
MemoryBarrier();
|
|
}
|
|
|
|
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
|
|
ATOMICOPS_COMPILER_BARRIER();
|
|
|
|
*ptr = value; // An x86 store acts as a release barrier
|
|
// for current AMD/Intel chips as of Jan 2008.
|
|
// See also Acquire_Load(), below.
|
|
|
|
// When new chips come out, check:
|
|
// IA-32 Intel Architecture Software Developer's Manual, Volume 3:
|
|
// System Programming Guide, Chatper 7: Multiple-processor management,
|
|
// Section 7.2, Memory Ordering.
|
|
// Last seen at:
|
|
// http://developer.intel.com/design/pentium4/manuals/index_new.htm
|
|
//
|
|
// x86 stores/loads fail to act as barriers for a few instructions (clflush
|
|
// maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
|
|
// not generated by the compiler, and are rare. Users of these instructions
|
|
// need to know about cache behaviour in any case since all of these involve
|
|
// either flushing cache lines or non-temporal cache hints.
|
|
}
|
|
|
|
inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
|
|
return *ptr;
|
|
}
|
|
|
|
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
|
|
Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
|
|
// for current AMD/Intel chips as of Jan 2008.
|
|
// See also Release_Store(), above.
|
|
ATOMICOPS_COMPILER_BARRIER();
|
|
return value;
|
|
}
|
|
|
|
inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
|
|
MemoryBarrier();
|
|
return *ptr;
|
|
}
|
|
|
|
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
|
|
Atomic64 old_value,
|
|
Atomic64 new_value) {
|
|
Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
|
|
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
|
|
__asm__ __volatile__("lfence" : : : "memory");
|
|
}
|
|
return x;
|
|
}
|
|
|
|
inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
|
|
Atomic64 old_value,
|
|
Atomic64 new_value) {
|
|
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
|
|
}
|
|
|
|
#endif // defined(__x86_64__)
|
|
|
|
} // namespace base::subtle
|
|
} // namespace base
|
|
|
|
#undef ATOMICOPS_COMPILER_BARRIER
|
|
|
|
#endif // BASE_ATOMICOPS_INTERNALS_X86_GCC_H_
|