淄博專業(yè)做網站簡單免費制作手機網站
自旋鎖作用
? ? ? 自旋鎖的是為了保護兩個核上的公共資源,也就是全局變量,只有在一方也就是一個核搶到了自選鎖,才能對公共資源進行操作修改,當然還有其他形似的鎖如互斥鎖,這里不比較兩者的區(qū)別,以前沒有深入的去了解自旋鎖的底層實現,只是簡單調用。
自旋鎖原理
? ? ?自旋鎖的底層實現原理其實是用到了各個架構比較交換的匯編指令,英飛凌的TriCore架構為
CMPSWAP.W,ARM架構雖然沒有比較交換指令,但是通過關閉preempt_disable禁止搶占來實現原子操作。
數據總線
? ? ??數據總線的一些基本概念這里就不提出來再講了。有一個細節(jié)是在總線上同一時刻只能有一個主設備控制總線傳輸操作。而對于多核來說也是如此,他們需要互相爭搶總線的使用權,而這一現象又能幫助我們實現一些原子操作。
總線操作
? ??使用總線對數據進行操作的時候并不是全部都能一次完成的,有時候可能需要多個操作才能實現我們編程中看似簡單的操作,而在找個時候就不一定能滿足我們的原子性了。
TriCore架構自旋鎖實現
boolean IfxCpu_acquireMutex(IfxCpu_mutexLock *lock)
{boolean retVal;volatile uint32 spinLockVal;retVal = FALSE;spinLockVal = 1UL;spinLockVal =(uint32)__cmpAndSwap(((unsigned int *)lock), spinLockVal, 0);/* Check if the SpinLock WAS set before the attempt to acquire spinlock */if (spinLockVal == 0){retVal = TRUE;}return retVal;
}/** \brief This function is a implementation of a binary semaphore using compare and swap instruction* \param address address of resource.* \param value This variable is updated with status of address* \param condition if the value of address matches with the value of condition, then swap of value & address occurs.**/
IFX_INLINE unsigned int Ifx__cmpAndSwap (unsigned int volatile *address,unsigned int value, unsigned int condition)
{unsigned long long reg64= value | (unsigned long long) condition << 32;__asm__ __volatile__ ("cmpswap.w [%[addr]]0, %A[reg]": [reg] "+d" (reg64): [addr] "a" (address): "memory");return reg64;
}
? ?這段代碼的邏輯及其簡單,就是去查找我們lock變量的值是否為0,如果為0便把它賦值為1,并且返回成功搶到鎖的信息。而有一個操作是值得關注的。__cmpAndSwap()?這一操作為什么能保證原子性并且能做到對變量進行加鎖的呢?這里使用了匯編語言對芯片進行操作,而cmpswap.w操作正是我們在數據手冊中找到的新指令。而正如注釋說這一個指令能比較兩個地址中的值是否相同,并完成交換。
? ?cmpswap.w等效如下代碼:
tmp = *x; //#tmp address的值
if(*x == z) // # z為condition
{*x = y; //#*address = values;
}
else
{*x = tmp;
}
return tmp
PowerPC架構自旋鎖實現?
static inline uint32 aSpinlock_Hal_Swap(uint32 Addr, register uint32 Value)
{uint32 result;register uint32 temp1,temp2;__asm__ __volatile__(/* prepare the decoration for the SWAP instruction */"mr %[temp11], %[Value]" "\n" /* load value in r6 */"e_lis %[temp22], 0x5000" "\n" /* r5 = 0x50000000 */"se_or %[temp11], %[temp22]" "\n" /* Value = Value | r5 *//* lwdcbx -> Load Word Decorated with Cache Bypass */"lwdcbx %[result], %[temp11], %[Addr]" "\n" /* SWAP Addr with r3 */: [result] "=r" (result): [Addr] "b" (Addr), [temp11]"r" (temp1), [temp22]"r" (temp2) , [Value]"r" (Value): "cc");return result;
}
? ? ?參考文檔:
??Aurix/Tricore實驗分享之103: 硬件mutex指令|英飛凌開發(fā)者技術社區(qū)
??TriCore架構多核多線程鎖探究(TC264雙核互斥鎖)-CSDN博客
? ?https://www.cnblogs.com/DoOrDie/p/9265754.html