
can be in both a Post and Start state. Also, the asserts were only correct assuming that we were never in the post and start state at the same time, which was obviously silly. refs trac:303 This commit was SVN r11428. The following Trac tickets were found above: Ticket 303 --> https://svn.open-mpi.org/trac/ompi/ticket/303
179 строки
5.1 KiB
C
179 строки
5.1 KiB
C
/*
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
* University Research and Technology
|
|
* Corporation. All rights reserved.
|
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
|
* of Tennessee Research Foundation. All rights
|
|
* reserved.
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
* University of Stuttgart. All rights reserved.
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
* All rights reserved.
|
|
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#ifndef OMPI_WIN_H
|
|
#define OMPI_WIN_H
|
|
|
|
#include "ompi_config.h"
|
|
#include "mpi.h"
|
|
|
|
#include "opal/class/opal_object.h"
|
|
#include "opal/class/opal_hash_table.h"
|
|
#include "ompi/errhandler/errhandler.h"
|
|
#include "ompi/info/info.h"
|
|
#include "ompi/communicator/communicator.h"
|
|
#include "ompi/group/group.h"
|
|
#include "ompi/mca/osc/osc.h"
|
|
|
|
#if defined(c_plusplus) || defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* flags */
|
|
#define OMPI_WIN_FREED 0x00000001
|
|
#define OMPI_WIN_INVALID 0x00000002
|
|
#define OMPI_WIN_NO_LOCKS 0x00000004
|
|
|
|
/* mode */
|
|
#define OMPI_WIN_ACCESS_EPOCH 0x00000001
|
|
#define OMPI_WIN_EXPOSE_EPOCH 0x00000002
|
|
#define OMPI_WIN_FENCE 0x00000010
|
|
#define OMPI_WIN_POSTED 0x00000020
|
|
#define OMPI_WIN_STARTED 0x00000040
|
|
#define OMPI_WIN_LOCK_ACCESS 0x00000080
|
|
|
|
OMPI_DECLSPEC extern ompi_pointer_array_t ompi_mpi_windows;
|
|
|
|
struct ompi_win_t {
|
|
opal_object_t w_base;
|
|
|
|
opal_mutex_t w_lock;
|
|
|
|
char w_name[MPI_MAX_OBJECT_NAME];
|
|
|
|
/* Group associated with this window. */
|
|
ompi_group_t *w_group;
|
|
|
|
/* Information about the state of the window. */
|
|
uint16_t w_flags;
|
|
|
|
/* Attributes */
|
|
opal_hash_table_t *w_keyhash;
|
|
|
|
/* index in Fortran <-> C translation array */
|
|
int w_f_to_c_index;
|
|
|
|
/* Error handling. This field does not have the "w_" prefix so
|
|
that the OMPI_ERRHDL_* macros can find it, regardless of
|
|
whether it's a comm, window, or file. */
|
|
ompi_errhandler_t *error_handler;
|
|
ompi_errhandler_type_t errhandler_type;
|
|
|
|
/* displacement factor */
|
|
int w_disp_unit;
|
|
|
|
void *w_baseptr;
|
|
long w_size;
|
|
|
|
/** Current epoch / mode (access, expose, lock, etc.). Checked by
|
|
the argument checking code in the MPI layer, set by the OSC
|
|
component. Modified without locking w_lock. */
|
|
volatile uint16_t w_mode;
|
|
|
|
/* one sided interface */
|
|
ompi_osc_base_module_t *w_osc_module;
|
|
};
|
|
typedef struct ompi_win_t ompi_win_t;
|
|
OMPI_DECLSPEC OBJ_CLASS_DECLARATION(ompi_win_t);
|
|
|
|
OMPI_DECLSPEC extern ompi_win_t ompi_mpi_win_null;
|
|
|
|
int ompi_win_init(void);
|
|
int ompi_win_finalize(void);
|
|
|
|
int ompi_win_create(void *base, long size, int disp_unit,
|
|
ompi_communicator_t *comm, ompi_info_t *info,
|
|
ompi_win_t **newwin);
|
|
|
|
int ompi_win_free(ompi_win_t *win);
|
|
|
|
int ompi_win_set_name(ompi_win_t *win, char *win_name);
|
|
int ompi_win_get_name(ompi_win_t *win, char *win_name, int *length);
|
|
|
|
int ompi_win_group(ompi_win_t *win, ompi_group_t **group);
|
|
|
|
/* Note that the defintion of an "invalid" window is closely related
|
|
to the defintion of an "invalid" communicator. See a big comment
|
|
in ompi/communicator/communicator.h about this. */
|
|
static inline int ompi_win_invalid(ompi_win_t *win) {
|
|
if (NULL == win ||
|
|
MPI_WIN_NULL == win ||
|
|
(OMPI_WIN_INVALID & win->w_flags) ||
|
|
(OMPI_WIN_FREED & win->w_flags)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static inline int ompi_win_peer_invalid(ompi_win_t *win, int peer) {
|
|
if (win->w_group->grp_proc_count <= peer) return true;
|
|
return false;
|
|
}
|
|
|
|
static inline int ompi_win_rank(ompi_win_t *win) {
|
|
return win->w_group->grp_my_rank;
|
|
}
|
|
|
|
static inline bool ompi_win_allow_locks(ompi_win_t *win) {
|
|
return (0 == (win->w_flags & OMPI_WIN_NO_LOCKS));
|
|
}
|
|
|
|
static inline int16_t ompi_win_get_mode(ompi_win_t *win) {
|
|
int16_t mode = win->w_mode;
|
|
opal_atomic_rmb();
|
|
return mode;
|
|
}
|
|
|
|
static inline void ompi_win_set_mode(ompi_win_t *win, int16_t mode) {
|
|
win->w_mode = mode;
|
|
opal_atomic_wmb();
|
|
}
|
|
|
|
static inline void ompi_win_append_mode(ompi_win_t *win, int16_t mode) {
|
|
win->w_mode |= mode;
|
|
opal_atomic_wmb();
|
|
}
|
|
|
|
static inline void ompi_win_remove_mode(ompi_win_t *win,
|
|
int16_t mode)
|
|
{
|
|
win->w_mode &= ~mode;
|
|
opal_atomic_wmb();
|
|
}
|
|
|
|
/* already in an access epoch */
|
|
static inline bool ompi_win_access_epoch(ompi_win_t *win) {
|
|
int16_t mode = ompi_win_get_mode(win);
|
|
return (OMPI_WIN_ACCESS_EPOCH & mode);
|
|
}
|
|
|
|
/* we're either already in an access epoch or can easily start one
|
|
(stupid fence rule). Either way, it's ok to be the origin of a
|
|
communication call. */
|
|
static inline bool ompi_win_comm_allowed(ompi_win_t *win) {
|
|
int16_t mode = ompi_win_get_mode(win);
|
|
return (OMPI_WIN_ACCESS_EPOCH & mode || OMPI_WIN_FENCE & mode);
|
|
}
|
|
|
|
#if defined(c_plusplus) || defined(__cplusplus)
|
|
}
|
|
#endif
|
|
#endif
|