我想知道它是否能夠確保line
被自動執行,因爲它可以由ISR和主要方面都可以執行。我工作的一個ARM9(LPC313x),並使用的RealView 4器(armcc)。這可以原子執行嗎?
foo() {
..
stack_var = ++volatile_var; // line
..
}
我正在尋找像_atomic_
爲C166,直接彙編代碼等任何程序,我寧願不要有禁用中斷。
非常感謝。
我想知道它是否能夠確保line
被自動執行,因爲它可以由ISR和主要方面都可以執行。我工作的一個ARM9(LPC313x),並使用的RealView 4器(armcc)。這可以原子執行嗎?
foo() {
..
stack_var = ++volatile_var; // line
..
}
我正在尋找像_atomic_
爲C166,直接彙編代碼等任何程序,我寧願不要有禁用中斷。
非常感謝。
從快看,C166 _atomic_
宏似乎利用了有效地掩蔽中斷的指令指定數量的持續時間的指令。 在ARM架構中沒有直接對應的東西。
當然你可以使用SWP指令(或工具鏈的RealView內在__swp)將圍繞臨界區的鎖。另一個答案中提到的ldrex/strex在ARM架構版本5中不存在,其中包含ARM9處理器。分別爲 http://infocenter.arm.com/help/topic/com.arm.doc.dui0491c/CJAHDCHB.html和http://infocenter.arm.com/help/topic/com.arm.doc.dui0489c/Chdbbbai.html。
對此的一種簡單的鎖機制(使用RealView工具鏈)將是:
{
/* Loop until lock acquired */
while (__swp(LOCKED, &lockvar) == LOCKED);
..
/* Critical section */
..
lockvar = UNLOCKED;
}
然而,這將導致ISR背景下死鎖時,主線程持有鎖。
我認爲屏蔽操作周圍的中斷可能是最毛茸茸的解決方案,但如果您的Main上下文在用戶模式下執行,則需要系統調用來實現。
不,我不認爲你永遠可以期待++volatile_var
是原子的,即使你沒有分配。爲此使用適當的原子基元。如果你的編譯器沒有提供這樣的擴展,你可以在網上找到一個簡短的內聯彙編器。我認爲彙編程序的指令是調用ldrex
和strex
來進行原子交換。
編輯:似乎在問題中要求的特定處理器類型沒有實現這些指令。
編輯:下應該用gcc工作,另外一個編譯器可能具有對__asm__
部分適應。
inline
size_t arm_ldrex(size_t volatile*ptr) {
size_t ret;
__asm__ volatile ("ldrex %0,[%1]\[email protected] load exclusive\n"
: "=&r" (ret)
: "r" (ptr)
: "cc", "memory"
);
return ret;
}
inline
_Bool arm_strex(size_t volatile*ptr, size_t val) {
size_t error;
__asm__ volatile ("strex %0,%1,[%2]\[email protected] store exclusive\n"
: "=&r" (error)
: "r" (val), "r" (ptr)
: "cc", "memory"
);
return !error;
}
inline
size_t atomic_add_fetch(size_t volatile *object, size_t operand) {
for (;;) {
size_t oldval = arm_ldrex(object);
size_t newval = oldval + operand;
if (arm_strex(object, newval)) return newval;
}
}
它是有益的,如果有人能拋出一些光,但不會以下被認爲是原子? ADD r0,r0,#1如何使用ldrex/strex來增加一個值?我肯定錯過了一些東西。 – TheLoneJoker 2011-03-24 15:39:26
@Jens,我對此有點新。能否請你點我的一些資源/文件,提供有關代碼的詳細信息__asm__揮發性( 「LDREX%0,[%1] \ t @負荷獨家\ n」 : 「= R」(RET) :「R 「(ptr) :」cc「,」memory「 ); 我不是很清楚裏面的東西是什麼意思。 – TheLoneJoker 2011-03-24 16:27:51
@TheLoneJoker這就是所謂的「內聯彙編」,插入到位的彙編程序指令,搜索該術語應該會爲您找到更多信息。我在這裏使用的變體是gcc,其他人可能也支持這樣的擴展,但在實現時可能看起來不同。 – 2011-03-24 17:18:04
謝謝unixsmurf。 – JoeSlav 2011-03-26 11:43:05
您可以在舊ARM上將'swpb'與'swp'混合使用以獲得多個/單個模式。即,**多個標誌制定者**和**單個標誌清晰**。最多可以使用四個「字節」或「**狀態」。 – 2013-02-19 22:44:09