diff --git a/crnlib/crn_core.h b/crnlib/crn_core.h index 6c8c7f06..482df5ff 100644 --- a/crnlib/crn_core.h +++ b/crnlib/crn_core.h @@ -82,7 +82,11 @@ #define CRNLIB_RESTRICT +#ifdef __APPLE__ + #define CRNLIB_FORCE_INLINE inline __attribute__((__always_inline__)) +#else #define CRNLIB_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) +#endif #define CRNLIB_INT64_FORMAT_SPECIFIER "%lli" #define CRNLIB_UINT64_FORMAT_SPECIFIER "%llu" diff --git a/crnlib/crn_dynamic_string.cpp b/crnlib/crn_dynamic_string.cpp index e3e76bde..dd4dd6ce 100644 --- a/crnlib/crn_dynamic_string.cpp +++ b/crnlib/crn_dynamic_string.cpp @@ -533,10 +533,10 @@ namespace crnlib return *this; } -#ifdef CRNLIB_BUILD_DEBUG void dynamic_string::check() const { - if (!m_pStr) + #ifdef CRNLIB_BUILD_DEBUG + if (!m_pStr) { CRNLIB_ASSERT(!m_buf_size && !m_len); } @@ -550,8 +550,8 @@ namespace crnlib CRNLIB_ASSERT(strlen(m_pStr) == m_len); #endif } - } #endif + } bool dynamic_string::ensure_buf(uint len, bool preserve_contents) { diff --git a/crnlib/crn_dynamic_string.h b/crnlib/crn_dynamic_string.h index e5eeac31..fd94abf4 100644 --- a/crnlib/crn_dynamic_string.h +++ b/crnlib/crn_dynamic_string.h @@ -135,11 +135,7 @@ namespace crnlib uint16 m_len; char* m_pStr; -#ifdef CRNLIB_BUILD_DEBUG void check() const; -#else - inline void check() const { } -#endif bool expand_buf(uint new_buf_size, bool preserve_contents); diff --git a/crnlib/crn_jpge.cpp b/crnlib/crn_jpge.cpp index 964f908d..ea02a2a1 100644 --- a/crnlib/crn_jpge.cpp +++ b/crnlib/crn_jpge.cpp @@ -12,7 +12,12 @@ #include #include + +#ifdef __APPLE__ +#include +#else #include +#endif #include "crn_core.h" diff --git a/crnlib/crn_mem.cpp b/crnlib/crn_mem.cpp index b7abfb9b..7f43ab72 100644 --- a/crnlib/crn_mem.cpp +++ b/crnlib/crn_mem.cpp @@ -3,7 +3,11 @@ #include "crn_core.h" #include "crn_console.h" #include "../inc/crnlib.h" +#ifdef __APPLE__ +#include +#else #include +#endif #if CRNLIB_USE_WIN32_API #include "crn_winhdr.h" #endif @@ -11,8 +15,12 @@ #define CRNLIB_MEM_STATS 0 #if !CRNLIB_USE_WIN32_API +#ifdef __APPLE__ +#define _msize malloc_size +#else #define _msize malloc_usable_size #endif +#endif namespace crnlib { diff --git a/crnlib/crn_platform.h b/crnlib/crn_platform.h index 3588e37a..95417539 100644 --- a/crnlib/crn_platform.h +++ b/crnlib/crn_platform.h @@ -18,7 +18,7 @@ void crnlib_fail(const char* pExp, const char* pFile, unsigned line); const bool c_crnlib_big_endian_platform = !c_crnlib_little_endian_platform; -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__APPLE__) #define crn_fopen(pDstFile, f, m) *(pDstFile) = fopen64(f, m) #define crn_fseek fseeko64 #define crn_ftell ftello64 diff --git a/crnlib/crn_threading_pthreads.cpp b/crnlib/crn_threading_pthreads.cpp index f57adb2d..a06fc30c 100644 --- a/crnlib/crn_threading_pthreads.cpp +++ b/crnlib/crn_threading_pthreads.cpp @@ -12,8 +12,12 @@ #endif #ifdef __GNUC__ +#ifdef __APPLE__ +#include +#else #include #endif +#endif #ifdef WIN32 #include @@ -29,6 +33,8 @@ namespace crnlib SYSTEM_INFO g_system_info; GetSystemInfo(&g_system_info); g_number_of_processors = math::maximum(1U, g_system_info.dwNumberOfProcessors); +#elif defined(__APPLE__) + g_number_of_processors = math::maximum(1, sysconf(_SC_NPROCESSORS_ONLN)); #elif defined(__GNUC__) g_number_of_processors = math::maximum(1, get_nprocs()); #else @@ -38,8 +44,14 @@ namespace crnlib crn_thread_id_t crn_get_current_thread_id() { +#ifdef __APPLE__ + __uint64_t thread_id = 0; + pthread_threadid_np(pthread_self(), &thread_id); + return thread_id; +#else // FIXME: Not portable return static_cast(pthread_self()); +#endif } void crn_sleep(unsigned int milliseconds) @@ -106,17 +118,31 @@ namespace crnlib semaphore::semaphore(long initialCount, long maximumCount, const char* pName) { - maximumCount, pName; CRNLIB_ASSERT(maximumCount >= initialCount); +#ifdef __APPLE__ + m_name = (pName != NULL ? pName : "crnlib"); + m_sem = sem_open(m_name.c_str(), O_CREAT, S_IRWXU, initialCount); + + if(m_sem == SEM_FAILED) + { + CRNLIB_FAIL("semaphore: sem_open() failed"); + } +#else + maximumCount, pName; if (sem_init(&m_sem, 0, initialCount)) { CRNLIB_FAIL("semaphore: sem_init() failed"); } +#endif } semaphore::~semaphore() { +#ifdef __APPLE__ + sem_unlink(m_name.c_str()); +#else sem_destroy(&m_sem); +#endif } void semaphore::release(long releaseCount) @@ -132,7 +158,11 @@ namespace crnlib #else while (releaseCount > 0) { +#ifdef __APPLE__ + status = sem_post(m_sem); +#else status = sem_post(&m_sem); +#endif if (status) break; releaseCount--; @@ -157,7 +187,11 @@ namespace crnlib #else while (releaseCount > 0) { +#ifdef __APPLE__ + sem_post(m_sem); +#else sem_post(&m_sem); +#endif releaseCount--; } #endif @@ -168,22 +202,37 @@ namespace crnlib int status; if (milliseconds == cUINT32_MAX) { +#ifdef __APPLE__ + status = sem_wait(m_sem); +#else status = sem_wait(&m_sem); +#endif } else { +#ifdef __APPLE__ + status = sem_trywait(m_sem); +#else struct timespec interval; interval.tv_sec = milliseconds / 1000; interval.tv_nsec = (milliseconds % 1000) * 1000000L; status = sem_timedwait(&m_sem, &interval); +#endif } if (status) { +#ifdef __APPLE__ + if(errno != EAGAIN) + { + CRNLIB_FAIL("semaphore: sem_wait() or sem_trywait() failed"); + } +#else if (errno != ETIMEDOUT) { CRNLIB_FAIL("semaphore: sem_wait() or sem_timedwait() failed"); } +#endif return false; } @@ -192,31 +241,45 @@ namespace crnlib spinlock::spinlock() { +#ifdef __APPLE__ + m_spinlock = OS_SPINLOCK_INIT; +#else if (pthread_spin_init(&m_spinlock, 0)) { CRNLIB_FAIL("spinlock: pthread_spin_init() failed"); } +#endif } spinlock::~spinlock() { +#ifndef __APPLE__ pthread_spin_destroy(&m_spinlock); +#endif } void spinlock::lock() { +#ifdef __APPLE__ + OSSpinLockLock(&m_spinlock); +#else if (pthread_spin_lock(&m_spinlock)) { CRNLIB_FAIL("spinlock: pthread_spin_lock() failed"); } +#endif } void spinlock::unlock() { +#ifdef __APPLE__ + OSSpinLockUnlock(&m_spinlock); +#else if (pthread_spin_unlock(&m_spinlock)) { CRNLIB_FAIL("spinlock: pthread_spin_unlock() failed"); } +#endif } task_pool::task_pool() : diff --git a/crnlib/crn_threading_pthreads.h b/crnlib/crn_threading_pthreads.h index 547bb884..9b1a4d13 100644 --- a/crnlib/crn_threading_pthreads.h +++ b/crnlib/crn_threading_pthreads.h @@ -14,6 +14,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + namespace crnlib { // g_number_of_processors defaults to 1. Will be higher on multicore machines. @@ -74,7 +78,12 @@ namespace crnlib bool wait(uint32 milliseconds = cUINT32_MAX); private: +#ifdef __APPLE__ + std::string m_name; + sem_t *m_sem; +#else sem_t m_sem; +#endif }; class spinlock @@ -87,7 +96,11 @@ namespace crnlib void unlock(); private: +#ifdef __APPLE__ + OSSpinLock m_spinlock; +#else pthread_spinlock_t m_spinlock; +#endif }; class scoped_spinlock diff --git a/crnlib/crn_timer.cpp b/crnlib/crn_timer.cpp index 1c6fc4a4..c4188789 100644 --- a/crnlib/crn_timer.cpp +++ b/crnlib/crn_timer.cpp @@ -26,7 +26,11 @@ namespace crnlib QueryPerformanceFrequency(reinterpret_cast(pTicks)); } #elif defined(__GNUC__) + #ifdef __APPLE__ +#include +#else #include +#endif inline void query_counter(timer_ticks *pTicks) { struct timeval cur_time; diff --git a/crnlib/crn_vector.cpp b/crnlib/crn_vector.cpp index 8c21125d..41a33d83 100644 --- a/crnlib/crn_vector.cpp +++ b/crnlib/crn_vector.cpp @@ -22,8 +22,8 @@ namespace crnlib return true; size_t new_capacity = min_new_capacity; - if ((grow_hint) && (!math::is_power_of_2(new_capacity))) - new_capacity = math::next_pow2(new_capacity); + if ((grow_hint) && (!math::is_power_of_2((uint64)new_capacity))) + new_capacity = math::next_pow2((uint64)new_capacity); CRNLIB_ASSERT(new_capacity && (new_capacity > m_capacity)); diff --git a/crnlib/crnlib.cpp b/crnlib/crnlib.cpp index 682efad8..3c523243 100644 --- a/crnlib/crnlib.cpp +++ b/crnlib/crnlib.cpp @@ -14,6 +14,34 @@ #include "crn_rg_etc1.h" + +inline bool crn_comp_params::check() const +{ + if ( (m_file_type > cCRNFileTypeDDS) || + (((int)m_quality_level < (int)cCRNMinQualityLevel) || ((int)m_quality_level > (int)cCRNMaxQualityLevel)) || + (m_dxt1a_alpha_threshold > 255) || + ((m_faces != 1) && (m_faces != 6)) || + ((m_width < 1) || (m_width > cCRNMaxLevelResolution)) || + ((m_height < 1) || (m_height > cCRNMaxLevelResolution)) || + ((m_levels < 1) || (m_levels > cCRNMaxLevels)) || + ((m_format < cCRNFmtDXT1) || (m_format >= cCRNFmtTotal)) || + ((m_crn_color_endpoint_palette_size) && ((m_crn_color_endpoint_palette_size < cCRNMinPaletteSize) || (m_crn_color_endpoint_palette_size > cCRNMaxPaletteSize))) || + ((m_crn_color_selector_palette_size) && ((m_crn_color_selector_palette_size < cCRNMinPaletteSize) || (m_crn_color_selector_palette_size > cCRNMaxPaletteSize))) || + ((m_crn_alpha_endpoint_palette_size) && ((m_crn_alpha_endpoint_palette_size < cCRNMinPaletteSize) || (m_crn_alpha_endpoint_palette_size > cCRNMaxPaletteSize))) || + ((m_crn_alpha_selector_palette_size) && ((m_crn_alpha_selector_palette_size < cCRNMinPaletteSize) || (m_crn_alpha_selector_palette_size > cCRNMaxPaletteSize))) || + (m_alpha_component > 3) || + (m_num_helper_threads > cCRNMaxHelperThreads) || + (m_dxt_quality > cCRNDXTQualityUber) || + (m_dxt_compressor_type >= cCRNTotalDXTCompressors) ) + { + return false; + } + return true; +} + +inline bool crn_mipmap_params::check() const { return true; } + + namespace crnlib { static void* realloc_func(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data) diff --git a/inc/crn_decomp.h b/inc/crn_decomp.h index 680beb1f..e455fa7b 100644 --- a/inc/crn_decomp.h +++ b/inc/crn_decomp.h @@ -317,6 +317,8 @@ namespace crnd #include #ifdef WIN32 #include +#elif defined(__APPLE__) +#include #else #include #endif @@ -374,7 +376,7 @@ namespace crnd const uint32 cIntBits = 32U; -#ifdef _WIN64 +#if defined(_WIN64) || defined(_LP64) typedef uint64 ptr_bits; #else #ifdef __x86_64__ @@ -2426,6 +2428,8 @@ namespace crnd { #ifdef WIN32 *pActual_size = p_new ? ::_msize(p_new) : 0; +#elif defined(__APPLE__) + *pActual_size = p_new ? malloc_size(p_new) : 0; #else *pActual_size = p_new ? malloc_usable_size(p_new) : 0; #endif @@ -2462,6 +2466,8 @@ namespace crnd { #ifdef WIN32 *pActual_size = ::_msize(p_final_block); +#elif defined(__APPLE__) + *pActual_size = ::malloc_size(p_final_block); #else *pActual_size = ::malloc_usable_size(p_final_block); #endif @@ -2476,6 +2482,8 @@ namespace crnd pUser_data; #ifdef WIN32 return p ? _msize(p) : 0; +#elif defined(__APPLE__) + return p ? malloc_size(p) : 0; #else return p ? malloc_usable_size(p) : 0; #endif diff --git a/inc/crnlib.h b/inc/crnlib.h index 1c3e0782..55d063c6 100644 --- a/inc/crnlib.h +++ b/inc/crnlib.h @@ -274,29 +274,7 @@ struct crn_comp_params } // Returns true if the input parameters are reasonable. - inline bool check() const - { - if ( (m_file_type > cCRNFileTypeDDS) || - (((int)m_quality_level < (int)cCRNMinQualityLevel) || ((int)m_quality_level > (int)cCRNMaxQualityLevel)) || - (m_dxt1a_alpha_threshold > 255) || - ((m_faces != 1) && (m_faces != 6)) || - ((m_width < 1) || (m_width > cCRNMaxLevelResolution)) || - ((m_height < 1) || (m_height > cCRNMaxLevelResolution)) || - ((m_levels < 1) || (m_levels > cCRNMaxLevels)) || - ((m_format < cCRNFmtDXT1) || (m_format >= cCRNFmtTotal)) || - ((m_crn_color_endpoint_palette_size) && ((m_crn_color_endpoint_palette_size < cCRNMinPaletteSize) || (m_crn_color_endpoint_palette_size > cCRNMaxPaletteSize))) || - ((m_crn_color_selector_palette_size) && ((m_crn_color_selector_palette_size < cCRNMinPaletteSize) || (m_crn_color_selector_palette_size > cCRNMaxPaletteSize))) || - ((m_crn_alpha_endpoint_palette_size) && ((m_crn_alpha_endpoint_palette_size < cCRNMinPaletteSize) || (m_crn_alpha_endpoint_palette_size > cCRNMaxPaletteSize))) || - ((m_crn_alpha_selector_palette_size) && ((m_crn_alpha_selector_palette_size < cCRNMinPaletteSize) || (m_crn_alpha_selector_palette_size > cCRNMaxPaletteSize))) || - (m_alpha_component > 3) || - (m_num_helper_threads > cCRNMaxHelperThreads) || - (m_dxt_quality > cCRNDXTQualityUber) || - (m_dxt_compressor_type >= cCRNTotalDXTCompressors) ) - { - return false; - } - return true; - } + bool check() const; // Helper to set/get flags from m_flags member. inline bool get_flag(crn_comp_flags flag) const { return (m_flags & flag) != 0; } @@ -439,7 +417,7 @@ struct crn_mipmap_params m_clamp_height = 0; } - inline bool check() const { return true; } + bool check() const; inline bool operator== (const crn_mipmap_params& rhs) const {