Provides data synchronization primitives for 64-bit applications.
Availability Library (liblapi_r.a)
#include <lapi.h>
int LAPI_Rmw64(hndl, op, tgt, tgt_var, in_val, prev_tgt_val, org_cntr)
lapi_handle_t hndl;
Rmw_ops_t op;
uint tgt;
long long *tgt_var;
long long *in_val;
long long *prev_tgt_val;
lapi_cntr_t *org_cntr;
include 'lapif.h'
LAPI_RMW64(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 (KIND=LAPI_LONG_LONG_TYPE) :: in_val, prev_tgt_val
TYPE (LAPI_CNTR_T) :: org_cntr
INTEGER ierror
Type of call: point-to-point communication (non-blocking)
This subroutine is the 64-bit version of LAPI_Rmw. It is used to synchronize two independent pieces of 64-bit 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;
}
This subroutine can also be used on a 32-bit processor.
All LAPI_Rmw64 calls are non-blocking. To test for completion, use the LAPI_Getcntr and LAPI_Waitcntr subroutines. LAPI_Rmw64 does not include a target counter (tgt_cntr), so LAPI_Rmw64 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.
{
long long local_var;
long long *addr_list;
/* both tasks initialize local_var to a value */
/* local_var addresses are exchanged and stored */
/* in addr_list (using LAPI_Address_init64) */
/* addr_list[tgt] now contains 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_Rmw64(hndl, FETCH_AND_ADD, tgt, addr_list[tgt],
value, prev_tgt_val, &org_cntr);
/* local_var on remote task has been increased */
/* by value. prev_tgt_val now contains value of */
/* local_var on remote task before the addition */
}
{
long long local_var;
long long *addr_list;
/* local_var addresses are exchanged and stored */
/* in addr_list (using LAPI_Address_init64). */
/* 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 the remote task */
LAPI_Rmw64(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. */
}
{
long long local_var;
long long *addr_list;
long long in_val[2];
/* local_var addresses are exchanged and stored */
/* in addr_list (using LAPI_Address_init64). */
/* 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 the remote task */
in_val[0] = comparator;
in_val[1] = value;
LAPI_Rmw64(hndl, COMPARE_AND_SWAP, tgt, addr_list[tgt],
in_val, prev_tgt_val, &org_cntr);
/* local_var on 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. */
}