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: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.swapon.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: Thu, 24 Apr 2014 16:05:41 +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 vb3Mkel0ngsnmhtMAXVSywSUVfwMXdz92Bq4u6o7+3vgbpR/Vx Cancel-Lock: sha1:Ljqh0vTfJ8tEYpWRXAkSpaqSWns= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 In-Reply-To: Xref: news.eternal-september.org comp.lang.ada:19569 Date: 2014-04-24T16:05:41+03:00 List-Id: On 14-04-24 03:20 , Simon Clubley wrote: > On 2014-04-23, Simon Wright wrote: >> Simon Clubley writes: >> >>> I wonder if we need something like that for Ada proper so we don't >>> have to read the register into a temporary variable first in order to >>> guarantee a single register read and a single register write while >>> updating a subset of bitfields in the register. >>> >>> Having to use a temporary variable to guarantee a update of, say, a >>> couple of bitfields (out of a possible large number of bitfields) at >>> the same time just feels as if it isn't elegant. >> >> But hardware isn't (usually) elegant! If what the hardware designer >> wants is for you to read the register, change the values you need to in >> the local copy, then write the modified value back, that's what the code >> should do, surely, without relying on compiler magic with obscure >> pragmas to make it happen? (Ada's pragma Atomic is quite obscure enough >> already!) > > The problem is the compiler does this automatically when you use C style > masks, Not really so, for the most common forms of C. AIUI, before C 2011 there was no way in C to declare that a particular variable or type should be "atomic" in the sense of being read and written indivisibly; this was only possible by using the predefined integer type sig_atomic_t. The C 1999 standard requires sig_atomic_t to be at least 8 bits wide, so it may be uncomfortably narrow on some machines. Of course, reasonable C compilers make sig_atomic_t be the widest type for which the target machine allows atomic load/store. On the other hand, some 32-bit machines have 16-bit I/O control registers, so a 32-bit sig_atomic_t would be too wide to be used for I/O control! Even qualifying the type or variable as volatile does not help, because volatility does not imply atomicity. > but you have to do the work manually when you try to write clean > code by using record bitfields (in Ada) or bitfield structs (in C) and > need to do the read/write exactly once and want to update more than one > of the bitfields at the same time. > > This whole discussion started when someone suggested that in a C > replacement language we should drop the use of masks when possible > in favour of a bitfield approach. I _strongly_ agree with this, but > neither C or Ada, as they stand, make it easy to do this. > > I proposed the following syntax for a C replacement language: > > atomic using uart0.config1 > .flag1 := 0; > .enable := 1; > .txdis := 0; > end atomic; This resembles the Pascal "with" statement, which is like an Ada "use" statement for the record variable: the record components are directly visible (without qualification) in the scope of the "with" statement. I would prefer a more general, expression-based solution: extend the aggregate notation with a form which combines an expression of a composite type, which provides the initial component values, and a partial aggregate, which uses named association to set new values for some of the components. This would be similar to an extension aggregate, but would override the initial values of some components, not combine an ancestor part with an extension part. For example, assume that the variables A and B are of a record type with the components x and y and some more components, Then, instead of the three statements B := A; B.x := 42; B.y := False; we could say something like B := (A overriding x => 42, y => False); (The "overriding" keyword is a bit misleading here, because it implies that the left-hand operand (A) overrides the right-hand aggregate, while the opposite should happen. Oh well.) This form of aggregate could implement the "atomic using", for example: uart0.config1 := (uart0.config1 overriding flag1 => 0, enable => 1, txdis => 0); Declaring uart0.config1 as atomic provides the single-read, single-write property in this assignment. This "overriding aggregate" would be useful in other ways, too, by making some temporary variables unnecessary. Perhaps it would be especially useful in contract aspects, where temporaries cannot be declared. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .