69,386
社区成员
发帖
与我相关
我的任务
分享
头晕了, 好像应该是这样:
.align 2
.global _XPEER2_atomic_CAS
.type _XPEER2_atomic_CAS, %function
_XPEER2_atomic_CAS:
stmfd sp! , {r4,lr}
1: mov r4 , 0
ldrex r3 , [r0]
teq r3 , r2
strexeq r4 , r1 , [r0]
teq r4 , #0
bne 1b
teq r3 , r2
moveq r0 , #1
movne r0 , #0
ldmfd sp! , {r4,pc}
.align 2
.global _XPEER2_atomic_CAS2
.type _XPEER2_atomic_CAS2, %function
_XPEER2_atomic_CAS2:
stmfd sp! , {r4-r7,lr}
ldr r4 , [r1,#0]
ldr r5 , [r1,#4]
ldr r6 , [r2,#0]
ldr r7 , [r2,#4]
1: mov r1 , #0
ldrexd r2 , r3 , [r0]
teq r2 , r6
teqeq r3 , r7
strexdeq r1 , r4 , r5 , [r0]
teq r1 , #0
bne 1b
teq r2 , r6
reqeq r3 , r7
moveq r0 , #1
movne r0 , #0
ldmfd sp! , {r4-r7,pc}
static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
{
unsigned long oldval, res;
do {
__asm__ __volatile__("@ atomic_cmpxchg\n"
"ldrex %1, [%2]\n"
"mov %0, #0\n"
"teq %1, %3\n"
"strexeq %0, %4, [%2]\n"
: "=&r" (res), "=&r" (oldval)
: "r" (&ptr->counter), "Ir" (old), "r" (new)
: "cc");
} while (res);
return oldval;
}
我感觉17楼贴出来的 cas2 应该是没有问题的, 不过我这暂时没有可以跑的板子, 唉, 先用自旋锁吧...
等几天先找个模拟器试试... iPhone 应该是可以跑的... 可以的话帮我把其他的也试试:
.file "ARMv6Atomic.S"
.text
.align 2
.global ARMv6_atomic_incl
.type ARMv6_atomic_incl, %function
ARMv6_atomic_incl:
1: ldrex r3 , [r0]
add r3 , r3 , #1
strex r2 , r3 , [r0]
teq r2 , #0
bne 1b
mov r0 , #0
teq r3 , #0
movne r0 , #1
bx lr
.align 2
.global ARMv6_atomic_decl
.type ARMv6_atomic_decl, %function
ARMv6_atomic_decl:
1: ldrex r3 , [r0]
sub r3 , r3 , #1
strex r2 , r3 , [r0]
teq r2 , #0
bne 1b
mov r0 , #0
teq r3 , #0
movne r0 , #1
bx lr
.align 2
.global ARMv6_atomic_incl_
.type ARMv6_atomic_incl_, %function
ARMv6_atomic_incl_:
1: ldrex r3 , [r0]
add r3 , r3 , #1
strex r2 , r3 , [r0]
teq r2 , #0
bne 1b
mov r0 , r3
bx lr
.align 2
.global ARMv6_atomic_decl_
.type ARMv6_atomic_decl_, %function
ARMv6_atomic_decl_:
1: ldrex r3 , [r0]
sub r3 , r3 , #1
strex r2 , r3 , [r0]
teq r2 , #0
bne 1b
mov r0 , r3
bx lr
.align 2
.global ARMv6_atomic_add
.type ARMv6_atomic_add, %function
ARMv6_atomic_add:
1: ldrex r3 , [r0]
add r3 , r3 , r1
strex r2 , r3 , [r0]
teq r2 , #0
bne 1b
mov r0 , r3
bx lr
.align 2
.global ARMv6_atomic_exchange
.type ARMv6_atomic_exchange, %function
ARMv6_atomic_exchange:
1: ldrex r3 , [r0]
strex r2 , r1 , [r0]
teq r2 , #0
bne 1b
mov r0 , r3
bx lr
.align 2
.global ARMv6_atomic_CAS
.type ARMv6_atomic_CAS, %function
ARMv6_atomic_CAS:
ldrex r3 , [r0]
teq r3 , r2
strexeq r3 , r1 , [r0]
eor r0 , r3 , #1
bx lr
.align 2
.global ARMv6_atomic_CAS2
.type ARMv6_atomic_CAS2, %function
ARMv6_atomic_CAS2:
stmfd sp! , {r4-r7,lr}
ldr r4 , [r1,#0]
ldr r5 , [r1,#4]
ldr r6 , [r2,#0]
ldr r7 , [r2,#4]
ldrexd r2 , r3 , [r0]
teq r2 , r6
teqeq r3 , r7
strexdeq r1 , r4 , r5 , [r0]
eor r0 , r1 , #1
ldmfd sp! , {r4-r7,pc}
文档上貌似是这样写的:
LDREX
LDREX loads data from memory.
*
If the physical address has the Shared TLB attribute, LDREX tags the physical address as exclusive access for the current processor, and clears any exclusive access tag for this processor for any other physical address.
*
Otherwise, it tags the fact that the executing processor has an outstanding tagged physical address.
STREX
STREX performs a conditional store to memory. The conditions are as follows:
*
If the physical address does not have the Shared TLB attribute, and the executing processor has an outstanding tagged physical address, the store takes place, the tag is cleared, and the value 0 is returned in Rd.
*
If the physical address does not have the Shared TLB attribute, and the executing processor does not have an outstanding tagged physical address, the store does not take place, and the value 1 is returned in Rd.
*
If the physical address has the Shared TLB attribute, and the physical address is tagged as exclusive access for the executing processor, the store takes place, the tag is cleared, and the value 0 is returned in Rd.
*
If the physical address has the Shared TLB attribute, and the physical address is not tagged as exclusive access for the executing processor, the store does not take place, and the value 1 is returned in Rd.