1
1
openmpi/oshmem/mca/atomic/mxm/atomic_mxm_cswap.c
Joshua Ladd 008a2af2d8 Cleaning up a bit
This commit was SVN r29240.
2013-09-24 22:09:36 +00:00

141 строка
3.7 KiB
C

/*
* Copyright (c) 2013 Mellanox Technologies, Inc.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "oshmem_config.h"
#include <stdio.h>
#include <stdlib.h>
#include "oshmem/constants.h"
#include "oshmem/mca/spml/spml.h"
#include "oshmem/mca/atomic/atomic.h"
#include "oshmem/mca/atomic/base/base.h"
#include "oshmem/mca/memheap/memheap.h"
#include "oshmem/runtime/runtime.h"
#include "atomic_mxm.h"
int mca_atomic_mxm_cswap(void *target,
void *prev,
const void *cond,
const void *value,
size_t nlong,
int pe)
{
unsigned my_pe;
uint8_t nlong_order;
void *remote_addr;
int ptl_id;
mxm_send_req_t sreq;
mxm_error_t mxm_err;
my_pe = oshmem_my_proc_id();
ptl_id = -1;
mxm_err = MXM_OK;
if (!prev || !target || !value) {
ATOMIC_ERROR("[#%d] Whether target, value or prev are not defined",
my_pe);
oshmem_shmem_abort(-1);
return OSHMEM_ERR_BAD_PARAM;
}
if ((pe < 0) || (pe >= oshmem_num_procs())) {
ATOMIC_ERROR("[#%d] PE=%d not valid", my_pe, pe);
oshmem_shmem_abort(-1);
return OSHMEM_ERR_BAD_PARAM;
}
switch (nlong) {
case 1:
nlong_order = 0;
break;
case 2:
nlong_order = 1;
break;
case 4:
nlong_order = 2;
break;
case 8:
nlong_order = 3;
break;
default:
ATOMIC_ERROR("[#%d] Type size must be 1/2/4 or 8 bytes.", my_pe);
oshmem_shmem_abort(-1);
return OSHMEM_ERR_BAD_PARAM;
}
ptl_id = oshmem_proc_group_all(pe)->transport_ids[0];
if (MXM_PTL_SHM == ptl_id) {
ptl_id = MXM_PTL_RDMA;
}
if (!mca_memheap.memheap_get_cached_mkey(pe,
target,
ptl_id,
&remote_addr)) {
ATOMIC_ERROR("[#%d] %p is not address of symmetric variable",
my_pe, target);
oshmem_shmem_abort(-1);
return OSHMEM_ERR_BAD_PARAM;
}
/* mxm request init */
sreq.base.state = MXM_REQ_NEW;
sreq.base.mq = mca_spml_self->mxm_mq;
sreq.base.conn = mca_spml_self->mxm_peers[pe]->mxm_conn;
sreq.base.completed_cb = NULL;
sreq.base.data_type = MXM_REQ_DATA_BUFFER;
/* set data */
sreq.base.data.buffer.ptr = (void *) value;
sreq.base.data.buffer.length = nlong;
sreq.base.data.buffer.memh = MXM_INVALID_MEM_HANDLE;
sreq.op.atomic.remote_vaddr = (uintptr_t) remote_addr;
#if MXM_API < MXM_VERSION(2,0)
sreq.base.flags = 0;
sreq.op.atomic.remote_memh = MXM_INVALID_MEM_HANDLE;
#else
sreq.flags = 0;
sreq.op.atomic.remote_mkey = MXM_INVALID_MEM_HANDLE;
#endif
sreq.op.atomic.order = nlong_order;
if (NULL == cond) {
sreq.opcode = MXM_REQ_OP_ATOMIC_SWAP;
} else {
#if MXM_API < MXM_VERSION(2,0)
memcpy(&sreq.op.atomic.value8, cond, nlong);
#else
memcpy(&sreq.op.atomic.value, cond, nlong);
#endif
sreq.opcode = MXM_REQ_OP_ATOMIC_CSWAP;
}
if (MXM_OK != (mxm_err = mxm_req_send(&sreq))) {
ATOMIC_ERROR("[#%d] mxm_req_send failed, mxm_error = %d",
my_pe, mxm_err);
oshmem_shmem_abort(-1);
return OSHMEM_ERROR;
}
mxm_req_wait(&sreq.base);
if (MXM_OK != sreq.base.error) {
ATOMIC_ERROR("[#%d] mxm_req_wait got non MXM_OK error: %d",
my_pe, sreq.base.error);
oshmem_shmem_abort(-1);
return OSHMEM_ERROR;
}
memcpy(prev, value, nlong);
return OSHMEM_SUCCESS;
}