Operator ‘__COMPARE_AND_SWAPΒΆ

The multicore operator is an extension of the IEC 61131-3 standard.

The operator can be used for implementing a semaphore, for example to guarantee exclusive access to a variable written to by different tasks.

__COMPARE_AND_SWAP gets a pointer to a data type __XWORD variable, an old value, and a new value as its input (example: bMutex := __COMPARE_AND_SWAP(ADR(dwSynch), dwOld, dwNew);). The old and new values can also be data type __XWORD variables. The referenced __XWORD variable is compared with the old value and if both are equal, then the new value is written. The result of the function is TRUE when the new value could be written.

Note

The compiler automatically replaces the data type __XWORD with DWORD on 32-bit systems and LWORD on 64-bit systems.

This operation is atomic, so it cannot be interrupted by another task, even on multicore platforms.

Example

The following example shows a typical usage. Exclusive access to a type STRING variable, which is addressed via the pstrOutput pointer, should be implemented.

The access to a string is not atomic. If multiple tasks write to the same string at the same time, then the contents may be inconsistent.

With this function, it is now possible to write the same STRING variable in different tasks.

FUNCTION ExclusiveStringWrite : BOOL
VAR_INPUT
        strToWrite : STRING;
        pstrOutput : POINTER TO STRING;
END_VAR
VAR_STAT
  dwSynch : __XWORD;
END_VAR
VAR
        bMutex: BOOL;
END_VAR

bMutex:= __COMPARE_AND_SWAP(ADR(dwSynch), 0, 1);
(* compare with 0 and write 1 as atomic operation *)
IF bMutex THEN                                       // bMutex is TRUE if write could be done
    pstrOutput^ := strToWrite;         // Now you can write safely on the string
    dwSynch := 0;                      // The __XWORD variable must be reset.
    ExclusiveStringWrite := TRUE;                // Writing was successful
ELSE
    ExclusiveStringWrite := FALSE;       // Writing was not successful
END_IF

See also