From 75089234ebfa58dcf6631865acd2297b1b604df6 Mon Sep 17 00:00:00 2001 From: fearog Date: Tue, 30 Jun 2015 16:33:57 +0300 Subject: [PATCH] - Patches for Android compatibility - build configuration, and memory allocation wrapper to work around the lack of a malloc_usable_size() equivalent. --- lzhamdecomp/lzham_core.h | 37 ++++++++++++++- lzhamdecomp/lzham_mem.cpp | 95 ++++++++++++++++++++++++++++++++++----- 2 files changed, 119 insertions(+), 13 deletions(-) diff --git a/lzhamdecomp/lzham_core.h b/lzhamdecomp/lzham_core.h index f4e2d4f..dfdfea0 100644 --- a/lzhamdecomp/lzham_core.h +++ b/lzhamdecomp/lzham_core.h @@ -165,7 +165,7 @@ #error TODO: Unknown Apple target #endif -#elif defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) && !defined(LZHAM_ANSI_CPLUSPLUS) +#elif defined(__linux__) && !defined(ANDROID) && (defined(__i386__) || defined(__x86_64__)) && !defined(LZHAM_ANSI_CPLUSPLUS) // --- Generic GCC/clang path for x86/x64, clang or GCC, Linux, OSX, FreeBSD or NetBSD, pthreads for threading, GCC built-ins for atomic ops. #define LZHAM_PLATFORM_PC 1 @@ -199,6 +199,41 @@ #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) #endif + #define LZHAM_NOTE_UNUSED(x) (void)x +#elif defined(ANDROID) && !defined(LZHAM_ANSI_CPLUSPLUS) + // Generic GCC path for Android, GCC built-ins for atomic ops. Basically identical to iOS path. + // Pthreads disabled because spin lock is missing..? + #define LZHAM_PLATFORM_PC 0 + + #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) + #define LZHAM_PLATFORM_PC_X64 0 + #define LZHAM_64BIT_POINTERS 1 + #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 + #else + #define LZHAM_PLATFORM_PC_X86 0 + #define LZHAM_64BIT_POINTERS 0 + #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 + #endif + + #define LZHAM_USE_UNALIGNED_INT_LOADS 0 + + #if __BIG_ENDIAN__ + #define LZHAM_BIG_ENDIAN_CPU 1 + #else + #define LZHAM_LITTLE_ENDIAN_CPU 1 + #endif + + #define LZHAM_USE_PTHREADS_API 0 + #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 + + #define LZHAM_RESTRICT + + #if defined(__clang__) + #define LZHAM_FORCE_INLINE inline + #else + #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) + #endif + #define LZHAM_NOTE_UNUSED(x) (void)x #else #warning Building as vanilla ANSI-C/C++, multi-threaded compression is disabled! Please configure lzhamdecomp/lzham_core.h. diff --git a/lzhamdecomp/lzham_mem.cpp b/lzhamdecomp/lzham_mem.cpp index 02f2324..c84d183 100644 --- a/lzhamdecomp/lzham_mem.cpp +++ b/lzhamdecomp/lzham_mem.cpp @@ -17,12 +17,83 @@ using namespace lzham; #define LZHAM_MEM_STATS 0 -#ifndef LZHAM_USE_WIN32_API - #ifndef __APPLE__ - #define _msize malloc_usable_size - #else - #define _msize malloc_size - #endif +#if !defined( ANDROID ) + + #define allocate( size ) malloc( size ) + #define reallocate( p, size ) realloc( p, size ) + #define deallocate( p ) free( p ) + #define getAllocationSize( p ) _msize( p ) + + #ifndef LZHAM_USE_WIN32_API + #if !defined(__APPLE__) && !defined(ANDROID) + #define getAllocationSize( p ) malloc_usable_size( p ) + #else + #define getAllocationSize( p ) malloc_size( p ) + #endif + #else + #define getAllocationSize( p ) _msize( p ) + #endif + +#else + +// Android does not have an API any more for discovering true allocation size, so we need to patch in that data ourselves. +static void* allocate( size_t size ) +{ + uint8* q = static_cast(malloc(LZHAM_MIN_ALLOC_ALIGNMENT + size)); + if (!q) + return NULL; + + uint8* p = q + LZHAM_MIN_ALLOC_ALIGNMENT; + reinterpret_cast(p)[-1] = size; + reinterpret_cast(p)[-2] = ~size; + + return p; +} + +static void deallocate( void* p ) +{ + if( p != NULL ) + { + const size_t num = reinterpret_cast(p)[-1]; + const size_t num_check = reinterpret_cast(p)[-2]; + LZHAM_ASSERT(num && (num == ~num_check)); + if (num == ~num_check) + { + free(reinterpret_cast(p) - LZHAM_MIN_ALLOC_ALIGNMENT); + } + } +} + +static size_t getAllocationSize( void* p ) +{ + const size_t num = reinterpret_cast(p)[-1]; + const size_t num_check = reinterpret_cast(p)[-2]; + LZHAM_ASSERT(num && (num == ~num_check)); + if (num == ~num_check) + return num; + + return 0; +} + +static void* reallocate( void* p, size_t size ) +{ + if( size == 0 ) + { + deallocate( p ); + return NULL; + } + + uint8* q = static_cast(realloc( p, LZHAM_MIN_ALLOC_ALIGNMENT + size )); + if (!q) + return NULL; + + uint8* newp = q + LZHAM_MIN_ALLOC_ALIGNMENT; + reinterpret_cast(newp)[-1] = size; + reinterpret_cast(newp)[-2] = ~size; + + return newp; +} + #endif namespace lzham @@ -86,15 +157,15 @@ namespace lzham if (!p) { - p_new = malloc(size); + p_new = allocate(size); LZHAM_ASSERT( (reinterpret_cast(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 ); if (pActual_size) - *pActual_size = p_new ? _msize(p_new) : 0; + *pActual_size = p_new ? getAllocationSize(p_new) : 0; } else if (!size) { - free(p); + deallocate(p); p_new = NULL; if (pActual_size) @@ -117,7 +188,7 @@ namespace lzham } else if (movable) { - p_new = realloc(p, size); + p_new = reallocate(p, size); if (p_new) { @@ -127,7 +198,7 @@ namespace lzham } if (pActual_size) - *pActual_size = _msize(p_final_block); + *pActual_size = getAllocationSize(p_final_block); } return p_new; @@ -136,7 +207,7 @@ namespace lzham static size_t lzham_default_msize(void* p, void* pUser_data) { LZHAM_NOTE_UNUSED(pUser_data); - return p ? _msize(p) : 0; + return p ? getAllocationSize(p) : 0; } static lzham_realloc_func g_pRealloc = lzham_default_realloc;