"Fossies" - the Fresh Open Source Software Archive

Member "mvapich2-2.3.2/src/include/mpimem.h" (8 Aug 2019, 21828 Bytes) of package /linux/misc/mvapich2-2.3.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mpimem.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.1_vs_2.3.2.

    1 /* Copyright (c) 2001-2019, The Ohio State University. All rights
    2  * reserved.
    3  *
    4  * This file is part of the MVAPICH2 software package developed by the
    5  * team members of The Ohio State University's Network-Based Computing
    6  * Laboratory (NBCL), headed by Professor Dhabaleswar K. (DK) Panda.
    7  *
    8  * For detailed copyright and licensing information, please refer to the
    9  * copyright file COPYRIGHT in the top level MVAPICH2 directory.
   10  *
   11  */
   12 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   13 /*
   14  *  (C) 2001 by Argonne National Laboratory.
   15  *      See COPYRIGHT in top-level directory.
   16  */
   17 #ifndef MPIMEM_H_INCLUDED
   18 #define MPIMEM_H_INCLUDED
   19 
   20 #ifndef MPICHCONF_H_INCLUDED
   21 #error 'mpimem.h requires that mpichconf.h be included first'
   22 #endif
   23 
   24 /* Make sure that we have the definitions for the malloc routines and size_t */
   25 #include <stdio.h>
   26 #include <stdlib.h>
   27 /* strdup is often declared in string.h, so if we plan to redefine strdup, 
   28    we need to include string first.  That is done below, only in the
   29    case where we redefine strdup */
   30 
   31 #if defined(__cplusplus)
   32 extern "C" {
   33 #endif
   34 
   35 #include "mpichconf.h"
   36 #include "mpl.h"
   37 
   38 #ifdef _OSU_MVAPICH_
   39 #include "mv2_mpit.h"
   40 #endif
   41 
   42 /* Define attribute as empty if it has no definition */
   43 #ifndef ATTRIBUTE
   44 #define ATTRIBUTE(a)
   45 #endif
   46 
   47 /* ------------------------------------------------------------------------- */
   48 /* mpimem.h */
   49 /* ------------------------------------------------------------------------- */
   50 /* Memory allocation */
   51 /* style: allow:malloc:2 sig:0 */
   52 /* style: allow:free:2 sig:0 */
   53 /* style: allow:strdup:2 sig:0 */
   54 /* style: allow:calloc:2 sig:0 */
   55 /* style: allow:realloc:1 sig:0 */
   56 /* style: allow:alloca:1 sig:0 */
   57 /* style: define:__strdup:1 sig:0 */
   58 /* style: define:strdup:1 sig:0 */
   59 /* style: allow:fprintf:5 sig:0 */   /* For handle debugging ONLY */
   60 /* style: allow:snprintf:1 sig:0 */
   61 
   62 /*D
   63   Memory - Memory Management Routines
   64 
   65   Rules for memory management:
   66 
   67   MPICH explicity prohibits the appearence of 'malloc', 'free', 
   68   'calloc', 'realloc', or 'strdup' in any code implementing a device or 
   69   MPI call (of course, users may use any of these calls in their code).  
   70   Instead, you must use 'MPIU_Malloc' etc.; if these are defined
   71   as 'malloc', that is allowed, but an explicit use of 'malloc' instead of
   72   'MPIU_Malloc' in the source code is not allowed.  This restriction is
   73   made to simplify the use of portable tools to test for memory leaks, 
   74   overwrites, and other consistency checks.
   75 
   76   Most memory should be allocated at the time that 'MPID_Init' is 
   77   called and released with 'MPID_Finalize' is called.  If at all possible,
   78   no other MPID routine should fail because memory could not be allocated
   79   (for example, because the user has allocated large arrays after 'MPI_Init').
   80   
   81   The implementation of the MPI routines will strive to avoid memory allocation
   82   as well; however, operations such as 'MPI_Type_index' that create a new
   83   data type that reflects data that must be copied from an array of arbitrary
   84   size will have to allocate memory (and can fail; note that there is an
   85   MPI error class for out-of-memory).
   86 
   87   Question:
   88   Do we want to have an aligned allocation routine?  E.g., one that
   89   aligns memory on a cache-line.
   90   D*/
   91 
   92 /* Define the string copy and duplication functions */
   93 /* Safer string routines */
   94 int MPIU_Strncpy( char *outstr, const char *instr, size_t maxlen );
   95 
   96 int MPIU_Strnapp( char *, const char *, size_t );
   97 char *MPIU_Strdup( const char * );
   98 
   99 /* ---------------------------------------------------------------------- */
  100 /* FIXME - The string routines do not belong in the memory header file  */
  101 /* FIXME - The string error code such be MPICH-usable error codes */
  102 #define MPIU_STR_SUCCESS    0
  103 #define MPIU_STR_FAIL      -1
  104 #define MPIU_STR_NOMEM      1
  105 
  106 /* FIXME: Global types like this need to be discussed and agreed to */
  107 typedef int MPIU_BOOL;
  108 
  109 /* FIXME: These should be scoped to only the routines that need them */
  110 #ifdef USE_HUMAN_READABLE_TOKENS
  111 
  112 #define MPIU_STR_QUOTE_CHAR     '\"'
  113 #define MPIU_STR_QUOTE_STR      "\""
  114 #define MPIU_STR_DELIM_CHAR     '='
  115 #define MPIU_STR_DELIM_STR      "="
  116 #define MPIU_STR_ESCAPE_CHAR    '\\'
  117 #define MPIU_STR_HIDE_CHAR      '*'
  118 #define MPIU_STR_SEPAR_CHAR     ' '
  119 #define MPIU_STR_SEPAR_STR      " "
  120 
  121 #else
  122 
  123 #define MPIU_STR_QUOTE_CHAR     '\"'
  124 #define MPIU_STR_QUOTE_STR      "\""
  125 #define MPIU_STR_DELIM_CHAR     '#'
  126 #define MPIU_STR_DELIM_STR      "#"
  127 #define MPIU_STR_ESCAPE_CHAR    '\\'
  128 #define MPIU_STR_HIDE_CHAR      '*'
  129 #define MPIU_STR_SEPAR_CHAR     '$'
  130 #define MPIU_STR_SEPAR_STR      "$"
  131 
  132 #endif
  133 
  134 int MPIU_Str_get_string_arg(const char *str, const char *key, char *val, 
  135                 int maxlen);
  136 int MPIU_Str_get_binary_arg(const char *str, const char *key, char *buffer, 
  137                 int maxlen, int *out_length);
  138 int MPIU_Str_get_int_arg(const char *str, const char *key, int *val_ptr);
  139 int MPIU_Str_add_string_arg(char **str_ptr, int *maxlen_ptr, const char *key, 
  140                 const char *val);
  141 int MPIU_Str_add_binary_arg(char **str_ptr, int *maxlen_ptr, const char *key, 
  142                 const char *buffer, int length);
  143 int MPIU_Str_add_int_arg(char **str_ptr, int *maxlen_ptr, const char *key, 
  144              int val);
  145 MPIU_BOOL MPIU_Str_hide_string_arg(char *str, const char *key);
  146 int MPIU_Str_add_string(char **str_ptr, int *maxlen_ptr, const char *val);
  147 int MPIU_Str_get_string(char **str_ptr, char *val, int maxlen);
  148 
  149 /* ------------------------------------------------------------------------- */
  150 
  151 void MPIU_trinit(int);
  152 void *MPIU_trmalloc(size_t, int, const char []);
  153 void MPIU_trfree(void *, int, const char []);
  154 int MPIU_trvalid(const char []);
  155 void MPIU_trspace(size_t *, size_t *);
  156 void MPIU_trid(int);
  157 void MPIU_trlevel(int);
  158 void MPIU_trDebugLevel(int);
  159 void *MPIU_trcalloc(size_t, size_t, int, const char []);
  160 void *MPIU_trrealloc(void *, size_t, int, const char[]);
  161 void *MPIU_trstrdup(const char *, int, const char[]);
  162 void MPIU_TrSetMaxMem(size_t);
  163 void MPIU_trdump(FILE *, int);
  164 
  165 #ifdef USE_MEMORY_TRACING
  166 /*M
  167   MPIU_Malloc - Allocate memory
  168 
  169   Synopsis:
  170 .vb
  171   void *MPIU_Malloc( size_t len )
  172 .ve
  173 
  174   Input Parameter:
  175 . len - Length of memory to allocate in bytes
  176 
  177   Return Value:
  178   Pointer to allocated memory, or null if memory could not be allocated.
  179 
  180   Notes:
  181   This routine will often be implemented as the simple macro
  182 .vb
  183   #define MPIU_Malloc(n) malloc(n)
  184 .ve
  185   However, it can also be defined as 
  186 .vb
  187   #define MPIU_Malloc(n) MPIU_trmalloc(n,__LINE__,__FILE__)
  188 .ve
  189   where 'MPIU_trmalloc' is a tracing version of 'malloc' that is included with 
  190   MPICH.
  191 
  192   Module:
  193   Utility
  194   M*/
  195 #define MPIU_Malloc(a)    MPIU_trmalloc((a),__LINE__,__FILE__)
  196 
  197 /*M
  198   MPIU_Calloc - Allocate memory that is initialized to zero.
  199 
  200   Synopsis:
  201 .vb
  202     void *MPIU_Calloc( size_t nelm, size_t elsize )
  203 .ve
  204 
  205   Input Parameters:
  206 + nelm - Number of elements to allocate
  207 - elsize - Size of each element.
  208 
  209   Notes:
  210   Like 'MPIU_Malloc' and 'MPIU_Free', this will often be implemented as a 
  211   macro but may use 'MPIU_trcalloc' to provide a tracing version.
  212 
  213   Module:
  214   Utility
  215   M*/
  216 #define MPIU_Calloc(a,b)  \
  217     MPIU_trcalloc((a),(b),__LINE__,__FILE__)
  218 
  219 /*M
  220   MPIU_Free - Free memory
  221 
  222   Synopsis:
  223 .vb
  224    void MPIU_Free( void *ptr )
  225 .ve
  226 
  227   Input Parameter:
  228 . ptr - Pointer to memory to be freed.  This memory must have been allocated
  229   with 'MPIU_Malloc'.
  230 
  231   Notes:
  232   This routine will often be implemented as the simple macro
  233 .vb
  234   #define MPIU_Free(n) free(n)
  235 .ve
  236   However, it can also be defined as 
  237 .vb
  238   #define MPIU_Free(n) MPIU_trfree(n,__LINE__,__FILE__)
  239 .ve
  240   where 'MPIU_trfree' is a tracing version of 'free' that is included with 
  241   MPICH.
  242 
  243   Module:
  244   Utility
  245   M*/
  246 #define MPIU_Free(a)                    \
  247 do {                                    \
  248     MPIU_trfree((void *)(a),__LINE__,__FILE__); \
  249     (a) = NULL;                         \
  250 } while(0)
  251 
  252 #define MPIU_Strdup(a)    MPIU_trstrdup(a,__LINE__,__FILE__)
  253 
  254 #define MPIU_Realloc(a,b)    MPIU_trrealloc((a),(b),__LINE__,__FILE__)
  255 
  256 /* Define these as invalid C to catch their use in the code */
  257 #define malloc(a)         'Error use MPIU_Malloc' :::
  258 #define calloc(a,b)       'Error use MPIU_Calloc' :::
  259 #define free(a)           'Error use MPIU_Free'   :::
  260 #define realloc(a,b)      'Error use MPIU_Realloc' :::
  261 
  262 #if defined(strdup) || defined(__strdup)
  263 #undef strdup
  264 #endif
  265     /* We include string.h first, so that if it contains a definition of 
  266      strdup, we won't have an obscure failure when a file include string.h
  267     later in the compilation process. */
  268 #include <string.h>
  269 
  270     /* The ::: should cause the compiler to choke; the string 
  271        will give the explanation */
  272 #undef strdup /* in case strdup is a macro */
  273 #define strdup(a)         'Error use MPIU_Strdup' :::
  274 
  275 #else /* USE_MEMORY_TRACING */
  276 /* No memory tracing; just use native functions */
  277 #define MPIU_Malloc(a)    malloc((size_t)(a))
  278 #define MPIU_Calloc(a,b)  calloc((size_t)(a),(size_t)(b))
  279 #define MPIU_Free(a)        \
  280 do {                        \
  281     free((void *)(a));      \
  282     (a) = NULL;             \
  283 } while (0)
  284 #define MPIU_Realloc(a,b)  realloc((void *)(a),(size_t)(b))
  285 
  286 #ifdef HAVE_STRDUP
  287 /* Watch for the case where strdup is defined as a macro by a header include */
  288 # if defined(NEEDS_STRDUP_DECL) && !defined(strdup)
  289 extern char *strdup( const char * );
  290 # endif
  291 #define MPIU_Strdup(a)    strdup(a)
  292 #else
  293 /* Don't define MPIU_Strdup, provide it in safestr.c */
  294 #endif /* HAVE_STRDUP */
  295 #endif /* USE_MEMORY_TRACING */
  296 
  297 #ifdef _OSU_MVAPICH_
  298 #   if ENABLE_PVAR_MEM
  299 #       undef MPIU_Malloc
  300 #       undef MPIU_Calloc
  301 #       undef MPIU_Free
  302 #       undef MPIU_Strdup
  303 #       undef MPIU_Realloc
  304 #
  305 void *MPIT_malloc (size_t size, int lineno, char const * filename);
  306 void *MPIT_calloc (size_t nelements, size_t elementSize, int lineno, char const *filename);
  307 void MPIT_free (void * ptr, int lineno, char const * filename);
  308 char *MPIT_strdup (const char * s, int lineno, char const * filename);
  309 void *MPIT_realloc (void * ptr, size_t size, int lineno, char const * filename);
  310 int MPIT_memalign (void ** ptr, size_t alignment, size_t size, int lineno, char const * filename);
  311 void MPIT_memalign_free (void * ptr, int lineno, char const * filename);
  312 void MPIT_shmdt (void * ptr, int lineno, char const * filename);
  313 #       define MPIU_Malloc(a)       MPIT_malloc(a, __LINE__, __FILE__)
  314 #       define MPIU_Calloc(a,b)     MPIT_calloc(a, b, __LINE__, __FILE__)
  315 #       define MPIU_Free(a)                     \
  316         do {                                    \
  317             MPIT_free((void *)(a), __LINE__, __FILE__);   \
  318             (a) = NULL;                         \
  319         } while(0)
  320 #       define MPIU_Strdup(a)       MPIT_strdup(a, __LINE__, __FILE__)
  321 #       define MPIU_Realloc(a,b)    MPIT_realloc(a, b, __LINE__, __FILE__)
  322 #       define MPIU_Memalign(a,b,c) MPIT_memalign(a, b, c, __LINE__, __FILE__)
  323 #       define MPIU_Memalign_Free(a) MPIT_memalign_free(a, __LINE__, __FILE__)
  324 #       define MPIU_shmdt(a)        MPIT_shmdt(a, __LINE__, __FILE__)
  325 #   else /* ENABLE_PVAR_MEM */
  326 /*
  327  * Forward declaration of function used to call the real free function
  328  */
  329 void Real_Free (void * ptr);
  330 #       define MPIU_Memalign(a,b,c) posix_memalign(a, b, c)
  331 #       define MPIU_Memalign_Free(a) Real_Free(a)
  332 #       define MPIU_shmdt(a) shmdt(a)
  333 #   endif /* ENABLE_PVAR_MEM */
  334 #endif /* _OSU_MVAPICH_ */
  335 
  336 /* Memory allocation macros. See document. */
  337 
  338 /* Standard macro for generating error codes.  We set the error to be
  339  * recoverable by default, but this can be changed. */
  340 #ifdef HAVE_ERROR_CHECKING
  341 #define MPIU_CHKMEM_SETERR(rc_,nbytes_,name_) \
  342      rc_=MPIR_Err_create_code( MPI_SUCCESS, \
  343           MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, \
  344           MPI_ERR_OTHER, "**nomem2", "**nomem2 %d %s", nbytes_, name_ )
  345 #else
  346 #define MPIU_CHKMEM_SETERR(rc_,nbytes_,name_) rc_=MPI_ERR_OTHER
  347 #endif
  348 
  349     /* CHKPMEM_REGISTER is used for memory allocated within another routine */
  350 
  351 /* Memory used and freed within the current scopy (alloca if feasible) */
  352 /* Configure with --enable-alloca to set USE_ALLOCA */
  353 #if defined(HAVE_ALLOCA) && defined(USE_ALLOCA)
  354 #ifdef HAVE_ALLOCA_H
  355 #include <alloca.h>
  356 #endif
  357 /* Define decl with a dummy definition to allow us to put a semi-colon
  358    after the macro without causing the declaration block to end (restriction
  359    imposed by C) */
  360 #define MPIU_CHKLMEM_DECL(n_) int dummy_ ATTRIBUTE((unused))
  361 #define MPIU_CHKLMEM_FREEALL()
  362 #define MPIU_CHKLMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,stmt_) \
  363 {pointer_ = (type_)alloca(nbytes_); \
  364     if (!(pointer_) && (nbytes_ > 0)) {    \
  365     MPIU_CHKMEM_SETERR(rc_,nbytes_,name_); \
  366     stmt_;\
  367 }}
  368 #else
  369 #define MPIU_CHKLMEM_DECL(n_) \
  370  void *(mpiu_chklmem_stk_[n_]); \
  371  int mpiu_chklmem_stk_sp_=0;\
  372  MPIU_AssertDeclValue(const int mpiu_chklmem_stk_sz_,n_)
  373 
  374 #define MPIU_CHKLMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,stmt_) \
  375 {pointer_ = (type_)MPIU_Malloc(nbytes_); \
  376 if (pointer_) { \
  377     MPIU_Assert(mpiu_chklmem_stk_sp_<mpiu_chklmem_stk_sz_);\
  378     mpiu_chklmem_stk_[mpiu_chklmem_stk_sp_++] = pointer_;\
  379  } else if (nbytes_ > 0) {               \
  380     MPIU_CHKMEM_SETERR(rc_,nbytes_,name_); \
  381     stmt_;\
  382 }}
  383 #define MPIU_CHKLMEM_FREEALL() \
  384     do { while (--mpiu_chklmem_stk_sp_ >= 0) {\
  385        MPIU_Free( mpiu_chklmem_stk_[mpiu_chklmem_stk_sp_] ); } } while(0)
  386 #endif /* HAVE_ALLOCA */
  387 #define MPIU_CHKLMEM_MALLOC(pointer_,type_,nbytes_,rc_,name_) \
  388     MPIU_CHKLMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_)
  389 #define MPIU_CHKLMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) \
  390     MPIU_CHKLMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,goto fn_fail)
  391 
  392 /* In some cases, we need to allocate large amounts of memory. This can
  393    be a problem if alloca is used, as the available stack space may be small.
  394    This is the same approach for the temporary memory as is used when alloca
  395    is not available. */
  396 #define MPIU_CHKLBIGMEM_DECL(n_) \
  397  void *(mpiu_chklbigmem_stk_[n_]);\
  398  int mpiu_chklbigmem_stk_sp_=0;\
  399  MPIU_AssertDeclValue(const int mpiu_chklbigmem_stk_sz_,n_)
  400 
  401 #define MPIU_CHKLBIGMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,stmt_) \
  402 {pointer_ = (type_)MPIU_Malloc(nbytes_); \
  403 if (pointer_) { \
  404     MPIU_Assert(mpiu_chklbigmem_stk_sp_<mpiu_chklbigmem_stk_sz_);\
  405     mpiu_chklbigmem_stk_[mpiu_chklbigmem_stk_sp_++] = pointer_;\
  406  } else if (nbytes_ > 0) {                     \
  407     MPIU_CHKMEM_SETERR(rc_,nbytes_,name_); \
  408     stmt_;\
  409 }}
  410 #define MPIU_CHKLBIGMEM_FREEALL() \
  411     { while (mpiu_chklbigmem_stk_sp_ > 0) {\
  412        MPIU_Free( mpiu_chklbigmem_stk_[--mpiu_chklbigmem_stk_sp_] ); } }
  413 
  414 #define MPIU_CHKLBIGMEM_MALLOC(pointer_,type_,nbytes_,rc_,name_) \
  415     MPIU_CHKLBIGMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_)
  416 #define MPIU_CHKLBIGMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) \
  417     MPIU_CHKLBIGMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,goto fn_fail)
  418 
  419 /* Persistent memory that we may want to recover if something goes wrong */
  420 #define MPIU_CHKPMEM_DECL(n_) \
  421  void *(mpiu_chkpmem_stk_[n_]) = { NULL };     \
  422  int mpiu_chkpmem_stk_sp_=0;\
  423  MPIU_AssertDeclValue(const int mpiu_chkpmem_stk_sz_,n_)
  424 #define MPIU_CHKPMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,stmt_) \
  425 {pointer_ = (type_)MPIU_Malloc(nbytes_); \
  426 if (pointer_) { \
  427     MPIU_Assert(mpiu_chkpmem_stk_sp_<mpiu_chkpmem_stk_sz_);\
  428     mpiu_chkpmem_stk_[mpiu_chkpmem_stk_sp_++] = pointer_;\
  429  } else if (nbytes_ > 0) {               \
  430     MPIU_CHKMEM_SETERR(rc_,nbytes_,name_); \
  431     stmt_;\
  432 }}
  433 #define MPIU_CHKPMEM_REGISTER(pointer_) \
  434     {MPIU_Assert(mpiu_chkpmem_stk_sp_<mpiu_chkpmem_stk_sz_);\
  435     mpiu_chkpmem_stk_[mpiu_chkpmem_stk_sp_++] = pointer_;}
  436 #define MPIU_CHKPMEM_REAP() \
  437     { while (--mpiu_chkpmem_stk_sp_ >= 0) {\
  438        MPIU_Free( mpiu_chkpmem_stk_[mpiu_chkpmem_stk_sp_] ); } }
  439 #define MPIU_CHKPMEM_COMMIT() \
  440     mpiu_chkpmem_stk_sp_ = 0
  441 #define MPIU_CHKPMEM_MALLOC(pointer_,type_,nbytes_,rc_,name_) \
  442     MPIU_CHKPMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_)
  443 #define MPIU_CHKPMEM_MALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) \
  444     MPIU_CHKPMEM_MALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,goto fn_fail)
  445 
  446 /* now the CALLOC version for zeroed memory */
  447 #define MPIU_CHKPMEM_CALLOC(pointer_,type_,nbytes_,rc_,name_) \
  448     MPIU_CHKPMEM_CALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_)
  449 #define MPIU_CHKPMEM_CALLOC_ORJUMP(pointer_,type_,nbytes_,rc_,name_) \
  450     MPIU_CHKPMEM_CALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,goto fn_fail)
  451 #define MPIU_CHKPMEM_CALLOC_ORSTMT(pointer_,type_,nbytes_,rc_,name_,stmt_) \
  452     do {                                                                   \
  453         pointer_ = (type_)MPIU_Calloc(1, (nbytes_));                       \
  454         if (pointer_) {                                                    \
  455             MPIU_Assert(mpiu_chkpmem_stk_sp_<mpiu_chkpmem_stk_sz_);        \
  456             mpiu_chkpmem_stk_[mpiu_chkpmem_stk_sp_++] = pointer_;          \
  457         }                                                                  \
  458         else if (nbytes_ > 0) {                                            \
  459             MPIU_CHKMEM_SETERR(rc_,nbytes_,name_);                         \
  460             stmt_;                                                         \
  461         }                                                                  \
  462     } while (0)
  463 
  464 /* A special version for routines that only allocate one item */
  465 #define MPIU_CHKPMEM_MALLOC1(pointer_,type_,nbytes_,rc_,name_,stmt_) \
  466 {pointer_ = (type_)MPIU_Malloc(nbytes_); \
  467     if (!(pointer_) && (nbytes_ > 0)) {    \
  468     MPIU_CHKMEM_SETERR(rc_,nbytes_,name_); \
  469     stmt_;\
  470 }}
  471 
  472 /* Provides a easy way to use realloc safely and avoid the temptation to use
  473  * realloc unsafely (direct ptr assignment).  Zero-size reallocs returning NULL
  474  * are handled and are not considered an error. */
  475 #define MPIU_REALLOC_OR_FREE_AND_JUMP(ptr_,size_,rc_) do { \
  476     void *realloc_tmp_ = MPIU_Realloc((ptr_), (size_)); \
  477     if ((size_) && !realloc_tmp_) { \
  478         MPIU_Free(ptr_); \
  479         MPIR_ERR_SETANDJUMP2(rc_,MPI_ERR_OTHER,"**nomem2","**nomem2 %d %s",(size_),MPL_QUOTE(ptr_)); \
  480     } \
  481     (ptr_) = realloc_tmp_; \
  482 } while (0)
  483 /* this version does not free ptr_ */
  484 #define MPIU_REALLOC_ORJUMP(ptr_,size_,rc_) do { \
  485     void *realloc_tmp_ = MPIU_Realloc((ptr_), (size_)); \
  486     if (size_) \
  487         MPIR_ERR_CHKANDJUMP2(!realloc_tmp_,rc_,MPI_ERR_OTHER,"**nomem2","**nomem2 %d %s",(size_),MPL_QUOTE(ptr_)); \
  488     (ptr_) = realloc_tmp_; \
  489 } while (0)
  490 
  491 #if defined(HAVE_STRNCASECMP)
  492 #   define MPIU_Strncasecmp strncasecmp
  493 #elif defined(HAVE_STRNICMP)
  494 #   define MPIU_Strncasecmp strnicmp
  495 #else
  496 /* FIXME: Provide a fallback function ? */
  497 #   error "No function defined for case-insensitive strncmp"
  498 #endif
  499 
  500 /* MPIU_Basename(path, basename)
  501    This function finds the basename in a path (ala "man 1 basename").
  502    *basename will point to an element in path.
  503    More formally: This function sets basename to the character just after the last '/' in path.
  504 */
  505 void MPIU_Basename(char *path, char **basename);
  506 
  507 /* Evaluates to a boolean expression, true if the given byte ranges overlap,
  508  * false otherwise.  That is, true iff [a_,a_+a_len_) overlaps with [b_,b_+b_len_) */
  509 #define MPIU_MEM_RANGES_OVERLAP(a_,a_len_,b_,b_len_) \
  510     ( ((char *)(a_) >= (char *)(b_) && ((char *)(a_) < ((char *)(b_) + (b_len_)))) ||  \
  511       ((char *)(b_) >= (char *)(a_) && ((char *)(b_) < ((char *)(a_) + (a_len_)))) )
  512 #if (!defined(NDEBUG) && defined(HAVE_ERROR_CHECKING))
  513 
  514 /* May be used to perform sanity and range checking on memcpy and mempcy-like
  515    function calls.  This macro will bail out much like an MPIU_Assert if any of
  516    the checks fail. */
  517 #define MPIU_MEM_CHECK_MEMCPY(dst_,src_,len_)                                                                   \
  518     do {                                                                                                        \
  519         if (len_ > 0) {                                                                                             \
  520             MPIU_Assert((dst_) != NULL);                                                                        \
  521             MPIU_Assert((src_) != NULL);                                                                        \
  522             MPL_VG_CHECK_MEM_IS_ADDRESSABLE((dst_),(len_));                                                     \
  523             MPL_VG_CHECK_MEM_IS_ADDRESSABLE((src_),(len_));                                                     \
  524             if (MPIU_MEM_RANGES_OVERLAP((dst_),(len_),(src_),(len_))) {                                          \
  525                 MPIU_Assert_fmt_msg(FALSE,("memcpy argument memory ranges overlap, dst_=%p src_=%p len_=%ld\n", \
  526                                            (dst_), (src_), (long)(len_)));                                      \
  527             }                                                                                                   \
  528         }                                                                                                       \
  529     } while (0)
  530 
  531 /* #if defined(CHANNEL_MRAIL) */
  532 #define MPIU_MEM_CHECK_MEMSET(dst_,c_,len_)                  \
  533     do {                                                     \
  534           MPIU_Assert( len_>0 );                              \
  535           MPL_VG_CHECK_MEM_IS_ADDRESSABLE((dst_),(len_));   \
  536     } while (0)
  537 /* #endif / * defined(CHANNEL_MRAIL) */
  538 
  539 #else
  540 #define MPIU_MEM_CHECK_MEMCPY(dst_,src_,len_) do {} while(0)
  541 /* #if defined(CHANNEL_MRAIL) */
  542   #define MPIU_MEM_CHECK_MEMSET(dst_,c_,len_)
  543 /* #endif / * defined(CHANNEL_MRAIL) */
  544 #endif
  545 
  546 /* valgrind macros are now provided by MPL (via mpl.h included in mpiimpl.h) */
  547 
  548 /* ------------------------------------------------------------------------- */
  549 /* end of mpimem.h */
  550 /* ------------------------------------------------------------------------- */
  551 
  552 #if defined(__cplusplus)
  553 }
  554 #endif
  555 #endif