diff options
Diffstat (limited to 'include/EASTL/internal/atomic/compiler/compiler.h')
-rw-r--r-- | include/EASTL/internal/atomic/compiler/compiler.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/include/EASTL/internal/atomic/compiler/compiler.h b/include/EASTL/internal/atomic/compiler/compiler.h new file mode 100644 index 0000000..65a4cd0 --- /dev/null +++ b/include/EASTL/internal/atomic/compiler/compiler.h @@ -0,0 +1,120 @@ +///////////////////////////////////////////////////////////////////////////////// +// Copyright (c) Electronic Arts Inc. All rights reserved. +///////////////////////////////////////////////////////////////////////////////// + + +#ifndef EASTL_ATOMIC_INTERNAL_COMPILER_H +#define EASTL_ATOMIC_INTERNAL_COMPILER_H + +#if defined(EA_PRAGMA_ONCE_SUPPORTED) + #pragma once +#endif + + +///////////////////////////////////////////////////////////////////////////////// +// +// Include the compiler specific implementations +// +#if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG) + + #include "gcc/compiler_gcc.h" + +#elif defined(EA_COMPILER_MSVC) + + #include "msvc/compiler_msvc.h" + +#endif + + +///////////////////////////////////////////////////////////////////////////////// + + +namespace eastl +{ + + +namespace internal +{ + + +/** + * NOTE: + * + * This can be used by specific compiler implementations to implement a data dependency compiler barrier. + * Some compiler barriers do not take in input dependencies as is possible with the gcc asm syntax. + * Thus we need a way to create a false dependency on the input variable so the compiler does not dead-store + * remove it. + * A volatile function pointer ensures the compiler must always load the function pointer and call thru it + * since the compiler cannot reason about any side effects. Thus the compiler must always assume the + * input variable may be accessed and thus cannot be dead-stored. This technique works even in the presence + * of Link-Time Optimization. A compiler barrier with a data dependency is useful in these situations. + * + * void foo() + * { + * eastl::vector<int> v; + * while (Benchmark.ContinueRunning()) + * { + * v.push_back(0); + * eastl::compiler_barrier(); OR eastl::compiler_barrier_data_dependency(v); + * } + * } + * + * We are trying to benchmark the push_back function of a vector. The vector v has only local scope. + * The compiler is well within its writes to remove all accesses to v even with the compiler barrier + * because there are no observable uses of the vector v. + * The compiler barrier data dependency ensures there is an input dependency on the variable so that + * it isn't removed. This is also useful when writing test code that the compiler may remove. + */ + +typedef void (*CompilerBarrierDataDependencyFuncPtr)(void*); + +extern EASTL_API volatile CompilerBarrierDataDependencyFuncPtr gCompilerBarrierDataDependencyFunc; + + +#define EASTL_COMPILER_ATOMIC_COMPILER_BARRIER_DATA_DEPENDENCY_FUNC(ptr) \ + eastl::internal::gCompilerBarrierDataDependencyFunc(ptr) + + +} // namespace internal + + +} // namespace eastl + + +///////////////////////////////////////////////////////////////////////////////// + + +#include "compiler_fetch_add.h" +#include "compiler_fetch_sub.h" + +#include "compiler_fetch_and.h" +#include "compiler_fetch_xor.h" +#include "compiler_fetch_or.h" + +#include "compiler_add_fetch.h" +#include "compiler_sub_fetch.h" + +#include "compiler_and_fetch.h" +#include "compiler_xor_fetch.h" +#include "compiler_or_fetch.h" + +#include "compiler_exchange.h" + +#include "compiler_cmpxchg_weak.h" +#include "compiler_cmpxchg_strong.h" + +#include "compiler_load.h" +#include "compiler_store.h" + +#include "compiler_barrier.h" + +#include "compiler_cpu_pause.h" + +#include "compiler_memory_barrier.h" + +#include "compiler_signal_fence.h" + +#include "compiler_thread_fence.h" + + +#endif /* EASTL_ATOMIC_INTERNAL_COMPILER_H */ |