Page 1 of 1
Re: Migrating my microkernel to 64-bit and SMP....
Posted: Thu Sep 20, 2012 10:56 am
by Combuster
Typically, an synchronisation instruction on x86 has the inherent property of being serializing, meaning anything you did before it is guaranteed to be visible to all other processors before the instruction itself can be started. You typically don't need any form of fences beyond that: there were several smp-capable x86 processors out before the fence instruction was even added.
Short answer: use the LOCK prefix.
EDIT: there's a race condition in there. It's also easy to fix:
Code: Select all
(1) atomically write '0' in section->status
(...) other thread makes it through steps 1..5
(2) rflags = other thread's flags
Re: Migrating my microkernel to 64-bit and SMP....
Posted: Thu Sep 20, 2012 12:40 pm
by Owen
the *FENCE instructions are mainly useful when interacting with external hardware (e.g. if you want to ensure that the framebuffer contents are flushed out of the CPU's write combiners). x86's implicit serialization is quite good (very close to sequential consistency).
The one exception is that x86 loads are not sequentially consistent. For example, the following
Code: Select all
Starting with [a]=0, [b]=0
Core A:
mov rax, [a]
mov rbx, [b]
Core B:
mov rax, 1
mov [b], rax
mov [a], rax
can return rax=1 rbx=0 on core A because the loads may be reordered. If you require strict ordering there, either redesign things to use locked instructions (e.g. cmpxchg) or insert an LFENCE between the two loads
Other architectures (e.g. ARM) are significantly more tricky (e.g. ARM critical sections will require one or more barriers)
Re: Migrating my microkernel to 64-bit and SMP....
Posted: Thu Sep 20, 2012 4:59 pm
by dschatz
A simple spinlock can be implemented with a cmpxchg to acquire the lock and a simple write to unlock. Because the unlock does not use an atomic instruction I put an mfence before the write that unlocks.