/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ /* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. * */ #ifndef MPIR_INFO_H_INCLUDED #define MPIR_INFO_H_INCLUDED /* ------------------------------------------------------------------------- */ /* Info */ /*TInfoOverview.tex 'MPI_Info' provides a way to create a list of '(key,value)' pairs where the 'key' and 'value' are both strings. Because many routines, both in the MPI implementation and in related APIs such as the PMI process management interface, require 'MPI_Info' arguments, we define a simple structure for each 'MPI_Info' element. Elements are allocated by the generic object allocator; the head element is always empty (no 'key' or 'value' is defined on the head element). For simplicity, we have not abstracted the info data structures; routines that want to work with the linked list may do so directly. Because the 'MPI_Info' type is a handle and not a pointer, an MPIR routine is provided to handle the deallocation of 'MPIR_Info' elements. See the implementation of 'MPI_Info_create' for how an Info type is allocated. Thread Safety: The info interface itself is not thread-robust. In particular, the routines 'MPI_INFO_GET_NKEYS' and 'MPI_INFO_GET_NTHKEY' assume that no other thread modifies the info key. (If the info routines had the concept of a next value, they would not be thread safe. As it stands, a user must be careful if several threads have access to the same info object.) Further, 'MPI_INFO_DUP', while not explicitly advising implementers to be careful of one thread modifying the 'MPI_Info' structure while 'MPI_INFO_DUP' is copying it, requires that the operation take place in a thread-safe manner. There isn'' much that we can do about these cases. There are other cases that must be handled. In particular, multiple threads are allowed to update the same info value. Thus, all of the update routines must be thread safe; the simple implementation used in the MPICH implementation uses locks. Note that the 'MPI_Info_delete' call does not need a lock; the defintion of thread-safety means that any order of the calls functions correctly; since it invalid either to delete the same 'MPI_Info' twice or to modify an 'MPI_Info' that has been deleted, only one thread at a time can call 'MPI_Info_free' on any particular 'MPI_Info' value. T*/ /*S MPIR_Info - Structure of an MPIR info Notes: There is no reference count because 'MPI_Info' values, unlike other MPI objects, may be changed after they are passed to a routine without changing the routine''s behavior. In other words, any routine that uses an 'MPI_Info' object must make a copy or otherwise act on any info value that it needs. A linked list is used because the typical 'MPI_Info' list will be short and a simple linked list is easy to implement and to maintain. Similarly, a single structure rather than separate header and element structures are defined for simplicity. No separate thread lock is provided because info routines are not performance critical; they may use the single critical section lock in the 'MPIR_Process' structure when they need a thread lock. This particular form of linked list (in particular, with this particular choice of the first two members) is used because it allows us to use the same routines to manage this list as are used to manage the list of free objects (in the file 'src/util/mem/handlemem.c'). In particular, if lock-free routines for updating a linked list are provided, they can be used for managing the 'MPIR_Info' structure as well. The MPI standard requires that keys can be no less that 32 characters and no more than 255 characters. There is no mandated limit on the size of values. Module: Info-DS S*/ struct MPIR_Info { MPIR_OBJECT_HEADER; /* adds handle and ref_count fields */ struct MPIR_Info *next; char *key; char *value; }; extern MPIR_Object_alloc_t MPIR_Info_mem; /* Preallocated info objects */ #define MPIR_INFO_N_BUILTIN 2 extern MPIR_Info MPIR_Info_builtin[MPIR_INFO_N_BUILTIN]; extern MPIR_Info MPIR_Info_direct[]; int MPIR_Info_get_impl(MPIR_Info * info_ptr, const char *key, int valuelen, char *value, int *flag); void MPIR_Info_get_nkeys_impl(MPIR_Info * info_ptr, int *nkeys); int MPIR_Info_get_nthkey_impl(MPIR_Info * info, int n, char *key); void MPIR_Info_get_valuelen_impl(MPIR_Info * info_ptr, const char *key, int *valuelen, int *flag); int MPIR_Info_set_impl(MPIR_Info * info_ptr, const char *key, const char *value); int MPIR_Info_dup_impl(MPIR_Info * info_ptr, MPIR_Info ** new_info_ptr); void MPIR_Info_free(MPIR_Info * info_ptr); int MPIR_Info_alloc(MPIR_Info ** info_p_p); #endif /* MPIR_INFO_H_INCLUDED */