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!border2.nntp.dca.giganews.com!nntp.giganews.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.fsmpi.rwth-aachen.de!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Simon Clubley Newsgroups: comp.lang.ada Subject: Re: Oberon and Wirthian languages Date: Thu, 24 Apr 2014 18:51:34 +0000 (UTC) Organization: A noiseless patient Spider 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> Injection-Date: Thu, 24 Apr 2014 18:51:34 +0000 (UTC) Injection-Info: mx05.eternal-september.org; posting-host="e458ff8b81bc0c159989eb0e36c6e372"; logging-data="19710"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/4vXC6ZXnUiBaLrIQsYBHAd6qpUl6aVnY=" User-Agent: slrn/0.9.8.1 (VMS/Multinet) Cancel-Lock: sha1:59JxkD/wknK1tTa6ICaLxJc1dEw= X-Original-Bytes: 6472 Xref: number.nntp.dca.giganews.com comp.lang.ada:186074 Date: 2014-04-24T18:51:34+00:00 List-Id: On 2014-04-24, Niklas Holsti wrote: > On 14-04-24 03:20 , Simon Clubley wrote: >> On 2014-04-23, Simon Wright wrote: >>> >>> 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. > Sorry, I probably wasn't clear enough. What I meant was that if you write (in C) something like: device_register = (device_register & mask1) | mask2; while accessing a volatile register then gcc generates exactly one read and exactly one write and the size of the access is the size of the device_register declaration. This is true at least on ARM and I have never seen any complaints about it being untrue on other architectures. > 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. > That's interesting. I wonder if this is a case of gcc implementing the "expected" behaviour and there's now a large set of code which relies on this "expected" behaviour. >> 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.) > Although I agree the syntax needs changing, I do like the general idea behind this suggestion. > 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. > Yes, it certainly does. > 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. > It will be interesting to see if Randy and company have any comments on this syntax. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world