From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from asav22.altibox.net (asav22.altibox.net [109.247.116.9]) by sourceware.org (Postfix) with ESMTPS id DF3103857C4E for ; Sun, 11 Oct 2020 12:16:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org DF3103857C4E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hesbynett.no Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=david.brown@hesbynett.no Received: from mail.jansenbrown.no (unknown [92.221.34.247]) by asav22.altibox.net (Postfix) with ESMTP id 6D3A42003E; Sun, 11 Oct 2020 14:16:08 +0200 (CEST) Received: from [192.168.4.245] (unicorn.lan [192.168.4.245]) by mail.jansenbrown.no (Postfix) with ESMTPSA id 7EB31201137; Sun, 11 Oct 2020 14:16:07 +0200 (CEST) Subject: Re: Atomic accesses on ARM microcontrollers To: Toby Douglass References: <945d5e74-b449-3746-6560-996d0437db76@hesbynett.no> <015e0ad8-8052-c63f-0eb1-4b9fa817cc10@hesbynett.no> Cc: GCC help From: David Brown Openpgp: preference=signencrypt Autocrypt: addr=david.brown@hesbynett.no; keydata= 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 Message-ID: <08ef1c04-8e03-5ae8-e070-0499984f21bd@hesbynett.no> Date: Sun, 11 Oct 2020 14:16:07 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-GB Content-Transfer-Encoding: 8bit X-CMAE-Score: 0 X-CMAE-Analysis: v=2.3 cv=Du94Bl3+ c=1 sm=1 tr=0 a=+Fy6h7hJ4UJcWgHwdIx3jg==:117 a=+Fy6h7hJ4UJcWgHwdIx3jg==:17 a=IkcTkHD0fZMA:10 a=afefHYAZSVUA:10 a=mDV3o1hIAAAA:8 a=U69lbO-vxhBp-88qzUMA:9 a=QEXdDO2ut3YA:10 a=5HELcnvsdcQA:10 a=_FVE-zBwftR9WsbkzFJk:22 X-Spam-Status: No, score=-5.7 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, KAM_SHORT, NICE_REPLY_A, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL, TXREP autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Oct 2020 12:16:13 -0000 On 10/10/2020 22:05, Toby Douglass wrote: > On 10/10/2020 21:43, David Brown wrote: >> On 09/10/2020 23:35, Toby Douglass wrote: >>> On 09/10/2020 20:28, David Brown wrote: > >>> I would like - but cannot - reply to the list, as their email server >>> does not handle encrypted email. >> >> I've put the help list on the cc to my reply - I assume that's okay for >> you. > > Yes. > >> (Your email to me was not encrypted, unless I am missing something.) > > I mean TLS for SMTP, as opposed to say PGP. > Ah, you have your own mail server that sends directly to the receiving server? I always set up my mail servers to send via my ISP's server (a "smarthost" in Debian setup terms). That makes this kind of thing an SEP. >>>> I work primarily with microcontrollers, with 32-bit ARM Cortex-M >>>> devices >>>> being the most common these days.  I've been trying out atomics in gcc, >>>> and I find it badly lacking. >>> >>> The 4.1.2 atomics or the later, replacement API? >> >> I am not sure what you mean here, or what "4.1.2" refers to - it doesn't >> match either the gcc manual or the C standards as far as I can see. > > GCC introduced its first API for atomics in version 4.1.2, these guys; > Jonathan Wakely explained the reference. I've read the manuals for a /lot/ of gcc versions over the years, but I don't have all the details in my head! > https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html > > Then in a later version, which I can't remember offhand, a second and > much evolved version of the API was introduced. > Yes. >> However, "atomic" also has a simpler, more fundamental and clearer >> meaning with a wider applicability - it means an operation that cannot >> be divided (or at least, cannot be /observed/ to be divided).  This is >> the meaning that is important to me here. > > Ah and you mentioned atomically writing larger objects, so we're past > just caring about say word tearing. > Yes. Sizes up to 4 bytes can be accessed atomically on this processor using "normal" operations, and 8 byte accesses are atomic if specific instructions are used. (gcc generates these for non-atomic accesses.) I am hoping to be able to put together a solution for using standard C11/C++11 atomic types of any size and know that these actually work correctly. It is not essential - I can make my own types, functions, etc., and use them as needed. But it would be nice and convenient to be able to use the standard types and functions. >From Jonathan's replies, it seems I can simply make my own libatomic implementations and use them. >> What it means is that if thread A stores a value in the >> atomic variable ax, and thread B attempts to read the value in ax, then >> B will read either the entire old value before the write, or the entire >> new value after the write - it will never read an inconsistent partial >> write. > > I could be wrong, but I think the only way you can do this with atomics > is copy-on-write.  Make a new copy of the data, and use an atomic to > flip a pointer, so the readers move atomically from the old version to > the new version. I've been thinking a bit more about this, inspired by your post here. And I believe you are correct - neither ldrex/strex nor load/store double register is sufficient for 64-bit atomic accesses on the 32-bit ARM, even for plain reads and writes. That's annoying - I had thought the double register read/writes were enough. But if the store double register is interruptible with a restart (and I can't find official documentation on the matter for the Cortex-M7), then an interrupted store could lead to an inconsistent read by the interrupting code. I guess I am back to the good old "disable interrupts" solution so popular in the microcontroller world. That always works. > >>>> These microcontrollers are all single core, so memory ordering does not >>>> matter. >>> >>> I am not sure this is true.  A single thread must make the world appear >>> as if events occur in the order specified in the source code, but I bet >>> you this already not true for interrupts. >> >> It is true even for interrupts. > > [snip] > > Thankyou for the insights.  I've done hardly any bare-metal work, so I'm > not familiar with the actual practicalities of interrupts and their > effect in these matters. > >>>    It may be for example they can be >>> re-ordered with regard to each other, and this is not being prevented. >> >> Do you mean the kind of re-ordering the compiler does for code? > > I was thinking here of the processor. > >> That is >> not in question here - at least, not to me.  I know what kinds of >> reorders are done, and how to prevent them if necessary.  (On a single >> core, "volatile" is all you need - though there are more efficient ways. > > I'm not sure about that.  I'd need to revisit the subject though to > rebuild my knowledge, so I can't make any assertion here - only that I > know I don't know one way or the other. > One thing we can all be sure about - this stuff is difficult, it needs a /lot/ of thought, and the documentation is often poor on the critical details. >> And while the cpu and memory system can include write store buffers, >> caches, etc., that can affect the order of data hitting the memory, >> these are not an issue in a single core system.  (They /are/ important >> for multi-core systems.) > > Yes, I think so too, but to be clear we mean single physical and single > logical core; no hyperthreading. > Yes, absolutely. >>> Also, I still don't quite think there *are* atomic loads/stores as such >>> - although having said that I'm now remembering the LOCK prefix on >>> Intel, which might be usable with a load.  That would then lock the >>> cache line and load - but, ah yes, it doesn't *mean* anything to >>> atomically load.  The very next micro-second you value could be replaced >>> a new write. >> >> Replacing values is not an issue.  The important part is the atomicity >> of the action.  When thread A reads variable ax, it doesn't matter if >> thread B (or an interrupt, or whatever) has changed ax just before the >> read, or just after the read - it matters that it cannot change it >> /during/ the read.  The key is /consistent/ values, not most up-to-date >> values. > > Yes.  I can see this from your earlier explanation regarding what you're > looking for with atomic writes. > >> I had a look through the github sources, but could not find anything >> relevant.  But obviously that library has a lot more code and features >> than I am looking for. > > I was only thinking of a single header file which contains the atomics > for ARM32.  However, it's not useful to you for what you're looking for > with atomic writes. > Thank you anyway - and thank you for making me think a little more, correcting a mistake I made!