This commit is contained in:
jeanlemotan
2024-07-02 18:10:39 +02:00
commit 48ab06b1d9
733 changed files with 321088 additions and 0 deletions
@@ -0,0 +1,190 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
#if defined(EA_PRAGMA_ONCE_SUPPORTED)
#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
#endif
#ifndef EATHREAD_GCC_EATHREAD_ATOMIC_GCC_H
#define EATHREAD_GCC_EATHREAD_ATOMIC_GCC_H
#include <EABase/eabase.h>
#include <stddef.h>
#include <eathread/internal/eathread_atomic_standalone.h>
#define EA_THREAD_ATOMIC_IMPLEMENTED
namespace EA
{
namespace Thread
{
/// class AtomicInt
/// Actual implementation may vary per platform. May require certain alignments, sizes,
/// and declaration specifications per platform.
template <class T>
class AtomicInt
{
public:
typedef AtomicInt<T> ThisType;
typedef T ValueType;
/// AtomicInt
/// Empty constructor. Intentionally leaves mValue in an unspecified state.
/// This is done so that an AtomicInt acts like a standard built-in integer.
AtomicInt()
{}
AtomicInt(ValueType n)
{ SetValue(n); }
AtomicInt(const ThisType& x)
: mValue(x.GetValue()) {}
AtomicInt& operator=(const ThisType& x)
{ mValue = x.GetValue(); return *this; }
ValueType GetValue() const
{ return mValue; }
ValueType GetValueRaw() const
{ return mValue; }
ValueType SetValue(ValueType n);
bool SetValueConditional(ValueType n, ValueType condition);
ValueType Increment();
ValueType Decrement();
ValueType Add(ValueType n);
// operators
inline operator const ValueType() const { return GetValue(); }
inline ValueType operator =(ValueType n) { SetValue(n); return n; }
inline ValueType operator+=(ValueType n) { return Add(n);}
inline ValueType operator-=(ValueType n) { return Add(-n);}
inline ValueType operator++() { return Increment();}
inline ValueType operator++(int) { return Increment() - 1;}
inline ValueType operator--() { return Decrement(); }
inline ValueType operator--(int) { return Decrement() + 1;}
protected:
volatile ValueType mValue;
};
// Recent versions of GCC have atomic primitives built into the compiler and standard library.
#if defined(EA_COMPILER_CLANG) || defined(__APPLE__) || (defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 403)) || defined(EA_COMPILER_RVCT) // GCC 4.3 or later. Depends on the GCC implementation.
template <> inline
AtomicInt<int32_t>::ValueType AtomicInt<int32_t>::GetValue() const
{ return __sync_add_and_fetch(const_cast<ValueType*>(&mValue), 0); }
template <> inline
AtomicInt<uint32_t>::ValueType AtomicInt<uint32_t>::GetValue() const
{ return __sync_add_and_fetch(const_cast<ValueType*>(&mValue), 0); }
template <> inline
AtomicInt<int32_t>::ValueType AtomicInt<int32_t>::SetValue(ValueType n)
{ __sync_synchronize(); return __sync_lock_test_and_set(&mValue, n); }
template <> inline
AtomicInt<uint32_t>::ValueType AtomicInt<uint32_t>::SetValue(ValueType n)
{ __sync_synchronize(); return __sync_lock_test_and_set(&mValue, n); }
template <> inline
bool AtomicInt<int32_t>::SetValueConditional(ValueType n, ValueType condition)
{ return (__sync_val_compare_and_swap(&mValue, condition, n) == condition); }
template <> inline
bool AtomicInt<uint32_t>::SetValueConditional(ValueType n, ValueType condition)
{ return (__sync_val_compare_and_swap(&mValue, condition, n) == condition); }
template <> inline
AtomicInt<int32_t>::ValueType AtomicInt<int32_t>::Increment()
{ return __sync_add_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<uint32_t>::ValueType AtomicInt<uint32_t>::Increment()
{ return __sync_add_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<int32_t>::ValueType AtomicInt<int32_t>::Decrement()
{ return __sync_sub_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<uint32_t>::ValueType AtomicInt<uint32_t>::Decrement()
{ return __sync_sub_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<int32_t>::ValueType AtomicInt<int32_t>::Add(ValueType n)
{ return __sync_add_and_fetch(&mValue, n); }
template <> inline
AtomicInt<uint32_t>::ValueType AtomicInt<uint32_t>::Add(ValueType n)
{ return __sync_add_and_fetch(&mValue, n); }
template <> inline
AtomicInt<int64_t>::ValueType AtomicInt<int64_t>::GetValue() const
{ return __sync_add_and_fetch(const_cast<ValueType*>(&mValue), 0); }
template <> inline
AtomicInt<uint64_t>::ValueType AtomicInt<uint64_t>::GetValue() const
{ return __sync_add_and_fetch(const_cast<ValueType*>(&mValue), 0); }
template <> inline
AtomicInt<int64_t>::ValueType AtomicInt<int64_t>::SetValue(ValueType n)
{ __sync_synchronize(); return __sync_lock_test_and_set(&mValue, n); }
template <> inline
AtomicInt<uint64_t>::ValueType AtomicInt<uint64_t>::SetValue(ValueType n)
{ __sync_synchronize(); return __sync_lock_test_and_set(&mValue, n); }
template <> inline
bool AtomicInt<int64_t>::SetValueConditional(ValueType n, ValueType condition)
{ return (__sync_val_compare_and_swap(&mValue, condition, n) == condition); }
template <> inline
bool AtomicInt<uint64_t>::SetValueConditional(ValueType n, ValueType condition)
{ return (__sync_val_compare_and_swap(&mValue, condition, n) == condition); }
template <> inline
AtomicInt<int64_t>::ValueType AtomicInt<int64_t>::Increment()
{ return __sync_add_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<uint64_t>::ValueType AtomicInt<uint64_t>::Increment()
{ return __sync_add_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<int64_t>::ValueType AtomicInt<int64_t>::Decrement()
{ return __sync_sub_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<uint64_t>::ValueType AtomicInt<uint64_t>::Decrement()
{ return __sync_sub_and_fetch(&mValue, 1); }
template <> inline
AtomicInt<int64_t>::ValueType AtomicInt<int64_t>::Add(ValueType n)
{ return __sync_add_and_fetch(&mValue, n); }
template <> inline
AtomicInt<uint64_t>::ValueType AtomicInt<uint64_t>::Add(ValueType n)
{ return __sync_add_and_fetch(&mValue, n); }
#endif
} // namespace Thread
} // namespace EA
#endif // EATHREAD_GCC_EATHREAD_ATOMIC_GCC_H
@@ -0,0 +1,73 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
#if defined(EA_PRAGMA_ONCE_SUPPORTED)
#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
#endif
/////////////////////////////////////////////////////////////////////////////
// Functionality related to memory and code generation synchronization.
/////////////////////////////////////////////////////////////////////////////
#ifndef EATHREAD_GCC_EATHREAD_SYNC_GCC_H
#define EATHREAD_GCC_EATHREAD_SYNC_GCC_H
#include <EABase/eabase.h>
#define EA_THREAD_SYNC_IMPLEMENTED
// EAProcessorPause
// Intel has defined a 'pause' instruction for x86 processors starting with the P4, though this simply
// maps to the otherwise undocumented 'rep nop' instruction. This pause instruction is important for
// high performance spinning, as otherwise a high performance penalty incurs.
#if defined(EA_PROCESSOR_X86) || defined(EA_PROCESSOR_X86_64)
#define EAProcessorPause() __asm__ __volatile__ ("rep ; nop")
#else
#define EAProcessorPause()
#endif
// EAReadBarrier / EAWriteBarrier / EAReadWriteBarrier
// The x86 processor memory architecture ensures read and write consistency on both single and
// multi processing systems. This makes programming simpler but limits maximimum system performance.
// We define EAReadBarrier here to be the same as EACompilerMemory barrier in order to limit the
// compiler from making any assumptions at its level about memory usage. Year 2003+ versions of the
// Microsoft SDK define a 'MemoryBarrier' statement which has the same effect as EAReadWriteBarrier.
#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 401) // GCC 4.1 or later
#define EAReadBarrier __sync_synchronize
#define EAWriteBarrier __sync_synchronize
#define EAReadWriteBarrier __sync_synchronize
#else
#define EAReadBarrier EACompilerMemoryBarrier
#define EAWriteBarrier EACompilerMemoryBarrier
#define EAReadWriteBarrier EACompilerMemoryBarrier
#endif
// EACompilerMemoryBarrier
#if defined(EA_PROCESSOR_ARM) || defined(EA_PROCESSOR_X86) || defined(EA_PROCESSOR_X86_64)
#define EACompilerMemoryBarrier() __asm__ __volatile__ ("":::"memory")
#else
#define EACompilerMemoryBarrier()
#endif
#endif // EATHREAD_GCC_EATHREAD_SYNC_GCC_H