Commit d16830c5 authored by David Goodell's avatar David Goodell
Browse files

[svn-r6980] eliminate the handle obj static initializer, init builtins with code

This is necessary because there is no portable way to statically initialize
mutexes.  Windows doesn't support it, and some older POSIX impls don't either.

No reviewer.
parent c2c93382
......@@ -372,12 +372,6 @@ typedef OPA_int_t MPIU_Handle_ref_count;
#define MPIU_OBJECT_HEADER \
int handle; \
MPIU_Handle_ref_count ref_count/*semicolon intentionally omitted*/
/* For static initialization of structures starting with MPIU_OBJECT_HEADER.
* This should be put inside of curly braces {} at the position corresponding to
* the MPIU_OBJECT_HEADER (should always be first unless you *really* know what
* you are doing) */
#define MPIU_OBJECT_HEADER_INITIALIZER(handle_val_, ref_cnt_val_) \
(handle_val_), MPIU_HANDLE_REF_COUNT_INITIALIZER(ref_cnt_val_)
/* ALL objects have the handle as the first value. */
/* Inactive (unused and stored on the appropriate avail list) objects
......
......@@ -3448,6 +3448,11 @@ int MPIR_Comm_is_node_consecutive( MPID_Comm *);
void MPIR_Free_err_dyncodes( void );
/* random initializers */
int MPIR_Group_init(void);
int MPIR_Comm_init(MPID_Comm *);
/* Collective functions cannot be called from multiple threads. These
are stubs used in the collective communication calls to check for
user error. Currently they are just being macroed out. */
......
......@@ -14,8 +14,9 @@
#endif
/* Preallocated comm objects */
MPID_Comm MPID_Comm_builtin[MPID_COMM_N_BUILTIN] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
MPID_Comm MPID_Comm_direct[MPID_COMM_PREALLOC] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
/* initialized in initthread.c */
MPID_Comm MPID_Comm_builtin[MPID_COMM_N_BUILTIN] = { {0} };
MPID_Comm MPID_Comm_direct[MPID_COMM_PREALLOC] = { {0} };
MPIU_Object_alloc_t MPID_Comm_mem = { 0, 0, 0, 0, MPID_COMM,
sizeof(MPID_Comm), MPID_Comm_direct,
MPID_COMM_PREALLOC};
......@@ -65,14 +66,43 @@ static void MPIR_Comm_dump_context_id(MPIR_Context_id_t context_id, char *out_st
have a similar check when building fault-tolerant versions of MPI).
*/
/* Create a new communicator with a context.
Do *not* initialize the other fields except for the reference count.
See MPIR_Comm_copy for a function to produce a copy of part of a
communicator
*/
/* Zeroes most non-handle fields in a communicator, as well as initializing any
* other special fields, such as a per-object mutex. Also defaults the
* reference count to 1, under the assumption that the caller holds a reference
* to it.
*
* !!! The resulting struct is _not_ ready for communication !!! */
int MPIR_Comm_init(MPID_Comm *comm_p)
{
int mpi_errno = MPI_SUCCESS;
MPIU_Object_set_ref(comm_p, 1);
/* Clear many items (empty means to use the default; some of these
may be overridden within the upper-level communicator initialization) */
comm_p->errhandler = NULL;
comm_p->attributes = NULL;
comm_p->remote_group = NULL;
comm_p->local_group = NULL;
comm_p->coll_fns = NULL;
comm_p->topo_fns = NULL;
comm_p->name[0] = '\0';
comm_p->is_node_aware = 0;
comm_p->node_comm = NULL;
comm_p->node_roots_comm = NULL;
comm_p->intranode_table = NULL;
comm_p->internode_table = NULL;
/* Fields not set include context_id, remote and local size, and
kind, since different communicator construction routines need
different values */
fn_fail:
return mpi_errno;
}
/*
/*
Create a communicator structure and perform basic initialization
(mostly clearing fields and updating the reference count).
*/
......@@ -81,7 +111,7 @@ static void MPIR_Comm_dump_context_id(MPIR_Context_id_t context_id, char *out_st
#undef FCNAME
#define FCNAME "MPIR_Comm_create"
int MPIR_Comm_create( MPID_Comm **newcomm_ptr )
{
{
int mpi_errno = MPI_SUCCESS;
MPID_Comm *newptr;
MPID_MPI_STATE_DECL(MPID_STATE_MPIR_COMM_CREATE);
......@@ -89,35 +119,12 @@ int MPIR_Comm_create( MPID_Comm **newcomm_ptr )
MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_COMM_CREATE);
newptr = (MPID_Comm *)MPIU_Handle_obj_alloc( &MPID_Comm_mem );
/* --BEGIN ERROR HANDLING-- */
if (!newptr) {
mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0 );
goto fn_fail;
}
/* --END ERROR HANDLING-- */
MPIU_ERR_CHKANDJUMP(!newptr, mpi_errno, MPI_ERR_OTHER, "**nomem")
*newcomm_ptr = newptr;
MPIU_Object_set_ref( newptr, 1 );
/* Clear many items (empty means to use the default; some of these
may be overridden within the communicator initialization) */
newptr->errhandler = 0;
newptr->attributes = 0;
newptr->remote_group = 0;
newptr->local_group = 0;
newptr->coll_fns = 0;
newptr->topo_fns = 0;
newptr->name[0] = 0;
newptr->is_node_aware = 0;
newptr->node_comm = NULL;
newptr->node_roots_comm = NULL;
newptr->intranode_table = NULL;
newptr->internode_table = NULL;
/* Fields not set include context_id, remote and local size, and
kind, since different communicator construction routines need
different values */
mpi_errno = MPIR_Comm_init(newptr);
if (mpi_errno) MPIU_ERR_POP(mpi_errno);
/* Insert this new communicator into the list of known communicators.
Make this conditional on debugger support to match the test in
......@@ -148,7 +155,10 @@ int MPIR_Setup_intercomm_localcomm( MPID_Comm *intercomm_ptr )
localcomm_ptr = (MPID_Comm *)MPIU_Handle_obj_alloc( &MPID_Comm_mem );
MPIU_ERR_CHKANDJUMP(!localcomm_ptr,mpi_errno,MPI_ERR_OTHER,"**nomem");
MPIU_Object_set_ref( localcomm_ptr, 1 );
/* get sensible default values for most fields (usually zeros) */
mpi_errno = MPIR_Comm_init(localcomm_ptr);
if (mpi_errno) MPIU_ERR_POP(mpi_errno);
/* use the parent intercomm's recv ctx as the basis for our ctx */
localcomm_ptr->recvcontext_id = MPID_CONTEXT_SET_FIELD(IS_LOCALCOMM, intercomm_ptr->recvcontext_id, 1);
localcomm_ptr->context_id = localcomm_ptr->recvcontext_id;
......@@ -166,33 +176,13 @@ int MPIR_Setup_intercomm_localcomm( MPID_Comm *intercomm_ptr )
localcomm_ptr->local_size = intercomm_ptr->local_size;
localcomm_ptr->rank = intercomm_ptr->rank;
/* More advanced version: if the group is available, dup it by
increasing the reference count */
localcomm_ptr->local_group = 0;
localcomm_ptr->remote_group = 0;
/* This is an internal communicator, so ignore */
localcomm_ptr->errhandler = 0;
/* FIXME : No local functions for the collectives */
localcomm_ptr->coll_fns = 0;
/* TODO More advanced version: if the group is available, dup it by
increasing the reference count instead of recreating it later */
/* FIXME : No coll_fns functions for the collectives */
/* FIXME : No local functions for the topology routines */
localcomm_ptr->topo_fns = 0;
/* We do *not* inherit any name */
localcomm_ptr->name[0] = 0;
localcomm_ptr->attributes = 0;
intercomm_ptr->local_comm = localcomm_ptr;
localcomm_ptr->is_node_aware = 0;
localcomm_ptr->node_comm = NULL;
localcomm_ptr->node_roots_comm = NULL;
localcomm_ptr->intranode_table = NULL;
localcomm_ptr->internode_table = NULL;
/* sets up the SMP-aware sub-communicators and tables */
mpi_errno = MPIR_Comm_commit(localcomm_ptr);
if (mpi_errno) MPIU_ERR_POP(mpi_errno);
......
......@@ -116,14 +116,9 @@ static int checkForUserErrcode( int );
#endif
/* Preallocated errorhandler objects */
MPID_Errhandler MPID_Errhandler_builtin[3] = {
{ MPIU_OBJECT_HEADER_INITIALIZER(MPI_ERRORS_ARE_FATAL, 0), },
{ MPIU_OBJECT_HEADER_INITIALIZER(MPI_ERRORS_RETURN, 0), },
{ MPIU_OBJECT_HEADER_INITIALIZER(MPIR_ERRORS_THROW_EXCEPTIONS, 0) },
};
MPID_Errhandler MPID_Errhandler_builtin[3] = { {0} };
MPID_Errhandler MPID_Errhandler_direct[MPID_ERRHANDLER_PREALLOC] =
{ { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
{ {0} };
MPIU_Object_alloc_t MPID_Errhandler_mem = { 0, 0, 0, 0, MPID_ERRHANDLER,
sizeof(MPID_Errhandler),
MPID_Errhandler_direct,
......@@ -413,6 +408,12 @@ int MPIR_Err_return_win( MPID_Win *win_ptr, const char fcname[], int errcode )
void MPIR_Err_init( void )
{
/* these are "stub" objects, so the other fields (which are statically
* initialized to zero) don't really matter */
MPID_Errhandler_builtin[0].handle = MPI_ERRORS_ARE_FATAL;
MPID_Errhandler_builtin[1].handle = MPI_ERRORS_RETURN;
MPID_Errhandler_builtin[2].handle = MPIR_ERRORS_THROW_EXCEPTIONS;
# if MPICH_ERROR_MSG_LEVEL >= MPICH_ERROR_MSG_ALL
MPIR_Err_stack_init();
# endif
......
......@@ -12,13 +12,29 @@
#endif
/* Preallocated group objects */
MPID_Group MPID_Group_builtin[MPID_GROUP_N_BUILTIN] = {
{ MPIU_OBJECT_HEADER_INITIALIZER(MPI_GROUP_EMPTY, 1), 0, MPI_UNDEFINED, -1, 0, } };
MPID_Group MPID_Group_direct[MPID_GROUP_PREALLOC] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
MPID_Group MPID_Group_builtin[MPID_GROUP_N_BUILTIN] = { {0} };
MPID_Group MPID_Group_direct[MPID_GROUP_PREALLOC] = { {0} };
MPIU_Object_alloc_t MPID_Group_mem = { 0, 0, 0, 0, MPID_GROUP,
sizeof(MPID_Group), MPID_Group_direct,
MPID_GROUP_PREALLOC};
int MPIR_Group_init(void)
{
int mpi_errno = MPI_SUCCESS;
MPIU_Assert(MPID_GROUP_N_BUILTIN == 1); /* update this func if this ever triggers */
MPID_Group_builtin[0].handle = MPI_GROUP_EMPTY;
MPIU_Object_set_ref(&MPID_Group_builtin[0], 1);
MPID_Group_builtin[0].size = 0;
MPID_Group_builtin[0].rank = MPI_UNDEFINED;
MPID_Group_builtin[0].idx_of_first_lpid = -1;
MPID_Group_builtin[0].lrank_to_lpid = NULL;
/* TODO hook for device here? */
return mpi_errno;
}
int MPIR_Group_release(MPID_Group *group_ptr)
{
......
......@@ -312,54 +312,34 @@ int MPIR_Init_thread(int * argc, char ***argv, int required, int * provided)
intially NULL and will be allocated by the device if the process group
was started using one of the MPI_Comm_spawn functions. */
MPIR_Process.comm_world = MPID_Comm_builtin + 0;
MPIR_Comm_init(MPIR_Process.comm_world);
MPIR_Process.comm_world->handle = MPI_COMM_WORLD;
MPIU_Object_set_ref( MPIR_Process.comm_world, 1 );
MPIR_Process.comm_world->context_id = 0 << MPID_CONTEXT_PREFIX_SHIFT;
MPIR_Process.comm_world->recvcontext_id = 0 << MPID_CONTEXT_PREFIX_SHIFT;
MPIR_Process.comm_world->attributes = NULL;
MPIR_Process.comm_world->local_group = NULL;
MPIR_Process.comm_world->remote_group = NULL;
MPIR_Process.comm_world->comm_kind = MPID_INTRACOMM;
/* This initialization of the comm name could be done only when
comm_get_name is called */
MPIU_Strncpy(MPIR_Process.comm_world->name, "MPI_COMM_WORLD",
MPI_MAX_OBJECT_NAME);
MPIR_Process.comm_world->errhandler = NULL; /* XXX */
MPIR_Process.comm_world->coll_fns = NULL; /* XXX */
MPIR_Process.comm_world->topo_fns = NULL; /* XXX */
MPIR_Process.comm_self = MPID_Comm_builtin + 1;
MPIR_Comm_init(MPIR_Process.comm_self);
MPIR_Process.comm_self->handle = MPI_COMM_SELF;
MPIU_Object_set_ref( MPIR_Process.comm_self, 1 );
MPIR_Process.comm_self->context_id = 1 << MPID_CONTEXT_PREFIX_SHIFT;
MPIR_Process.comm_self->recvcontext_id = 1 << MPID_CONTEXT_PREFIX_SHIFT;
MPIR_Process.comm_self->attributes = NULL;
MPIR_Process.comm_self->local_group = NULL;
MPIR_Process.comm_self->remote_group = NULL;
MPIR_Process.comm_self->comm_kind = MPID_INTRACOMM;
MPIU_Strncpy(MPIR_Process.comm_self->name, "MPI_COMM_SELF",
MPI_MAX_OBJECT_NAME);
MPIR_Process.comm_self->errhandler = NULL; /* XXX */
MPIR_Process.comm_self->coll_fns = NULL; /* XXX */
MPIR_Process.comm_self->topo_fns = NULL; /* XXX */
#ifdef MPID_NEEDS_ICOMM_WORLD
MPIR_Process.icomm_world = MPID_Comm_builtin + 2;
MPIR_Comm_init(MPIR_Process.icomm_world);
MPIR_Process.icomm_world->handle = MPIR_ICOMM_WORLD;
MPIU_Object_set_ref( MPIR_Process.icomm_world, 1 );
MPIR_Process.icomm_world->context_id = 2 << MPID_CONTEXT_PREFIX_SHIFT;
MPIR_Process.icomm_world->recvcontext_id= 2 << MPID_CONTEXT_PREFIX_SHIFT;
MPIR_Process.icomm_world->attributes = NULL;
MPIR_Process.icomm_world->local_group = NULL;
MPIR_Process.icomm_world->remote_group = NULL;
MPIR_Process.icomm_world->comm_kind = MPID_INTRACOMM;
/* This initialization of the comm name could be done only when
comm_get_name is called */
MPIU_Strncpy(MPIR_Process.icomm_world->name, "MPI_ICOMM_WORLD",
MPI_MAX_OBJECT_NAME);
MPIR_Process.icomm_world->errhandler = NULL; /* XXX */
MPIR_Process.icomm_world->coll_fns = NULL; /* XXX */
MPIR_Process.icomm_world->topo_fns = NULL; /* XXX */
/* Note that these communicators are not ready for use - MPID_Init
will setup self and world, and icomm_world if it desires it. */
......@@ -379,6 +359,7 @@ int MPIR_Init_thread(int * argc, char ***argv, int required, int * provided)
MPIR_Err_init();
#endif
MPIR_Datatype_init();
MPIR_Group_init();
MPIR_Nest_init();
/* MPIU_Timer_pre_init(); */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment