From 4f92fa96273b7bce9570e1f2dc70bf6709019a77 Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Sat, 12 Jun 2004 10:15:05 +0000 Subject: [PATCH] Update to registry - prep to moving to new directory structure. This commit was SVN r1235. --- src/rte/universe/registry/registry.c | 86 +++++++++ src/rte/universe/registry/registry.h | 265 ++++++++++++++++----------- 2 files changed, 245 insertions(+), 106 deletions(-) diff --git a/src/rte/universe/registry/registry.c b/src/rte/universe/registry/registry.c index 940d7258ce..4355b61db4 100644 --- a/src/rte/universe/registry/registry.c +++ b/src/rte/universe/registry/registry.c @@ -41,6 +41,42 @@ 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 @@ -103,6 +139,54 @@ OBJ_CLASS_INSTANCE( 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 @@ -121,6 +205,8 @@ struct ompi_registry_core_t { 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; diff --git a/src/rte/universe/registry/registry.h b/src/rte/universe/registry/registry.h index 154809cacd..3cc94c6cea 100644 --- a/src/rte/universe/registry/registry.h +++ b/src/rte/universe/registry/registry.h @@ -26,10 +26,9 @@ * 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 independetly maintained for each registry segment. Users can obtain - * an index of token-key values by requesting it through the ompi_registry_index() - * function, and can define/delete token-key values using the ompi_registry_definekey() - * and ompi_registry_deletekey() functions, respectively. + * 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 @@ -43,6 +42,9 @@ /* * includes */ +#include +#include +#include #include "ompi_config.h" #include "include/constants.h" @@ -51,54 +53,29 @@ /** Define the notification actions for the subscription system */ /** Notifies subscriber when object is modified */ -#define OMPI_REGISTRY_NOTIFY_MODIFICATION 0x01 +#define OMPI_REGISTRY_NOTIFY_MODIFICATION 0x0001 /** Notifies subscriber when another subscriber is added */ -#define OMPI_REGISTRY_NOTIFY_ADD_SUBSCRIBER 0x02 +#define OMPI_REGISTRY_NOTIFY_ADD_SUBSCRIBER 0x0002 /** Notifies subscriber when object is removed from registry */ -#define OMPI_REGISTRY_NOTIFY_DELETE 0x04 +#define OMPI_REGISTRY_NOTIFY_DELETE 0x0004 /** Notifies subscriber upon any action - effectively an OR of all other flags */ -#define OMPI_REGISTRY_NOTIFY_ALL 0xff +#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 */ -/** 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 */ - /** Return value structure for registry requests. * A request for information stored within the registry returns a linked list of values that @@ -110,6 +87,8 @@ OBJ_CLASS_INSTANCE( */ 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 */ }; @@ -159,70 +138,158 @@ OBJ_CLASS_INSTANCE( */ 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 be replaced with the new object. + * 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. * - * 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 + * @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 overwrite A boolean value that indicates whether or not to overwrite an existing - * entry if all tokens match. A value of "true" indicates overwrite is permitted - a value - * of "false" indicates that overwrite is forbidden. In the latter case, attempting to - * overwrite an existing entry will result in an error condition being returned. - * @param object A pointer to the object to be stored on the registry. The registry will create + * @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 is stored as an object of uint8_t (unsigned 8-bit int) type. The pointer must be cast - * into the uint8_t type when passed. + * 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. - * @param segment A pointer to a character string stating the registry segment to be used. - * @param token A pointer to a character string containing a token that defines the object - * being stored. This token can later be used to retrieve the object. The registry uses the - * ompi_registry_getkey() function to translate the token to an integer key prior to storing - * the object. If the token is not currently defined in the segment's dictionary, a new - * dictionary entry will automatically be created. - * @param tokens... Additional tokens (provided as pointers to character strings) can be - * provided to further identify the object being stored. - * @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 store the object - most * likely due to specifying a non-existent segment or lack of available memory. */ -int ompi_registry_put(bool overwrite, uint8_t *object, int size, char *segment, char *token, ...); +int ompi_registry_put(uint16_t action, char *segment, char **tokens, uint8_t *object, int size); -/** Retrieve an object from the registry. - * The ompi_registry_get() function retrieves 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 that match - * the search criteria. +/** Place multiple objects on the registry. + * Same functionality as the single object ompi_registry_put() function. * - * CAUTION: The ompi_registry_get() 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 + * @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 segment Pointer to a character string defining the segment of the registry. - * @param token Pointer to a character string containing the token to be retrieved. - * @param tokens... Additional tokens (provided as pointers to character strings) can be - * provided to further identify the object being retrieved. - * @param NULL The last parameter in the function call MUST be a NULL to terminate the - * variable list of arguments. + * @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. * - * @retval object Pointer to a linked list of ompi_registry_value structures, each containing - * a pointer to a copy of the object retrieved from the registry, the size of the object in bytes, - * and a pointer to the next link in the list (which is NULL for the last link). The object - * is returned as a *uint8_t since the object's internal structure is unknown to the registry. - * @retval NULL Indicates that the specified object could not be found. + * 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. */ -ompi_registry_value_t *ompi_registry_get(char *segment, char *token, ...); +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. @@ -247,7 +314,7 @@ ompi_registry_value_t *ompi_registry_get(char *segment, char *token, ...); * @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_del(char *segment, char *token, ...); +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 @@ -265,28 +332,14 @@ int ompi_registry_del(char *segment, char *token, ...); * @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 The last parameter in the function call MUST be a NULL to terminate the - * variable list of arguments. + * @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, ...); - -/** Obtain a list of the current registry segments. - * The ompi_registry_segment_index() function provides a list of the segments currently defined - * within this registry. - * - * @param - No parameters are passed to this function. - * - * @retval keyvalues A pointer to a linked list of segment token-key pairs. - * @retval NULL Indicates that no segments are currently defined within this registry - i.e., the - * registry is completely empty. - * - */ -ompi_keytable_t *ompi_registry_segment_index(void); +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 @@ -313,7 +366,7 @@ ompi_keytable_t *ompi_registry_segment_index(void); * @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 *token, ...); +int ompi_registry_subscribe(int caller, uint8_t action, char *segment, char **tokens); /** Unsubscribe from a registry object. * @@ -337,4 +390,4 @@ int ompi_registry_subscribe(int caller, uint8_t action, char *segment, char *tok * @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 *token, ...); +int ompi_registry_unsubscribe(int caller, uint8_t action, char *segment, char **tokens);