Enable the PMIx notification callback system. This currently is only supported by the pmix120 component, which is not selected by default. All other components will ignore error registration requests, and thus do not support debugger attach when launched via mpirun. Note that direct launched applications will support such attachment, but may not do so in a scalable fashion.
Fixes ##1225
This commit is contained in:
parent
c18af0d61f
commit
60a7bc2e50
@ -91,7 +91,7 @@ OMPI_DECLSPEC void __opal_attribute_noreturn__
|
||||
#define OMPI_ERROR_LOG ORTE_ERROR_LOG
|
||||
|
||||
/* Init and finalize objects and operations */
|
||||
#define ompi_rte_init(a, b) orte_init(a, b, ORTE_PROC_MPI)
|
||||
OMPI_DECLSPEC int ompi_rte_init(int *pargc, char ***pargv);
|
||||
#define ompi_rte_finalize() orte_finalize()
|
||||
OMPI_DECLSPEC void ompi_rte_wait_for_debugger(void);
|
||||
|
||||
|
@ -52,6 +52,79 @@
|
||||
|
||||
extern ompi_rte_orte_component_t mca_rte_orte_component;
|
||||
|
||||
typedef struct {
|
||||
volatile bool active;
|
||||
int status;
|
||||
int errhandler;
|
||||
} errhandler_t;
|
||||
|
||||
static void register_cbfunc(int status, int errhndler, void *cbdata)
|
||||
{
|
||||
errhandler_t *cd = (errhandler_t*)cbdata;
|
||||
cd->status = status;
|
||||
cd->errhandler = errhndler;
|
||||
cd->active = false;
|
||||
}
|
||||
|
||||
static volatile bool wait_for_release = true;
|
||||
static int errhandler = -1;
|
||||
|
||||
static void notify_cbfunc(int status,
|
||||
opal_list_t *procs,
|
||||
opal_list_t *info,
|
||||
opal_pmix_release_cbfunc_t cbfunc,
|
||||
void *cbdata)
|
||||
{
|
||||
if (NULL != cbfunc) {
|
||||
cbfunc(cbdata);
|
||||
}
|
||||
wait_for_release = false;
|
||||
}
|
||||
|
||||
|
||||
int ompi_rte_init(int *pargc, char ***pargv)
|
||||
{
|
||||
int rc;
|
||||
opal_list_t info;
|
||||
opal_value_t val;
|
||||
errhandler_t cd;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_init(pargc, pargv, ORTE_PROC_MPI))) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!orte_standalone_operation) {
|
||||
/* register to receive any debugger release */
|
||||
OBJ_CONSTRUCT(&info, opal_list_t);
|
||||
OBJ_CONSTRUCT(&val, opal_value_t);
|
||||
val.key = strdup(OPAL_PMIX_ERROR_NAME);
|
||||
val.type = OPAL_INT;
|
||||
val.data.integer = OPAL_ERR_DEBUGGER_RELEASE;
|
||||
opal_list_append(&info, &val.super);
|
||||
cd.status = ORTE_ERROR;
|
||||
cd.errhandler = -1;
|
||||
cd.active = true;
|
||||
|
||||
opal_pmix.register_errhandler(&info, notify_cbfunc, register_cbfunc, &cd);
|
||||
|
||||
/* let the MPI progress engine run while we wait for
|
||||
* registration to complete */
|
||||
OMPI_WAIT_FOR_COMPLETION(cd.active);
|
||||
/* safely deconstruct the list */
|
||||
opal_list_remove_first(&info);
|
||||
OBJ_DESTRUCT(&val);
|
||||
OBJ_DESTRUCT(&info);
|
||||
if (OPAL_SUCCESS != cd.status) {
|
||||
/* ouch - we are doomed */
|
||||
ORTE_ERROR_LOG(cd.status);
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
errhandler = cd.errhandler;
|
||||
}
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
void ompi_rte_abort(int error_code, char *fmt, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
@ -100,10 +173,10 @@ void ompi_rte_abort(int error_code, char *fmt, ...)
|
||||
* attaching debuggers -- see big comment in
|
||||
* orte/tools/orterun/debuggers.c explaining the two scenarios.
|
||||
*/
|
||||
|
||||
void ompi_rte_wait_for_debugger(void)
|
||||
{
|
||||
int debugger;
|
||||
orte_rml_recv_cb_t xfer;
|
||||
|
||||
/* See lengthy comment in orte/tools/orterun/debuggers.c about
|
||||
orte_in_parallel_debugger */
|
||||
@ -117,12 +190,12 @@ void ompi_rte_wait_for_debugger(void)
|
||||
/* if not, just return */
|
||||
return;
|
||||
}
|
||||
|
||||
/* if we are being debugged, then we need to find
|
||||
* the correct plug-ins
|
||||
*/
|
||||
ompi_debugger_setup_dlls();
|
||||
|
||||
/* wait for the debugger to attach */
|
||||
if (orte_standalone_operation) {
|
||||
/* spin until debugger attaches and releases us */
|
||||
while (MPIR_debug_gate == 0) {
|
||||
@ -133,23 +206,9 @@ void ompi_rte_wait_for_debugger(void)
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
/* only the rank=0 proc waits for either a message from the
|
||||
* HNP or for the debugger to attach - everyone else will just
|
||||
* spin in * the grpcomm barrier in ompi_mpi_init until rank=0
|
||||
* joins them.
|
||||
*/
|
||||
if (0 != ORTE_PROC_MY_NAME->vpid) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* VPID 0 waits for a message from the HNP */
|
||||
OBJ_CONSTRUCT(&xfer, orte_rml_recv_cb_t);
|
||||
xfer.active = true;
|
||||
orte_rml.recv_buffer_nb(OMPI_NAME_WILDCARD,
|
||||
ORTE_RML_TAG_DEBUGGER_RELEASE,
|
||||
ORTE_RML_NON_PERSISTENT,
|
||||
orte_rml_recv_callback, &xfer);
|
||||
/* let the MPI progress engine run while we wait */
|
||||
OMPI_WAIT_FOR_COMPLETION(xfer.active);
|
||||
/* now wait for the notification to occur */
|
||||
OMPI_WAIT_FOR_COMPLETION(wait_for_release);
|
||||
/* deregister the errhandler */
|
||||
opal_pmix.deregister_errhandler(errhandler, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,9 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -449,3 +449,12 @@ int opal_dss_compare_jobid(opal_jobid_t *value1,
|
||||
return OPAL_EQUAL;
|
||||
}
|
||||
|
||||
int opal_dss_compare_status(int *value1, int *value2, opal_data_type_t type)
|
||||
{
|
||||
if (*value1 > *value2) return OPAL_VALUE1_GREATER;
|
||||
|
||||
if (*value2 > *value1) return OPAL_VALUE2_GREATER;
|
||||
|
||||
return OPAL_EQUAL;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -61,6 +61,7 @@ int opal_dss_std_copy(void **dest, void *src, opal_data_type_t type)
|
||||
|
||||
case OPAL_INT:
|
||||
case OPAL_UINT:
|
||||
case OPAL_STATUS:
|
||||
datasize = sizeof(int);
|
||||
break;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
|
||||
@ -332,6 +332,9 @@ int opal_dss_pack_jobid(opal_buffer_t *buffer, const void *src,
|
||||
int opal_dss_pack_vpid(opal_buffer_t *buffer, const void *src,
|
||||
int32_t num_vals, opal_data_type_t type);
|
||||
|
||||
int opal_dss_pack_status(opal_buffer_t *buffer, const void *src,
|
||||
int32_t num_vals, opal_data_type_t type);
|
||||
|
||||
/*
|
||||
* Internal unpack functions
|
||||
*/
|
||||
@ -401,6 +404,8 @@ int opal_dss_unpack_jobid(opal_buffer_t *buffer, void *dest,
|
||||
int opal_dss_unpack_vpid(opal_buffer_t *buffer, void *dest,
|
||||
int32_t *num_vals, opal_data_type_t type);
|
||||
|
||||
int opal_dss_unpack_status(opal_buffer_t *buffer, void *dest,
|
||||
int32_t *num_vals, opal_data_type_t type);
|
||||
|
||||
/*
|
||||
* Internal copy functions
|
||||
@ -497,6 +502,8 @@ int opal_dss_compare_jobid(opal_jobid_t *value1,
|
||||
opal_jobid_t *value2,
|
||||
opal_data_type_t type);
|
||||
|
||||
int opal_dss_compare_status(int *value1, int *value2, opal_data_type_t type);
|
||||
|
||||
/*
|
||||
* Internal print functions
|
||||
*/
|
||||
@ -536,6 +543,7 @@ int opal_dss_print_time(char **output, char *prefix, time_t *src, opal_data_type
|
||||
int opal_dss_print_name(char **output, char *prefix, opal_process_name_t *name, opal_data_type_t type);
|
||||
int opal_dss_print_jobid(char **output, char *prefix, opal_process_name_t *src, opal_data_type_t type);
|
||||
int opal_dss_print_vpid(char **output, char *prefix, opal_process_name_t *src, opal_data_type_t type);
|
||||
int opal_dss_print_status(char **output, char *prefix, int *src, opal_data_type_t type);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -611,6 +611,17 @@ int opal_dss_open(void)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
tmp = OPAL_STATUS;
|
||||
if (OPAL_SUCCESS != (rc = opal_dss.register_type(opal_dss_pack_status,
|
||||
opal_dss_unpack_status,
|
||||
(opal_dss_copy_fn_t)opal_dss_std_copy,
|
||||
(opal_dss_compare_fn_t)opal_dss_compare_status,
|
||||
(opal_dss_print_fn_t)opal_dss_print_status,
|
||||
OPAL_DSS_UNSTRUCTURED,
|
||||
"OPAL_STATUS", &tmp))) {
|
||||
return rc;
|
||||
}
|
||||
/* All done */
|
||||
|
||||
opal_dss_initialized = true;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -1240,3 +1240,20 @@ int opal_dss_pack_vpid(opal_buffer_t *buffer, const void *src,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* STATUS
|
||||
*/
|
||||
int opal_dss_pack_status(opal_buffer_t *buffer, const void *src,
|
||||
int32_t num_vals, opal_data_type_t type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Turn around and pack the real type */
|
||||
ret = opal_dss_pack_buffer(buffer, src, num_vals, OPAL_INT);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
OPAL_ERROR_LOG(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -25,6 +25,7 @@
|
||||
#include "opal_stdint.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "opal/util/error.h"
|
||||
#include "opal/dss/dss_internal.h"
|
||||
|
||||
int opal_dss_print(char **output, char *prefix, void *src, opal_data_type_t type)
|
||||
@ -1060,3 +1061,29 @@ int opal_dss_print_vpid(char **output, char *prefix,
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
int opal_dss_print_status(char **output, char *prefix,
|
||||
int *src, opal_data_type_t type)
|
||||
{
|
||||
char *prefx;
|
||||
|
||||
/* deal with NULL prefix */
|
||||
if (NULL == prefix) asprintf(&prefx, " ");
|
||||
else prefx = prefix;
|
||||
|
||||
/* if src is NULL, just print data type and return */
|
||||
if (NULL == src) {
|
||||
asprintf(output, "%sData type: OPAL_STATUS\tValue: NULL pointer", prefx);
|
||||
if (prefx != prefix) {
|
||||
free(prefx);
|
||||
}
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
asprintf(output, "%sData type: OPAL_STATUS\tValue: %s", prefx, opal_strerror(*src));
|
||||
if (prefx != prefix) {
|
||||
free(prefx);
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
@ -13,9 +13,9 @@
|
||||
* Copyright (c) 2007-2011 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -120,6 +120,8 @@ typedef struct {
|
||||
#define OPAL_NAME (opal_data_type_t) 50
|
||||
#define OPAL_JOBID (opal_data_type_t) 51
|
||||
#define OPAL_VPID (opal_data_type_t) 52
|
||||
#define OPAL_STATUS (opal_data_type_t) 53
|
||||
|
||||
/* OPAL Dynamic */
|
||||
#define OPAL_DSS_ID_DYNAMIC (opal_data_type_t) 100
|
||||
|
||||
@ -245,6 +247,7 @@ typedef struct {
|
||||
float fval;
|
||||
double dval;
|
||||
struct timeval tv;
|
||||
int status;
|
||||
opal_process_name_t name;
|
||||
opal_bool_array_t flag_array;
|
||||
opal_uint8_array_t byte_array;
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012-2015 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -1519,3 +1519,20 @@ int opal_dss_unpack_vpid(opal_buffer_t *buffer, void *dest,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* STATUS
|
||||
*/
|
||||
int opal_dss_unpack_status(opal_buffer_t *buffer, void *dest,
|
||||
int32_t *num_vals, opal_data_type_t type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Turn around and unpack the real type */
|
||||
ret = opal_dss_unpack_buffer(buffer, dest, num_vals, OPAL_INT);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
OPAL_ERROR_LOG(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -80,7 +80,8 @@ enum {
|
||||
OPAL_ERR_AUTHENTICATION_FAILED = (OPAL_ERR_BASE - 50),
|
||||
OPAL_ERR_COMM_FAILURE = (OPAL_ERR_BASE - 51),
|
||||
OPAL_ERR_SERVER_NOT_AVAIL = (OPAL_ERR_BASE - 52),
|
||||
OPAL_ERR_IN_PROCESS = (OPAL_ERR_BASE - 53)
|
||||
OPAL_ERR_IN_PROCESS = (OPAL_ERR_BASE - 53),
|
||||
OPAL_ERR_DEBUGGER_RELEASE = (OPAL_ERR_BASE - 54)
|
||||
};
|
||||
|
||||
#define OPAL_ERR_MAX (OPAL_ERR_BASE - 100)
|
||||
|
@ -42,6 +42,7 @@ mca_pmix_pmix112_la_CPPFLAGS = \
|
||||
-I$(srcdir)/pmix/include $(opal_pmix_pmix112_CPPFLAGS)
|
||||
mca_pmix_pmix112_la_LDFLAGS = -module -avoid-version $(opal_pmix_pmix112_LDFLAGS)
|
||||
mca_pmix_pmix112_la_LIBADD = $(opal_pmix_pmix112_LIBS)
|
||||
mca_pmix_pmix112_la_DEPENDENCIES = $(mca_pmix_pmix112_la_LIBADD)
|
||||
|
||||
noinst_LTLIBRARIES = $(component_noinst)
|
||||
libmca_pmix_pmix112_la_SOURCES =$(sources)
|
||||
@ -49,3 +50,4 @@ libmca_pmix_pmix112_la_CFLAGS = $(opal_pmix_pmix112_CFLAGS)
|
||||
libmca_pmix_pmix112_la_CPPFLAGS = -I$(srcdir)/pmix/include $(opal_pmix_pmix112_CPPFLAGS)
|
||||
libmca_pmix_pmix112_la_LDFLAGS = -module -avoid-version $(opal_pmix_pmix112_LDFLAGS)
|
||||
libmca_pmix_pmix112_la_LIBADD = $(opal_pmix_pmix112_LIBS)
|
||||
libmca_pmix_pmix112_la_DEPENDENCIES = $(mca_pmix_pmix112_la_LIBADD)
|
||||
|
@ -431,6 +431,7 @@ int pmix1_server_notify_error(int status,
|
||||
op->cbdata = cbdata;
|
||||
|
||||
rc = pmix1_convert_opalrc(status);
|
||||
opal_output(0, "CALLING NOTIFY ERROR");
|
||||
rc = PMIx_Notify_error(rc, ps, psz, eps, esz,
|
||||
pinfo, sz, opcbfunc, op);
|
||||
if (PMIX_SUCCESS != rc) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
# Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
|
||||
# Copyright (c) 2015 Research Organization for Information Science
|
||||
# and Technology (RIST). All rights reserved.
|
||||
@ -42,6 +42,7 @@ mca_pmix_pmix120_la_CPPFLAGS = \
|
||||
-I$(srcdir)/pmix/include $(opal_pmix_pmix120_CPPFLAGS)
|
||||
mca_pmix_pmix120_la_LDFLAGS = -module -avoid-version $(opal_pmix_pmix120_LDFLAGS)
|
||||
mca_pmix_pmix120_la_LIBADD = $(opal_pmix_pmix120_LIBS)
|
||||
mca_pmix_pmix120_la_DEPENDENCIES = $(mca_pmix_pmix120_la_LIBADD)
|
||||
|
||||
noinst_LTLIBRARIES = $(component_noinst)
|
||||
libmca_pmix_pmix120_la_SOURCES =$(sources)
|
||||
@ -49,3 +50,4 @@ libmca_pmix_pmix120_la_CFLAGS = $(opal_pmix_pmix120_CFLAGS)
|
||||
libmca_pmix_pmix120_la_CPPFLAGS = -I$(srcdir)/pmix/include $(opal_pmix_pmix120_CPPFLAGS)
|
||||
libmca_pmix_pmix120_la_LDFLAGS = -module -avoid-version $(opal_pmix_pmix120_LDFLAGS)
|
||||
libmca_pmix_pmix120_la_LIBADD = $(opal_pmix_pmix120_LIBS)
|
||||
libmca_pmix_pmix120_la_DEPENDENCIES = $(libmca_pmix_pmix120_la_LIBADD)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015 Intel, Inc. All rights reserved
|
||||
* Copyright (c) 2013-2016 Intel, Inc. All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
@ -63,8 +63,18 @@ BEGIN_C_DECLS
|
||||
#define PMIX_MAX_NSLEN 255
|
||||
#define PMIX_MAX_KEYLEN 511
|
||||
|
||||
/* define a *wildcard* value for requests involving rank */
|
||||
#define PMIX_RANK_WILDCARD -1
|
||||
/* define a value for requests for job-level data
|
||||
* where the info itself isn't associated with any
|
||||
* specific rank, or when a request involves
|
||||
* a rank that isn't known - e.g., when someone requests
|
||||
* info thru one of the legacy interfaces where the rank
|
||||
* is typically encoded into the key itself since there is
|
||||
* no rank parameter in the API itself */
|
||||
#define PMIX_RANK_UNDEF INT32_MAX
|
||||
/* define a value to indicate that the user wants the
|
||||
* data for the given key from every rank that posted
|
||||
* that key */
|
||||
#define PMIX_RANK_WILDCARD INT32_MAX-1
|
||||
|
||||
/* define a set of "standard" PMIx attributes that can
|
||||
* be queried. Implementations (and users) are free to extend as
|
||||
@ -163,7 +173,7 @@ BEGIN_C_DECLS
|
||||
|
||||
/* error handler registration and notification info keys */
|
||||
#define PMIX_ERROR_NAME "pmix.errname" // enum pmix_status_t specific error to be notified
|
||||
#define PMIX_ERROR_GROUP_COMM "pmix.errgroup.comm" // bool - set true to get comm errors notification
|
||||
#define PMIX_ERROR_GROUP_COMM "pmix.errgroup.comm" // bool - set true to get comm errors notification
|
||||
#define PMIX_ERROR_GROUP_ABORT "pmix.errgroup.abort" // bool -set true to get abort errors notification
|
||||
#define PMIX_ERROR_GROUP_MIGRATE "pmix.errgroup.migrate" // bool -set true to get migrate errors notification
|
||||
#define PMIX_ERROR_GROUP_RESOURCE "pmix.errgroup.resource" // bool -set true to get resource errors notification
|
||||
@ -199,7 +209,7 @@ BEGIN_C_DECLS
|
||||
|
||||
/**** PMIX ERROR CONSTANTS ****/
|
||||
/* PMIx errors are always negative, with 0 reserved for success */
|
||||
#define PMIX_ERROR_MIN -50 // set equal to number of non-zero entries in enum
|
||||
#define PMIX_ERROR_MIN -52 // set equal to number of non-zero entries in enum
|
||||
|
||||
typedef enum {
|
||||
PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER = PMIX_ERROR_MIN,
|
||||
@ -257,6 +267,8 @@ typedef enum {
|
||||
PMIX_ERR_SILENT,
|
||||
PMIX_ERROR,
|
||||
|
||||
PMIX_ERR_GRP_FOUND,
|
||||
PMIX_ERR_DFLT_FOUND,
|
||||
PMIX_SUCCESS
|
||||
} pmix_status_t;
|
||||
|
||||
@ -288,6 +300,9 @@ typedef enum {
|
||||
PMIX_TIMEVAL,
|
||||
PMIX_TIME,
|
||||
|
||||
PMIX_STATUS, // needs to be tracked separately from integer for those times
|
||||
// when we are embedded and it needs to be converted to the
|
||||
// host error definitions
|
||||
PMIX_HWLOC_TOPO,
|
||||
PMIX_VALUE,
|
||||
PMIX_INFO_ARRAY,
|
||||
@ -411,6 +426,7 @@ typedef struct {
|
||||
float fval;
|
||||
double dval;
|
||||
struct timeval tv;
|
||||
pmix_status_t status;
|
||||
pmix_info_array_t array;
|
||||
pmix_byte_object_t bo;
|
||||
} data;
|
||||
@ -494,6 +510,7 @@ extern void pmix_value_load(pmix_value_t *v, void *data,
|
||||
/**** PMIX INFO STRUCT ****/
|
||||
typedef struct {
|
||||
char key[PMIX_MAX_KEYLEN+1]; // ensure room for the NULL terminator
|
||||
bool required; // defaults to optional (i.e., required=false)
|
||||
pmix_value_t value;
|
||||
} pmix_info_t;
|
||||
|
||||
@ -531,6 +548,10 @@ typedef struct {
|
||||
(void)strncpy((m)->key, (k), PMIX_MAX_KEYLEN); \
|
||||
pmix_value_load(&((m)->value), (v), (t)); \
|
||||
} while(0);
|
||||
#define PMIX_INFO_REQUIRED(m) \
|
||||
(m)->required = true;
|
||||
#define PMIX_INFO_OPTIONAL(m) \
|
||||
(m)->required = false;
|
||||
|
||||
|
||||
/**** PMIX LOOKUP RETURN STRUCT ****/
|
||||
|
@ -9,7 +9,7 @@
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -136,6 +136,10 @@ int pmix_bfrop_std_copy(void **dest, void *src, pmix_data_type_t type)
|
||||
datasize = sizeof(time_t);
|
||||
break;
|
||||
|
||||
case PMIX_STATUS:
|
||||
datasize = sizeof(pmix_status_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
return PMIX_ERR_UNKNOWN_DATA_TYPE;
|
||||
}
|
||||
@ -166,7 +170,7 @@ int pmix_bfrop_copy_string(char **dest, char *src, pmix_data_type_t type)
|
||||
|
||||
return PMIX_SUCCESS;
|
||||
}
|
||||
/* compare function for pmix_value_t*/
|
||||
/* compare function for pmix_value_t */
|
||||
bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1)
|
||||
{
|
||||
bool rc = false;
|
||||
@ -213,6 +217,9 @@ bool pmix_value_cmp(pmix_value_t *p, pmix_value_t *p1)
|
||||
case PMIX_STRING:
|
||||
rc = strcmp(p->data.string, p1->data.string);
|
||||
break;
|
||||
case PMIX_STATUS:
|
||||
rc = (p->data.status == p1->data.status);
|
||||
break;
|
||||
default:
|
||||
pmix_output(0, "COMPARE-PMIX-VALUE: UNSUPPORTED TYPE %d", (int)p->type);
|
||||
}
|
||||
@ -293,6 +300,9 @@ pmix_status_t pmix_value_xfer(pmix_value_t *p, pmix_value_t *src)
|
||||
p->data.tv.tv_sec = src->data.tv.tv_sec;
|
||||
p->data.tv.tv_usec = src->data.tv.tv_usec;
|
||||
break;
|
||||
case PMIX_STATUS:
|
||||
memcpy(&p->data.status, &src->data.status, sizeof(pmix_status_t));
|
||||
break;
|
||||
case PMIX_INFO_ARRAY:
|
||||
p->data.array.size = src->data.array.size;
|
||||
if (0 < src->data.array.size) {
|
||||
@ -343,6 +353,7 @@ int pmix_bfrop_copy_info(pmix_info_t **dest, pmix_info_t *src,
|
||||
{
|
||||
*dest = (pmix_info_t*)malloc(sizeof(pmix_info_t));
|
||||
(void)strncpy((*dest)->key, src->key, PMIX_MAX_KEYLEN);
|
||||
(*dest)->required = src->required;
|
||||
return pmix_value_xfer(&(*dest)->value, &src->value);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -275,6 +275,8 @@ int pmix_bfrop_pack_timeval(pmix_buffer_t *buffer, const void *src,
|
||||
int32_t num_vals, pmix_data_type_t type);
|
||||
int pmix_bfrop_pack_time(pmix_buffer_t *buffer, const void *src,
|
||||
int32_t num_vals, pmix_data_type_t type);
|
||||
int pmix_bfrop_pack_status(pmix_buffer_t *buffer, const void *src,
|
||||
int32_t num_vals, pmix_data_type_t type);
|
||||
|
||||
#if PMIX_HAVE_HWLOC
|
||||
int pmix_bfrop_pack_topo(pmix_buffer_t *buffer, const void *src,
|
||||
@ -337,6 +339,8 @@ int pmix_bfrop_unpack_timeval(pmix_buffer_t *buffer, void *dest,
|
||||
int32_t *num_vals, pmix_data_type_t type);
|
||||
int pmix_bfrop_unpack_time(pmix_buffer_t *buffer, void *dest,
|
||||
int32_t *num_vals, pmix_data_type_t type);
|
||||
int pmix_bfrop_unpack_status(pmix_buffer_t *buffer, void *dest,
|
||||
int32_t *num_vals, pmix_data_type_t type);
|
||||
|
||||
#if PMIX_HAVE_HWLOC
|
||||
int pmix_bfrop_unpack_topo(pmix_buffer_t *buffer, void *dest,
|
||||
@ -427,6 +431,7 @@ int pmix_bfrop_print_double(char **output, char *prefix, double *src, pmix_data_
|
||||
|
||||
int pmix_bfrop_print_timeval(char **output, char *prefix, struct timeval *src, pmix_data_type_t type);
|
||||
int pmix_bfrop_print_time(char **output, char *prefix, time_t *src, pmix_data_type_t type);
|
||||
int pmix_bfrop_print_status(char **output, char *prefix, pmix_status_t *src, pmix_data_type_t type);
|
||||
|
||||
#if PMIX_HAVE_HWLOC
|
||||
int pmix_bfrop_print_topo(char **output, char *prefix,
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -289,6 +289,12 @@ pmix_status_t pmix_bfrop_open(void)
|
||||
pmix_bfrop_std_copy,
|
||||
pmix_bfrop_print_time);
|
||||
|
||||
PMIX_REGISTER_TYPE("PMIX_STATUS", PMIX_STATUS,
|
||||
pmix_bfrop_pack_status,
|
||||
pmix_bfrop_unpack_status,
|
||||
pmix_bfrop_std_copy,
|
||||
pmix_bfrop_print_status);
|
||||
|
||||
#if PMIX_HAVE_HWLOC
|
||||
PMIX_REGISTER_TYPE("PMIX_HWLOC_TOPO", PMIX_HWLOC_TOPO,
|
||||
pmix_bfrop_pack_topo,
|
||||
@ -395,6 +401,8 @@ pmix_status_t pmix_bfrop_close(void)
|
||||
void pmix_value_load(pmix_value_t *v, void *data,
|
||||
pmix_data_type_t type)
|
||||
{
|
||||
pmix_byte_object_t *bo;
|
||||
|
||||
v->type = type;
|
||||
if (NULL == data) {
|
||||
/* just set the fields to zero */
|
||||
@ -457,9 +465,13 @@ void pmix_value_load(pmix_value_t *v, void *data,
|
||||
case PMIX_TIMEVAL:
|
||||
memcpy(&(v->data.tv), data, sizeof(struct timeval));
|
||||
break;
|
||||
case PMIX_STATUS:
|
||||
memcpy(&(v->data.status), data, sizeof(pmix_status_t));
|
||||
break;
|
||||
case PMIX_BYTE_OBJECT:
|
||||
v->data.bo.bytes = data;
|
||||
memcpy(&(v->data.bo.size), data, sizeof(size_t));
|
||||
bo = (pmix_byte_object_t*)data;
|
||||
v->data.bo.bytes = bo->bytes;
|
||||
memcpy(&(v->data.bo.size), &bo->size, sizeof(size_t));
|
||||
break;
|
||||
case PMIX_TIME:
|
||||
case PMIX_HWLOC_TOPO:
|
||||
@ -569,6 +581,10 @@ pmix_status_t pmix_value_unload(pmix_value_t *kv, void **data,
|
||||
memcpy(*data, &(kv->data.tv), sizeof(struct timeval));
|
||||
*sz = sizeof(struct timeval);
|
||||
break;
|
||||
case PMIX_STATUS:
|
||||
memcpy(*data, &(kv->data.status), sizeof(pmix_status_t));
|
||||
*sz = sizeof(pmix_status_t);
|
||||
break;
|
||||
case PMIX_BYTE_OBJECT:
|
||||
if (NULL != kv->data.bo.bytes && 0 < kv->data.bo.size) {
|
||||
*data = kv->data.bo.bytes;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* Copyright (c) 2015 Mellanox Technologies, Inc.
|
||||
@ -406,6 +406,26 @@ int pmix_bfrop_pack_time(pmix_buffer_t *buffer, const void *src,
|
||||
}
|
||||
|
||||
|
||||
/* STATUS */
|
||||
int pmix_bfrop_pack_status(pmix_buffer_t *buffer, const void *src,
|
||||
int32_t num_vals, pmix_data_type_t type)
|
||||
{
|
||||
int ret = PMIX_SUCCESS;
|
||||
int32_t i;
|
||||
pmix_status_t *ssrc = (pmix_status_t *)src;
|
||||
int32_t status;
|
||||
|
||||
for (i = 0; i < num_vals; ++i) {
|
||||
status = (int32_t)ssrc[i];
|
||||
if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int32(buffer, &status, 1, PMIX_INT32))) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return PMIX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* PACK FUNCTIONS FOR GENERIC PMIX TYPES */
|
||||
static int pack_val(pmix_buffer_t *buffer,
|
||||
pmix_value_t *p)
|
||||
@ -503,6 +523,11 @@ static int pack_val(pmix_buffer_t *buffer,
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case PMIX_STATUS:
|
||||
if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.status, 1, PMIX_STATUS))) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case PMIX_INFO_ARRAY:
|
||||
if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.array, 1, PMIX_INFO_ARRAY))) {
|
||||
return ret;
|
||||
@ -563,6 +588,10 @@ int pmix_bfrop_pack_info(pmix_buffer_t *buffer, const void *src,
|
||||
if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_string(buffer, &foo, 1, PMIX_STRING))) {
|
||||
return ret;
|
||||
}
|
||||
/* pack required flag */
|
||||
if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_bool(buffer, &info[i].required, 1, PMIX_BOOL))) {
|
||||
return ret;
|
||||
}
|
||||
/* pack the type */
|
||||
if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_int(buffer, &info[i].value.type, 1, PMIX_INT))) {
|
||||
return ret;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -27,6 +27,7 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "src/util/error.h"
|
||||
#include "src/buffer_ops/internal.h"
|
||||
|
||||
int pmix_bfrop_print(char **output, char *prefix, void *src, pmix_data_type_t type)
|
||||
@ -540,6 +541,32 @@ int pmix_bfrop_print_timeval(char **output, char *prefix,
|
||||
return PMIX_SUCCESS;
|
||||
}
|
||||
|
||||
int pmix_bfrop_print_status(char **output, char *prefix,
|
||||
pmix_status_t *src, pmix_data_type_t type)
|
||||
{
|
||||
char *prefx;
|
||||
|
||||
/* deal with NULL prefix */
|
||||
if (NULL == prefix) asprintf(&prefx, " ");
|
||||
else prefx = prefix;
|
||||
|
||||
/* if src is NULL, just print data type and return */
|
||||
if (NULL == src) {
|
||||
asprintf(output, "%sData type: PMIX_STATUS\tValue: NULL pointer", prefx);
|
||||
if (prefx != prefix) {
|
||||
free(prefx);
|
||||
}
|
||||
return PMIX_SUCCESS;
|
||||
}
|
||||
|
||||
asprintf(output, "%sData type: PMIX_STATUS\tValue: %s", prefx, PMIx_Error_string(*src));
|
||||
if (prefx != prefix) {
|
||||
free(prefx);
|
||||
}
|
||||
|
||||
return PMIX_SUCCESS;
|
||||
}
|
||||
|
||||
/* PRINT FUNCTIONS FOR GENERIC PMIX TYPES */
|
||||
|
||||
/*
|
||||
@ -632,6 +659,10 @@ int pmix_bfrop_print_value(char **output, char *prefix,
|
||||
asprintf(output, "%sPMIX_VALUE: Data type: PMIX_TIMEVAL\tValue: %ld.%06ld", prefx,
|
||||
(long)src->data.tv.tv_sec, (long)src->data.tv.tv_usec);
|
||||
break;
|
||||
case PMIX_STATUS:
|
||||
asprintf(output, "%sPMIX_VALUE: Data type: PMIX_STATUS\tValue: %s", prefx,
|
||||
PMIx_Error_string(src->data.status));
|
||||
break;
|
||||
default:
|
||||
asprintf(output, "%sPMIX_VALUE: Data type: UNKNOWN\tValue: UNPRINTABLE", prefx);
|
||||
break;
|
||||
@ -648,8 +679,8 @@ int pmix_bfrop_print_info(char **output, char *prefix,
|
||||
char *tmp;
|
||||
|
||||
pmix_bfrop_print_value(&tmp, NULL, &src->value, PMIX_VALUE);
|
||||
asprintf(output, "%sKEY: %s %s", prefix, src->key,
|
||||
(NULL == tmp) ? "NULL" : tmp);
|
||||
asprintf(output, "%sKEY: %s REQD: %s %s", prefix, src->key,
|
||||
src->required ? "Y" : "N", (NULL == tmp) ? "PMIX_VALUE: NULL" : tmp);
|
||||
if (NULL != tmp) {
|
||||
free(tmp);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* Copyright (c) 2015 Mellanox Technologies, Inc.
|
||||
@ -500,6 +500,20 @@ int pmix_bfrop_unpack_time(pmix_buffer_t *buffer, void *dest,
|
||||
}
|
||||
|
||||
|
||||
int pmix_bfrop_unpack_status(pmix_buffer_t *buffer, void *dest,
|
||||
int32_t *num_vals, pmix_data_type_t type)
|
||||
{
|
||||
pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack_status * %d\n", (int)*num_vals);
|
||||
/* check to see if there's enough data in buffer */
|
||||
if (pmix_bfrop_too_small(buffer, (*num_vals)*(sizeof(pmix_status_t)))) {
|
||||
return PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER;
|
||||
}
|
||||
|
||||
/* unpack the data */
|
||||
return pmix_bfrop_unpack_int32(buffer, dest, num_vals, PMIX_INT32);
|
||||
}
|
||||
|
||||
|
||||
/* UNPACK FUNCTIONS FOR GENERIC PMIX TYPES */
|
||||
|
||||
/*
|
||||
@ -672,6 +686,11 @@ int pmix_bfrop_unpack_info(pmix_buffer_t *buffer, void *dest,
|
||||
}
|
||||
(void)strncpy(ptr[i].key, tmp, PMIX_MAX_KEYLEN);
|
||||
free(tmp);
|
||||
/* unpack the required flag */
|
||||
m=1;
|
||||
if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_bool(buffer, &ptr[i].required, &m, PMIX_BOOL))) {
|
||||
return ret;
|
||||
}
|
||||
/* unpack value - since the value structure is statically-defined
|
||||
* instead of a pointer in this struct, we directly unpack it to
|
||||
* avoid the malloc */
|
||||
|
@ -10,7 +10,7 @@
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2013-2015 Intel, Inc. All rights reserved
|
||||
# Copyright (c) 2013-2016 Intel, Inc. All rights reserved
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
@ -26,10 +26,14 @@ headers += \
|
||||
src/class/pmix_object.h \
|
||||
src/class/pmix_list.h \
|
||||
src/class/pmix_pointer_array.h \
|
||||
src/class/pmix_hash_table.h
|
||||
src/class/pmix_hash_table.h \
|
||||
src/class/pmix_hotel.h \
|
||||
src/class/pmix_ring_buffer.h
|
||||
|
||||
sources += \
|
||||
src/class/pmix_object.c \
|
||||
src/class/pmix_list.c \
|
||||
src/class/pmix_pointer_array.c \
|
||||
src/class/pmix_hash_table.c
|
||||
src/class/pmix_hash_table.c \
|
||||
src/class/pmix_hotel.c \
|
||||
src/class/pmix_ring_buffer.c
|
||||
|
136
opal/mca/pmix/pmix120/pmix/src/class/pmix_hotel.c
Normal file
136
opal/mca/pmix/pmix120/pmix/src/class/pmix_hotel.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, LLC. All rights reserved
|
||||
* Copyright (c) 2015-2016 Intel, Inc. All rights reserved
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include <private/autogen/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include PMIX_EVENT_HEADER
|
||||
#include "src/class/pmix_hotel.h"
|
||||
|
||||
|
||||
static void local_eviction_callback(int fd, short flags, void *arg)
|
||||
{
|
||||
pmix_hotel_room_eviction_callback_arg_t *eargs =
|
||||
(pmix_hotel_room_eviction_callback_arg_t*) arg;
|
||||
void *occupant = eargs->hotel->rooms[eargs->room_num].occupant;
|
||||
|
||||
/* Remove the occurpant from the room.
|
||||
|
||||
Do not change this logic without also changing the same logic
|
||||
in pmix_hotel_checkout() and
|
||||
pmix_hotel_checkout_and_return_occupant(). */
|
||||
pmix_hotel_t *hotel = eargs->hotel;
|
||||
pmix_hotel_room_t *room = &(hotel->rooms[eargs->room_num]);
|
||||
room->occupant = NULL;
|
||||
hotel->last_unoccupied_room++;
|
||||
assert(hotel->last_unoccupied_room < hotel->num_rooms);
|
||||
hotel->unoccupied_rooms[hotel->last_unoccupied_room] = eargs->room_num;
|
||||
|
||||
/* Invoke the user callback to tell them that they were evicted */
|
||||
hotel->evict_callback_fn(hotel,
|
||||
eargs->room_num,
|
||||
occupant);
|
||||
}
|
||||
|
||||
|
||||
int pmix_hotel_init(pmix_hotel_t *h, int num_rooms,
|
||||
pmix_event_base_t *evbase,
|
||||
uint32_t eviction_timeout,
|
||||
int eviction_event_priority,
|
||||
pmix_hotel_eviction_callback_fn_t evict_callback_fn)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Bozo check */
|
||||
if (num_rooms <= 0 ||
|
||||
NULL == evict_callback_fn) {
|
||||
return PMIX_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
h->num_rooms = num_rooms;
|
||||
h->evbase = evbase;
|
||||
h->eviction_timeout.tv_usec = eviction_timeout % 1000000;
|
||||
h->eviction_timeout.tv_sec = eviction_timeout / 1000000;
|
||||
h->evict_callback_fn = evict_callback_fn;
|
||||
h->rooms = (pmix_hotel_room_t*)malloc(num_rooms * sizeof(pmix_hotel_room_t));
|
||||
if (NULL != evict_callback_fn) {
|
||||
h->eviction_args =
|
||||
(pmix_hotel_room_eviction_callback_arg_t*)malloc(num_rooms * sizeof(pmix_hotel_room_eviction_callback_arg_t));
|
||||
}
|
||||
h->unoccupied_rooms = (int*) malloc(num_rooms * sizeof(int));
|
||||
h->last_unoccupied_room = num_rooms - 1;
|
||||
|
||||
for (i = 0; i < num_rooms; ++i) {
|
||||
/* Mark this room as unoccupied */
|
||||
h->rooms[i].occupant = NULL;
|
||||
|
||||
/* Setup this room in the unoccupied index array */
|
||||
h->unoccupied_rooms[i] = i;
|
||||
|
||||
/* Setup the eviction callback args */
|
||||
h->eviction_args[i].hotel = h;
|
||||
h->eviction_args[i].room_num = i;
|
||||
|
||||
/* Create this room's event (but don't add it) */
|
||||
if (NULL != h->evbase) {
|
||||
event_assign(&(h->rooms[i].eviction_timer_event),
|
||||
h->evbase,
|
||||
-1, 0, local_eviction_callback,
|
||||
&(h->eviction_args[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return PMIX_SUCCESS;
|
||||
}
|
||||
|
||||
static void constructor(pmix_hotel_t *h)
|
||||
{
|
||||
h->num_rooms = 0;
|
||||
h->evbase = NULL;
|
||||
h->eviction_timeout.tv_sec = 0;
|
||||
h->eviction_timeout.tv_usec = 0;
|
||||
h->evict_callback_fn = NULL;
|
||||
h->rooms = NULL;
|
||||
h->eviction_args = NULL;
|
||||
h->unoccupied_rooms = NULL;
|
||||
h->last_unoccupied_room = -1;
|
||||
}
|
||||
|
||||
static void destructor(pmix_hotel_t *h)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Go through all occupied rooms and destroy their events */
|
||||
if (NULL != h->evbase) {
|
||||
for (i = 0; i < h->num_rooms; ++i) {
|
||||
if (NULL != h->rooms[i].occupant) {
|
||||
event_del(&(h->rooms[i].eviction_timer_event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != h->rooms) {
|
||||
free(h->rooms);
|
||||
}
|
||||
if (NULL != h->eviction_args) {
|
||||
free(h->eviction_args);
|
||||
}
|
||||
if (NULL != h->unoccupied_rooms) {
|
||||
free(h->unoccupied_rooms);
|
||||
}
|
||||
}
|
||||
|
||||
PMIX_CLASS_INSTANCE(pmix_hotel_t,
|
||||
pmix_object_t,
|
||||
constructor,
|
||||
destructor);
|
354
opal/mca/pmix/pmix120/pmix/src/class/pmix_hotel.h
Normal file
354
opal/mca/pmix/pmix120/pmix/src/class/pmix_hotel.h
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Los Alamos National Security, LLC. All rights reserved
|
||||
* Copyright (c) 2015-2016 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* This file provides a "hotel" class:
|
||||
*
|
||||
* - A hotel has a fixed number of rooms (i.e., storage slots)
|
||||
* - An arbitrary data pointer can check into an empty room at any time
|
||||
* - The occupant of a room can check out at any time
|
||||
* - Optionally, the occupant of a room can be forcibly evicted at a
|
||||
* given time (i.e., when an pmix timer event expires).
|
||||
* - The hotel has finite occupancy; if you try to checkin a new
|
||||
* occupant and the hotel is already full, it will gracefully fail
|
||||
* to checkin.
|
||||
*
|
||||
* One use case for this class is for ACK-based network retransmission
|
||||
* schemes (NACK-based retransmission schemes probably can use
|
||||
* pmix_ring_buffer).
|
||||
*
|
||||
* For ACK-based retransmission schemes, a hotel might be used
|
||||
* something like this:
|
||||
*
|
||||
* - when a message is sent, check it in to a hotel with a timer
|
||||
* - if an ACK is received, check it out of the hotel (which also cancels
|
||||
* the timer)
|
||||
* - if an ACK isn't received in time, the timer will expire and the
|
||||
* upper layer will get a callback with the message
|
||||
* - if an ACK is received late (i.e., after its timer has expired),
|
||||
* then checkout will gracefully fail
|
||||
*
|
||||
* Note that this class intentionally provides pretty minimal
|
||||
* functionality. It is intended to be used in performance-critical
|
||||
* code paths -- extra functionality would simply add latency.
|
||||
*
|
||||
* There is an pmix_hotel_init() function to create a hotel, but no
|
||||
* corresponding finalize; the destructor will handle all finalization
|
||||
* issues. Note that when a hotel is destroyed, it will delete all
|
||||
* pending events from the event base (i.e., all pending eviction
|
||||
* callbacks); no further eviction callbacks will be invoked.
|
||||
*/
|
||||
|
||||
#ifndef PMIX_HOTEL_H
|
||||
#define PMIX_HOTEL_H
|
||||
|
||||
#include <private/autogen/config.h>
|
||||
#include "private/types.h"
|
||||
#include "private/prefetch.h"
|
||||
#include "pmix/pmix_common.h"
|
||||
#include "src/class/pmix_object.h"
|
||||
#include PMIX_EVENT_HEADER
|
||||
#include <pmix/rename.h>
|
||||
#include "src/util/output.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
struct pmix_hotel_t;
|
||||
|
||||
/* User-supplied function to be invoked when an occupant is evicted. */
|
||||
typedef void (*pmix_hotel_eviction_callback_fn_t)(struct pmix_hotel_t *hotel,
|
||||
int room_num,
|
||||
void *occupant);
|
||||
|
||||
/* Note that this is an internal data structure; it is not part of the
|
||||
public pmix_hotel interface. Public consumers of pmix_hotel
|
||||
shouldn't need to use this struct at all (we only have it here in
|
||||
this .h file because some functions are inlined for speed, and need
|
||||
to get to the internals of this struct).
|
||||
|
||||
The room struct should be as small as possible to be cache
|
||||
friendly. Specifically: it would be great if multiple rooms could
|
||||
fit in a single cache line because we'll always allocate a
|
||||
contiguous set of rooms in an array. */
|
||||
typedef struct {
|
||||
void *occupant;
|
||||
pmix_event_t eviction_timer_event;
|
||||
} pmix_hotel_room_t;
|
||||
|
||||
/* Note that this is an internal data structure; it is not part of the
|
||||
public pmix_hotel interface. Public consumers of pmix_hotel
|
||||
shouldn't need to use this struct at all (we only have it here in
|
||||
this .h file because some functions are inlined for speed, and need
|
||||
to get to the internals of this struct).
|
||||
|
||||
Use a unique struct for holding the arguments for eviction
|
||||
callbacks. We *could* make the to-be-evicted pmix_hotel_room_t
|
||||
instance as the argument, but we don't, for 2 reasons:
|
||||
|
||||
1. We want as many pmix_hotel_room_t's to fit in a cache line as
|
||||
possible (i.e., to be as cache-friendly as possible). The
|
||||
common/fast code path only needs to access the data in the
|
||||
pmix_hotel_room_t (and not the callback argument data).
|
||||
|
||||
2. Evictions will be uncommon, so we don't mind penalizing them a
|
||||
bit by making the data be in a separate cache line.
|
||||
*/
|
||||
typedef struct {
|
||||
struct pmix_hotel_t *hotel;
|
||||
int room_num;
|
||||
} pmix_hotel_room_eviction_callback_arg_t;
|
||||
|
||||
typedef struct pmix_hotel_t {
|
||||
/* make this an object */
|
||||
pmix_object_t super;
|
||||
|
||||