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. */
}