📄 hxmutexlock.h
字号:
inline static int_HXMutexSetBit(HX_MUTEX pLock){ volatile int nOldBit; __asm__ __volatile__("swap [%0], %1" : "=r" (pLock), "=&r" (nOldBit) : "0" (pLock), "1" (1)); return nOldBit;}/*********************************************************************** * Solaris / sparc / native compiler * * Implementation Notes: * Uses assembly mutex * native-compiler syntax */#elif defined _SOLARIS /* native compiler */extern "C" int _HXMutexSetBitCAS(HX_MUTEX pLock);extern "C" int _HXMutexSetBitSWAP(HX_MUTEX pLock);extern "C" int _HXMutexClearBit(HX_MUTEX pLock);#define _HXMutexSetBit(pLock) _HXMutexSetBitCAS(pLock)#define _HXMutexYieldCPUIfNeeded() /* not needed */#define _HXMutexInitBit(pLock) _HXMutexClearBit(pLock)#define _HXMutexDestroyBit(pLock) /* not needed *//*********************************************************************** * IRIX / MIPS * * Implementation Notes: * Uses native mutex calls acquire_lock/etc. * On this platform we explicitly yield the processor */#elif defined _IRIX#define _HXMutexYieldCPUIfNeeded() sginap(0)#define _HXMutexSetBit(pLock) acquire_lock(pLock)#define _HXMutexClearBit(pLock) release_lock(pLock)#define _HXMutexInitBit(pLock) init_lock(pLock)#define _HXMutexDestroyBit(pLock) /* not needed *//*********************************************************************** * AIX / PowerPC * * Implementation Notes: * Uses native mutex calls msem_lock/etc. */#elif defined _AIX// NATIVE MUTEX//this doesn't work cleanly, we had to customize HXMutexLock() for AIX#define _HXMutexYieldCPUIfNeeded() /* not needed */#define _HXMutexSetBit(pLock) msem_lock(pLock, MSEM_IF_NOWAIT)#define _HXMutexClearBit(pLock) msem_unlock(pLock, 0)#define _HXMutexInitBit(pLock) msem_init(pLock, MSEM_UNLOCKED)#define _HXMutexDestroyBit(pLock) msem_remove(pLock)// ASSEMBLY MUTEX//#include <sched.h>//#define _HXMutexYieldCPUIfNeeded() sched_yield()//extern "C" int _HXMutexSetBit(HX_MUTEX pLock);//extern "C" int _HXMutexClearBit(HX_MUTEX pLock);//#define _HXMutexInitBit(pLock) _HXMutexClearBit(pLock)//#define _HXMutexDestroyBit(pLock) /* not needed *//*********************************************************************** * HP-UX / Itanium * * Implementation Notes: * Uses non-inline assembly mutex call _HXMutexSetBit(), defined * in common/util/platform/hpux/spinlock-ia64.s. XXX: make this inline. */#elif defined _HPUX && defined _IA64extern "C" int _HXMutexSetBit(HX_MUTEX pLock);extern "C" int _HXMutexClearBit(HX_MUTEX pLock);#define _HXMutexYieldCPUIfNeeded() /* not needed */#define _HXMutexInitBit(pLock) _HXMutexClearBit(pLock)#define _HXMutexDestroyBit(pLock) /* not needed *//*********************************************************************** * HP-UX / PA-RISC * * Implementation Notes: * Uses non-inline assembly mutex call load_and_clear(), defined * in common/util/platform/hpux/spin.s. XXX: make this inline. * The logic of this mutex is backwards from most of our others, * 1 means clear, 0 means set. */#elif defined _HPUX#define _HXMutexYieldCPUIfNeeded() /* not needed */#define _HXMutexSetBit(pLock) (load_and_clear((char* volatile)pLock) == 0)#define _HXMutexClearBit(pLock) release_spinlock(pLock)#define _HXMutexInitBit(pLock) _HXMutexClearBit(pLock)#define _HXMutexDestroyBit(pLock) /* not needed *//*********************************************************************** * Tru64 (OSF/1) / Alpha * * Implementation Notes: * Uses native mutex calls __LOCK_LONG_RETRY/etc. * * TODO: * This native mutex is much slower than on other platforms. * Change this to use assembly. */#elif defined _OSF1#define _HXMutexYieldCPUIfNeeded() /* not needed */#define _HXMutexSetBit(pLock) (__LOCK_LONG_RETRY(pLock, 1) == 0)#define _HXMutexClearBit(pLock) __UNLOCK_LONG(pLock)#define _HXMutexInitBit(pLock) _HXMutexClearBit(pLock)#define _HXMutexDestroyBit(pLock) /* not needed *//*********************************************************************** * Misc. Unix / x86 (Linux, FreeBSD...) * * Implementation Notes: * Uses assembly mutex * GCC inline-assembly syntax * * TODO: add non-x86 support for Linux/FreeBSD/etc. */#else#define _HXMutexYieldCPUIfNeeded() /* not needed */#define _HXMutexInitBit(pLock) _HXMutexClearBit(pLock)#define _HXMutexDestroyBit(pLock) /* not needed */#define _HXMutexClearBit(pLock) (*(pLock) = 0)/* * GCC gets really mad if we use eax / ebx in the assembly below. * We use ecx / edx instead (cross your fingers =) */inline static int_HXMutexSetBit(HX_MUTEX pLock){ volatile int nOldBit; __asm__ __volatile__("xchg %%ecx, (%%edx)" : "=c" (nOldBit) : "c" (1), "d" (pLock)); return nOldBit;}#endif/*********************************************************************** * Common code, shared by multiple platforms * */#if !defined(HELIX_FEATURE_SERVER) && !defined(HX_MUTEX_PRIVATE_COLLISION_COUNTERS) && !defined(HX_MUTEX_PRIVATE_COLLISION_COUNTERS)//default for non-server products is to not use the collision counters#define HX_MUTEX_NO_COLLISION_COUNTERS#endif#if defined HX_MUTEX_NO_COLLISION_COUNTERS#define HXMutexCollision(p) /* nothing */#elif defined HX_MUTEX_PRIVATE_COLLISION_COUNTERS/* User must define their own HXMutexCollision(p) */#elseextern HX_MUTEX g_pServerMainLock;extern UINT32* g_pConcurrentOps;extern UINT32* g_pConcurrentMemOps;inline voidHXMutexCollision(HX_MUTEX pLock){ ++(*g_pConcurrentOps); if (pLock != g_pServerMainLock) ++(*g_pConcurrentMemOps);}#endif#ifndef HX_MUTEX_CUSTOM_COLLISION_DELAY#define HXMutexCollisionDelay(n) microsleep(n)#else/* User must define their own HXMutexCollisionDelay() */#endif//will obsolete these old names shortly...#define HXCreateMutex() HXMutexCreate()#define HXInitMutex(p) HXMutexInit(p)#define HXUnInitMutex(p) HXMutexUnInit(p)#define HXDestroyMutex(p) HXMutexDestroy(p)#ifdef HX_MUTEX_USE_MANAGED_LOCKSHX_RESULT AddManagedMutex(HX_MUTEX pMutex);HX_RESULT RemoveManagedMutex(HX_MUTEX pMutex);#endifinline voidHXMutexLock(HX_MUTEX pLock, BOOL bWait = FALSE){#ifdef XXXDC_USE_BACKOFF if (_HXMutexSetBit(pLock)) { register int nInitialTries = 1; register int nDelay = BACKOFF_START; //spin on reads for a bit (not writes) while (*pLock && nInitialTries < BACKOFF_THRESHOLD) { HXMutexCollision(pLock); ++nInitialTries; } while(_HXMutexSetBit(pLock)) { _HXMutexYieldCPUIfNeeded(); if (bWait) { HXMutexCollisionDelay(nDelay); nDelay = nDelay * BACKOFF_FACTOR; if (nDelay > BACKOFF_MAX) nDelay = BACKOFF_MAX; } HXMutexCollision(pLock); } }#elif defined _AIX do { if (msem_lock(pLock, 0) == 0) break; } while (errno == EINTR);#else while(_HXMutexSetBit(pLock)) { _HXMutexYieldCPUIfNeeded(); if (bWait) { HXMutexCollisionDelay(HX_MUTEX_DELAY); } HXMutexCollision(pLock); }#endif#ifdef HX_MUTEX_USE_MANAGED_LOCKS AddManagedMutex(pLock);#endif}inline BOOLHXMutexTryLock(HX_MUTEX pLock){#ifdef _AIX BOOL bRet = (msem_lock(pLock, 0) == 0);#ifdef HX_MUTEX_USE_MANAGED_LOCKS if (bRet) AddManagedMutex(pLock);#endif return bRet;#else if (_HXMutexSetBit(pLock)) { HXMutexCollision(pLock); return FALSE; }#ifdef HX_MUTEX_USE_MANAGED_LOCKS AddManagedMutex(pLock);#endif return TRUE;#endif}inline voidHXMutexUnlock(HX_MUTEX pLock){#ifdef HX_MUTEX_USE_MANAGED_LOCKS RemoveManagedMutex(pLock);#endif _HXMutexClearBit(pLock);}inline HX_MUTEXHXMutexCreate(){ HX_MUTEX pLock = (HX_MUTEX) new HX_MUTEX_BASE_TYPE; _HXMutexInitBit(pLock); return pLock;}inline voidHXMutexInit(HX_MUTEX pLock){ _HXMutexClearBit(pLock);}inline voidHXMutexUnInit(HX_MUTEX pLock){ /* no-op */}inline voidHXMutexDestroy(HX_MUTEX pLock){ _HXMutexDestroyBit(pLock);#if defined _WINDOWS delete (void*)pLock;#else delete pLock;#endif}#endif /* _HXMUTEXLOCK_H_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -