From 35e661fdf901bd8af13bf5addb4b1bddaeae32bf Mon Sep 17 00:00:00 2001 From: Arkshine Date: Mon, 29 Sep 2014 18:36:37 +0200 Subject: [PATCH] Sync AMTL from upstream --- public/amtl/am-atomics.h | 36 ++++++++++++++++++++++++++++++++++-- public/amtl/am-refcounting.h | 5 +++++ public/amtl/am-threadlocal.h | 5 +++-- public/amtl/am-utility.h | 9 +++++++-- public/amtl/am-vector.h | 13 +++++++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) diff --git a/public/amtl/am-atomics.h b/public/amtl/am-atomics.h index e32d1df9..a9926d92 100644 --- a/public/amtl/am-atomics.h +++ b/public/amtl/am-atomics.h @@ -38,9 +38,13 @@ namespace ke { extern "C" { long __cdecl _InterlockedIncrement(long volatile *dest); long __cdecl _InterlockedDecrement(long volatile *dest); + long __cdecl _InterlockedIncrement64(long long volatile *dest); + long __cdecl _InterlockedDecrement64(long long volatile *dest); } # pragma intrinsic(_InterlockedIncrement) # pragma intrinsic(_InterlockedDecrement) +# pragma intrinsic(_InterlockedIncrement64) +# pragma intrinsic(_InterlockedDecrement64) #endif template @@ -50,7 +54,7 @@ template <> struct AtomicOps<4> { #if defined(_MSC_VER) - typedef long Type; + typedef volatile long Type; static Type Increment(Type *ptr) { return _InterlockedIncrement(ptr); @@ -59,7 +63,7 @@ struct AtomicOps<4> return _InterlockedDecrement(ptr); }; #elif defined(__GNUC__) - typedef int Type; + typedef volatile int Type; // x86/x64 notes: When using GCC < 4.8, this will compile to a spinlock. // On 4.8+, or when using Clang, we'll get the more optimal "lock addl" @@ -73,6 +77,34 @@ struct AtomicOps<4> #endif }; +template <> +struct AtomicOps<8> +{ +#if defined(_MSC_VER) + typedef volatile long long Type; + + static Type Increment(Type *ptr) { + return _InterlockedIncrement64(ptr); + } + static Type Decrement(Type *ptr) { + return _InterlockedDecrement64(ptr); + }; +#elif defined(__GNUC__) + typedef volatile int64_t Type; + + // x86/x64 notes: When using GCC < 4.8, this will compile to a spinlock. + // On 4.8+, or when using Clang, we'll get the more optimal "lock addl" + // variant. + static Type Increment(Type *ptr) { + return __sync_add_and_fetch(ptr, 1); + } + static Type Decrement(Type *ptr) { + return __sync_sub_and_fetch(ptr, 1); + } +#endif +}; + + class AtomicRefCount { typedef AtomicOps Ops; diff --git a/public/amtl/am-refcounting.h b/public/amtl/am-refcounting.h index ea869464..ea2dc244 100644 --- a/public/amtl/am-refcounting.h +++ b/public/amtl/am-refcounting.h @@ -143,6 +143,11 @@ class PassRef bool operator !() const { return !thing_; } +#if defined(KE_CXX11) + explicit operator bool() const { + return !!thing_; + } +#endif T *release() const { return ReturnAndVoid(thing_); diff --git a/public/amtl/am-threadlocal.h b/public/amtl/am-threadlocal.h index df4c023c..bacecd4b 100644 --- a/public/amtl/am-threadlocal.h +++ b/public/amtl/am-threadlocal.h @@ -31,6 +31,7 @@ #define _include_amtl_thread_local_h_ #include +#include namespace ke { @@ -82,7 +83,7 @@ class ThreadLocal #if !defined(KE_SINGLE_THREADED) private: - int allocated_; + volatile int allocated_; public: ThreadLocal() { @@ -116,7 +117,7 @@ class ThreadLocal TlsSetValue(key_, reinterpret_cast(t)); } bool allocate() { - if (InterlockedCompareExchange(&allocated_, 1, 0) == 1) + if (InterlockedCompareExchange((volatile LONG *)&allocated_, 1, 0) == 1) return true; key_ = TlsAlloc(); return key_ != TLS_OUT_OF_INDEXES; diff --git a/public/amtl/am-utility.h b/public/amtl/am-utility.h index 1e31e067..bec35efa 100644 --- a/public/amtl/am-utility.h +++ b/public/amtl/am-utility.h @@ -36,6 +36,8 @@ #include #if defined(_MSC_VER) # include +#else +# include #endif #include @@ -116,6 +118,9 @@ class AutoPtr t_ = t; return t_; } + T **address() { + return &t_; + } T *operator =(Moveable > other) { delete t_; t_ = other->t_; @@ -384,8 +389,8 @@ class StackLinked # define KE_U64_FMT "%I64u" #elif defined(__GNUC__) # define KE_SIZET_FMT "%zu" -# define KE_I64_FMT "%lld" -# define KE_U64_FMT "%llu" +# define KE_I64_FMT "%" PRId64 +# define KE_U64_FMT "%" PRIu64 #else # error "Implement format specifier string" #endif diff --git a/public/amtl/am-vector.h b/public/amtl/am-vector.h index 4f01bb97..d6d5a55f 100644 --- a/public/amtl/am-vector.h +++ b/public/amtl/am-vector.h @@ -160,6 +160,19 @@ class Vector : public AllocPolicy return data_; } + bool resize(size_t newLength) { + if (newLength < length()) { + while (newLength < length()) + pop(); + } else if (newLength > length()) { + if (!ensure(newLength)) + return false; + size_t count = newLength - length(); + for (size_t i = 0; i < count; i++) + infallibleAppend(T()); + } + return true; + } bool ensure(size_t desired) { if (desired <= length()) return true;