Okay, let's see if the system gets rid of the old registry files this time. Also added new location to configure.ac, and picked up a change to the sys_info header.
This commit was SVN r1239.
Этот коммит содержится в:
родитель
bf86e88d5f
Коммит
4c28cb8b3d
@ -814,6 +814,7 @@ AC_CONFIG_FILES([
|
|||||||
src/mca/pml/base/Makefile
|
src/mca/pml/base/Makefile
|
||||||
src/mca/ptl/Makefile
|
src/mca/ptl/Makefile
|
||||||
src/mca/ptl/base/Makefile
|
src/mca/ptl/base/Makefile
|
||||||
|
src/mca/gpr/Makefile
|
||||||
|
|
||||||
src/mpi/Makefile
|
src/mpi/Makefile
|
||||||
src/mpi/c/Makefile
|
src/mpi/c/Makefile
|
||||||
@ -829,7 +830,6 @@ AC_CONFIG_FILES([
|
|||||||
src/tools/wrappers/Makefile
|
src/tools/wrappers/Makefile
|
||||||
|
|
||||||
src/rte/universe/Makefile
|
src/rte/universe/Makefile
|
||||||
src/rte/universe/registry/Makefile
|
|
||||||
|
|
||||||
test/Makefile
|
test/Makefile
|
||||||
test/support/Makefile
|
test/support/Makefile
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
# -*- makefile -*-
|
|
||||||
#
|
|
||||||
# $HEADER$
|
|
||||||
#
|
|
||||||
|
|
||||||
include $(top_srcdir)/config/Makefile.options
|
|
||||||
|
|
||||||
AM_CPPFLAGS = \
|
|
||||||
-DOMPI_PREFIX="\"$(prefix)\"" \
|
|
||||||
-DOMPI_BINDIR="\"$(bindir)\"" \
|
|
||||||
-DOMPI_LIBDIR="\"$(libdir)\"" \
|
|
||||||
-DOMPI_INCDIR="\"$(includedir)\"" \
|
|
||||||
-DOMPI_PKGLIBDIR="\"$(pkglibdir)\"" \
|
|
||||||
-DOMPI_SYSCONFDIR="\"$(sysconfdir)\"" \
|
|
||||||
-DOMPI_CONFIGURE_USER="\"@OMPI_CONFIGURE_USER@\"" \
|
|
||||||
-DOMPI_CONFIGURE_HOST="\"@OMPI_CONFIGURE_HOST@\"" \
|
|
||||||
-DOMPI_CONFIGURE_DATE="\"@OMPI_CONFIGURE_DATE@\""
|
|
||||||
|
|
||||||
libs = $(top_builddir)/src/libmpi.la
|
|
||||||
|
|
||||||
bin_PROGRAMS = \
|
|
||||||
registry
|
|
||||||
|
|
||||||
registry_SOURCES = \
|
|
||||||
registry.h \
|
|
||||||
registry.c
|
|
||||||
|
|
||||||
registry_LDADD = \
|
|
||||||
$(libs) \
|
|
||||||
$(LIBMPI_EXTRA_LIBS) \
|
|
||||||
$(LIBOMPI_EXTRA_LIBS)
|
|
||||||
|
|
||||||
registry__DFLAGS = $(LIBMPI_EXTRA_LDFLAGS) $(LIBOMPI_EXTRA_LDFLAGS)
|
|
||||||
registry_DEPENDENCIES = $(libs) \
|
|
||||||
$(registry_LDADD)
|
|
||||||
|
|
||||||
clean-local:
|
|
||||||
test -z "$(OMPI_CXX_TEMPLATE_REPOSITORY)" || $(RM) -rf $(OMPI_CXX_TEMPLATE_REPOSITORY)
|
|
@ -1,737 +0,0 @@
|
|||||||
/*
|
|
||||||
* $HEADER$
|
|
||||||
*/
|
|
||||||
/** @file:
|
|
||||||
*
|
|
||||||
* The Open MPI general purpose registry - implementation.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* includes
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
|
|
||||||
#include "ompi_config.h"
|
|
||||||
#include "include/constants.h"
|
|
||||||
#include "rte/universe/registry/registry.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* globals
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct ompi_registry_t {
|
|
||||||
ompi_list_t registry;
|
|
||||||
ompi_list_t segment_dict;
|
|
||||||
unsigned long int lastkey;
|
|
||||||
ompi_list_t freekeys;
|
|
||||||
};
|
|
||||||
typedef struct ompi_registry_t ompi_registry_t;
|
|
||||||
|
|
||||||
ompi_registry_t ompi_registry;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* local type definitions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Dictionary of token-key pairs.
|
|
||||||
* This structure is used to create a linked list of token-key pairs. All calls to
|
|
||||||
* registry functions pass character string tokens for programming clarity - the ompi_keytable
|
|
||||||
* structure is used to translate those strings into an integer key value, thus allowing
|
|
||||||
* for faster searches of the registry. This structure is also used to return token-key pairs
|
|
||||||
* from the dictionary in response to an ompi_registry_index() call.
|
|
||||||
*/
|
|
||||||
struct ompi_keytable_t {
|
|
||||||
ompi_list_item_t item; /**< Allows this item to be placed on a list */
|
|
||||||
char *token; /**< Char string that defines the key */
|
|
||||||
unsigned long int key; /**< Numerical value assigned by registry to represent token string */
|
|
||||||
};
|
|
||||||
typedef struct ompi_keytable_t ompi_keytable_t;
|
|
||||||
|
|
||||||
/* constructor - used to initialize state of keytable instance */
|
|
||||||
static void ompi_keytable_construct(ompi_keytable_t* keytable)
|
|
||||||
{
|
|
||||||
keytable->token = NULL;
|
|
||||||
keytable->key = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destructor - used to free any resources held by instance */
|
|
||||||
static void ompi_keytable_destructor(ompi_keytable_t* keytable)
|
|
||||||
{
|
|
||||||
if (NULL != keytable->token) {
|
|
||||||
free(keytable->token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define instance of ompi_class_t */
|
|
||||||
OBJ_CLASS_INSTANCE(
|
|
||||||
ompi_keytable_t, /* type name */
|
|
||||||
ompi_list_item_t, /* parent "class" name */
|
|
||||||
ompi_keytable_construct, /* constructor */
|
|
||||||
ompi_keytable_destructor); /* destructor */
|
|
||||||
|
|
||||||
/** List of keys that describe a stored object.
|
|
||||||
* Each object stored in the registry may have as many keys describing it as the
|
|
||||||
* creator desires. This structure is used to create a linked list of keys
|
|
||||||
* associated with each object.
|
|
||||||
*/
|
|
||||||
struct ompi_keylist_t {
|
|
||||||
ompi_list_item_t item; /**< Allows this item to be placed on a list */
|
|
||||||
unsigned long int key; /**< Numerical key that defines stored object */
|
|
||||||
};
|
|
||||||
typedef struct ompi_keylist_t ompi_keylist_t;
|
|
||||||
|
|
||||||
/* constructor - used to initialize state of keytable instance */
|
|
||||||
static void ompi_keylist_construct(ompi_keylist_t* keylist)
|
|
||||||
{
|
|
||||||
keylist->key = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destructor - used to free any resources held by instance */
|
|
||||||
static void ompi_keylist_destructor(ompi_keylist_t* keylist)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define instance of ompi_class_t */
|
|
||||||
OBJ_CLASS_INSTANCE(
|
|
||||||
ompi_keylist_t, /* type name */
|
|
||||||
ompi_list_item_t, /* parent "class" name */
|
|
||||||
ompi_keylist_construct, /* constructor */
|
|
||||||
ompi_keylist_destructor); /* destructor */
|
|
||||||
|
|
||||||
|
|
||||||
/** List of subscribers to a stored object.
|
|
||||||
* Each object can have an arbitrary number of subscribers desiring notification
|
|
||||||
* upon specified actions being performed against the object. This structure is
|
|
||||||
* used to create a linked list of subscribers for objects.
|
|
||||||
*/
|
|
||||||
struct ompi_subscribe_list_t {
|
|
||||||
ompi_list_item_t item; /**< Allows this item to be placed on a list */
|
|
||||||
unsigned long int id; /**< ID of the subscriber */
|
|
||||||
uint8_t action; /**< Bit-mask of actions that trigger notification */
|
|
||||||
};
|
|
||||||
typedef struct ompi_subscribe_list_t ompi_subscribe_list_t;
|
|
||||||
|
|
||||||
/* constructor - used to initialize state of keytable instance */
|
|
||||||
static void ompi_subscribe_list_construct(ompi_subscribe_list_t* subscriber)
|
|
||||||
{
|
|
||||||
subscriber->id = 0;
|
|
||||||
subscriber->action = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destructor - used to free any resources held by instance */
|
|
||||||
static void ompi_subscribe_list_destructor(ompi_subscribe_list_t* subscriber)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define instance of ompi_class_t */
|
|
||||||
OBJ_CLASS_INSTANCE(
|
|
||||||
ompi_subscribe_list_t, /* type name */
|
|
||||||
ompi_list_item_t, /* parent "class" name */
|
|
||||||
ompi_subscribe_list_construct, /* constructor */
|
|
||||||
ompi_subscribe_list_destructor); /* destructor */
|
|
||||||
|
|
||||||
|
|
||||||
/** List of replicas that hold a stored object.
|
|
||||||
* Each object can have an arbitrary number of replicas that hold a copy
|
|
||||||
* of the object. The GPR requires that each object be replicated in at least
|
|
||||||
* two locations. This structure is used to create a linked list of
|
|
||||||
* replicas for the object.
|
|
||||||
*/
|
|
||||||
struct ompi_replica_list_t {
|
|
||||||
ompi_list_item_t item; /**< Allows this item to be placed on a list */
|
|
||||||
char *name; /**< Name of the replica */
|
|
||||||
};
|
|
||||||
typedef struct ompi_subscribe_list_t ompi_subscribe_list_t;
|
|
||||||
|
|
||||||
/* constructor - used to initialize state of keytable instance */
|
|
||||||
static void ompi_replica_list_construct(ompi_replica_list_t* replica)
|
|
||||||
{
|
|
||||||
replica->name = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destructor - used to free any resources held by instance */
|
|
||||||
static void ompi_replica_list_destructor(ompi_replica_list_t* replica)
|
|
||||||
{
|
|
||||||
if (NULL != replica->name) {
|
|
||||||
free(replica->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define instance of ompi_class_t */
|
|
||||||
OBJ_CLASS_INSTANCE(
|
|
||||||
ompi_replica_list_t, /* type name */
|
|
||||||
ompi_list_item_t, /* parent "class" name */
|
|
||||||
ompi_replica_list_construct, /* constructor */
|
|
||||||
ompi_replica_list_destructor); /* destructor */
|
|
||||||
|
|
||||||
/** Write invalidate structure.
|
|
||||||
* The structure used to indicate that an object has been updated somewhere else in the GPR.
|
|
||||||
* The structure contains a flag indicating that the locally stored copy of the object
|
|
||||||
* is no longer valid, a time tag indicating the time of the last known modification
|
|
||||||
* of the object within the global registry, and the replica holding the last known
|
|
||||||
* up-to-date version of the object.
|
|
||||||
*/
|
|
||||||
struct ompi_write_invalidate_t {
|
|
||||||
bool invalidate;
|
|
||||||
time_t last_mod;
|
|
||||||
char *replica;
|
|
||||||
};
|
|
||||||
typedef struct ompi_write_invalidate_t ompi_write_invalidate_t;
|
|
||||||
|
|
||||||
|
|
||||||
/** The core registry structure.
|
|
||||||
* Each segment of the registry contains a linked list of registry entries. This structure
|
|
||||||
* represents a link in that list. The structure contains a linked list of the keys that
|
|
||||||
* define this particular object, the size of the object, a pointer to the object, and a linked
|
|
||||||
* list of subscribers to this object. Objects are stored as unsigned bytes - knowledge of any
|
|
||||||
* structure within the objects is the responsibility of the calling functions. The repository
|
|
||||||
* has no knowledge of what is in the structure, nor any way of determining such structure.
|
|
||||||
*
|
|
||||||
* At this time, no security is provided on an object-level basis. Thus, all requests for an
|
|
||||||
* object are automatically granted. This may be changed at some future time by adding an
|
|
||||||
* "authorization" linked list of ID's and their access rights to this structure.
|
|
||||||
*/
|
|
||||||
struct ompi_registry_core_t {
|
|
||||||
ompi_list_item_t item; /**< Allows this item to be placed on a list */
|
|
||||||
ompi_list_t keys; /**< Linked list of keys that define stored object */
|
|
||||||
int object_size; /**< Size of stored object, in bytes */
|
|
||||||
uint8_t *object; /**< Pointer to stored object */
|
|
||||||
ompi_list_t subscriber; /**< Linked list of subscribers to this object */
|
|
||||||
ompi_list_t replicas; /**< Linked list of replicas that also contain this object */
|
|
||||||
ompi_write_invalidate_t write_invalidate; /**< Structure containing write invalidate info */
|
|
||||||
};
|
|
||||||
typedef struct ompi_registry_core_t ompi_registry_core_t;
|
|
||||||
|
|
||||||
/* constructor - used to initialize state of keytable instance */
|
|
||||||
static void ompi_registry_core_construct(ompi_registry_core_t* reg)
|
|
||||||
{
|
|
||||||
reg->object = NULL;
|
|
||||||
reg->object_size = 0;
|
|
||||||
OBJ_CONSTRUCT(®->subscriber, ompi_list_t);
|
|
||||||
OBJ_CONSTRUCT(®->keys, ompi_list_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destructor - used to free any resources held by instance */
|
|
||||||
static void ompi_registry_core_destructor(ompi_registry_core_t* reg)
|
|
||||||
{
|
|
||||||
if (NULL != reg->object) {
|
|
||||||
free(reg->object);
|
|
||||||
}
|
|
||||||
OBJ_DESTRUCT(®->subscriber);
|
|
||||||
OBJ_DESTRUCT(®->keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define instance of ompi_class_t */
|
|
||||||
OBJ_CLASS_INSTANCE(
|
|
||||||
ompi_registry_core_t, /* type name */
|
|
||||||
ompi_list_item_t, /* parent "class" name */
|
|
||||||
ompi_registry_core_construct, /* constructor */
|
|
||||||
ompi_registry_core_destructor); /* destructor */
|
|
||||||
|
|
||||||
|
|
||||||
/** Registry segment definition.
|
|
||||||
* The registry is subdivided into segments, each defining a unique domain. The "universe" segment
|
|
||||||
* is automatically created to allow the exchange of information supporting universe-level functions.
|
|
||||||
* Similarly, a segment is automatically created for each MPI CommWorld within the universe - the
|
|
||||||
* name for that segment is stored in each CommWorld's ompi_system_info structure so program
|
|
||||||
* elements within that CommWorld can access it. The segment structure serves as the "head" of a linked
|
|
||||||
* list of registry elements for that segment. Each segment also holds its own token-key dictionary
|
|
||||||
* to avoid naming conflicts between tokens from CommWorlds sharing a given universe.
|
|
||||||
*/
|
|
||||||
struct ompi_registry_segment_t {
|
|
||||||
ompi_list_item_t item; /**< Allows this item to be placed on a list */
|
|
||||||
unsigned long int segment; /**< ID of registry segment */
|
|
||||||
unsigned long int lastkey; /**< Highest key value used */
|
|
||||||
ompi_list_t reg_list; /**< Linked list of stored objects within this segment */
|
|
||||||
ompi_list_t keytable; /**< Token-key dictionary for this segment */
|
|
||||||
ompi_list_t freekeys; /**< List of keys that have been made available */
|
|
||||||
};
|
|
||||||
typedef struct ompi_registry_segment_t ompi_registry_segment_t;
|
|
||||||
|
|
||||||
/* constructor - used to initialize state of segment instance */
|
|
||||||
static void ompi_registry_segment_construct(ompi_registry_segment_t* seg)
|
|
||||||
{
|
|
||||||
seg->segment = 0;
|
|
||||||
seg->lastkey = 0;
|
|
||||||
OBJ_CONSTRUCT(&seg->reg_list, ompi_list_t);
|
|
||||||
OBJ_CONSTRUCT(&seg->keytable, ompi_list_t);
|
|
||||||
OBJ_CONSTRUCT(&seg->freekeys, ompi_list_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destructor - used to free any resources held by instance */
|
|
||||||
static void ompi_registry_segment_destructor(ompi_registry_segment_t* seg)
|
|
||||||
{
|
|
||||||
OBJ_DESTRUCT(&seg->reg_list);
|
|
||||||
OBJ_DESTRUCT(&seg->keytable);
|
|
||||||
OBJ_DESTRUCT(&seg->freekeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define instance of ompi_class_t */
|
|
||||||
OBJ_CLASS_INSTANCE(
|
|
||||||
ompi_registry_segment_t, /* type name */
|
|
||||||
ompi_list_item_t, /* parent "class" name */
|
|
||||||
ompi_registry_segment_construct, /* constructor */
|
|
||||||
ompi_registry_segment_destructor); /* destructor */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* internal function prototypes
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Retrieve a registry key value for a given token string.
|
|
||||||
* The ompi_registry_getkey() function is used to translate a token string for a particular
|
|
||||||
* segment of the registry into its associated (integer) key value.
|
|
||||||
*
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry being queried.
|
|
||||||
* @param token Pointer to a character string containing the token to be translated. If token=NULL,
|
|
||||||
* the function returns the key value corresponding to the specified segment itself.
|
|
||||||
*
|
|
||||||
* @retval key Unsigned long integer value corresponding to the specified token within the specified segment.
|
|
||||||
* @retval -1 Indicates that the segment and/or token could not be found.
|
|
||||||
*/
|
|
||||||
unsigned long int ompi_registry_getkey(char *segment, char *token);
|
|
||||||
|
|
||||||
/** Add a token to a segment's dictionary.
|
|
||||||
* The ompi_registry_definekey() function allows the addition of a new definition to
|
|
||||||
* the registry's token-key dictionaries. The specified token is assigned an integer
|
|
||||||
* value within the specified segment, and the entry is added to the segment's token-key
|
|
||||||
* dictionary.
|
|
||||||
*
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry being queried.
|
|
||||||
* @param token Pointer to a character string containing the token to be defined. If token=NULL,
|
|
||||||
* the function adds the token to the segment dictionary, thus defining a new segment name.
|
|
||||||
*
|
|
||||||
* @retval key Unsigned long integer value corresponding to the specified token within the specified segment.
|
|
||||||
* @retval -1 Indicates that the entry could not be created.
|
|
||||||
*/
|
|
||||||
unsigned long int ompi_registry_definekey(char *segment, char *token);
|
|
||||||
|
|
||||||
/** Delete a token from a segment's dictionary.
|
|
||||||
* The ompi_registry_deletekey() function allows the removal of a definition from the
|
|
||||||
* registry's token-key dictionaries. This should be used with caution! Deletion of
|
|
||||||
* a token-key pair causes the registry to search through all entries within that segment
|
|
||||||
* for objects that include the specified token-key pair in their description. The reference
|
|
||||||
* is subsequently removed, and any object for which this was the SOLE key will also
|
|
||||||
* be removed from the registry!
|
|
||||||
*
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry.
|
|
||||||
* @param token Pointer to a character string containing the token to be deleted. If token=NULL,
|
|
||||||
* the function deletes the specified segment name from the segment dictionary.
|
|
||||||
*
|
|
||||||
* @retval OMPI_SUCCESS Indicating that the operation was successful.
|
|
||||||
* @retval OMPI_ERROR Indicates that the operation failed - most likely caused by specifying
|
|
||||||
* a token that did not exist within the specified segment, or a non-existent segment.
|
|
||||||
*/
|
|
||||||
int ompi_registry_deletekey(char *segment, char *token);
|
|
||||||
|
|
||||||
ompi_registry_segment_t *ompi_registry_findseg(char *segment);
|
|
||||||
|
|
||||||
ompi_keytable_t *ompi_registry_finddictentry(char *segment, char *token);
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
/* ompi_keytable_t *keytable;
|
|
||||||
ompi_registry_core_t *reg;
|
|
||||||
*/
|
|
||||||
ompi_registry_segment_t *seg;
|
|
||||||
uint8_t *object;
|
|
||||||
|
|
||||||
/* initialize the global registry list */
|
|
||||||
OBJ_CONSTRUCT(&ompi_registry.registry, ompi_list_t);
|
|
||||||
|
|
||||||
/* initialize the global dictionary for segment id's */
|
|
||||||
OBJ_CONSTRUCT(&ompi_registry.segment_dict, ompi_list_t);
|
|
||||||
OBJ_CONSTRUCT(&ompi_registry.freekeys, ompi_list_t);
|
|
||||||
ompi_registry.lastkey = 0;
|
|
||||||
|
|
||||||
/* define the "universe" segment key */
|
|
||||||
if (0 == ompi_registry_definekey("universe", NULL)) {
|
|
||||||
fprintf(stderr, "registry_init(error): could not create universe dictionary entry\n");
|
|
||||||
exit(OMPI_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the "universe" segment */
|
|
||||||
seg = OBJ_NEW(ompi_registry_segment_t); /* allocate a new segment */
|
|
||||||
seg->segment = ompi_registry_getkey("universe", NULL);
|
|
||||||
ompi_list_append(&ompi_registry.registry, &seg->item); /* add to the global registry */
|
|
||||||
|
|
||||||
printf("initialized universe seg %ld\n", seg->segment);
|
|
||||||
|
|
||||||
if (0 == ompi_registry_definekey("universe", "ipsy-doodles")) {
|
|
||||||
fprintf(stderr, "well, ipsy-doodles define didn't work\n");
|
|
||||||
exit(OMPI_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ipsy-doodles ok: %ld\n", ompi_registry_getkey("universe", "ipsy-doodles"));
|
|
||||||
|
|
||||||
if (0 == ompi_registry_definekey("commworld-1", NULL)) {
|
|
||||||
fprintf(stderr, "commworld 1 failed\n");
|
|
||||||
exit(OMPI_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("commworld ok: %ld\n", ompi_registry_getkey("commworld-1", NULL));
|
|
||||||
|
|
||||||
object = (uint8_t *)malloc(200);
|
|
||||||
|
|
||||||
ompi_registry_put(false, object, sizeof(object), "commworld-1", "tok1", "tok2", "tok3", "tok4", NULL);
|
|
||||||
|
|
||||||
/* keytable = (ompi_keytable *)malloc(sizeof(ompi_keytable));
|
|
||||||
keytable->token = strdup("universe");
|
|
||||||
keytable->key = 1;
|
|
||||||
keytable->next = NULL;
|
|
||||||
|
|
||||||
nextkey = (ompi_keytable *)malloc(sizeof(ompi_keytable));
|
|
||||||
nextkey->token = strdup("commworld-1");
|
|
||||||
nextkey->key = 1;
|
|
||||||
keytable->next = nextkey;
|
|
||||||
nextkey->next = NULL;
|
|
||||||
|
|
||||||
registry = (ompi_registry_core *)malloc(sizeof(ompi_registry_core));
|
|
||||||
registry->primary_key = ompi_getkey("universe");
|
|
||||||
registry->keys = (ompi_keylist *)malloc(sizeof(ompi_keylist));
|
|
||||||
registry->keys->key = ompi_getkey("commworld-1");
|
|
||||||
registry->keys->next = NULL;
|
|
||||||
registry->object_size = 100;
|
|
||||||
registry->object = (uint8_t *)malloc(100);
|
|
||||||
registry->subscriber = (ompi_subscribe_list *)malloc(sizeof(ompi_subscribe_list));
|
|
||||||
registry->subscriber->id = 1;
|
|
||||||
registry->subscriber->action = OMPI_REGISTRY_NOTIFY_MODIFICATION | OMPI_REGISTRY_NOTIFY_DELETE;
|
|
||||||
|
|
||||||
printf("universe key = %d\n", registry->primary_key);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
ompi_registry_segment_t *ompi_registry_findseg(char *segment)
|
|
||||||
{
|
|
||||||
ompi_keytable_t *ptr_seg;
|
|
||||||
ompi_registry_segment_t *seg;
|
|
||||||
|
|
||||||
/* search the registry segments to find which one is being referenced */
|
|
||||||
for (ptr_seg = (ompi_keytable_t*)ompi_list_get_first(&ompi_registry.segment_dict);
|
|
||||||
ptr_seg != (ompi_keytable_t*)ompi_list_get_end(&ompi_registry.segment_dict);
|
|
||||||
ptr_seg = (ompi_keytable_t*)ompi_list_get_next(ptr_seg)) {
|
|
||||||
if (0 == strcmp(segment, ptr_seg->token)) {
|
|
||||||
fprintf(stderr, "findseg: found segment token %s key %ld\n", ptr_seg->token, ptr_seg->key);
|
|
||||||
/* search ompi_registry to find segment */
|
|
||||||
for (seg=(ompi_registry_segment_t*)ompi_list_get_first(&ompi_registry.registry);
|
|
||||||
seg != (ompi_registry_segment_t*)ompi_list_get_end(&ompi_registry.registry);
|
|
||||||
seg = (ompi_registry_segment_t*)ompi_list_get_next(seg)) {
|
|
||||||
fprintf(stderr, "findseg: checking seg\n");
|
|
||||||
if(seg->segment == ptr_seg->key) {
|
|
||||||
fprintf(stderr, "findseg: found segment key %ld\n", seg->segment);
|
|
||||||
return(seg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(NULL); /* couldn't find the specified segment */
|
|
||||||
}
|
|
||||||
|
|
||||||
ompi_keytable_t *ompi_registry_finddictentry(char *segment, char *token)
|
|
||||||
{
|
|
||||||
ompi_keytable_t *ptr_seg;
|
|
||||||
ompi_keytable_t *ptr_key;
|
|
||||||
ompi_registry_segment_t *seg;
|
|
||||||
|
|
||||||
/* search the registry segments to find which one is being referenced */
|
|
||||||
for (ptr_seg = (ompi_keytable_t*)ompi_list_get_first(&ompi_registry.segment_dict);
|
|
||||||
ptr_seg != (ompi_keytable_t*)ompi_list_get_end(&ompi_registry.segment_dict);
|
|
||||||
ptr_seg = (ompi_keytable_t*)ompi_list_get_next(ptr_seg)) {
|
|
||||||
if (0 == strcmp(segment, ptr_seg->token)) {
|
|
||||||
if (NULL == token) { /* just want segment token-key pair */
|
|
||||||
return(ptr_seg);
|
|
||||||
}
|
|
||||||
/* search ompi_registry to find segment */
|
|
||||||
for (seg=(ompi_registry_segment_t*)ompi_list_get_first(&ompi_registry.registry);
|
|
||||||
seg != (ompi_registry_segment_t*)ompi_list_get_end(&ompi_registry.registry);
|
|
||||||
seg = (ompi_registry_segment_t*)ompi_list_get_next(seg)) {
|
|
||||||
if(seg->segment == ptr_seg->key) {
|
|
||||||
/* got segment - now find specified token-key pair in that dictionary */
|
|
||||||
for (ptr_key = (ompi_keytable_t*)ompi_list_get_first(&seg->keytable);
|
|
||||||
ptr_key != (ompi_keytable_t*)ompi_list_get_end(&seg->keytable);
|
|
||||||
ptr_key = (ompi_keytable_t*)ompi_list_get_next(ptr_key)) {
|
|
||||||
if (0 == strcmp(token, ptr_key->token)) {
|
|
||||||
return(ptr_key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(NULL); /* couldn't find the specified entry */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(NULL); /* couldn't find segment, even though we found entry in registry dict */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(NULL); /* couldn't find segment token-key pair */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long int ompi_registry_getkey(char *segment, char *token)
|
|
||||||
{
|
|
||||||
ompi_keytable_t *ptr_key;
|
|
||||||
|
|
||||||
/* find registry segment */
|
|
||||||
ptr_key = ompi_registry_finddictentry(segment, NULL);
|
|
||||||
if (NULL != ptr_key) {
|
|
||||||
if (NULL == token) { /* only want segment key */
|
|
||||||
return(ptr_key->key);
|
|
||||||
}
|
|
||||||
/* if token specified, find the dictionary entry that matches token */
|
|
||||||
ptr_key = ompi_registry_finddictentry(segment, token);
|
|
||||||
if (NULL != ptr_key) {
|
|
||||||
return(ptr_key->key);
|
|
||||||
}
|
|
||||||
return(0); /* couldn't find dictionary entry */
|
|
||||||
}
|
|
||||||
return(0); /* couldn't find segment */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long int ompi_registry_definekey(char *segment, char *token)
|
|
||||||
{
|
|
||||||
ompi_registry_segment_t *seg;
|
|
||||||
ompi_keytable_t *ptr_seg, *ptr_key, *new;
|
|
||||||
|
|
||||||
/* protect against errors */
|
|
||||||
if (NULL == segment) {
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if token is NULL, then this is defining a segment name. Check dictionary to ensure uniqueness */
|
|
||||||
if (NULL == token) {
|
|
||||||
for (ptr_seg = (ompi_keytable_t*)ompi_list_get_first(&ompi_registry.segment_dict);
|
|
||||||
ptr_seg != (ompi_keytable_t*)ompi_list_get_end(&ompi_registry.segment_dict);
|
|
||||||
ptr_seg = (ompi_keytable_t*)ompi_list_get_next(ptr_seg)) {
|
|
||||||
if (0 == strcmp(segment, ptr_seg->token)) {
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* okay, name is not previously taken. Define a key value for it and return */
|
|
||||||
new = OBJ_NEW(ompi_keytable_t);
|
|
||||||
new->token = strdup(segment);
|
|
||||||
if (0 == ompi_list_get_size(&ompi_registry.freekeys)) { /* no keys waiting for reuse */
|
|
||||||
ompi_registry.lastkey++;
|
|
||||||
new->key = ompi_registry.lastkey;
|
|
||||||
} else {
|
|
||||||
ptr_key = (ompi_keytable_t*)ompi_list_remove_first(&ompi_registry.freekeys);
|
|
||||||
new->key = ptr_key->key;
|
|
||||||
}
|
|
||||||
ompi_list_append(&ompi_registry.segment_dict, &new->item);
|
|
||||||
return(new->key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* okay, token is specified */
|
|
||||||
/* search the registry segments to find which one is being referenced */
|
|
||||||
seg = ompi_registry_findseg(segment);
|
|
||||||
if (NULL != seg) {
|
|
||||||
/* using that segment, check dictionary to ensure uniqueness */
|
|
||||||
for (ptr_key = (ompi_keytable_t*)ompi_list_get_first(&seg->keytable);
|
|
||||||
ptr_key != (ompi_keytable_t*)ompi_list_get_end(&seg->keytable);
|
|
||||||
ptr_key = (ompi_keytable_t*)ompi_list_get_next(ptr_key)) {
|
|
||||||
if (0 == strcmp(token, ptr_key->token)) {
|
|
||||||
return(0); /* already taken, report error */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* okay, token is unique - create dictionary entry */
|
|
||||||
new = OBJ_NEW(ompi_keytable_t);
|
|
||||||
new->token = strdup(token);
|
|
||||||
if (0 == ompi_list_get_size(&seg->freekeys)) { /* no keys waiting for reuse */
|
|
||||||
seg->lastkey++;
|
|
||||||
new->key = seg->lastkey;
|
|
||||||
} else {
|
|
||||||
ptr_key = (ompi_keytable_t*)ompi_list_remove_first(&seg->freekeys);
|
|
||||||
new->key = ptr_key->key;
|
|
||||||
}
|
|
||||||
ompi_list_append(&seg->keytable, &new->item);
|
|
||||||
return(new->key);
|
|
||||||
}
|
|
||||||
/* couldn't find segment */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ompi_registry_deletekey(char *segment, char *token)
|
|
||||||
{
|
|
||||||
ompi_registry_segment_t *seg;
|
|
||||||
ompi_registry_core_t *reg, *prev;
|
|
||||||
ompi_keytable_t *ptr_seg, *ptr_key, *new, *regkey;
|
|
||||||
ompi_subscribe_list_t *subscriber;
|
|
||||||
|
|
||||||
/* protect ourselves against errors */
|
|
||||||
if (NULL == segment) {
|
|
||||||
return(OMPI_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the segment */
|
|
||||||
seg = ompi_registry_findseg(segment);
|
|
||||||
if (NULL != seg) {
|
|
||||||
/* if specified token is NULL, then this is deleting a segment name.*/
|
|
||||||
if (NULL == token) {
|
|
||||||
/* empty the segment's registry */
|
|
||||||
while (0 < ompi_list_get_size(&seg->reg_list)) {
|
|
||||||
ompi_list_remove_last(&seg->reg_list);
|
|
||||||
}
|
|
||||||
/* empty the segment's dictionary */
|
|
||||||
while (0 < ompi_list_get_size(&seg->keytable)) {
|
|
||||||
ompi_list_remove_last(&seg->keytable);
|
|
||||||
}
|
|
||||||
/* empty the list of free keys */
|
|
||||||
while (0 < ompi_list_get_size(&seg->freekeys)) {
|
|
||||||
ompi_list_remove_last(&seg->freekeys);
|
|
||||||
}
|
|
||||||
/* now remove segment from global registry */
|
|
||||||
ompi_list_remove_item(&ompi_registry.registry, &seg->item);
|
|
||||||
/* add key to global registry's freekey list */
|
|
||||||
new = OBJ_NEW(ompi_keytable_t);
|
|
||||||
new->token = NULL;
|
|
||||||
new->key = ptr_seg->key;
|
|
||||||
ompi_list_append(&ompi_registry.freekeys, &new->item);
|
|
||||||
/* NEED TO RE-FIND PTR_SEG */
|
|
||||||
/* now remove the dictionary entry from the global registry dictionary*/
|
|
||||||
ompi_list_remove_item(&ompi_registry.segment_dict, &ptr_seg->item);
|
|
||||||
return(OMPI_SUCCESS);
|
|
||||||
} else { /* token not null, so need to find dictionary element to delete */
|
|
||||||
ptr_key = ompi_registry_finddictentry(segment, token);
|
|
||||||
if (NULL != ptr_key) {
|
|
||||||
/* found key in dictionary */
|
|
||||||
/* need to search this segment's registry to find all instances of key - then delete them */
|
|
||||||
for (reg = (ompi_registry_core_t*)ompi_list_get_first(&seg->reg_list);
|
|
||||||
reg != (ompi_registry_core_t*)ompi_list_get_end(&seg->reg_list);
|
|
||||||
reg = (ompi_registry_core_t*)ompi_list_get_next(reg)) {
|
|
||||||
/* check the subscriber list */
|
|
||||||
for (subscriber = (ompi_subscribe_list_t*)ompi_list_get_first(®->subscriber);
|
|
||||||
(subscriber != (ompi_subscribe_list_t*)ompi_list_get_end(®->subscriber)
|
|
||||||
&& (subscriber->id != ptr_key->key));
|
|
||||||
subscriber = (ompi_subscribe_list_t*)ompi_list_get_next(subscriber));
|
|
||||||
if (subscriber != (ompi_subscribe_list_t*)ompi_list_get_end(®->subscriber)) {
|
|
||||||
ompi_list_remove_item(®->subscriber, &subscriber->item);
|
|
||||||
}
|
|
||||||
/* check the key list */
|
|
||||||
for (regkey = (ompi_keytable_t*)ompi_list_get_first(®->keys);
|
|
||||||
(regkey != (ompi_keytable_t*)ompi_list_get_end(®->keys))
|
|
||||||
&& (regkey->key != ptr_key->key);
|
|
||||||
regkey = (ompi_keytable_t*)ompi_list_get_next(regkey));
|
|
||||||
if (regkey != (ompi_keytable_t*)ompi_list_get_end(®->keys)) {
|
|
||||||
ompi_list_remove_item(®->keys, ®key->item);
|
|
||||||
}
|
|
||||||
/* if this was the last key, then remove the registry entry itself */
|
|
||||||
if (0 == ompi_list_get_size(®->keys)) {
|
|
||||||
while (0 < ompi_list_get_size(®->subscriber)) {
|
|
||||||
ompi_list_remove_last(®->subscriber);
|
|
||||||
}
|
|
||||||
prev = (ompi_registry_core_t*)ompi_list_get_prev(reg);
|
|
||||||
ompi_list_remove_item(&seg->reg_list, ®->item);
|
|
||||||
reg = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* add key to this segment's freekey list */
|
|
||||||
new = OBJ_NEW(ompi_keytable_t);
|
|
||||||
new->token = NULL;
|
|
||||||
new->key = ptr_key->key;
|
|
||||||
ompi_list_append(&seg->freekeys, &new->item);
|
|
||||||
/* now remove the dictionary entry from the segment's dictionary */
|
|
||||||
ompi_list_remove_item(&seg->keytable, &ptr_key->item);
|
|
||||||
return(OMPI_SUCCESS);
|
|
||||||
}
|
|
||||||
return(OMPI_ERROR); /* if we get here, then we couldn't find token in dictionary */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(OMPI_ERROR); /* if we get here, then we couldn't find segment */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ompi_registry_definesegment(char *segment)
|
|
||||||
{
|
|
||||||
if (0 == ompi_registry_definekey(segment, NULL)) {
|
|
||||||
return(OMPI_ERROR);
|
|
||||||
}
|
|
||||||
return(OMPI_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ompi_registry_put(bool overwrite, uint8_t *object, int size, char *segment, char *token, ...)
|
|
||||||
{
|
|
||||||
va_list ap, ap1;
|
|
||||||
int num_tokens=1, i;
|
|
||||||
char *tokenel, **tokenlist, **tok_ptr;
|
|
||||||
ompi_keytable_t *ptr_seg;
|
|
||||||
ompi_registry_segment_t *seg;
|
|
||||||
|
|
||||||
#if __STDC__
|
|
||||||
va_start(ap, token);
|
|
||||||
va_start(ap1, token);
|
|
||||||
#else
|
|
||||||
va_start(ap);
|
|
||||||
va_start(ap1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* protect ourselves against errors */
|
|
||||||
if (NULL == segment || NULL == object || 0 == size || NULL == token) {
|
|
||||||
return(OMPI_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get list of tokens */
|
|
||||||
while (NULL != (tokenel=va_arg(ap, char*))) {
|
|
||||||
num_tokens++;
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenlist = (char **)malloc(num_tokens);
|
|
||||||
tok_ptr = tokenlist;
|
|
||||||
*tok_ptr = strdup(token);
|
|
||||||
tok_ptr++;
|
|
||||||
while (NULL != (tokenel=va_arg(ap1, char*))) {
|
|
||||||
*tok_ptr = strdup(tokenel);
|
|
||||||
tok_ptr++;
|
|
||||||
}
|
|
||||||
va_end(ap);
|
|
||||||
va_end(ap1);
|
|
||||||
|
|
||||||
for (i=0, tok_ptr=tokenlist; i<num_tokens; i++) {
|
|
||||||
fprintf(stderr, "put: token %s\n", *tok_ptr);
|
|
||||||
tok_ptr++;
|
|
||||||
}
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
/* find the segment */
|
|
||||||
seg = ompi_registry_findseg(segment);
|
|
||||||
if (NULL != seg) {
|
|
||||||
}
|
|
||||||
return(OMPI_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ompi_registry_value_t *ompi_registry_get(char *segment, char *token, ...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ompi_registry_del(char *segment, char *token, ...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ompi_keytable_t *ompi_registry_index(char *segment, ...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ompi_keytable_t *ompi_registry_segment_index(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ompi_registry_subscribe(int caller, uint8_t action, char *segment, char *token, ...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ompi_registry_unsubscribe(int caller, uint8_t action, char *segment, char *token, ...)
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,393 +0,0 @@
|
|||||||
/*
|
|
||||||
* $HEADER$
|
|
||||||
*/
|
|
||||||
/** @file:
|
|
||||||
*
|
|
||||||
* The Open MPI general purpose registry.
|
|
||||||
*
|
|
||||||
* The Open MPI system contains a general purpose registry for use by both
|
|
||||||
* applications and internal systems to dynamically share information. For
|
|
||||||
* speed purposes, the registry is divided into "segments", each labelled
|
|
||||||
* with an appropriate "token" string that describes its contents. Segments
|
|
||||||
* are automatically provided for the "universe" and for each MPI CommWorld.
|
|
||||||
* At this time, all segments may be accessed by any application within the universe, thus
|
|
||||||
* providing a mechanism for cross-CommWorld communications (with the requirement
|
|
||||||
* that all participating CommWorlds must reside within the same universe). In the future,
|
|
||||||
* some form of security may be provided to limit access privileges between
|
|
||||||
* segments.
|
|
||||||
*
|
|
||||||
* Within each registry segment, there exists a list of objects that have
|
|
||||||
* been "put" onto the registry. Each object must be tagged with at least
|
|
||||||
* one token, but may be tagged with as many tokens as the creator desires.
|
|
||||||
* Retrieval requests must specify the segment and at least one token, but
|
|
||||||
* can specify an arbitrary number of tokens to describe the search. The registry
|
|
||||||
* will return a list of all objects that meet the search criteria.
|
|
||||||
*
|
|
||||||
* Tokens are defined as character strings, thus allowing for clarity in
|
|
||||||
* the program. However, for speed purposes, tokens are translated into
|
|
||||||
* integer keys prior to storing an object. A table of token-key pairs
|
|
||||||
* is independently maintained for each registry segment. Users can obtain
|
|
||||||
* an index of tokens within a dictionary by requesting it through the ompi_registry_index()
|
|
||||||
* function.
|
|
||||||
*
|
|
||||||
* The registry also provides a subscription capability whereby a caller
|
|
||||||
* can subscribe to a stored object and receive notification when various actions
|
|
||||||
* are performed on that object. Currently supported actions include modification,
|
|
||||||
* the addition of another subscriber, and deletion. Notifications are sent via
|
|
||||||
* the OOB communication channel.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* includes
|
|
||||||
*/
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/inttypes.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "ompi_config.h"
|
|
||||||
#include "include/constants.h"
|
|
||||||
#include "class/ompi_list.h"
|
|
||||||
|
|
||||||
/** Define the notification actions for the subscription system
|
|
||||||
*/
|
|
||||||
/** Notifies subscriber when object is modified */
|
|
||||||
#define OMPI_REGISTRY_NOTIFY_MODIFICATION 0x0001
|
|
||||||
/** Notifies subscriber when another subscriber is added */
|
|
||||||
#define OMPI_REGISTRY_NOTIFY_ADD_SUBSCRIBER 0x0002
|
|
||||||
/** Notifies subscriber when object is removed from registry */
|
|
||||||
#define OMPI_REGISTRY_NOTIFY_DELETE 0x0004
|
|
||||||
/** Notifies subscriber upon any action - effectively an OR of all other flags */
|
|
||||||
#define OMPI_REGISTRY_NOTIFY_ALL 0xffff
|
|
||||||
|
|
||||||
|
|
||||||
/** Define the action bit-masks for registry put and gets.
|
|
||||||
*/
|
|
||||||
/** Overwrite permission */
|
|
||||||
#define OMPI_REGISTRY_OVERWRITE 0x0001
|
|
||||||
/** AND tokens together for search results */
|
|
||||||
#define OMPI_REGISTRY_AND 0x0002
|
|
||||||
/** OR tokens for search results */
|
|
||||||
#define OMPI_REGISTRY_OR 0x0004
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* structures
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** Return value structure for registry requests.
|
|
||||||
* A request for information stored within the registry returns a linked list of values that
|
|
||||||
* correspond to the provided tokens. The linked list is terminated by a "next" value of NULL.
|
|
||||||
* Each link in the list contains a pointer to a copy of the registry object, and the size
|
|
||||||
* of that object in bytes. Note that the pointer is to a \em copy of the object, and not
|
|
||||||
* to the registry object itself. This prevents inadvertent modification of the registry, but
|
|
||||||
* may require the recipient to release the structure's memory when done.
|
|
||||||
*/
|
|
||||||
struct ompi_registry_value_t {
|
|
||||||
ompi_list_item_t item; /**< Allows this item to be placed on a list */
|
|
||||||
char *segment; /**< Name of segment this object came from */
|
|
||||||
ompi_key_table_t keylist; /**< List of keys describing the object */
|
|
||||||
uint8_t *object; /**< Pointer to object being returned */
|
|
||||||
int object_size; /**< Size of returned object, in bytes */
|
|
||||||
};
|
|
||||||
typedef struct ompi_registry_value_t ompi_registry_value_t;
|
|
||||||
|
|
||||||
/* constructor - used to initialize state of keytable instance */
|
|
||||||
static void ompi_registry_value_construct(ompi_registry_value_t* reg_val)
|
|
||||||
{
|
|
||||||
reg_val->object = NULL;
|
|
||||||
reg_val->object_size = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destructor - used to free any resources held by instance */
|
|
||||||
static void ompi_registry_value_destructor(ompi_registry_value_t* reg_val)
|
|
||||||
{
|
|
||||||
if (NULL != reg_val->object) {
|
|
||||||
free(reg_val->object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define instance of ompi_class_t */
|
|
||||||
OBJ_CLASS_INSTANCE(
|
|
||||||
ompi_registry_value_t, /* type name */
|
|
||||||
ompi_list_item_t, /* parent "class" name */
|
|
||||||
ompi_registry_value_construct, /* constructor */
|
|
||||||
ompi_registry_value_destructor); /* destructor */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* external function prototypes
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Define a new registry segment.
|
|
||||||
* The ompi_registry_definesegment() function allows the caller to create a new registry
|
|
||||||
* segment with the specified name. Each segment is given its own token-key dictionary and
|
|
||||||
* object storage list. There is no limit nor restrictions on the number of segments
|
|
||||||
* that can be created and who can create them, or for what they can be used. Attempts to
|
|
||||||
* define a segment with a name that already exists will return an error.
|
|
||||||
*
|
|
||||||
* @param segment A pointer to a character string containing the name of the segment
|
|
||||||
* to be created.
|
|
||||||
*
|
|
||||||
* @retval OMPI_SUCCESS Indicates that the operation was successfully completed.
|
|
||||||
* @retval OMPI_ERROR Indicates that the operation failed - most likely due to the
|
|
||||||
* prior existence of a segment with an identical name.
|
|
||||||
*/
|
|
||||||
int ompi_registry_definesegment(char *segment);
|
|
||||||
|
|
||||||
/** Define multiple new registry segments.
|
|
||||||
* Same functionality as the single segment request ompi_registry_definesegment().
|
|
||||||
*
|
|
||||||
* @param segments A pointer to an array of character strings containing the names of
|
|
||||||
* the segments to be created. The last entry in the array must be a string of length
|
|
||||||
* zero ("\0").
|
|
||||||
*
|
|
||||||
* @retval OMPI_SUCCESS Indicates that the operation was successfully completed.
|
|
||||||
* @retval OMPI_ERROR Indicates that the operation failed - most likely due to the
|
|
||||||
* prior existence of a segment with an identical name.
|
|
||||||
*/
|
|
||||||
int ompi_registry_definesegmentv(char **segments);
|
|
||||||
|
|
||||||
/** Place an object on the registry.
|
|
||||||
* The ompi_registry_put() function places an object on the registry within the specified
|
|
||||||
* registry segment. At least one token describing the object must be provided - an unlimited
|
|
||||||
* number of additional tokens may also be provided. Note that placing an object on the
|
|
||||||
* registry where another object with all tokens identical already exists will cause the
|
|
||||||
* prior object to either: (a) be replaced with the new object, if the action bit-mask
|
|
||||||
* includes overwrite permission, or (b) generate an error, if the action bit-mask does
|
|
||||||
* not include overwrite permission.
|
|
||||||
*
|
|
||||||
* @param action A bit-mask constructed from the defined action values that controls
|
|
||||||
* the behaviour of the function.
|
|
||||||
*
|
|
||||||
* @param segment A pointer to a character string stating the registry segment to be used.
|
|
||||||
*
|
|
||||||
* @param tokens An array of one or more pointers to characters string containing a token
|
|
||||||
* that defines the object
|
|
||||||
* being stored.
|
|
||||||
*
|
|
||||||
* CAUTION: The array of tokens MUST end with a string of zero length ("\0")! Failure to correctly
|
|
||||||
* terminate the array will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param object A pointer to pre-packed buffer to be stored on the registry. The registry will create
|
|
||||||
* a copy of the object. Since the registry has no knowledge of the object's internal structure,
|
|
||||||
* the object must be pre-packed by the caller to ensure accurate communication to other
|
|
||||||
* requestors on systems of different architecture.
|
|
||||||
*
|
|
||||||
* @param size Integer value of the size of the object being passed, in bytes.
|
|
||||||
*
|
|
||||||
* @retval OMPI_SUCCESS Indicates that the operation was successful.
|
|
||||||
* @retval OMPI_ERROR Indicates that the registry was unable to store the object - most
|
|
||||||
* likely due to specifying a non-existent segment or lack of available memory.
|
|
||||||
*/
|
|
||||||
int ompi_registry_put(uint16_t action, char *segment, char **tokens, uint8_t *object, int size);
|
|
||||||
|
|
||||||
/** Place multiple objects on the registry.
|
|
||||||
* Same functionality as the single object ompi_registry_put() function.
|
|
||||||
*
|
|
||||||
* @param actions A pointer to an array of bit-masks constructed from the defined action value
|
|
||||||
* that control the behaviour of the function. The number of bit-mask values must equal the
|
|
||||||
* number of segments provided.
|
|
||||||
*
|
|
||||||
* @param segments A pointer to an array of character strings stating the registry segment to
|
|
||||||
* be used for each object. The last entry in the array must point to a string of zero length.
|
|
||||||
*
|
|
||||||
* CAUTION: Failure to correctly
|
|
||||||
* terminate the array will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param tokens A two-dimensional array of one or more pointers to character strings, each row
|
|
||||||
* containing at least one token that defines the corresponding object being stored. The number
|
|
||||||
* of rows in the array must match the number of segments provided.
|
|
||||||
*
|
|
||||||
* CAUTION: Each row in the array of tokens MUST end with a string of zero length ("\0")!
|
|
||||||
* Failure to correctly
|
|
||||||
* terminate the array will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param object A pointer to an array of pre-packed buffers to be stored on the registry.
|
|
||||||
* The registry will create
|
|
||||||
* a copy of each object. Since the registry has no knowledge of the object's internal structure,
|
|
||||||
* each object must be pre-packed by the caller to ensure accurate communication to other
|
|
||||||
* requestors on systems of different architecture. The number of entries in the array must
|
|
||||||
* match the number of segments provided.
|
|
||||||
*
|
|
||||||
* @param size Pointer to an array of integer values of the size of the objects being passed,
|
|
||||||
* in bytes. The number of entries in the array must match the number of segments provided.
|
|
||||||
*
|
|
||||||
* @retval OMPI_SUCCESS Indicates that the operation was successful.
|
|
||||||
* @retval OMPI_ERROR Indicates that the registry was unable to store the objects - most
|
|
||||||
* likely due to specifying a non-existent segment or lack of available memory.
|
|
||||||
*/
|
|
||||||
int ompi_registry_putv(uint16_t *actions, char **segments, char ***tokens, uint8_t **objects, int *sizes);
|
|
||||||
|
|
||||||
/** Retrieve an object from the registry.
|
|
||||||
* The ompi_registry_get() function retrieves one or more packed buffers, each containing a copy of an
|
|
||||||
* object previously stored on
|
|
||||||
* the registry. The caller must provide the registry segment containing the object, and at
|
|
||||||
* least one token that describes it. An unlimited number of additional tokens describing the
|
|
||||||
* object may be provided. The function will return a linked list of all objects whose description
|
|
||||||
* contains: (a) the entire specified collection of tokens, if the action bit-mask includes
|
|
||||||
* the AND bit, or (b) any one of the specified tokens, if the action bit-mask includes
|
|
||||||
* the OR bit. Failure to provide either of these two bits defaults to the AND condition.
|
|
||||||
*
|
|
||||||
* @param action A bit-mask constructed from the defined registry action flags that controls
|
|
||||||
* the behaviour of the function, as previously described.
|
|
||||||
*
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry.
|
|
||||||
*
|
|
||||||
* @param tokens Pointer to an array of pointers to character strings containing one or
|
|
||||||
* more tokens describing the object to be retrieved.
|
|
||||||
*
|
|
||||||
* CAUTION: The array must end with a string of zero length ("\0")! Failure to correctly
|
|
||||||
* terminate the array will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @retval object Pointer to a linked list of ompi_registry_value_t structures, each containing
|
|
||||||
* the name of the segment,
|
|
||||||
* a linked list of the tokens that describe the object,
|
|
||||||
* a pointer to a packed buffer containing a copy of the object retrieved from the registry,
|
|
||||||
* and the size of the object in bytes. The caller must unpack the buffer to access
|
|
||||||
* the information in the object.
|
|
||||||
* @retval NULL Indicates that no object meeting the provided specifications could not be found.
|
|
||||||
*/
|
|
||||||
ompi_registry_value_t *ompi_registry_get(uint16_t action, char *segment, char **tokens);
|
|
||||||
|
|
||||||
/** Perform multiple retrieves from the registry.
|
|
||||||
* The ompi_registry_getv() function allows the caller to execute multiple ompi_registry_get()
|
|
||||||
* calls in a single call, thus saving message overhead for faster response.
|
|
||||||
*
|
|
||||||
* @param action An array of bit-masks constructed from the defined registry action flags that control
|
|
||||||
* the behaviour of the function for each requested retrieval, as previously described.
|
|
||||||
*
|
|
||||||
* @param segment An array of pointers to character strings defining the segment of the registry
|
|
||||||
* for each retrieval. The last value in the array must be a string of zero length.
|
|
||||||
*
|
|
||||||
* CAUTION: Failure to correctly
|
|
||||||
* terminate the array will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param tokens A two-dimensional array of one or more pointers to character strings, each row
|
|
||||||
* containing at least one token that defines the corresponding object being stored. The number
|
|
||||||
* of rows in the array must match the number of segments provided.
|
|
||||||
*
|
|
||||||
* CAUTION: Each row in the array of tokens MUST end with a string of zero length ("\0")!
|
|
||||||
* Failure to correctly
|
|
||||||
* terminate the array will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @retval object Pointer to a linked list of ompi_registry_value_t structures, each containing
|
|
||||||
* the name of the segment, a linked list of the tokens that describe the object,
|
|
||||||
* a pointer to a packed buffer containing a copy of the object retrieved from the registry,
|
|
||||||
* and the size of the object in bytes. The caller must unpack the buffer to access
|
|
||||||
* the information in the object.
|
|
||||||
* @retval NULL Indicates that no object meeting the provided specifications could not be found
|
|
||||||
* for any of the requested retrievals.
|
|
||||||
*/
|
|
||||||
ompi_registry_value_t *ompi_registry_getv(uint16_t *action, char **segment, char ***tokens);
|
|
||||||
|
|
||||||
|
|
||||||
/** Delete an object from the registry.
|
|
||||||
* The ompi_registry_del() function removes an object that was previously stored on the registry.
|
|
||||||
* The caller must provide the registry segment containing the object, and at
|
|
||||||
* least one token that describes it. An unlimited number of additional tokens describing the
|
|
||||||
* object may be provided.
|
|
||||||
*
|
|
||||||
* CAUTION: The function will delete ALL objects that match the search criteria.
|
|
||||||
*
|
|
||||||
* CAUTION: The ompi_registry_del() function call MUST end with a NULL parameter! The C variable
|
|
||||||
* argument system does not provide for a mechanism by which we can determine the number of
|
|
||||||
* arguments that were passed. Failure to terminate the argument list with a NULL will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry.
|
|
||||||
* @param token Pointer to a character string containing the token to be deleted.
|
|
||||||
* @param tokens... Additional tokens (provided as pointers to character strings) can be
|
|
||||||
* provided to further identify the object being deleted.
|
|
||||||
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
|
|
||||||
* variable list of arguments.
|
|
||||||
* @retval OMPI_SUCCESS Indicates that the operation was successful.
|
|
||||||
* @retval OMPI_ERROR Indicates that the registry was unable to delete the object - most
|
|
||||||
* likely due to specifying a non-existent segment or object.
|
|
||||||
*/
|
|
||||||
int ompi_registry_delete(char *segment, char **tokens);
|
|
||||||
|
|
||||||
/** Obtain an index of the registry token-key dictionary.
|
|
||||||
* The ompi_registry_index() function provides a list of the token-key pairs within
|
|
||||||
* a specified dictionary. The caller must provide the name of the segment being
|
|
||||||
* queried - this will return a linked list of all token-key pairs within that segment's
|
|
||||||
* dictionary. Alternatively, the caller may also provide an unlimited number of tokens
|
|
||||||
* which the caller would like to have translated - the function will then return a
|
|
||||||
* linked list of token-key pairs. Any tokens not found will be ignored.
|
|
||||||
*
|
|
||||||
* CAUTION: The ompi_registry_index() function call MUST end with a NULL parameter! The C variable
|
|
||||||
* argument system does not provide for a mechanism by which we can determine the number of
|
|
||||||
* arguments that were passed. Failure to terminate the argument list with a NULL will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry.
|
|
||||||
* @param tokens... Additional tokens (provided as pointers to character strings) can be
|
|
||||||
* provided that the caller would like to have translated.
|
|
||||||
* @param NULL If segment parameter is NULL, then segment index returned.
|
|
||||||
*
|
|
||||||
* @retval keyvalues A pointer to a linked list of token-key pairs. Any tokens not found
|
|
||||||
* will be ignored and will, therefore, not be included in the returned list.
|
|
||||||
* @retval NULL Indicates that the operation failed - most likely caused by failing to specify
|
|
||||||
* any token that exists within the specified segment, or a non-existent segment.
|
|
||||||
*/
|
|
||||||
ompi_keytable_t *ompi_registry_index(char *segment);
|
|
||||||
|
|
||||||
/** Subscribe to a registry object.
|
|
||||||
* The ompi_registry_subscribe() function allows the caller to be notified when specific actions
|
|
||||||
* are taken on the specified object. Notification will be sent via the OOB communication channel.
|
|
||||||
* The caller must provide an ID that allows the OOB to properly route the notification message.
|
|
||||||
*
|
|
||||||
* CAUTION: The ompi_registry_subscribe() function call MUST end with a NULL parameter! The C variable
|
|
||||||
* argument system does not provide for a mechanism by which we can determine the number of
|
|
||||||
* arguments that were passed. Failure to terminate the argument list with a NULL will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param caller The ID of the caller - used to route any subsequent notifications.
|
|
||||||
* @param action A bit-mask value formed using the OMPI_REGISTRY_NOTIFY flags that indicates
|
|
||||||
* the action that shall trigger notification of the caller.
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry.
|
|
||||||
* @param token Pointer to a character string containing the token of the object to which
|
|
||||||
* the caller is subscribing.
|
|
||||||
* @param tokens... Additional tokens (provided as pointers to character strings) can be
|
|
||||||
* provided to further identify the object to which the caller is subscribing.
|
|
||||||
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
|
|
||||||
* variable list of arguments.
|
|
||||||
*
|
|
||||||
* @retval OMPI_SUCCESS Indicates that the operation was successful.
|
|
||||||
* @retval OMPI_ERROR Indicates that the operation failed - most likely caused by specifying
|
|
||||||
* an object that did not exist within the specified segment, or a non-existent segment.
|
|
||||||
*/
|
|
||||||
int ompi_registry_subscribe(int caller, uint8_t action, char *segment, char **tokens);
|
|
||||||
|
|
||||||
/** Unsubscribe from a registry object.
|
|
||||||
*
|
|
||||||
* CAUTION: The ompi_registry_put() function call MUST end with a NULL parameter! The C variable
|
|
||||||
* argument system does not provide for a mechanism by which we can determine the number of
|
|
||||||
* arguments that were passed. Failure to terminate the argument list with a NULL will result
|
|
||||||
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
|
|
||||||
*
|
|
||||||
* @param caller The ID of the caller wishing to remove its subscription to the object.
|
|
||||||
* @param segment Pointer to a character string defining the segment of the registry.
|
|
||||||
* @param token Pointer to a character string containing the token of the object to which
|
|
||||||
* the caller is subscribed.
|
|
||||||
* @param tokens... Additional tokens (provided as pointers to character strings) can be
|
|
||||||
* provided to further identify the object to which the caller is subscribed.
|
|
||||||
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
|
|
||||||
* variable list of arguments.
|
|
||||||
*
|
|
||||||
* @retval OMPI_SUCCESS Indicates that the operation was successful. Note that this value will
|
|
||||||
* also be returned if the caller was not previously subscribed to the specified object since an
|
|
||||||
* unsubscribe request would have resulted in the same end condition.
|
|
||||||
* @retval OMPI_ERROR Indicates that the operation failed - most likely caused by specifying
|
|
||||||
* an object that did not exist within the specified segment, or a non-existent segment.
|
|
||||||
*/
|
|
||||||
int ompi_registry_unsubscribe(int caller, uint8_t action, char *segment, char **tokens);
|
|
@ -5,6 +5,9 @@
|
|||||||
/** @file:
|
/** @file:
|
||||||
*
|
*
|
||||||
* Populates global structure with system-specific information.
|
* Populates global structure with system-specific information.
|
||||||
|
*
|
||||||
|
* Notes: add limits.h, compute size of integer and other types via sizeof(type)*CHAR_BIT
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,26 +4,41 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
include $(top_srcdir)/config/Makefile.options
|
include $(top_srcdir)/config/Makefile.options
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/test/support -DOMPI_ENABLE_DEBUG_OVERRIDE=1
|
|
||||||
|
|
||||||
noinst_PROGRAMS = \
|
AM_CPPFLAGS = \
|
||||||
ompi_session_dir
|
-DLAM_PREFIX="\"$(prefix)\"" \
|
||||||
|
-DLAM_BINDIR="\"$(bindir)\"" \
|
||||||
|
-DLAM_LIBDIR="\"$(libdir)\"" \
|
||||||
|
-DLAM_INCDIR="\"$(includedir)\"" \
|
||||||
|
-DLAM_PKGLIBDIR="\"$(pkglibdir)\"" \
|
||||||
|
-DLAM_SYSCONFDIR="\"$(sysconfdir)\"" \
|
||||||
|
-DLAM_CONFIGURE_USER="\"@LAM_CONFIGURE_USER@\"" \
|
||||||
|
-DLAM_CONFIGURE_HOST="\"@LAM_CONFIGURE_HOST@\"" \
|
||||||
|
-DLAM_CONFIGURE_DATE="\"@LAM_CONFIGURE_DATE@\""
|
||||||
|
|
||||||
ompi_session_dir_SOURCES = ompi_session_dir.c
|
libs = $(top_builddir)/src/libmpi.la
|
||||||
ompi_session_dir_LDADD = \
|
|
||||||
$(top_builddir)/src/class/ompi_object.lo \
|
bin_PROGRAMS = \
|
||||||
$(top_builddir)/src/mem/malloc.lo \
|
openmpi
|
||||||
$(top_builddir)/src/util/output.lo \
|
|
||||||
$(top_builddir)/src/util/argv.lo \
|
openmpi_SOURCES = \
|
||||||
$(top_builddir)/src/util/strncpy.lo \
|
openmpi.h \
|
||||||
$(top_builddir)/src/threads/mutex.lo \
|
ompi_init.h \
|
||||||
$(top_builddir)/src/threads/mutex_pthread.lo \
|
os_session_dir.c \
|
||||||
$(top_builddir)/src/threads/mutex_spinlock.lo \
|
ompi_init.c \
|
||||||
$(top_builddir)/src/threads/mutex_spinwait.lo \
|
openmpi.c
|
||||||
|
|
||||||
|
openmpi_LDADD = \
|
||||||
|
$(libs) \
|
||||||
|
$(LIBMPI_EXTRA_LIBS) \
|
||||||
|
$(LIBLAM_EXTRA_LIBS) \
|
||||||
$(top_builddir)/src/util/os_path.lo \
|
$(top_builddir)/src/util/os_path.lo \
|
||||||
$(top_builddir)/src/util/os_create_dirpath.lo \
|
$(top_builddir)/src/util/os_create_dirpath.lo \
|
||||||
$(top_builddir)/src/util/sys_info.lo \
|
$(top_builddir)/src/util/sys_info.lo
|
||||||
$(top_builddir)/src/rte/universe/os_session_dir.o \
|
|
||||||
$(top_builddir)/test/support/libsupport.la
|
|
||||||
ompi_session_dir_DEPENDENCIES = $(ompi_session_dir_LDADD)
|
|
||||||
|
|
||||||
|
openmpi_DFLAGS = $(LIBMPI_EXTRA_LDFLAGS) $(LIBLAM_EXTRA_LDFLAGS)
|
||||||
|
openmpi_DEPENDENCIES = $(libs) \
|
||||||
|
$(openmpi_LDADD)
|
||||||
|
|
||||||
|
clean-local:
|
||||||
|
test -z "$(LAM_CXX_TEMPLATE_REPOSITORY)" || $(RM) -rf $(LAM_CXX_TEMPLATE_REPOSITORY)
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user