CGPの置換表ロック

書き方の悪いコード片ですが、ご自由にお使いください。

 

書き込みロック

while (1)
{
	__int8 oldlock,newlock;
	oldlock = hashn[hashadd].counter;
	while (oldlock & 0x1)
	{
		_mm_pause();
		oldlock = hashn[hashadd].counter;
	}
	newlock = oldlock + 0x1;
	if (_InterlockedCompareExchange8(&(hashn[hashadd].counter), newlock, oldlock) == oldlock)
	{
		break;
	}
}

書き込みアンロック

	_WriteBarrier();
	hashn[hashadd].counter++;

読み込み

do
{
	do
	{
		countertmp = hashn[hashadd].counter;
	} while (countertmp & 1);
	_ReadBarrier();
	nowhash = hashn[hashadd];
} while (countertmp != nowhash.counter);

よくみたら読み込みにpause入れて無いや。追加しないと。

(ここから2017/1/21 20:36追記)

書いていませんでしたがx86あるいはx64専用です。

このコードではコンパイラの最適化の抑制が足りなくて読み込みのときに壊れた値を読み出す可能性があります*1

nowhash = hashn[hashadd];の部分を手動で順番を制御してコンパイラの最適化でも並び替えられないよう*2に修正しないと!

 

*1:今さっき気づいた

*2:Out of Orderによる並び替えは起こってもx64のmemory orderingのおかげで問題は起こらないはず