Date: Mon, 9 Nov 2015 19:04:57 +1100 From: George Abdelmalik <gabdelmalik@uniridge.com.au> To: Konstantin Belousov <kostikbel@gmail.com> Cc: freebsd-arm@freebsd.org Subject: Re: atomic_testandset_int seems unimplemented Message-ID: <564053A9.3000604@uniridge.com.au> In-Reply-To: <563DE43D.7030107@uniridge.com.au> References: <563DA3E8.2060802@uniridge.com.au> <20151107113011.GW2257@kib.kiev.ua> <563DE43D.7030107@uniridge.com.au>
next in thread | previous in thread | raw e-mail | index | archive | help
On 07/11/15 22:45, George Abdelmalik wrote: > On 07/11/15 22:30, Konstantin Belousov wrote: >> On Sat, Nov 07, 2015 at 06:10:32PM +1100, George Abdelmalik wrote: >>> Hi, >>> >>> My reading of atomic(9) implies that the atomic_testandset_* family of >>> functions should be present >>> on the arm architecture, however I don't see any evidence of it in any >>> of the expected locations, >>> ./sys/arm/include/atomic-v4.h >>> ./sys/arm/include/atomic-v6.h >>> ./sys/arm/include/atomic.h >>> >>> Is there some impediment within the architecture which doesn't make >>> that >>> semantic possible or is >>> it just that there is no in-tree consumer yet? >> No consumers, apparently. testandset has somewhat rarely needed >> semantic, >> and readandclear semantic is not complimentary, to confuse the users >> even >> more. >> >>> Any thoughts on this matter would be appreciated, or better yet a >>> possible implementation - sadly for >>> me assembly is not my strength. >> Below is the patch for ARMv6. I did not tested the _64 implementation, >> and I also doubt that we run in big endian mode for ARMv6 at all. >> Do you also need an implementation for ARMv5 ? > No I don't need ARMv5, my target is a Xilinx Zynq SOC which is > ARMv7 that we will only run in little endian mode. > > Thanks for the below patch. I will try it out tomorrow and report > back my experience. > > George. >> >> diff --git a/sys/arm/include/atomic-v6.h b/sys/arm/include/atomic-v6.h >> index d22f7e1..9ee8043 100644 >> --- a/sys/arm/include/atomic-v6.h >> +++ b/sys/arm/include/atomic-v6.h >> @@ -593,6 +593,60 @@ atomic_store_rel_long(volatile u_long *p, u_long v) >> *p = v; >> } >> +static __inline int >> +atomic_testandset_32(volatile uint32_t *p, u_int v) >> +{ >> + uint32_t tmp, tmp2, res, mask; >> + >> + mask = 1u << (v & 0x1f); >> + tmp = tmp2 = 0; >> + __asm __volatile( >> + "1: ldrex %0, [%3] \n" >> + " orr %1, %0, %4 \n" >> + " strex %2, %1, [%3] \n" >> + " cmp %2, #0 \n" >> + " it ne \n" >> + " bne 1b \n" >> + : "=&r" (res), "=&r" (tmp), "=&r" (tmp2), "+&r" (p) >> + : "r" (mask) >> + : "cc", "memory"); >> + return ((res & mask) != 0); >> +} >> + >> +static __inline int >> +atomic_testandset_int(volatile u_int *p, u_int v) >> +{ >> + >> + return (atomic_testandset_32((volatile uint32_t *)p, v)); >> +} >> + >> +static __inline int >> +atomic_testandset_long(volatile u_long *p, u_int v) >> +{ >> + >> + return (atomic_testandset_32((volatile uint32_t *)p, v)); >> +} >> + >> +static __inline int >> +atomic_testandset_64(volatile uint64_t *p, u_int v) >> +{ >> + volatile uint32_t *p32; >> + >> + p32 = (volatile uint32_t *)p; >> +#if BYTE_ORDER == LITTLE_ENDIAN >> + if (v >= 32) { >> + v &= 0x1f; >> + p32++; >> + } >> +#else >> + if (v >= 32) >> + v &= 0x1f; >> + else >> + p32++; >> +#endif >> + return (atomic_testandset_32(p32, v)); >> +} >> + >> #undef ATOMIC_ACQ_REL >> #undef ATOMIC_ACQ_REL_LONG > > _______________________________________________ > freebsd-arm@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-arm > To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org" Hi Konstantin, Thanks again for this. I've not yet run it on my Zedboard, due to unrelated issues of my own making, although it compiles fine into my project. It would be great to see it in the tree whenever you get the chance. Kindest regards, George. -- George Abdelmalik Director Principal Software Engineer Uniridge Pty Ltd http://www.uniridge.com.au/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?564053A9.3000604>