Operadores: __XADD
El operador multinúcleo es una extensión del estándar IEC 61131-3.
El operador se puede utilizar para implementar un contador atómico. Si una variable entera con una suma normal, por ejemplo iTest := iTest + 1; se incrementa, entonces esta operación no se realiza atómicamente. Otro acceso a la variable podría tener lugar entre la lectura y la escritura de la variable.
Si el contador se incrementa en varias tareas, el resultado del conteo puede ser menor que el número de conteos. Entonces, si dos tareas ejecutan el código anterior una vez y la variable previamente el valor 0 tenía, entonces la variable puede tener posteriormente el valor 1 tener. Esto es particularmente problemático cuando las matrices se procesan en varias tareas y se requiere un índice único para la matriz para cada procesamiento.
los operadores __XADD recibe un puntero a una variable del tipo como el primer sumando cuando se llama DINT y como segundo sumando un valor del tipo DINT . __XADD devuelve el valor antiguo del primer sumando y suma el segundo sumando al primer sumando en el mismo paso.
Por ejemplo, la llamada a la función puede verse así: diOld := __XADD(ADR(diVar), deAdd);
El siguiente ejemplo muestra un uso típico. Se debe llenar una matriz a partir de dos tareas, se deben usar todas las posiciones de la matriz y no se debe sobrescribir ninguna posición.
Con esta función, varias tareas pueden llenar una matriz booleana.
FUNCTION WriteToNextArrayPosition : BOOL
VAR_EXTERNAL
g_diIndex : DINT; // Index and array are globally defined and used by multiple tasks
g_boolArray : ARRAY [0..1000] OF BOOL;
END_VAR
VAR_INPUT
bToWrite : BOOL;
END_VAR
VAR
diIndex : DWORD;
END_VAR
diIndex := __XADD(ADR(g_diIndex), 1); // Returns a unique index
WriteToNextArrayPosition := FALSE;
IF (diIndex >= 0 AND diIndex <= 1000) THEN
g_boolArray[diIndex] := bToWrite; //Writes to unique index
WriteToNextArrayPosition := TRUE; // TRUE: Array was not full yet
END_IF