CS returns a FIXED BINARY(31) value that indicates if the old and current values in a compare and swap were equal.
|
CS compares the "current" and "old" values. If they are equal, the "new" value is copied over the "current", and a value of 0 is returned. If they are unequal, the "current" value is copied over the "old", and a value of 1 is returned.
So, CS could be implemented as the following PL/I function, but then it would not be atomic at all. :
cs: proc( old_Addr, current_Addr, new )
returns( fixed bin(31) byvalue )
options( byvalue );
dcl old_Addr pointer;
dcl current_Addr pointer;
dcl new fixed bin(31);
dcl old fixed bin(31) based(old_addr);
dcl current fixed bin(31) based(current_addr);
if current = old then
do;
current = new;
return( 0 );
end;
else
do;
old = current;
return( 1 );
end;
end;
On z/OS, the CS built-in function implements the CS instruction. For a detailed description of this function, read the appendices in the Principles of Operations manual.
On Intel, the CDS built-in function uses the Intel cmpxchg4 instruction. The cmpxchg4 instruction takes the address of a "current" value, a "new" value and an "old" value. It returns the original "current" value and updates it with the "new" value only if it equaled the "old" value.
So, on Intel, the CS built-in function is implemented via the following inline function:
cs: proc( old_Addr, current_Addr, new )
returns( fixed bin(31) byvalue )
options( byvalue );
dcl old_Addr pointer;
dcl current_Addr pointer;
dcl new fixed bin(31);
dcl old fixed bin(31) based(old_addr);
dcl current fixed bin(31) based(current_addr);
if cmpxchg4( current_Addr, new, old ) = old then
do;
return( 0 );
end;
else
do;
old = current;
return( 1 );
end;
end;