d5d2d5c4d8
Dave Goodell correctly pointed out that it is unusual to return MPI error classes from internal ompi functions. Correct this in the RMA case by adding an internal error code to match MPI_ERR_RMA_SYNC. This does change OMPI_ERR_MAX. I don't think this will cause any problems with ABI. cmr=v1.7.5:reviewer=jsquyres This commit was SVN r31012.
249 строки
5.5 KiB
C
249 строки
5.5 KiB
C
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
|
/*
|
|
* Copyright (c) 2011 Sandia National Laboratories. All rights reserved.
|
|
* Copyright (c) 2014 Los Alamos National Security, LLC. All rights
|
|
* reserved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#include "ompi_config.h"
|
|
|
|
#include "ompi/mca/osc/osc.h"
|
|
#include "ompi/mca/osc/base/base.h"
|
|
#include "ompi/mca/osc/base/osc_base_obj_convert.h"
|
|
|
|
#include "osc_sm.h"
|
|
|
|
|
|
static inline uint32_t
|
|
lk_fetch_add32(ompi_osc_sm_module_t *module,
|
|
int target,
|
|
size_t offset,
|
|
uint32_t delta)
|
|
{
|
|
/* opal_atomic_add_32 is an add then fetch so delta needs to be subtracted out to get the
|
|
* old value */
|
|
return opal_atomic_add_32((int32_t*) ((char*) &module->node_states[target].lock + offset),
|
|
delta) - delta;
|
|
}
|
|
|
|
|
|
static inline void
|
|
lk_add32(ompi_osc_sm_module_t *module,
|
|
int target,
|
|
size_t offset,
|
|
uint32_t delta)
|
|
{
|
|
opal_atomic_add_32((int32_t*) ((char*) &module->node_states[target].lock + offset),
|
|
delta);
|
|
}
|
|
|
|
|
|
static inline uint32_t
|
|
lk_fetch32(ompi_osc_sm_module_t *module,
|
|
int target,
|
|
size_t offset)
|
|
{
|
|
opal_atomic_mb ();
|
|
return (uint32_t) *((char*) &module->node_states[target].lock + offset);
|
|
}
|
|
|
|
|
|
static inline int
|
|
start_exclusive(ompi_osc_sm_module_t *module,
|
|
int target)
|
|
{
|
|
uint32_t me = lk_fetch_add32(module, target,
|
|
offsetof(ompi_osc_sm_lock_t, counter), 1);
|
|
|
|
while (me != lk_fetch32(module, target,
|
|
offsetof(ompi_osc_sm_lock_t, write))) {
|
|
opal_progress();
|
|
}
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
static inline int
|
|
end_exclusive(ompi_osc_sm_module_t *module,
|
|
int target)
|
|
{
|
|
lk_add32(module, target, offsetof(ompi_osc_sm_lock_t, write), 1);
|
|
lk_add32(module, target, offsetof(ompi_osc_sm_lock_t, read), 1);
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
static inline int
|
|
start_shared(ompi_osc_sm_module_t *module,
|
|
int target)
|
|
{
|
|
uint32_t me = lk_fetch_add32(module, target,
|
|
offsetof(ompi_osc_sm_lock_t, counter), 1);
|
|
|
|
while (me != lk_fetch32(module, target,
|
|
offsetof(ompi_osc_sm_lock_t, read))) {
|
|
opal_progress();
|
|
}
|
|
|
|
lk_add32(module, target, offsetof(ompi_osc_sm_lock_t, read), 1);
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
static inline int
|
|
end_shared(ompi_osc_sm_module_t *module,
|
|
int target)
|
|
{
|
|
lk_add32(module, target, offsetof(ompi_osc_sm_lock_t, write), 1);
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_lock(int lock_type,
|
|
int target,
|
|
int assert,
|
|
struct ompi_win_t *win)
|
|
{
|
|
ompi_osc_sm_module_t *module =
|
|
(ompi_osc_sm_module_t*) win->w_osc_module;
|
|
int ret;
|
|
|
|
if (lock_none != module->outstanding_locks[target]) {
|
|
return OMPI_ERR_RMA_SYNC;
|
|
}
|
|
|
|
if (0 == (assert & MPI_MODE_NOCHECK)) {
|
|
if (MPI_LOCK_EXCLUSIVE == lock_type) {
|
|
module->outstanding_locks[target] = lock_exclusive;
|
|
ret = start_exclusive(module, target);
|
|
} else {
|
|
module->outstanding_locks[target] = lock_shared;
|
|
ret = start_shared(module, target);
|
|
}
|
|
} else {
|
|
module->outstanding_locks[target] = lock_nocheck;
|
|
ret = OMPI_SUCCESS;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_unlock(int target,
|
|
struct ompi_win_t *win)
|
|
{
|
|
ompi_osc_sm_module_t *module =
|
|
(ompi_osc_sm_module_t*) win->w_osc_module;
|
|
int ret;
|
|
|
|
/* ensure all memory operations have completed */
|
|
opal_atomic_mb();
|
|
|
|
if (module->outstanding_locks[target] == lock_nocheck) {
|
|
ret = OMPI_SUCCESS;
|
|
} else if (module->outstanding_locks[target] == lock_exclusive) {
|
|
ret = end_exclusive(module, target);
|
|
module->outstanding_locks[target] = lock_none;
|
|
} else if (module->outstanding_locks[target] == lock_shared) {
|
|
ret = end_shared(module, target);
|
|
module->outstanding_locks[target] = lock_none;
|
|
} else {
|
|
ret = OMPI_ERR_RMA_SYNC;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_lock_all(int assert,
|
|
struct ompi_win_t *win)
|
|
{
|
|
ompi_osc_sm_module_t *module =
|
|
(ompi_osc_sm_module_t*) win->w_osc_module;
|
|
int ret, i, comm_size;
|
|
|
|
comm_size = ompi_comm_size(module->comm);
|
|
for (i = 0 ; i < comm_size ; ++i) {
|
|
ret = ompi_osc_sm_lock(MPI_LOCK_SHARED, i, assert, win);
|
|
if (OMPI_SUCCESS != ret) return ret;
|
|
}
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_unlock_all(struct ompi_win_t *win)
|
|
{
|
|
ompi_osc_sm_module_t *module =
|
|
(ompi_osc_sm_module_t*) win->w_osc_module;
|
|
int ret, i, comm_size;
|
|
|
|
comm_size = ompi_comm_size(module->comm);
|
|
for (i = 0 ; i < comm_size ; ++i) {
|
|
ret = ompi_osc_sm_unlock(i, win);
|
|
if (OMPI_SUCCESS != ret) return ret;
|
|
}
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_sync(struct ompi_win_t *win)
|
|
{
|
|
opal_atomic_mb();
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_flush(int target,
|
|
struct ompi_win_t *win)
|
|
{
|
|
opal_atomic_mb();
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_flush_all(struct ompi_win_t *win)
|
|
{
|
|
opal_atomic_mb();
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_flush_local(int target,
|
|
struct ompi_win_t *win)
|
|
{
|
|
opal_atomic_mb();
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
ompi_osc_sm_flush_local_all(struct ompi_win_t *win)
|
|
{
|
|
opal_atomic_mb();
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|