multithreading - memory barrier and atomic_t on linux -
recently, reading linux kernel space codes, see this
uint64_t used; uint64_t blocked; used = atomic64_read(&g_variable->used); //#1 barrier(); //#2 blocked = atomic64_read(&g_variable->blocked); //#3 what semantics of code snippet? make sure #1 executes before #3 #2. litter bit confused, becasue
#a in 64 bit platform, atomic64_read macro expanded to
used = (&g_variable->used)->counter // counter volatile. in 32 bits platform, converted use lock cmpxchg8b. assume these 2 have same semantic, , 64 bits version, think means:
- all-or-nothing, can exclude case address unaligned , word size large cpu's native word size.
- no optimization, force cpu read memory location.
atomic64_read doesn't have semantic preserve read ordering!!! see this
#b barrier macro defined as
/* optimization barrier */ /* "volatile" due gcc bugs */ #define barrier() __asm__ __volatile__("": : :"memory") from wiki this prevents gcc compiler reordering read , write.
what confused how disable reorder optimization cpu? in addition, can think barrier macro full fence?
32-bit x86 processors don't provide simple atomic read operations 64-bit types. atomic operation on 64-bit types on such cpus deals "normal" registers lock cmpxchg8b, why used here. alternative use movq , mmx/xmm registers, requires knowledge of fpu state/registers, , requires operations on value done mmx/xmm instructions.
on 64-bit x86_64 processors, aligned reads of 64-bit types atomic, , can done mov instruction, plain read required --- use of volatile ensure compiler read, , doesn't cache previous value.
as read ordering, inline assembler quote ensures compiler emits instructions in right order, , required on x86/x86_64 cpus, provided writes correctly sequenced. locked writes on x86 have total ordering; plain mov writes provide "causal consistency", if thread x=1 y=2, if thread b reads y==2 subsequent read of x see x==1.
on ia-64, powerpc, sparc, , other processors more relaxed memory model there may more atomic64_read() , barrier().
Comments
Post a Comment