Subject: Re: bit set/clr macro's; atomic instructions.
To: None <port-m68k@NetBSD.ORG>
From: der Mouse <mouse@Holo.Rodents.Montreal.QC.CA>
List: port-m68k
Date: 09/11/1996 08:50:39
[Quoting multiple people here...]

>> As I pointed out in my original post, the compile generates a 3
>> instruction sequence for those operations (when <var> is volatile).
>> This sequence is vulnerable for device interrupts.  This means that
>> if you are manipulating say interrupt mask-registers in code running
>> at spl0 and in an interrupt handler, you should either:
>>     1- guard the operation with spl-calls
>>     2- make sure the operation is done within a single instruction
>> or you may [lose].  Because I think the first option is an overkill,
>> the macro's provide the second option.

Are there no 68k family CPUs that can interrupt partway through an
instruction?  I know some VAX instructions are interruptible, but the
68k doesn't have the monster instructions like MOVTUC the VAX does.

> There is another way to avoid spl* calls in these situations:  All
> you need to do is store your binary flags each in a char variable.

> 	union {
> 		int ssir_int;
> 		char ssir_c[4];
> 	} ssir;

> Then you can "set a bit" by just slamming 1 into one of the char
> slots.  In this case, you can even check four values at one time in
> the service routine (though that will need an spl).

_May_ need an spl, depending - you don't always need to lock around
such accesses, depending on what you're doing and which pieces of code
can interrupt which other pieces.

You're also depending on the compiler to generate a single load or
store byte instruction, and at that one which executes uninterruptibly,
which is probably safe since we're on port-m68k, not c-language-lawyer
(on the latter, I'd point out that not all machines _have_ load/store
byte instructions, and thus could need to implement the char store as a
word load, fiddle one byte, word store).

> I'd suggest examining whether this technique might allow you to avoid
> machine-dependent tricks as well as avoid spl* calls.

The ability to store a single char as a single uninterruptible
operation without reading and rewriting at least one adjacent char (and
of course without explicitly locking out interrupts) is inherently
machine-dependent....

[Note: the rest of this message probably belongs on c-language-lawyer
rather than port-m68k... :-)]

> The "correct" (language lawyer) way to do it
> 	((char *)&intval)[N] = 1;
> is a bit more disturbing, but is actually guaranteed to work.

Is it?  It certainly is when accessing memory obtained from malloc via
a char pointer, but I don't think it is when the memory was allocated
by declaring a variable...or, of course, when the type being cast to is
not a character type.

> The two relevant references:  6.3.2.3 [...] 6.3.4

> Somewhere in there, and I can't find it, there is a guarantee that
> you can access any object whatsoever as a sequence of character type
> objects, and that copying it to an array of characters and back is
> safe, etc etc.

I thought that was an interpretation ruling, not an original part of
the standard.  That piece is why I remarked that the trick just above
works when the memory came from malloc and is accessed via chars.  (The
accessed via chars bit is because the copy-sequence-of-subobjects is
not promised to work for anything but chars (as seebs remarked); the
via malloc part is because malloc returns memory suitable for any use,
whereas it is - I think - possible that memory obtained by declaring
(say) an int is special somehow, such that, while it's true you can
copy the int value by copying the chars that make it up, some of those
chars may not entirely exist and in particular some of them might not
be able to take on the values you're trying to store into them.

>> 	((char *)&intval)[N] = 1;
> I am unable to find anything in ANSI C which specifies that a casted
> pointer must reference the same storage.

I think there's a special case for character types, and as I remarked
above I think it was an interpretation ruling.

					der Mouse

			       mouse@rodents.montreal.qc.ca
		     01 EE 31 F6 BB 0C 34 36  00 F3 7C 5A C1 A0 67 1D