[comp.lang.asm370] STOSM/STNSM

VALDIS@VTVM1.CC.VT.EDU (Valdis Kletnieks) (11/11/89)

OK.. Here's the problem.  You often get stuck writing a subroutine
that cannot tolerate any interrupts, but you don't know for sure what
the system mask is when you get called.

Solution:

... leadin code here
MASKOFF  STNSM  MASKON+1,X'00'
        (protected code here)
MASKON   STOSM  MASKOFF+1,X'FF'

The STNSM will stick the current mask into the immediate field of the STOSM,
and then set the mask to zeros.  Then when you hit the STOSM, the 'FF' has
been replaced by the actual mask you were running on, and ORing in that
results in the original mask again.

Note that this code is *NOT* suitable for AP or MP configurations.
Anybody got a version that works in a multiprocessor environment?

Now, are you using TR or TRT to find the last non-blank?  And what's this
about BXLE? :-)

CS is pretty simple really - there's a good description on page A-40
of the S/370 PrincOp (GA22-7000-10).  All it does is fetch a value,
compare it, and if it's the same update.  It's used for serializing
code.  Example (cribbing from A-40.. :) - you have a lock word, that
if it's a 0 you can proceed, but if it's a 1 you have to wait.  The
person who gets the lock sets it to 1 when he enters, and to 0 when he leaves.

       SR     R1,R1     get a zero.
       LA     R2,1      get a one.
LOOP   CS     R1,R2,LOCKWORD  do it
       BC     4,LOOP    if somebody else got it, spin.
... locked code here
       ST     R1,LOCKWORD clear the flag

What the CS will do is:
       Fetch LOCKWORD
       Compare to R1
       If EQUAL, STORE R2 at LONGWORD
       else set condition code.

So if you come in and it's zero, you fall through and set to 1 all in one
shot, while if it's a 1 you just spin...

Of course, THIS case could have been done with TS.  See the example in
the PrincOp on how to do multiple bits and other extensions of the idea.

                                   Valdis

P85025@BARILVM.BITNET (Doron Shikmoni) (11/12/89)

From Valdis:

>CS is pretty simple really - there's a good description on page A-40
>of the S/370 PrincOp (GA22-7000-10).  All it does is fetch a value,
>compare it, and if it's the same update.  It's used for serializing
>code.

This is a dangerously incomplete description. See below.

>       Example (cribbing from A-40.. :) - you have a lock word, that
>if it's a 0 you can proceed, but if it's a 1 you have to wait.  The
>person who gets the lock sets it to 1 when he enters, and to 0 when he leaves.
>
>       SR     R1,R1     get a zero.
>       LA     R2,1      get a one.
>LOOP   CS     R1,R2,LOCKWORD  do it
>       BC     4,LOOP    if somebody else got it, spin.
>... locked code here
>       ST     R1,LOCKWORD clear the flag

This code demonstrates one of the common bugs introduced via CS. It does
not maintain any serialization!!!! See below.

>What the CS will do is:
>       Fetch LOCKWORD
>       Compare to R1
>       If EQUAL, STORE R2 at LONGWORD
>       else set condition code.

There's your bug. The last line should be replaced with the following two:

else LOAD LOCKWORD into R1.
set condition code.

NOW, please read your code section again. Assuming that you meant "0"
to read "unlocked" and "1" to read "locked", you can see that your code
allows everyone to be in the critical section at the same time. No spin
will ever occur; if get bad CC on the first try, R1 is loaded with "1";
then, the next (single) spin will get a CC of zero, and your lock has
been picked...

This is a very common error done with CS and CDS; and since actual lock
clashes are rare, statistically, such bugs may be sitting in many programs,
waiting for the best time to incarnate, a-la Murphy....

The corrected code will look like this (making minimal change to your
example):

       LA     R2,1      get a one.
LOOP   SR     R1,R1     get a zero.
       CS     R1,R2,LOCKWORD  do it
       BC     4,LOOP    if somebody else got it, spin.
... locked code here
       ST     R1,LOCKWORD clear the flag

As a matter of taste, I'd also change the "BC  4" to "BNE". But this
is only a matter of taste, which is not arguable.

Regards
Doron

VALDIS@VTVM1.CC.VT.EDU (Valdis Kletnieks) (11/13/89)

Doron:

You're quite right.  And the first time I tried replying, I had it right.
However, I managed to flame out my CMS in the middle, and the second time
around, I retyped what I *thought* I had typed the FIRST time (when I was
peeking at the PrincOps..

Moral of the story:

Always double-proofread anything you are interrupted while writing.
Especially if you're trying to act like you know something about
multiprocessing.... :-(

                                      Valdis