From mboxrd@z Thu Jan 1 00:00:00 1970 From: Robin Farine To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org Subject: Re: libstdc++/3584: arm-specific atomic operations not atomic Date: Wed, 11 Jul 2001 10:36:00 -0000 Message-id: <20010711173600.29538.qmail@sourceware.cygnus.com> X-SW-Source: 2001-07/msg00302.html List-Id: The following reply was made to PR libstdc++/3584; it has been noted by GNATS. From: Robin Farine To: Richard.Earnshaw@arm.com Cc: robin.farine@terminus.org, gcc-gnats@gcc.gnu.org Subject: Re: libstdc++/3584: arm-specific atomic operations not atomic Date: 11 Jul 2001 19:34:59 +0200 Richard Earnshaw writes: [...] > The code for this variant would be: > @ r0 = address (struct {int lock, int value}), r1 = increment. > mov r2, #INT_MIN > 0: > swp r3, r2, [r0] > cmp r3, #INT_MIN > beq 0b @ already locked > @ We now have the lock > ldr r2, [r0, #4] > add r2, r2, r1 > str r2, [r0, #4] > str r3, [r0] @ Release the lock. > mov r2 This certainly works correctly but it would introduce another problem. If another thread already holds the lock, the current thread would just spin hopelessly until the thread that holds the lock gets the CPU and releases it. This could result into a dead-lock if the spinning thread has a higher priority than the lock owner. With the swap instruction (in contrast to test-and-set ;-)), I think that such routines implementations have to depend on the threading model to explicitly release the CPU when they fail to get the lock. Something like: @ r0 = address (struct {int lock, int value}), r1 = increment. ... @ prolog mov r2, 1 0: swp r3, r2, [r0] teq r3, #0 beq 1f @ got the lock mov lr, pc ldr pc, .thread_yield b 0b .thread_yield: .word thread_yield 1: @ We now have the lock ldr r2, [r0, #4] add r2, r2, r1 str r2, [r0, #4] str r3, [r0] @ Release the lock. mov r2