As far as I know, a function call acts as a compiler barrier, but not as a CPU barrier.
This tutorial says the following:
acquiring a lock implies acquire semantics, while releasing a lock
implies release semantics! All the memory operations in between are
contained inside a nice little barrier sandwich, preventing any
undesireable memory reordering across the boundaries.
I assume that the above quote is talking about CPU reordering and not about compiler reordering.
But I don't understand how does a mutex lock and unlock causes the CPU to give these functions acquire and release semantics.
For example, if we have the following C code:
pthread_mutex_lock(&lock);
i = 10;
j = 20;
pthread_mutex_unlock(&lock);
The above C code is translated into the following (pseudo) assembly instructions:
push the address of lock into the stack
call pthread_mutex_lock()
mov 10 into i
mov 20 into j
push the address of lock into the stack
call pthread_mutex_unlock()
Now what prevents the CPU from reordering mov 10 into i
and mov 20 into j
to above call pthread_mutex_lock()
or to below call pthread_mutex_unlock()
?
If it is the call
instruction that prevents the CPU from doing the reordering, then why is the tutorial I quoted makes it seem like it is the mutex lock and unlock functions that prevents the CPU reordering, why the tutorial I quoted didn't say that any function call will prevent the CPU reordering?
My question is about the x86 architecture.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…