|
|
|
|
|
|
|
|
static auto _Lock_nonmember2(_LA& _LkN) ->decltype(_LkN._ReturnValue())
|
|
|
static auto _Lock_nonmember2(_LA& _LkN) ->decltype(_LkN._ReturnValue())
|
|
|
{
|
|
|
{
|
|
|
// lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
|
|
|
// lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
|
|
|
#if defined(__GNUC__)
|
|
|
|
|
|
for (;;)
|
|
|
for (;;)
|
|
|
{
|
|
|
{
|
|
|
auto _Result__ = LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 0, 1));
|
|
|
auto _Result__ = LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 0, 1));
|
|
|
|
|
|
|
|
|
_Result__ = LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 1, 0));
|
|
|
_Result__ = LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 1, 0));
|
|
|
if (!_Result__) break;
|
|
|
if (!_Result__) break;
|
|
|
}
|
|
|
}
|
|
|
#else
|
|
|
|
|
|
while (LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 0, 1)) &&
|
|
|
|
|
|
LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 1, 0)))
|
|
|
|
|
|
{ // keep trying
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
template<_LockAssembleT _LA>
|
|
|
template<_LockAssembleT _LA>
|