Subject: Crow: my eating thereof.
Careless of me. Apologies.
Of course Binyamin is right. Since the "runner" can get interrupted, then
the runner needs to run within a transaction too. (Getting interrupted
includes the z/OS LPAR getting interrupted by LPAR processing, which
covers even the disabled PSW case)
I sort of doubt that z/Architecture could have a "smart enough" pointer to
work, as you can get undispatched at any point if enabled (and the LPAR
can get undispatched at any point). If you're lucky enough that you'd blow
up if the storage went away while you weren't looking, you could protect
yourself with recovery. If the storage can get re-instated so that your
reference does not blow up, then you'd have to rely on data verification
which is at best difficult to ensure.
Do note that there are limitations (the actual limit is not architected)
to the amount of data you can touch in a non-constrained transaction.
There are cases where the two competitors do not need both to be within a
transaction (consider a CS to update a count, and an "add 1 to the count"
within a transaction). If the storage being examined can "go away", more
care needs to be taken.
The typical approach is approximately this:
Old way:
- Runner gets enq shared
- Updater gets enq exclusive
New way (changing both Runner and Updater):
- Fallback path: same as old way but add "set a footprint once ENQ is
held" and clear once ENQ is released
- Transaction:
Begin Transaction
if footprint is on, end transaction and use fallback path
run or update
End Transaction
The footprint is key (the non-constrained transaction needs to serialize
against the fallback path and thus know that it is in play).
For serialization using something like the LOCAL lock, this can also help
you to avoid having the transaction contend with all local lock
obtains/releases for your space, instead contending only with those places
where the footprint is set.
Peter Relson
z/OS Core Technology Design