📄 atomic_functions.h
字号:
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
xadd dword ptr [ecx], eax
/* Since this is pre-increment, we need to inc eax to catch up with the
* real value
*/
inc eax
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
else
{
_asm
{
/* pop 1 into eax, which can then be atomically added into *pl (held
* in ecx). Since it's an xadd it exchanges the previous value into eax
*/
mov eax, 1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
lock xadd dword ptr [ecx], eax
/* Since this is pre-increment, we need to inc eax to catch up with the
* real value
*/
inc eax
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
}
/** \brief
*
* \ingroup group__library__synch
*/
WINSTL_ATOMIC_FNS_IMPL_(ws_sint32_t) atomic_predecrement(ws_sint32_t volatile* /* pl */)
{
if(s_up)
{
_asm
{
/* pop 1 into eax, which can then be atomically added into *pl (held
* in ecx). Since it's an xadd it exchanges the previous value into eax
*/
mov eax, -1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
xadd dword ptr [ecx], eax
/* Since this is pre-decrement, we need to inc eax to catch up with the
* real value
*/
dec eax
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
else
{
_asm
{
/* pop 1 into eax, which can then be atomically added into *pl (held
* in ecx). Since it's an xadd it exchanges the previous value into eax
*/
mov eax, -1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
lock xadd dword ptr [ecx], eax
/* Since this is pre-decrement, we need to inc eax to catch up with the
* real value
*/
dec eax
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
}
/** \brief
*
* \ingroup group__library__synch
*/
WINSTL_ATOMIC_FNS_IMPL_(ws_sint32_t) atomic_postincrement(ws_sint32_t volatile* /* pl */)
{
if(s_up)
{
_asm
{
/* pop 1 into eax, which can then be atomically added into *pl (held
* in ecx). Since it's an xadd it exchanges the previous value into eax
*/
mov eax, 1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
xadd dword ptr [ecx], eax
/* Since this is post-increment, we need do nothing, since the previous
* value is in eax
*/
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
else
{
_asm
{
/* pop 1 into eax, which can then be atomically added into *pl (held
* in ecx). Since it's an xadd it exchanges the previous value into eax
*/
mov eax, 1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
lock xadd dword ptr [ecx], eax
/* Since this is post-increment, we need do nothing, since the previous
* value is in eax
*/
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
}
/** \brief
*
* \ingroup group__library__synch
*/
WINSTL_ATOMIC_FNS_IMPL_(ws_sint32_t) atomic_postdecrement(ws_sint32_t volatile* /* pl */)
{
if(s_up)
{
_asm
{
/* pop 1 into eax, which can then be atomically added into *pl (held
* in ecx). Since it's an xadd it exchanges the previous value into eax
*/
mov eax, -1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
xadd dword ptr [ecx], eax
/* Since this is post-decrement, we need do nothing, since the previous
* value is in eax
*/
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
else
{
_asm
{
/* pop 1 into eax, which can then be atomically added into *pl (held
* in ecx). Since it's an xadd it exchanges the previous value into eax
*/
mov eax, -1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
lock xadd dword ptr [ecx], eax
/* Since this is post-decrement, we need do nothing, since the previous
* value is in eax
*/
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
}
/** \brief
*
* \ingroup group__library__synch
*/
WINSTL_ATOMIC_FNS_IMPL_(void) atomic_increment(ws_sint32_t volatile* /* pl */)
{
if(s_up)
{
_asm
{
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
add dword ptr [ecx], 1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
else
{
_asm
{
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
/* The IA-32 Intel Architecture Software Developer's Manual, volume 2
* states that a LOCK can be prefixed to ADD, but CodePlay VectorC
* has a problem with it.
*/
#if defined(STLSOFT_COMPILER_IS_VECTORC)
mov eax, 1
lock xadd dword ptr [ecx], eax
#else /* ? compiler */
lock add dword ptr [ecx], 1
#endif /* compiler */
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
}
/** \brief
*
* \ingroup group__library__synch
*/
WINSTL_ATOMIC_FNS_IMPL_(void) atomic_decrement(ws_sint32_t volatile* /* pl */)
{
if(s_up)
{
_asm
{
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
add dword ptr [ecx], -1
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
else
{
_asm
{
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
#if defined(STLSOFT_COMPILER_IS_VECTORC)
mov eax, -1
lock xadd dword ptr [ecx], eax
#else /* ? compiler */
/* This might be wrong */
lock sub dword ptr [ecx], 1
#endif /* compiler */
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
}
/** \brief
*
* \ingroup group__library__synch
*/
WINSTL_ATOMIC_FNS_IMPL_(ws_sint32_t) atomic_read(ws_sint32_t volatile const* /* pl */)
{
if(s_up)
{
_asm
{
mov eax, 0
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
/* pop 0 into eax, which can then be atomically added into *pl (held
* in ecx), leaving the value unchanged.
*/
xadd dword ptr [ecx], eax
/* Since it's an xadd it exchanges the previous value into eax, which
* is exactly what's required
*/
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
ret
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
ret 4
#endif /* call-conv */
}
}
else
{
_asm
{
mov eax, 0
#if defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_FASTCALL)
/* __fastcall: ecx is pl */
#elif defined(WINSTL_ATOMIC_FNS_CALLCONV_IS_STDCALL)
/* __stdcall: arguments are on the stack */
mov ecx, dword ptr [esp + 4]
#else
# error Need to define calling convention
#endif /* call-conv */
/* pop 0 into eax, which can then be atomically added into *pl (held
* in ecx), leaving the value unchanged.
*/
lock xadd dword ptr [ecx], eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -