アトミック CAS を使用します。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683560(v=vs.85).aspx
ロックフリーにすることはできますが、待機フリーにすることはできません。
キリルが示唆しているように、これはあなたの場合のスピンロックに似ています。
これは必要なことだと思いますが、まったくテストしていないため、先に進む前にすべての可能性を検討して使用することをお勧めします。
inline bool
InterlockedSetIfEqual(volatile LONG* dest, LONG exchange, LONG comperand)
{
return comperand == ::InterlockedCompareExchange(dest, exchange, comperand);
}
inline bool InterlockedDecrementNotZero(volatile LONG* ptr)
{
LONG comperand;
LONG exchange;
do {
comperand = *ptr;
exchange = comperand-1;
if (comperand <= 0) {
return false;
}
} while (!InterlockedSetIfEqual(ptr,exchange,comperand));
return true;
}
保留中の作業項目がゼロ未満になる理由については、疑問が残ります。インクリメントの数がデクリメントの数と一致することを本当に確認する必要があり、すべて問題ありません。この制約に違反している場合は、おそらくアサートまたは例外を追加します。