| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- // File: lzham_platform.h
- // See Copyright Notice and license at the end of include/lzham.h
- #pragma once
- bool lzham_is_debugger_present(void);
- void lzham_debug_break(void);
- void lzham_output_debug_string(const char* p);
- // actually in lzham_assert.cpp
- void lzham_assert(const char* pExp, const char* pFile, unsigned line);
- void lzham_fail(const char* pExp, const char* pFile, unsigned line);
- #ifdef WIN32
- #define LZHAM_BREAKPOINT DebuggerBreak();
- #define LZHAM_BUILTIN_EXPECT(c, v) c
- #elif defined(__GNUC__) && !defined EMSCRIPTEN // ESENTHEL CHANGED
- #define LZHAM_BREAKPOINT asm("int $3");
- #define LZHAM_BUILTIN_EXPECT(c, v) __builtin_expect(c, v)
- #else
- #define LZHAM_BREAKPOINT
- #define LZHAM_BUILTIN_EXPECT(c, v) c
- #endif
- #if defined(__GNUC__) && LZHAM_PLATFORM_PC
- extern __inline__ __attribute__((__always_inline__,__gnu_inline__)) void lzham_yield_processor()
- {
- __asm__ __volatile__("pause");
- }
- #elif LZHAM_PLATFORM_X360
- #define lzham_yield_processor() \
- YieldProcessor(); \
- __asm { or r0, r0, r0 } \
- YieldProcessor(); \
- __asm { or r1, r1, r1 } \
- YieldProcessor(); \
- __asm { or r0, r0, r0 } \
- YieldProcessor(); \
- __asm { or r1, r1, r1 } \
- YieldProcessor(); \
- __asm { or r0, r0, r0 } \
- YieldProcessor(); \
- __asm { or r1, r1, r1 } \
- YieldProcessor(); \
- __asm { or r0, r0, r0 } \
- YieldProcessor(); \
- __asm { or r1, r1, r1 }
- #else
- LZHAM_FORCE_INLINE void lzham_yield_processor()
- {
- #if LZHAM_USE_MSVC_INTRINSICS
- #if LZHAM_PLATFORM_PC_X64
- _mm_pause();
- #else
- YieldProcessor();
- #endif
- #else
- // No implementation
- #endif
- }
- #endif
- #ifndef _MSC_VER
- int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...);
- int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args);
- #endif
- #if LZHAM_PLATFORM_X360
- #define LZHAM_MEMORY_EXPORT_BARRIER MemoryBarrier();
- #else
- // Barriers shouldn't be necessary on x86/x64.
- // TODO: Should use __sync_synchronize() on other platforms that support GCC.
- #define LZHAM_MEMORY_EXPORT_BARRIER
- #endif
- #if LZHAM_PLATFORM_X360
- #define LZHAM_MEMORY_IMPORT_BARRIER MemoryBarrier();
- #else
- // Barriers shouldn't be necessary on x86/x64.
- // TODO: Should use __sync_synchronize() on other platforms that support GCC.
- #define LZHAM_MEMORY_IMPORT_BARRIER
- #endif
- // Note: It's very important that LZHAM_READ_BIG_ENDIAN_UINT32() is fast on the target platform.
- // This is used to read every DWORD from the input stream.
- #if LZHAM_USE_UNALIGNED_INT_LOADS
- #if LZHAM_BIG_ENDIAN_CPU
- #define LZHAM_READ_BIG_ENDIAN_UINT32(p) *reinterpret_cast<const uint32*>(p)
- #else
- #if defined(LZHAM_USE_MSVC_INTRINSICS)
- #define LZHAM_READ_BIG_ENDIAN_UINT32(p) _byteswap_ulong(*reinterpret_cast<const uint32*>(p))
- #elif defined(__GNUC__)
- #define LZHAM_READ_BIG_ENDIAN_UINT32(p) __builtin_bswap32(*reinterpret_cast<const uint32*>(p))
- #else
- #define LZHAM_READ_BIG_ENDIAN_UINT32(p) utils::swap32(*reinterpret_cast<const uint32*>(p))
- #endif
- #endif
- #else
- #define LZHAM_READ_BIG_ENDIAN_UINT32(p) ((reinterpret_cast<const uint8*>(p)[0] << 24) | (reinterpret_cast<const uint8*>(p)[1] << 16) | (reinterpret_cast<const uint8*>(p)[2] << 8) | (reinterpret_cast<const uint8*>(p)[3]))
- #endif
- #if LZHAM_USE_WIN32_ATOMIC_FUNCTIONS
- extern "C" __int64 _InterlockedCompareExchange64(__int64 volatile * Destination, __int64 Exchange, __int64 Comperand);
- #if defined(_MSC_VER)
- #pragma intrinsic(_InterlockedCompareExchange64)
- #endif
- #endif // LZHAM_USE_WIN32_ATOMIC_FUNCTIONS
- namespace lzham
- {
- #if LZHAM_USE_WIN32_ATOMIC_FUNCTIONS
- typedef LONG atomic32_t;
- typedef LONGLONG atomic64_t;
- // Returns the original value.
- inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return InterlockedCompareExchange(pDest, exchange, comparand);
- }
- // Returns the original value.
- inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 7) == 0);
- return _InterlockedCompareExchange64(pDest, exchange, comparand);
- }
- // Returns the resulting incremented value.
- inline atomic32_t atomic_increment32(atomic32_t volatile *pDest)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return InterlockedIncrement(pDest);
- }
- // Returns the resulting decremented value.
- inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return InterlockedDecrement(pDest);
- }
- // Returns the original value.
- inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return InterlockedExchange(pDest, val);
- }
- // Returns the resulting value.
- inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return InterlockedExchangeAdd(pDest, val) + val;
- }
- // Returns the original value.
- inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return InterlockedExchangeAdd(pDest, val);
- }
- #elif LZHAM_USE_GCC_ATOMIC_BUILTINS
- typedef long atomic32_t;
- typedef long long atomic64_t;
- // Returns the original value.
- inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return __sync_val_compare_and_swap(pDest, comparand, exchange);
- }
- // Returns the original value.
- inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 7) == 0);
- return __sync_val_compare_and_swap(pDest, comparand, exchange);
- }
- // Returns the resulting incremented value.
- inline atomic32_t atomic_increment32(atomic32_t volatile *pDest)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return __sync_add_and_fetch(pDest, 1);
- }
- // Returns the resulting decremented value.
- inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return __sync_sub_and_fetch(pDest, 1);
- }
- // Returns the original value.
- inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return __sync_lock_test_and_set(pDest, val);
- }
- // Returns the resulting value.
- inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return __sync_add_and_fetch(pDest, val);
- }
- // Returns the original value.
- inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return __sync_fetch_and_add(pDest, val);
- }
- #else
- #define LZHAM_NO_ATOMICS 1
- // Atomic ops not supported - but try to do something reasonable. Assumes no threading at all.
- typedef long atomic32_t;
- typedef long long atomic64_t;
- inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- atomic32_t cur = *pDest;
- if (cur == comparand)
- *pDest = exchange;
- return cur;
- }
- inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 7) == 0);
- atomic64_t cur = *pDest;
- if (cur == comparand)
- *pDest = exchange;
- return cur;
- }
- inline atomic32_t atomic_increment32(atomic32_t volatile *pDest)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return (*pDest += 1);
- }
- inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return (*pDest -= 1);
- }
- inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- atomic32_t cur = *pDest;
- *pDest = val;
- return cur;
- }
- inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- return (*pDest += val);
- }
- inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val)
- {
- LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
- atomic32_t cur = *pDest;
- *pDest += val;
- return cur;
- }
- #endif
- #if LZHAM_BUFFERED_PRINTF
- void lzham_buffered_printf(const char *format, ...);
- void lzham_flush_buffered_printf();
- #else
- inline void lzham_buffered_printf(const char *format, ...) { (void)format; }
- inline void lzham_flush_buffered_printf() { }
- #endif
- } // namespace lzham
|