- 论坛徽章:
- 0
|
回复 12# uliux - static inline void UtilLock(lock_t* pstLock)
- {
- uint32_t uiTmp;
- __asm__ __volatile__(
- "1: ldrex %0, [%1]\n"
- " teq %0, #0\n"
- " bne 1b\n"
- " strexeq %0, %2, [%1]\n"
- " teqeq %0, #0\n"
- " bne 1b\n"
- " dmb\n"
- : "=&r" (uiTmp)
- : "r" (&pstLock->uiLock), "r" (1)
- : "cc");
- return;
- }
复制代码 上述代码是ARM的汇编指令,还有我说的是可以通过spinlock这段代码可以实现在单CPU中实现锁机制。
主要原理就是通过CPU支持的特殊原子操作指令(在ARM中ldrex/strex),再加上进程按时间片调度。
还有Linux自己中的互斥量也是采用这些来实现的。只不过不是死查询,还有切换进程机制。
还有下面代码,比如内核中的提供的原子加法操作、原子设置bit位等,都是基于这样的原理。
注,以上都是基于ARM cortex a9的指令写的。其它的我不能保证正确。但认为原理应该类似。- static inline void UtilAtomicAdd(int32_t iCounter, atomic_t* pstAtomic)
- {
- uint32_t uiTmp;
- int32_t iRet;
- __asm__ __volatile__("@ atomic_add\n"
- "1: ldrex %0, [%3]\n"
- " add %0, %0, %4\n"
- " strex %1, %0, [%3]\n"
- " teq %1, #0\n"
- " bne 1b\n"
- " dmb\n"
- : "=&r" (iRet), "=&r" (uiTmp), "+Qo" (pstAtomic->iCounter)
- : "r" (&pstAtomic->iCounter), "Ir" (iCounter)
- : "cc");
- return;
- }
复制代码 |
|