Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the corresponding prefix in arm assembly for "lock" in x86?

I have a x86 assembly code:

unsigned int oldval;

__asm__ __volatile__ (
"movl   $1, %0  \n"
"lock xaddl %0, (%1)    \n"
: "=a" (oldval) :  "b" (n))l;

return oldval;

and I want to translate it into arm assembly. Is there any prefix in arm assembly that does the same thing as "lock" here?

like image 321
ballballbobo Avatar asked Jan 28 '26 20:01

ballballbobo


2 Answers

I don't know ARM, but from glossing over the manual, the following should approximate your atomic exchange-and-add:

foo:
    LDREX R1, [R0]         ;  R0 is "n", load linked
    ADD   R2, R1, 1        ;  R2 = R1 + 1
    STREX R3, R2, [R0]     ;  store conditionally, R3 = 0 if and only if success
    CBNZ  R3, foo          ;  on failure, try again

    ;; now return R1 to "oldval"

Unlike on x86, it would appear that this code could take arbitrarily long to succeed, but I'm not sure whether there are any guarantees that this will eventually succeed.

However, note that the ARM approach is safer, since the conditional store will success precisely when it should. By contrast, your x86 code (which looks like taken from a kernel spin lock?) just adds one to *n and tests whether the original *n was zero. If enough threads attempt this concurrently, then *n can overflow and be zero even though you weren't allowed to take the lock.

like image 163
Kerrek SB Avatar answered Jan 31 '26 19:01

Kerrek SB


The lock prefix is only useful for memory accesses. Since ARM can't do arithmetic on memory, there is not directly corresponding operation. If you're on a high-enough version of the ARM core, you can use the dmb, dsb and isb instructions for synchronization. Otherwise, you'll need some sort of mutex.

like image 30
Drew McGowen Avatar answered Jan 31 '26 19:01

Drew McGowen