Migrating my microkernel to 64-bit and SMP....

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Migrating my microkernel to 64-bit and SMP....

Post 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 
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Migrating my microkernel to 64-bit and SMP....

Post 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)
dschatz
Member
Member
Posts: 61
Joined: Wed Nov 10, 2010 10:55 pm

Re: Migrating my microkernel to 64-bit and SMP....

Post 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.
Post Reply