Provides data synchronization primitives.
Availability Library (liblapi_r.a)
#include <lapi.h>
 
int LAPI_Rmw(hndl, op, tgt, tgt_var, in_val, prev_tgt_val, org_cntr)
 
lapi_handle_t hndl;
RMW_ops_t op;
uint tgt;
int *tgt_var;
int *in_val;
int *prev_tgt_val;
lapi_cntr_t *org_cntr;
include 'lapif.h'
 
LAPI_RMW(hndl, op, tgt, tgt_var, in_val, prev_tgt_val, org_cntr, ierror)
INTEGER hndl
INTEGER op
INTEGER tgt
INTEGER (KIND=LAPI_ADDR_TYPE) :: tgt_var
INTEGER in_val
INTEGER prev_tgt_val
TYPE (LAPI_CNTR_T) :: org_cntr
INTEGER ierror
Type of call: point-to-point communication (non-blocking)
Use this subroutine to synchronize two independent pieces of data, such as two tasks sharing a common data structure. The operation is performed at the target task (tgt) and is atomic. The operation takes an input value (in_val) from the origin and performs one of four operations (op) on a variable (tgt_var) at the target (tgt), and then replaces the target variable (tgt_var) with the results of the operation (op). The original value (prev_tgt_val) of the target variable (tgt_var) is returned to the origin.
*prev_tgt_val = *tgt_var;
*tgt_var      = f(*tgt_var, *in_val);
where:
f(a,b) = a + b for FETCH_AND_ADD
f(a,b) = a | b for FETCH_AND_OR (bitwise or)
f(a,b) = b for SWAP
 if(*tgt_var == in_val[0]) {
   *prev_tgt_val = TRUE;
   *tgt_var      = in_val[1];
} else {
   *prev_tgt_val = FALSE;
}
All LAPI_Rmw calls are non-blocking. To test for completion, use the LAPI_Getcntr and LAPI_Waitcntr subroutines. LAPI_Rmw does not include a target counter (tgt_cntr), so LAPI_Rmw calls do not provide any indication of completion on the target task (tgt).
LAPI statistics are not reported for shared memory communication and data transfer, or for messages that a task sends to itself.
{
       int local_var;
       int *addr_list;
       /* both tasks initialize local_var to a value       */
       /* local_var addresses are exchanged and stored     */
       /* in addr_list (using LAPI_Address_init).          */
       /* addr_list[tgt] now contains the address of       */
       /* local_var on tgt                                 */
       .
       .
       .
       /* add value to local_var on some task               */
       /* use LAPI to add value to local_var on remote task */
       LAPI_Rmw(hndl, FETCH_AND_ADD, tgt, addr_list[tgt],
                value, prev_tgt_val, &org_cntr);
       /* local_var on the remote task has been increased   */
       /* by value.  prev_tgt_val now contains the value    */
       /* of local_var on remote task before the addition   */
}
{
      int local_var;
      int *addr_list;
      /* local_var addresses are exchanged and stored  */
      /* in addr_list (using LAPI_Address_init).       */
      /* addr_list[tgt] now contains the address of    */
      /* local_var on tgt.                             */
      .
      .
      . 
      /* local_var is assigned some value              */
      /* assign local_var to local_var on remote task  */
      LAPI_Rmw(hndl, SWAP, tgt, addr_list[tgt],
               local_var, prev_tgt_val, &org_cntr);
      /* local_var on the remote task is now equal to  */ 
      /* local_var on the local task. prev_tgt_val now */ 
      /* contains the value of local_var on the remote */  
      /* task before the swap.                         */
}
{
      int local_var;
      int *addr_list;
      int in_val[2];
      /* local_var addresses are exchanged and stored        */
      /* in addr_list (using LAPI_Address_init).             */
      /* addr_list[tgt] now contains the address of          */
      /* local_var on tgt.                                   */
      .
      .
      .
      /* if local_var on remote_task is equal to comparator, */
      /* assign value to local_var on remote task            */
			
      in_val[0] = comparator;
      in_val[1] = value;
      LAPI_Rmw(hndl, COMPARE_AND_SWAP, tgt, addr_list[tgt],
               in_val, prev_tgt_val, &org_cntr);
      /* local_var on the remote task is now in_val[1] if it */
      /* had previously been equal to in_val[0]. If the swap */
      /* was performed, prev_tgt_val now contains TRUE;      */ 
      /* otherwise, it contains FALSE.                       */
}