Planning to use transactional execution

The HLASM element of z/OS provides a print exit named ASMAXTXP, which you can use in your assembly. It flags as errors things that violate a transactional execution restriction, to the extent it can determine those violations.

The user of transactions has control over such things as:
Consider the following simple transaction:
LA    2,Source_Data_Word
LA    3,Target_Data_Word
TBEGIN theTDB,X'8000'    <<The "80" indicates to restore GRs 0-1 upon abort, each
                           bit in that byte corresponds to a double register pair.>>
BRC   7,Transaction_aborted
L     1,0(,2)
ST    1,0(,3)
TEND
<<When you get here, register 1 will have been changed by the "L", and the target 
  word will have been set.>>
...
Transaction_aborted DS 0H
<<When you get here, all the registers will have the value they had before the 
TBEGIN instruction, the target word will be unchanged, and the TDB, identified on
the TBEGIN instruction, will contain information about the transaction abort.>>
You can think of stores within a transaction as being "rolled back" upon transaction abort. Similarly, you can think of the registers as being saved at the transaction begin and then (optionally) rolled back to their pre-transaction begin values.
When using nonconstrained transactions, the transaction must be serialized against the fall-back path. For example, if one processor is within a transaction and another within the fall-back path, each needs to know enough to protect itself against the other. Also, typically, a fall-back path needs to be serialized against other concurrent execution of that fall-back path. You can think of the fall-back path as needing "real" serialization (hardware or software-provided) and the transaction needing to be able to tell that the fall-back path is running. One way of accomplishing this is for the fall-back path to set a footprint when it has obtained "real" serialization and for the transaction to query that footprint. For example, consider a group of updates that need to be done atomically:
Fall-Back Path

	ENQ
	Set bit I_Have_ENQ
	the group of updates
	Reset bit I_Have_ENQ
	DEQ


Transaction

	TBEGIN
	BRC xx,Transaction_Aborted
	If I_Have_ENQ is on then TABORT
	the group of updates
	TEND
Even this simple example is incomplete. To avoid cases where a spin would result (when the ENQ holder does not get a chance to reset the bit), the transaction path needs to limit the number of times that the transaction is started over. This can be done using a counter in a register that is not restored upon the abort or a non-transactional store. Thus, at "Transaction_Aborted", there might be a test to see if flow should proceed to the fall-back path or back to the TBEGIN.
Note: With this sort of approach, multiple transactional users do not conflict with each other with respect to the I_Have_ENQ bit (as, to them, it is just being read), but of course they do conflict with each other with respect to the stores in the update group. A fall-back path does conflict with the transaction such that its setting of I_Have_ENQ will cause an in-process transaction to be aborted.