From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: border2.nntp.dca3.giganews.com!backlog4.nntp.dca3.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!goblin1!goblin2!goblin.stu.neva.ru!news.internetdienste.de!news.tu-darmstadt.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Oberon and Wirthian languages Date: Tue, 22 Apr 2014 22:13:50 +0300 Organization: Tidorum Ltd Message-ID: References: <1ljwj8f.1wqbhvuabsdw1N%csampson@inetworld.net> <51c7d6d4-e3be-44d5-a4ce-f7e875345588@googlegroups.com> <%J32v.70539$kp1.45343@fx14.iad> <8761m535e4.fsf_-_@ludovic-brenta.org> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: individual.net Nqt5d3SJsNB2Yh4Ku3YfAQUagyihoGydjBPsfZGf48/wKW1YSp Cancel-Lock: sha1:SySlLBzAuG13UJFJwJxJFViQs/o= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 In-Reply-To: X-Original-Bytes: 6375 Xref: number.nntp.dca.giganews.com comp.lang.ada:185942 Date: 2014-04-22T22:13:50+03:00 List-Id: On 14-04-22 15:25 , Simon Clubley wrote: > On 2014-04-22, Simon Wright wrote: > > In general memory mapped I/O you have to do a register read/modify bit > field/register write sequence in units of the register size. > > Consider a atomic record with 3 bit fields called A, B and C. > > Now consider a Ada record assignment statement which sets the values of > the 3 bit fields. The question is how is the assignment to the 3 bit > fields turned into code ? If the record variable Rec has the Atomic aspect, then by the Ada RM any assignment Rec := expr must write Rec exactly once, indivisibly, and this write should (per implementation advice) be implemented by a single store instruction. This applies whatever the right-hand-side expr is. Note, however, that if the right-hand-side expr includes some references to (i.e. reads of) Rec, then there is no guarantee that the read-write sequence as a whole is indivisible. > Is it something like this (which is how it looks in C with masks): Here one should separate between C 2011 on the one hand and earlier C standards on the other. (For C 2011 my reference is the "final" draft N1570, which is on the web.) In C 2011, a "compound assignment is a read-modify-write operation with memory_order_seq_cst memory order semantics". That is, in C 2011 an update like "v &= mask", where v is an _Atomic variable, is an atomic *update* with respect to other C threads (but perhaps not with respect to other memory bus activity; I admit to an incomplete understanding here). Note that this is rather different from the meaning of the Atomic aspect in Ada, which only makes each read indivisible, and each write indivisible, but does not guarantee indivisibility of some read-modify-write sequence. In earlier C standards such as the 1999 standard, the only concept of atomicity was the predefined type sig_atomic_t, which corresponds closely to the Ada Atomic aspect, that is, the whole variable can be read or written with one memory access. > ldr r2, [r3, #register_offset] > -- Load device register contents into r2 > -- r3 contains device base address > orr r2, r2, #1 -- Set bit field A to 1 > {Additional code here to modify bitfields B and C} > str r2, [r3, #register_offset] > -- Write all changes to device register at once Yes, this looks like an Ada assignment of the form Tmp := Rec; Rec := (A => 1, B => expr1, C => expr2, D => Tmp.D, E => Tmp.E, ...); where Rec has aspect Atomic and assuming that the compiler was able to optimize out the "no effect" expressions for the unchanged components D, E, .... Note that the following "simpler" assignment Rec := (A => 1, B => expr1, C => expr2, D => Rec.D, E => Rec.E, ...); cannot give the code above -- the two (or more) uses of Rec in the aggregate force the code to read (load) Rec two (or more) times, because an Atomic variable is also Volatile. (That is how I understand it, but I'm not entirely sure if each appearance of an object's name in the source code as a primary implies the evaluation of the object and therefore a "read" of the object.) This assumes a reasonable implementation of the Volatile aspect. > or is the Ada compiler allowed to do this: > > ldr r2, [r3, #register_offset] > orr r2, r2, #1 -- Set bit field A to 1 > str r2, [r3, #register_offset] -- Update bit field A only > > ldr r2, [r3, #register_offset] > {Code here to modify bitfield B} > str r2, [r3, #register_offset] -- Update bit field B only > > ldr r2, [r3, #register_offset] > {Code here to modify bitfield C} > str r2, [r3, #register_offset] -- Update bit field C only No, three stores to Rec can result only if the source code contains three assignments to Rec as a whole, or some assignments to components of Rec. > Ie: performs a atomic update of each bit field, In what sense do you call these bit-field updates "atomic"? Yes, the entire record variable is read with one memory access and written with one memory access; this is the Atomic aspect in Ada and C 1999. But no, they are not "atomic read-modify-write updates" in the sense of C 2011 _Atomic, or in the sense of Ada protected operations. I assume, as usual, that instruction sequences such as those above are not indivisible. > You also then have additional issues around wanting to, say, update bit > fields B and C at the same time while preserving the current value of > bit field A (which is where my "atomic using" suggestion comes in for > a C replacement language). The _Atomic qualifier of C 2011 might be used to make that whole update atomic, with respect to C threads, if all the modified bits are set to 0, or all are set to 1, because then the update can be coded as one C compound assignment (Rec &= mask, or Rec |= mask, respectively). But if some bits are set to 0 and others to 1, then the update cannot be one C compound assignment beause both an "and" and an "or" operation are required. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .