comp.lang.ada
 help / color / mirror / Atom feed
* Pragma Atomic
@ 2001-01-09 22:44 Adam Beneschan
  2001-01-09 23:16 ` mark.biggar
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Adam Beneschan @ 2001-01-09 22:44 UTC (permalink / raw)


I'm having trouble understanding what pragma Atomic is for.

The RM says that "all reads and updates of the object as a whole are
indivisible."  (C.6(15)) The RM never defines what "indivisible"
means, however.  On first glance, my understanding would be that if
you have an indivisible record type:

    type Rectype is record
        Field1 : integer;
        Field2 : integer;
    end record;
    pragma Atomic (Rectype);

then when you read (or write) an object of that type, nothing can come
between the read of Field1 and the read of Field2.  Thus, the process
can't be interrupted in between reads of the two fields, and no other
processor on a multi-processor system can access the object in between
and (say) modify Field2 after the first processor reads Field1.  At
least, that's my interpretation of the word.  It wouldn't make sense
to declare a scalar object, whose size is a natural size on the
processor, to be Atomic, since the processor's reads and writes of
such an object would automatically be indivisible anyway.

However, the examples in the Rationale, Section C.5, don't make sense
to me.  One is

    Buffer: array (1..Max) of Integer;
    pragma Atomic_Components(Buffer);

in which "Atomic" is applied to each Integer component; and then we
have

    type IO_Rec_Type is
      record
        ...
        Reset: Boolean;
        pragma Atomic(Reset);
      end record;

The Rationale explains this as follows:

"By declaring ... Reset to be atomic, the user ensures that reads and
writes of these fields are not removed by optimization, and are
performed indivisibly."  The part about reading and writing not being
optimized away follows because pragma Atomic implies pragma Volatile,
right?  As for reads and writes being performed indivisibly, Reset is
one bit, so how could a read or write of it be "divisible"?

To confuse me even further, AARM95
(http://www.ada-auth.org/~acats/arm-html/AA-C-6.html) says "Pragma
Atomic replaces Ada 83's pragma Shared. The name 'Shared' was
confusing, because the pragma was not used to mark variables as
shared."  I'm not sure how the previous Shared pragma had anything to
do with indivisiblity or atomicity, however, so I don't see how Atomic
replaces it.  Seemingly contradicting this is the Rationale, which
says "the pragma Shared was removed from the language and replaced by
the pragmas Atomic and Volatile."

Could someone PLEASE help clear things up for me?  Perhaps the term
"indivisible" has some other definition that everyone in the world
except me knows about?  Any explanation from someone in the know would
be very much appreciated.

                                -- thanks, Adam



Sent via Deja.com
http://www.deja.com/



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Pragma Atomic
  2001-01-09 22:44 Pragma Atomic Adam Beneschan
@ 2001-01-09 23:16 ` mark.biggar
  2001-01-10  4:27 ` Robert Dewar
  2001-01-10 17:53 ` Nick Roberts
  2 siblings, 0 replies; 6+ messages in thread
From: mark.biggar @ 2001-01-09 23:16 UTC (permalink / raw)


In article <93g48c$ehk$1@nnrp1.deja.com>,
  Adam Beneschan <adam@irvine.com> wrote:
> I'm having trouble understanding what pragma Atomic is for.
>
> The RM says that "all reads and updates of the object as a whole are
> indivisible."  (C.6(15)) The RM never defines what "indivisible"
> means, however.  On first glance, my understanding would be that if
> you have an indivisible record type:
>
>     type Rectype is record
>         Field1 : integer;
>         Field2 : integer;
>     end record;
>     pragma Atomic (Rectype);
>
> then when you read (or write) an object of that type, nothing can come
> between the read of Field1 and the read of Field2.  Thus, the process
> can't be interrupted in between reads of the two fields, and no other
> processor on a multi-processor system can access the object in between
> and (say) modify Field2 after the first processor reads Field1.  At
> least, that's my interpretation of the word.

That's a correct interpretation.

>It wouldn't make sense
> to declare a scalar object, whose size is a natural size on the
> processor, to be Atomic, since the processor's reads and writes of
> such an object would automatically be indivisible anyway.

Not necessarilly, consider reading a 32 bit scalar on a computer
with a 16 bit memory bus, or more likely reading a 64 bit float on
a 32 bit computer.  Also memory cache line boundries can also
effect this.

> However, the examples in the Rationale, Section C.5, don't make sense
> to me.  One is
>
>     Buffer: array (1..Max) of Integer;
>     pragma Atomic_Components(Buffer);
>
> in which "Atomic" is applied to each Integer component;

Now consider an ada implementation with 32 bit intergers where the
machine has a single instruction to move multiple bytes that is
interuptable.  The pragma may well mean that you can't use that
instruction to move data into and out of Buffer, but must use a
loop around a gurenteed atomic move instruction..

> and then we
> have
>
>     type IO_Rec_Type is
>       record
>         ...
>         Reset: Boolean;
>         pragma Atomic(Reset);
>       end record;
>
> The Rationale explains this as follows:
>
> "By declaring ... Reset to be atomic, the user ensures that reads and
> writes of these fields are not removed by optimization, and are
> performed indivisibly."  The part about reading and writing not being
> optimized away follows because pragma Atomic implies pragma Volatile,
> right?  As for reads and writes being performed indivisibly, Reset is
> one bit, so how could a read or write of it be "divisible"?

First that is no gurentee that Reset is really only one bit, unless
the record also has a pragma pack or a rep spec, Reset may well
be alocated 32 bits for effecienty reasons.

> To confuse me even further, AARM95
> (http://www.ada-auth.org/~acats/arm-html/AA-C-6.html) says "Pragma
> Atomic replaces Ada 83's pragma Shared. The name 'Shared' was
> confusing, because the pragma was not used to mark variables as
> shared."  I'm not sure how the previous Shared pragma had anything to
> do with indivisiblity or atomicity, however, so I don't see how Atomic
> replaces it.  Seemingly contradicting this is the Rationale, which
> says "the pragma Shared was removed from the language and replaced by
> the pragmas Atomic and Volatile."
>
> Could someone PLEASE help clear things up for me?  Perhaps the term
> "indivisible" has some other definition that everyone in the world
> except me knows about?  Any explanation from someone in the know would
> be very much appreciated.

No you have it right, you just didn't considered all the possible
implemtations out there.

--
Mark Biggar
mark.biggar@trustedsyslabs.com


Sent via Deja.com
http://www.deja.com/



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Pragma Atomic
  2001-01-09 22:44 Pragma Atomic Adam Beneschan
  2001-01-09 23:16 ` mark.biggar
@ 2001-01-10  4:27 ` Robert Dewar
  2001-01-10 17:53 ` Nick Roberts
  2 siblings, 0 replies; 6+ messages in thread
From: Robert Dewar @ 2001-01-10  4:27 UTC (permalink / raw)


In article <93g48c$ehk$1@nnrp1.deja.com>,
  Adam Beneschan <adam@irvine.com> wrote:
> It wouldn't make sense to declare a scalar object, whose size
> is a natural size on the processor, to be Atomic, since the
> processor's reads and writes of
> such an object would automatically be indivisible anyway.

AARGH! It is this kind of thinking that leads to casually
non-portable code. Just think about what you are saying, you
are saying that if you write

   type x is mod 2 ** 64;
   v : x;

and you know that you are operating on a 64-bit machine where
64-bit reads and writes are indivisible, and further more you
happen to know that the compiler uses these instructions for
reading and writing v, then you need not delare v Atomic
because it is not needed!

The whole point of Atomic is to *check* that your assumption
that reads and writes are atomic is correct. It is not unusual
in an Ada compiler for pragma Atomic to have no effect on the
code that pragma Volatile would not have. THe difference is
that you are asking the compiler to check that on the target
you are using, you will indeed get Atomic access.

So please declare v Atomic in the code above. It will have no
effect on your 64-bit machine, but it will cause your code to
be considered illegal when you port it to a 32-bit machine that
does not support your expectations.

> Atomic replaces Ada 83's pragma Shared. The name 'Shared' was
> confusing, because the pragma was not used to mark variables
> as shared."  I'm not sure how the previous Shared pragma had
> anything to do with indivisiblity or atomicity,

Pleaes read the Ada 83 RM which makes this quite clear.

> however, so I don't see how Atomic
> replaces it.

Because pragma Atomic in Ada 95 means EXACTLY the same
think as pragma Shared in Ada 83. The name change was to
avoid the confusing name (which certainly confused you :-)


Sent via Deja.com
http://www.deja.com/



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Pragma Atomic
  2001-01-09 22:44 Pragma Atomic Adam Beneschan
  2001-01-09 23:16 ` mark.biggar
  2001-01-10  4:27 ` Robert Dewar
@ 2001-01-10 17:53 ` Nick Roberts
  2001-01-11 14:00   ` Tucker Taft
  2 siblings, 1 reply; 6+ messages in thread
From: Nick Roberts @ 2001-01-10 17:53 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message
news:93g48c$ehk$1@nnrp1.deja.com...
> I'm having trouble understanding what pragma Atomic is for.
>
> The RM says that "all reads and updates of the object as a whole are
> indivisible."  (C.6(15)) The RM never defines what "indivisible"
> means, however.  On first glance, my understanding would be that if
> you have an indivisible record type:
>
>     type Rectype is record
>         Field1 : integer;
>         Field2 : integer;
>     end record;
>     pragma Atomic (Rectype);
>
> then when you read (or write) an object of that type, nothing can come
> between the read of Field1 and the read of Field2.  Thus, the process
> can't be interrupted in between reads of the two fields, and no other
> processor on a multi-processor system can access the object in between
> and (say) modify Field2 after the first processor reads Field1.  At
> least, that's my interpretation of the word.

I agree with your interpretation this far.

> It wouldn't make sense
> to declare a scalar object, whose size is a natural size on the
> processor, to be Atomic, since the processor's reads and writes of
> such an object would automatically be indivisible anyway.

Yes it does make sense, because not all scalar objects are the size of a
'natural' machine word, and not all machine architectures have a memory bus
the same width as the natural machine width.

Sometimes a scalar will have the size of two or four machine or memory
words, and sometimes half or a quarter of one. In these cases, it is
possible for one ordinary access to be divisible, either because two (or
more) instructions are needed for the access (e.g. two 16-bit load
instructions to read one 32-bit integer) which may be interrupted inbetween,
or because one instruction causes two (or more) memory transactions to be
issued (e.g. two 16-bit memory reads for a single 32-bit integer load
instruction) and another processor executing in parallel interleaves its
memory transactions [writes*] with them. I'm sure there are further
possibilities (on unusal architectures).

> However, the examples in the Rationale, Section C.5, don't make sense
> to me.  One is
>
>     Buffer: array (1..Max) of Integer;
>     pragma Atomic_Components(Buffer);
>
> in which "Atomic" is applied to each Integer component;

Hopefully my explanation for pragma Atomic being applied to scalars explains
this one.

> and then we have
>
>     type IO_Rec_Type is
>       record
>         ...
>         Reset: Boolean;
>         pragma Atomic(Reset);
>       end record;
>
> The Rationale explains this as follows:
>
> "By declaring ... Reset to be atomic, the user ensures that reads and
> writes of these fields are not removed by optimization, and are
> performed indivisibly."

> The part about reading and writing not being
> optimized away follows because pragma Atomic implies pragma Volatile,
> right?

Yes, I agree with this.

> As for reads and writes being performed indivisibly, Reset is
> one bit, so how could a read or write of it be "divisible"?

Reset is not necessarily one bit. It may be a size chosen by the compiler
(e.g. one word), or determined by a representation clause.

Furthermore, if it is one bit in size, it may (indeed it is liekly to) cause
normal accesses to it to be divisible. To effect one read access, a typical
machine will need to: load the word containing the bit; mask off the rest of
the word; perhaps shift the bit along. If this takes several instructions,
those instructions will probably be interruptible.

Ironically, applying the pragma Atomic to a Boolean object or type may
actually cause the compiler to choose a word size for it (when it would have
chosen 1 bit otherwise).

> To confuse me even further, AARM95
> (http://www.ada-auth.org/~acats/arm-html/AA-C-6.html) says "Pragma
> Atomic replaces Ada 83's pragma Shared. The name 'Shared' was
> confusing, because the pragma was not used to mark variables as
> shared."  I'm not sure how the previous Shared pragma had anything to
> do with indivisiblity or atomicity, however, so I don't see how Atomic
> replaces it.  Seemingly contradicting this is the Rationale, which
> says "the pragma Shared was removed from the language and replaced by
> the pragmas Atomic and Volatile."

I'll leave others to comment on this.

> Could someone PLEASE help clear things up for me?  Perhaps the term
> "indivisible" has some other definition that everyone in the world
> except me knows about?  Any explanation from someone in the know would
> be very much appreciated.
>
>                                 -- thanks, Adam

I hope I've cleared some things up!

--
Nick Roberts
http://www.AdaOS.org




* If they were also reads, they would actually be harmless**.
** Except possibly for memory-mapped I/O!







^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Pragma Atomic
  2001-01-10 17:53 ` Nick Roberts
@ 2001-01-11 14:00   ` Tucker Taft
  2001-01-11 15:06     ` Nick Roberts
  0 siblings, 1 reply; 6+ messages in thread
From: Tucker Taft @ 2001-01-11 14:00 UTC (permalink / raw)


Nick Roberts wrote:
> ...
> > As for reads and writes being performed indivisibly, Reset is
> > one bit, so how could a read or write of it be "divisible"?
> 
> Reset is not necessarily one bit. It may be a size chosen by the compiler
> (e.g. one word), or determined by a representation clause.
> 
> Furthermore, if it is one bit in size, it may (indeed it is liekly to) cause
> normal accesses to it to be divisible. To effect one read access, a typical
> machine will need to: load the word containing the bit; mask off the rest of
> the word; perhaps shift the bit along. If this takes several instructions,
> those instructions will probably be interruptible.

This is not really the problem.  The thing which has to be "indivisible"
is the interaction with memory, and in this case, the read from
memory is generally just one uninterruptable instruction.
The problem is more with "write" where it is supposed to involve
exactly one memory access instruction, but in general, to write
a bit field, you must first read the entire surrounding word, make
the appropriate change, and then rewrite the entire surrounding
word, which violates the volatility rules by incurring an extra
"read", and if neighboring bits are also volatile, causes further
violations of volatility.  So the original questioner is in some
sense right that a single bit marked atomic is not saying much
more than marking the single bit volatile.

> ...> >                                 -- thanks, Adam
> 
> I hope I've cleared some things up!
> 
> --
> Nick Roberts

-- 
-Tucker Taft   stt@avercom.net   http://www.averstar.com/~stt/
Chief Technology Officer, AverCom, Inc. (A Titan Company) Burlington, MA  USA
(AverCom was formed 1/1/01 from the Commercial Division of AverStar)
(http://www.averstar.com/services/ebusiness_applications.html)



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Pragma Atomic
  2001-01-11 14:00   ` Tucker Taft
@ 2001-01-11 15:06     ` Nick Roberts
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Roberts @ 2001-01-11 15:06 UTC (permalink / raw)


Sorry, I should have used the 'write' example for the Boolean bit :-)

--
Nick Roberts
http://www.AdaOS.org


"Tucker Taft" <stt@averstar.com> wrote in message
news:3A5DBC6C.1E665DA7@averstar.com...
> This is not really the problem.  The thing which has to be "indivisible"
> ...





^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-01-11 15:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-01-09 22:44 Pragma Atomic Adam Beneschan
2001-01-09 23:16 ` mark.biggar
2001-01-10  4:27 ` Robert Dewar
2001-01-10 17:53 ` Nick Roberts
2001-01-11 14:00   ` Tucker Taft
2001-01-11 15:06     ` Nick Roberts

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox