z/Architecture: compare and swap example Updating Counters In this example, a 32-bit counter is updated by a program using the COMPARE AND SWAP instruction to ensure that the counter will be correctly updated. The original value of the counter is obtained by loading the word containing the counter into register r7. This value is moved into general register r8 to provide a modifiable copy, and general register r6 (containing an increment to the counter) is added to the modifiable copy to provide the updated counter value. The COMPARE AND SWAP instruction is used to ensure valid storing of the counter. The program updating the counter checks the result by examining the condition code. The condition code 0 indicates a successful update, and the program can proceed. If the counter had been changed between the time that the program loaded its original value and the time that it executed the COMPARE AND SWAP instruction, the execution would have loaded the new counter value into general register 7 and set the condition code to 1, indicating an unsuccessful update. The program must then repeat the update sequence until the execution of the COMPARE AND SWAP instruction results in a successful update. The following instruction sequence performs the above procedure: LGHI r6,1 Put increment value (one) into register r6 (LGHI is Load Grand Halfword Immediate) L r7,CNTR Put original counter value into GR7 LOOP LR r8,r7 Set up copy in GR8 to modify (Load Register r8 with contents of r7) AR r8,r6 Increment copy (Add Registers r8 and r6. put result in r8) CS r7,r8,CNTR Update counter in storage via compare and swap BC r4,LOOP If original value had changed, update new value (Brand on condition to loop, or not) ... CNTR Some heap storage location - one full word, or 32 bits. The following example shows two CPUs, A and B, executing this instruction sequence simultaneously: both CPUs attempt to add one to CNTR. CPU A CPU B Comments _______ _______ _________ GR7 GR8 CNTR GR7 GR8 ___ ___ ____ ___ ___ 16 16 16 CPU A loads GR7 and GR8 from CNTR 16 16 CPU B loads GR7 and GR8 from CNTR 17 CPU B adds one to GR8 17 CPU A adds one to GR8 17 CPU A executes CS; successful match, store 17 CPU B executes CS; no match, GR7 changed to CNTR value 18 CPU B loads GR8 from GR7, adds one to GR8 18 CPU B executes CS; successful match, store