How to compare and swap atomically in ARM7?

回眸只為那壹抹淺笑 提交于 2019-12-04 19:23:42

I have found a similar implementation for __kernel_cmpxchg function in Linux kernel source.

It has been written for ARMv5 and earlier, and It seems to work for ARM7TDMI (ARMv4).

1:      ldr     r3, [r2]        @ load current val
        subs    r3, r3, r0      @ compare with oldval
2:      streq   r1, [r2]        @ store newval if eq
        rsbs    r0, r3, #0      @ set return val and C flag
        bx      lr              @ or "mov pc, lr" if no thumb support

Details can be found at this link.

There are two important issues that I would like to warn,

1- __kernel_cmpxchg returns 0 when swap occurred, while __sync_bool_compare_and_swap function returns true.

2- function prototypes are different.

typedef int (*__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
#define __kernel_cmpxchg ((__kernel_cmpxchg_t)0xffff0fc0)

bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)

Therefore I had to change the usage as below,

void set_bit_atomic(int mask)
{
    volatile int tmp;
    do {
        tmp = g_var;
    } while (my_compare_and_swap(tmp, tmp | mask, &g_var));
}

Caveat: This code does not work properly without kernel support. See the comments below.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!