#include "pmix_config.h"
#include <stdio.h>
#include <string.h>
#include "pmix_common.h"
#include "src/include/pmix_globals.h"
#include "src/threads/pmix_tsd.h"
#include "src/util/pmix_error.h"
#include "src/util/pmix_name_fns.h"
#include "src/util/pmix_printf.h"
#define PMIX_PRINT_NAME_ARGS_MAX_SIZE 300
#define PMIX_PRINT_NAME_ARG_NUM_BUFS 16
#define PMIX_SCHEMA_DELIMITER_CHAR '.'
#define PMIX_SCHEMA_WILDCARD_CHAR '*'
#define PMIX_SCHEMA_WILDCARD_STRING "*"
#define PMIX_SCHEMA_INVALID_CHAR '$'
#define PMIX_SCHEMA_INVALID_STRING "$"
static bool fns_init = false;
static pmix_tsd_key_t print_args_tsd_key;
char *pmix_print_args_null = "NULL";
typedef struct {
char *buffers[PMIX_PRINT_NAME_ARG_NUM_BUFS];
int cntr;
} pmix_print_args_buffers_t;
static void buffer_cleanup(void *value)
{
int i;
pmix_print_args_buffers_t *ptr;
if (NULL != value) {
ptr = (pmix_print_args_buffers_t *) value;
for (i = 0; i < PMIX_PRINT_NAME_ARG_NUM_BUFS; i++) {
free(ptr->buffers[i]);
}
free(ptr);
}
}
static pmix_print_args_buffers_t *get_print_name_buffer(void)
{
pmix_print_args_buffers_t *ptr;
int ret, i;
if (!fns_init) {
if (PMIX_SUCCESS != (ret = pmix_tsd_key_create(&print_args_tsd_key, buffer_cleanup))) {
PMIX_ERROR_LOG(ret);
return NULL;
}
fns_init = true;
}
ret = pmix_tsd_getspecific(print_args_tsd_key, (void **) &ptr);
if (PMIX_SUCCESS != ret)
return NULL;
if (NULL == ptr) {
ptr = (pmix_print_args_buffers_t *) malloc(sizeof(pmix_print_args_buffers_t));
for (i = 0; i < PMIX_PRINT_NAME_ARG_NUM_BUFS; i++) {
ptr->buffers[i] = (char *) malloc((PMIX_PRINT_NAME_ARGS_MAX_SIZE + 1) * sizeof(char));
}
ptr->cntr = 0;
ret = pmix_tsd_setspecific(print_args_tsd_key, (void *) ptr);
}
return (pmix_print_args_buffers_t *) ptr;
}
static char *print_args(char *ns, pmix_rank_t rnk)
{
pmix_print_args_buffers_t *ptr;
char *rank;
int index;
ptr = get_print_name_buffer();
if (NULL == ptr) {
PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE);
return pmix_print_args_null;
}
if (NULL == ns) {
index = ptr->cntr;
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "[NO-NAME]");
ptr->cntr++;
if (PMIX_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
}
return ptr->buffers[index];
}
rank = pmix_util_print_rank(rnk);
index = ptr->cntr;
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "[%s,%s]", ns, rank);
ptr->cntr++;
if (PMIX_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
}
return ptr->buffers[index];
}
char *pmix_util_print_name_args(const pmix_proc_t *name)
{
if (NULL == name) {
return print_args(NULL, PMIX_RANK_UNDEF);
}
return print_args((char *) name->nspace, name->rank);
}
char *pmix_util_print_pname_args(const pmix_name_t *name)
{
if (NULL == name) {
return print_args(NULL, PMIX_RANK_UNDEF);
}
return print_args((char *) name->nspace, name->rank);
}
char *pmix_util_print_rank(const pmix_rank_t vpid)
{
pmix_print_args_buffers_t *ptr;
int index;
ptr = get_print_name_buffer();
if (NULL == ptr) {
PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE);
return pmix_print_args_null;
}
index = ptr->cntr;
if (PMIX_RANK_UNDEF == vpid) {
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "UNDEF");
} else if (PMIX_RANK_WILDCARD == vpid) {
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "WILDCARD");
} else if (PMIX_RANK_LOCAL_NODE == vpid) {
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "LOCAL_NODE");
} else if (PMIX_RANK_LOCAL_PEERS == vpid) {
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "LOCAL_PEERS");
} else if (PMIX_RANK_INVALID == vpid) {
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "INVALID");
} else {
pmix_snprintf(ptr->buffers[index], PMIX_PRINT_NAME_ARGS_MAX_SIZE, "%ld", (long) vpid);
}
ptr->cntr++;
if (PMIX_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
}
return ptr->buffers[index];
}
int pmix_util_compare_proc(const void *a, const void *b)
{
const pmix_proc_t *proc_a = (pmix_proc_t *)a;
const pmix_proc_t *proc_b = (pmix_proc_t *)b;
int nspace_dif = strncmp(proc_a->nspace, proc_b->nspace, PMIX_MAX_NSLEN);
if (nspace_dif != 0)
return nspace_dif;
return proc_a->rank - proc_b->rank;
}