Whoops, cut/paste from wrong buffer...! atomic_add() would be :
return (int)__sync_add_and_fetch(&v->counter, i);
Cheers,
~Pev
On 27 October 2010 13:01, David Peverley <[email protected]> wrote:
> Hi Cyril,
>
> Was your change to modify librttest.h as follows :
> /* atomic_add - add integer to atomic variable and returns a value.
> * i: integer value to add
> * v: pointer of type atomic_t
> */
> static inline void atomic_add( int i, atomic_t *v )
> {
> (void)__sync_add_and_fetch(&v->counter, i);
> }
>
> /* atomic_inc: atomically increment the integer passed by reference
> */
> static inline int atomic_inc(atomic_t *v)
> {
> return (int)__sync_add_and_fetch(&v->counter, 1);
> }
>
> Cheers,
>
> ~Pev
>
> On 27 October 2010 13:10, Cyril Hrubis <[email protected]> wrote:
>> Hi!
>>> >> > The realtime tests aren't compiled for ARM currently as there's no
>>> >> > implementation of atomic_add() in :
>>> >> > testcases/realtime/include/librttest.h
>>> >> >
>>> >> > As a side note - in this function can we change the #error to not be
>>> >> > blank and read something along the lines of :
>>> >> > #error ERROR: atomic_add: Architecture not supported for compilation
>>> >> >
>>> >> > Anyway, the existing function here supports three architectures and
>>> >> > lifts the implementations as follows :
>>> >> > __x86_64__ || __i386__
>>> >> > arch/x86/include/asm/atomic_32.h
>>> >> > __powerpc__
>>> >> > arch/powerpc/include/asm/atomic.h (might need review!)
>>> >> > __sh__
>>> >> > arch/sh/include/asm/atomic-llsc.h (might need review!)
>>> >> >
>>> >> > Logically we can add an ARM case following the same logic. Looking in :
>>> >> > arch/arm/include/asm/atomic.h
>>> >> >
>>> >> > We can implement this easily for v6+ architectures. The case for
>>> >> > atomic_add in librttest.h would look something like :
>>> >> > #elif defined(__arm__) && (__LINUX_ARM_ARCH__ >= 6)
>>> >> > unsigned long tmp;
>>> >> > int result;
>>> >> >
>>> >> > __asm__ __volatile__(
>>> >> > "1: ldrex %0, [%2]\n"
>>> >> > " add %0, %0, %3\n"
>>> >> > " strex %1, %0, [%2]\n"
>>> >> > " teq %1, #0\n"
>>> >> > " bne 1b"
>>> >> > : "=&r" (result), "=&r" (tmp)
>>> >> > : "r" (&v->counter), "Ir" (i)
>>> >> > : "cc");
>>> >> >
>>> >> > return result;
>>> >> >
>>> >> > For < v6 architectures this isn't easy as they don't implement
>>> >> > ldrex/strex. The atomic.h implementation won't work as it's a kernel
>>> >> > only implementation using local_irq_save() and local_irq_restore() so
>>> >> > obviously no use for userspace atomic add.
>>> >> >
>>> >> > After reading up for a while I've come across a very cunning trick in
>>> >> > the kernel where an atomic compare/exchange is implemented in
>>> >> > __kuser_cmpxchg. This is implemented in :
>>> >> > arch/arm/kernel/entry-armv.S
>>> >> >
>>> >> > This tantalisingly comments :
>>> >> > /*
>>> >> > * For example, a user space atomic_add implementation could look
>>> >> > like this:
>>> >> > *
>>> >> > * #define atomic_add(ptr, val) \
>>> >> > * ({ register unsigned int *__ptr asm("r2") = (ptr); \
>>> >> > * register unsigned int __result asm("r1"); \
>>> >> > * asm volatile ( \
>>> >> > * "1: @ atomic_add\n\t" \
>>> >> > * "ldr r0, [r2]\n\t" \
>>> >> > * "mov r3, #0xffff0fff\n\t" \
>>> >> > * "add lr, pc, #4\n\t" \
>>> >> > * "add r1, r0, %2\n\t" \
>>> >> > * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
>>> >> > * "bcc 1b" \
>>> >> > * : "=&r" (__result) \
>>> >> > * : "r" (__ptr), "rIL" (val) \
>>> >> > * : "r0","r3","ip","lr","cc","memory" ); \
>>> >> > * __result; })
>>> >> > */
>>> >> >
>>> >> > So translating this into librttest.h format gives :
>>> >> > #elif defined(__arm__) && (__LINUX_ARM_ARCH__ < 6)
>>> >> > register unsigned int result asm("r1");
>>> >> >
>>> >> > /* See, arm/kernel/entry-armv.S:__kernel_cmpxchg() */
>>> >> > __asm__ __volatile__ (
>>> >> > "1: ldr r0, [r2]\n\t"
>>> >> > " mov r3, #0xffff0fff\n\t"
>>> >> > " add lr, pc, #4\n\t"
>>> >> > " add r1, r0, %2\n\t"
>>> >> > " add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t"
>>> >> > " bcc 1b"
>>> >> > : "=&r" (result)
>>> >> > : "r" (&v->counter), "rIL" (i)
>>> >> > : "r0","r3","ip","lr","cc","memory" );
>>> >> >
>>> >> > return result;
>>> >> >
>>> >> > Does this look reasonable to you guys?
>>> >>
>>> >> CCing Gowrishankar from IBM.
>>> >
>>> > We recently agreed to use gcc buildins as the inline assembler was
>>> > broken anyway. But it seems that this patch hasn't made it into git.
>>> >
>>> > Garret could you please commit patch from Gowrishankar from thread
>>> > "[PATCH] fix realtime atomic_add() inline asm". It basically removes all
>>> > the
>>> > inline assembler in favor of __sync_add_and_fetch().
>>>
>>> Hmmm... did we reach closure on that issue? I thought it was still
>>> outstanding...
>>
>> Well it seems, at least to me, that everybody agreed for that change. I
>> personally checked that this change works for me and gave my ack.
>>
>> --
>> Cyril Hrubis
>> [email protected]
>>
>
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list