Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Mar 2009 15:46:50 -0600 (MDT)
From:      "M. Warner Losh" <imp@bsdimp.com>
To:        tinguely@casselton.net
Cc:        freebsd-arm@FreeBSD.org
Subject:   Re: ARM atomic question
Message-ID:  <20090324.154650.-679995243.imp@bsdimp.com>
In-Reply-To: <200903242105.n2OL5phe074750@casselton.net>
References:  <200903242105.n2OL5phe074750@casselton.net>

next in thread | previous in thread | raw e-mail | index | archive | help
In message: <200903242105.n2OL5phe074750@casselton.net>
            Mark Tinguely <tinguely@casselton.net> writes:
: 
: I am rewriting the existing ARM atomic instruction for the new ldrex/strex
: in the ARMv6 architecture. 
: 
: I have 3 questions for atomic_fetchadd_32():
: 
: #ifdef KERNEL
: static __inline uint32_t
: atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
: {
:         uint32_t value;
: 
:         __with_interrupts_disabled(
:         {
:                 value = *p;
:                 *p += v;
:         });
:         return (value);
: }
:  
: #else /* !_KERNEL */
: 
: static __inline uint32_t
: atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
: {
:         uint32_t start, ras_start = ARM_RAS_START;
: 
:         __asm __volatile("1:\n"
:             "adr        %1, 1b\n"
:             "str        %1, [%0]\n"
:             "adr        %1, 2f\n"
:             "str        %1, [%0, #4]\n"
:             "ldr        %1, [%2]\n"
: 
: 	1) how does this make it atomic? no one reads ras_start or ras_end
: 	   to verify that it has not changed since I set it. This applies
: 	   to all non-kernel atomic commands.

The kernel looks at these addresses when it does a context switch.
Since there are no atomic ops, and you can't disable interrupts in
userland, we settle for the next worse thing: set critical sections
that are restarted if the kernel interrupts them.

:             "add        %1, %1, %3\n"
: 			^^
: 	2) start is now (*p + v) not *p. It will return the wrong value
: 	   compared to the kernel version.
: 
:             "str        %0, [%2]\n"
: 			^^
: 	3) *p is assigned the ras_start address.

That I'm not sure of...

:             "2:\n"
:             "mov        %3, #0\n"
:             "str        %3, [%0]\n"
:             "mov        %3, #0xffffffff\n"
:             "str        %3, [%0, #4]\n"
:             : "+r" (ras_start), "=r" (start), "+r" (p), "+r" (v)
:             : : "memory");
:         return (start);
: #endif
: 
: 4) Is there a list of atomic commands that should be implemented?

Someone else will have to answer this.

Warner



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090324.154650.-679995243.imp>