📄 hxmutexlock.h
字号:
: "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 _IA64
extern "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) */
#else
extern HX_MUTEX g_pServerMainLock;
extern UINT32* g_pConcurrentOps;
extern UINT32* g_pConcurrentMemOps;
inline void
HXMutexCollision(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_LOCKS
HX_RESULT AddManagedMutex(HX_MUTEX pMutex);
HX_RESULT RemoveManagedMutex(HX_MUTEX pMutex);
#endif
inline void
HXMutexLock(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 BOOL
HXMutexTryLock(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 void
HXMutexUnlock(HX_MUTEX pLock)
{
#ifdef HX_MUTEX_USE_MANAGED_LOCKS
RemoveManagedMutex(pLock);
#endif
_HXMutexClearBit(pLock);
}
inline HX_MUTEX
HXMutexCreate()
{
HX_MUTEX pLock = (HX_MUTEX) new HX_MUTEX_BASE_TYPE;
_HXMutexInitBit(pLock);
return pLock;
}
inline void
HXMutexInit(HX_MUTEX pLock)
{
_HXMutexClearBit(pLock);
}
inline void
HXMutexUnInit(HX_MUTEX pLock)
{
/* no-op */
}
inline void
HXMutexDestroy(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 + -