DarwinCommon.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. #pragma once
  2. #ifdef __LP64__
  3. #define BF64
  4. #else
  5. #define BF32
  6. #endif
  7. #define BOOST_DETAIL_NO_CONTAINER_FWD
  8. #include <stdint.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <pthread.h>
  12. #include <time.h>
  13. #include <assert.h>
  14. #include <sys/time.h>
  15. //#include <libkern/OSAtomic.h>
  16. #include <cstdlib>
  17. #include <unistd.h>
  18. #include <wchar.h>
  19. #include <math.h>
  20. #include <stdarg.h>
  21. #include <string.h>
  22. #include <pthread.h>
  23. #include <wctype.h>
  24. #include <stddef.h>
  25. #include <mach/error.h>
  26. //#define errno (*__error())
  27. //#define offsetof(type, member) __builtin_offsetof (type, member)
  28. extern "C"
  29. {
  30. //#define FFI_BUILDING
  31. //#include "third_party/libffi/x86_64-apple-darwin12.5.0/include/ffi.h"
  32. }
  33. #define BF_ENDIAN_LITTLE
  34. #define _NOEXCEPT noexcept
  35. #define NTAPI
  36. #define FFI_STDCALL FFI_DEFAULT_ABI
  37. #define FFI_THISCALL FFI_DEFAULT_ABI
  38. #define FFI_FASTCALL FFI_DEFAULT_ABI
  39. #define INVALID_SOCKET -1
  40. typedef uint64_t uint64;
  41. typedef uint32_t uint32;
  42. typedef uint16_t uint16;
  43. typedef uint8_t uint8;
  44. typedef int64_t int64;
  45. typedef int32_t int32;
  46. typedef int16_t int16;
  47. typedef int8_t int8;
  48. typedef unsigned int uint;
  49. #define BF_PLATFORM_LINUX
  50. #define BF_PLATFORM_NAME "BF_PLATFORM_LINUX"
  51. //#define BF_PLATFORM_SDL
  52. #define NOP
  53. //#define BF_NOTHROW throw ()
  54. //#define BF_NOTHROW noexcept
  55. #define BF_NOTHROW
  56. #ifdef BF64
  57. typedef int64 intptr;
  58. typedef uint64 uintptr;
  59. #else
  60. typedef int32 intptr;
  61. typedef uint32 uintptr;
  62. #endif
  63. typedef wchar_t* BSTR;
  64. typedef int HRESULT;
  65. typedef uint8 BYTE;
  66. typedef uint16 WORD;
  67. typedef uint32 DWORD;
  68. typedef int32 LONG;
  69. typedef pthread_key_t BFTlsKey;
  70. typedef pthread_t BF_THREADID;
  71. typedef pthread_t BF_THREADHANDLE;
  72. #define BF_TLS_DECLSPEC thread_local
  73. //:int64 abs(int64 val);
  74. #define _stricmp stricmp
  75. #define strnicmp strncasecmp
  76. struct IID
  77. {
  78. unsigned long Data1;
  79. unsigned short Data2;
  80. unsigned short Data3;
  81. unsigned char Data4[ 8 ];
  82. };
  83. typedef void* HANDLE;
  84. typedef void* HMODULE;
  85. // We only need the stdcall attribute for x32?
  86. //#define BFSTDCALL __attribute__((stdcall))
  87. //#include "../notwin/NotWin.h"
  88. #ifdef DEBUG
  89. #define _DEBUG
  90. #endif
  91. #define NOT_IMPL throw "Unimplemented";
  92. //ARM
  93. #if defined(__x86_64__) || defined(__i386__)
  94. #define BF_FULL_MEMORY_FENCE() __asm__ __volatile__("mfence": : :"memory")
  95. #define BF_SPINWAIT_NOP() __asm__ volatile ("pause\n" : : : "memory" );
  96. #else
  97. #define BF_FULL_MEMORY_FENCE() __sync_synchronize()
  98. #define BF_SPINWAIT_NOP() ((void) 0)
  99. #endif
  100. #define BF_COMPILER_FENCE() __asm__ __volatile__("": : :"memory")
  101. #define BF_THREAD_YIELD() sched_yield()
  102. #if defined _DEBUG || defined BF_DEBUG_ASSERTS
  103. #define BF_ASSERT(_Expression) (void)( (!!(_Expression)) || (Beefy::BFFatalError(#_Expression, __FILE__, __LINE__), 0) )
  104. #else
  105. #define BF_ASSERT(_Expression) (void)(0)
  106. #endif
  107. #define BF_ASSERT_REL(_Expression) (void)( (!!(_Expression)) || (Beefy::BFFatalError(#_Expression, __FILE__, __LINE__), 0) )
  108. #define BF_FATAL(msg) (void) ((Beefy::BFFatalError(msg, __FILE__, __LINE__), 0) )
  109. #if defined _DEBUG || defined BF_DEBUG_ASSERTS
  110. #define BF_DBG_FATAL(msg) (void) ((Beefy::BFFatalError(msg, __FILE__, __LINE__), 0) )
  111. #else
  112. #define BF_DBG_FATAL(msg)
  113. #endif
  114. #define BF_NOINLINE __attribute__ ((noinline))
  115. #define BF_NAKED
  116. #define stricmp strcasecmp
  117. #define _alloca alloca
  118. #define DIR_SEP_CHAR '/'
  119. #define DIR_SEP_CHAR_ALT '\\'
  120. static char* itoa(int value, char* str, int base)
  121. {
  122. if (base == 16)
  123. sprintf(str, "%X", value);
  124. else
  125. sprintf(str, "%d", value);
  126. return str;
  127. }
  128. inline uint32 InterlockedCompareExchange(volatile uint32* dest, uint32 exch, uint32 comp)
  129. {
  130. return __sync_val_compare_and_swap(dest, comp, exch);
  131. }
  132. inline uint64 InterlockedCompareExchange64(volatile int64* dest, int64 exch, int64 comp)
  133. {
  134. return __sync_val_compare_and_swap(dest, comp, exch);
  135. }
  136. inline void* InterlockedCompareExchangePointer(void* volatile* dest, void* exch, void* comp)
  137. {
  138. return __sync_val_compare_and_swap(dest, comp, exch);
  139. }
  140. inline uint32 InterlockedExchange(volatile uint32* dest, uint32 val)
  141. {
  142. return __sync_lock_test_and_set(dest, val);
  143. }
  144. inline uint64 InterlockedExchange64(volatile int64* dest, int64 val)
  145. {
  146. return __sync_lock_test_and_set(dest, val);
  147. }
  148. inline uint32 InterlockedExchangeAdd(volatile uint32* dest, uint32 val)
  149. {
  150. return __sync_add_and_fetch(dest, val);
  151. }
  152. inline int32 InterlockedIncrement(volatile uint32* val)
  153. {
  154. return __sync_add_and_fetch(val, 1);
  155. }
  156. inline int64 InterlockedIncrement64(volatile int64* val)
  157. {
  158. return __sync_add_and_fetch(val, 1);
  159. }
  160. inline int32 InterlockedDecrement(volatile uint32* val)
  161. {
  162. return __sync_add_and_fetch(val, -1);
  163. }
  164. inline int64 InterlockedDecrement64(volatile int64* val)
  165. {
  166. return __sync_add_and_fetch(val, -1);
  167. }
  168. #if 0
  169. #pragma once
  170. #ifdef __LP64__
  171. #define BF64
  172. #else
  173. #define BF32
  174. #endif
  175. #define BOOST_DETAIL_NO_CONTAINER_FWD
  176. #include <stdint.h>
  177. #include <stdlib.h>
  178. #include <pthread.h>
  179. #include <time.h>
  180. #include <assert.h>
  181. #include <sys/time.h>
  182. #include <libkern/OSAtomic.h>
  183. #include <cstdlib>
  184. #include <unistd.h>
  185. #include <wchar.h>
  186. #include <math.h>
  187. extern "C"
  188. {
  189. #define FFI_BUILDING
  190. #include "third_party/libffi/x86_64-apple-darwin12.5.0/include/ffi.h"
  191. }
  192. #define FFI_STDCALL FFI_DEFAULT_ABI
  193. #define FFI_THISCALL FFI_DEFAULT_ABI
  194. #define FFI_FASTCALL FFI_DEFAULT_ABI
  195. typedef uint64_t uint64;
  196. typedef uint32_t uint32;
  197. typedef uint16_t uint16;
  198. typedef uint8_t uint8;
  199. typedef int64_t int64;
  200. typedef int32_t int32;
  201. typedef int16_t int16;
  202. typedef int8_t int8;
  203. typedef unsigned int uint;
  204. #define BF_PLATFORM_DARWIN
  205. #define BF_PLATFORM_SDL
  206. #define NOP
  207. //#define BF_NOTHROW throw ()
  208. //#define BF_NOTHROW noexcept
  209. #define BF_NOTHROW
  210. #ifdef BF64
  211. typedef int64 intptr;
  212. typedef uint64 uintptr;
  213. #else
  214. typedef int32 intptr;
  215. typedef uint32 uintptr;
  216. #endif
  217. typedef wchar_t* BSTR;
  218. typedef int HRESULT;
  219. typedef uint32 DWORD;
  220. typedef int32 LONG;
  221. typedef pthread_key_t BFTlsKey;
  222. typedef pthread_t BF_THREADID;
  223. int64 abs(int64 val) noexcept;
  224. struct IID
  225. {
  226. unsigned long Data1;
  227. unsigned short Data2;
  228. unsigned short Data3;
  229. unsigned char Data4[ 8 ];
  230. };
  231. typedef void* HANDLE;
  232. typedef void* HMODULE;
  233. #include "../notwin/NotWin.h"
  234. #ifdef DEBUG
  235. #define _DEBUG
  236. #endif
  237. //ARM
  238. #if defined(__x86_64__) || defined(__i386__)
  239. #define BF_FULL_MEMORY_FENCE() __asm__ __volatile__("mfence": : :"memory")
  240. #define BF_SPINWAIT_NOP() __asm__ volatile ("pause\n" : : : "memory" );
  241. #else
  242. #define BF_FULL_MEMORY_FENCE() __sync_synchronize()
  243. #define BF_SPINWAIT_NOP() ((void) 0)
  244. #endif
  245. #define BF_COMPILER_FENCE() __asm__ __volatile__("": : :"memory")
  246. #define BF_THREAD_YIELD() sched_yield()
  247. #define BF_ASSERT assert
  248. #define BF_FATAL(msg) assert(msg == 0)
  249. #define BF_NOINLINE __attribute__ ((noinline))
  250. #define BF_NAKED
  251. #define _alloca alloca
  252. namespace Beefy
  253. {
  254. class CritSect
  255. {
  256. private:
  257. pthread_mutex_t mCriticalSection;
  258. public:
  259. CritSect(void)
  260. {
  261. pthread_mutexattr_t attributes;
  262. pthread_mutexattr_init(&attributes);
  263. pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);
  264. pthread_mutex_init(&mCriticalSection, &attributes);
  265. pthread_mutexattr_destroy(&attributes);
  266. }
  267. ~CritSect(void)
  268. {
  269. pthread_mutex_destroy(&mCriticalSection);
  270. }
  271. bool TryLock()
  272. {
  273. return pthread_mutex_trylock( &mCriticalSection ) == 0;
  274. }
  275. void Lock()
  276. {
  277. pthread_mutex_lock( &mCriticalSection );
  278. }
  279. void Unlock()
  280. {
  281. pthread_mutex_unlock(&mCriticalSection);
  282. }
  283. };
  284. class SyncEvent
  285. {
  286. private:
  287. pthread_mutex_t mMutex;
  288. pthread_cond_t mCondition;
  289. uint32 mSet;
  290. bool mManualReset;
  291. bool mInitialState;
  292. int mSetCount;
  293. int mWaitForCountFail;
  294. int mWaitForCountSucceed;
  295. public:
  296. SyncEvent(bool manualReset = false, bool initialState = false)
  297. {
  298. mManualReset = manualReset;
  299. mSet = initialState;
  300. int result = pthread_mutex_init(&mMutex, NULL);
  301. BF_ASSERT(result == 0);
  302. result = pthread_cond_init(&mCondition, NULL);
  303. BF_ASSERT(result == 0);
  304. mInitialState = initialState;
  305. mSetCount = 0;
  306. mWaitForCountFail = 0;
  307. mWaitForCountSucceed = 0;
  308. }
  309. ~SyncEvent()
  310. {
  311. pthread_cond_destroy(&mCondition);
  312. pthread_mutex_destroy(&mMutex);
  313. }
  314. void Set()
  315. {
  316. pthread_mutex_lock(&mMutex);
  317. mSet = true;
  318. pthread_cond_signal(&mCondition);
  319. pthread_mutex_unlock(&mMutex);
  320. mSetCount++;
  321. }
  322. void Reset()
  323. {
  324. mSet = false;
  325. }
  326. bool WaitFor(uint32 timeout)
  327. {
  328. int result = pthread_mutex_lock(&mMutex);
  329. BF_ASSERT(result == 0);
  330. while (!mSet)
  331. {
  332. struct timespec ts;
  333. struct timeval tv;
  334. gettimeofday(&tv, NULL);
  335. uint64 nsec = (uint64)timeout * 1000000;
  336. ts.tv_nsec = tv.tv_usec * 1000;
  337. ts.tv_sec = tv.tv_sec;
  338. ts.tv_nsec += nsec % 1000000000;
  339. ts.tv_sec += nsec / 1000000000;
  340. ts.tv_sec += (ts.tv_nsec / 1000000000);
  341. ts.tv_nsec %= 1000000000;
  342. result = pthread_cond_timedwait(&mCondition, &mMutex, &ts);
  343. if (timeout == (uint32)-1)
  344. BF_ASSERT(result == 0);
  345. if (result != 0)
  346. {
  347. // Timeout
  348. mWaitForCountFail++;
  349. pthread_mutex_unlock(&mMutex);
  350. return false;
  351. }
  352. }
  353. if (!mManualReset)
  354. mSet = false;
  355. mWaitForCountSucceed++;
  356. pthread_mutex_unlock(&mMutex);
  357. return true;
  358. }
  359. };
  360. }
  361. inline uint32 InterlockedCompareExchange(volatile uint32* dest, uint32 exch, uint32 comp)
  362. {
  363. while (true)
  364. {
  365. if (OSAtomicCompareAndSwap32Barrier((int32)comp, (int32)exch, (volatile int32*)dest))
  366. return comp;
  367. // We don't want to return *dest being equal to 'comp' if the CAS result was false
  368. uint32 oldVal = *dest;
  369. if (oldVal != comp)
  370. return oldVal;
  371. }
  372. }
  373. inline uint64 InterlockedCompareExchange64(volatile int64* dest, int64 exch, int64 comp)
  374. {
  375. while (true)
  376. {
  377. if (OSAtomicCompareAndSwap64Barrier((int64)comp, (int64)exch, (volatile int64*)dest))
  378. return comp;
  379. // We don't want to return *dest being equal to 'comp' if the CAS result was false
  380. uint64 oldVal = *dest;
  381. if (oldVal != comp)
  382. return oldVal;
  383. }
  384. }
  385. inline void* InterlockedCompareExchangePointer(void* volatile* dest, void* exch, void* comp)
  386. {
  387. while (true)
  388. {
  389. if (OSAtomicCompareAndSwapPtrBarrier(comp, exch, dest))
  390. return comp;
  391. // We don't want to return *dest being equal to 'comp' if the CAS result was false
  392. void* oldVal = *dest;
  393. if (oldVal != comp)
  394. return oldVal;
  395. }
  396. }
  397. inline uint32 InterlockedExchange(volatile uint32* dest, uint32 val)
  398. {
  399. while (true)
  400. {
  401. uint32 oldVal = *dest;
  402. if (OSAtomicCompareAndSwap32Barrier((int32)oldVal, (int32)val, (volatile int32*)dest))
  403. return oldVal;
  404. }
  405. }
  406. inline uint64 InterlockedExchange64(volatile int64* dest, int64 val)
  407. {
  408. while (true)
  409. {
  410. uint64 oldVal = *dest;
  411. if (OSAtomicCompareAndSwap64Barrier((int64)oldVal, (int64)val, (volatile int64*)dest))
  412. return oldVal;
  413. }
  414. }
  415. inline uint32 InterlockedExchangeAdd(volatile uint32* dest, uint32 val)
  416. {
  417. return 0;
  418. }
  419. inline int32 InterlockedIncrement(volatile uint32* val)
  420. {
  421. return OSAtomicIncrement32Barrier((int32*)val);
  422. }
  423. inline int64 InterlockedIncrement64(volatile int64* val)
  424. {
  425. return OSAtomicIncrement64Barrier(val);
  426. }
  427. inline int32 InterlockedDecrement(volatile uint32* val)
  428. {
  429. return OSAtomicDecrement32Barrier((int32*)val);
  430. }
  431. inline int64 InterlockedDecrement64(volatile int64* val)
  432. {
  433. return OSAtomicDecrement64Barrier(val);
  434. }
  435. #endif