次の単純なミューテックス定義を考えてみましょう:
class Mutex {
private:
bool lock;
public:
void acquire();
void release();
Mutex() {
lock = 0;
}
};
そして、次のacquire()
func 実現 (compare と swap 操作を使用):
void Mutex::acquire() {
bool oldValue;
__atomic_load(&lock, &oldValue, 0);
bool newValue = true;
while (!__atomic_compare_exchange_n(&lock, &oldValue, newValue, true, 0, 0)) {
sched_yield();
}
}
その場合、次のアセンブリ コードを取得します。
movzx eax, BYTE PTR [rsp+15]
lock cmpxchg BYTE PTR [rbx], bpl
je .L9
または使用する場合__atomic_test_and_set
:
void Mutex::acquire() {
while (__atomic_test_and_set(&lock, 0)) {
sched_yield();
}
}
次のアセンブリ コードを取得します。
mov eax, ebp
xchg al, BYTE PTR [rbx]
test al, al
jne .L6
しかし、アトミックな Test-and-Set および CAS 操作 ( x86 および他のアーキテクチャ上の同等のもの) のxchg
ハードウェア サポートがない場合はどうなるでしょうか? lock cmpxchg
この場合、コンパイラはどのソリューションを使用しますか?
PS - gcc 8.2 を使用してアセンブリ コードを生成しました__atomic_
。組み込み関数は次のとおりです。