I have a question about mutex implementation in Linux kernel on an ARM platform.
__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
int __ex_flag, __res;
__asm__ (
"ldrex %0, [%2] \n\t"
"sub %0, %0, #1 \n\t"
"strex %1, %0, [%2] " //for ARMv6+ ,kernel use ldrex/strex implement mutex lock.
: "=&r" (__res), "=&r" (__ex_flag)
: "r" (&(count)->counter)
: "cc","memory" );
__res |= __ex_flag; //How can we know the "strex" operation is successfully finished or not?
//The status of (atomic_t *count) is different in these two cases.
//I wonder this is a bug ,or I did not understand the lock mechanism so well.
if (unlikely(__res != 0))
fail_fn(count);
}
Thank you very much for your suggestion or answer to this question. Anything will be appreciated.
For more information about the source code, please refer to ; http://lxr.oss.org.cn/source/arch/arm/include/asm/mutex.h?v=3.5.2;a=arm
The file path is:
linux-3.5.2/arch/arm/include/asm/mutex.h
__resis zero if successfulNote that
__resis or’d with__ex_flagSo if either of the
ldrexorstrexoperations has failed the check fails.Note: if the value was accessed after
ldrexthe exclusive access fails;strexfails and the value will not be stored. There’s more information about this in the info center:The point is that if the exclusive access fails, either on load or store the kernel will know about it because
__ex_flags=1or__res=1, if it doesn’t fail, but the mutex was already locked we will still know about it because__res=0xFFFFFFFFat that point it doesn’t matter if the exclusive access has failed or not because the mutex was locked.Now, the only problem I see is that it will store
0xFFFFFFFFinto count, but that will probably be incremented again when whoever locked the mutex unlocks it, which means it could be a way for more than one thread to wait on the mutex. This is from the comments in your link: