📄 atomic_functions.h
字号:
// __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
// 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 */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -