Здравствуйте, netch80, Вы писали:
N>1. Что за компилятор?
Apple LLVM version 9.1.0
N>2. Явная ошибка:
B>> __asm {
B>> outer:
B>> mov rbx,flag
B>> mov eax,[rbx]
B>> cmp eax,0
B>> jne outer
B>> xor ecx,ecx
B>> xor eax, eax
B>> mov rbx,flag
B>> loop:
B>> inc ecx
B>> lock bts [rbx], eax // lock + bts atomic test-and-set
B>> jnc loop
N>CF=0 как раз если было 0, то есть спинлок захвачен. Нафига в этом случае возвращаться на loop? Ты делаешь всё наоборот — если захватил, идёшь на круг
N>Тут лучше ложится jc outer (и вообще, outer и loop совместить)
ммм... моя логика такая:
если мьютекс еще не захвачен ( == 0) то вызов 'bts [rbx], eax' в керри положит старое значени 0, и атомарно в память 1
(но, до этого момента, другой поток УЖЕ мог прочитать 0 в таком же outer цикле, и перейти на inner этап)
теперь проц дает гарантию что lock bts атомарно положит там 1 хотя бы в одном из потоков!
т.е у кого то carry будет == 0 а у кого == 1
вот у того, кого 0 — тот захватил первым