summaryrefslogtreecommitdiffstats
path: root/src/H5MM.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5MM.c')
-rw-r--r--src/H5MM.c408
1 files changed, 7 insertions, 401 deletions
diff --git a/src/H5MM.c b/src/H5MM.c
index 4213e0f..aa4c6ce 100644
--- a/src/H5MM.c
+++ b/src/H5MM.c
@@ -13,8 +13,6 @@
/*-------------------------------------------------------------------------
*
* Created: H5MM.c
- * Jul 10 1997
- * Robb Matzke
*
* Purpose: Memory management functions
*
@@ -35,45 +33,14 @@
/****************/
/* Local Macros */
/****************/
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
-#define H5MM_SIG_SIZE 4
-#define H5MM_HEAD_GUARD_SIZE 8
-#define H5MM_TAIL_GUARD_SIZE 8
-#define H5MM_BLOCK_FROM_BUF(mem) \
- ((H5MM_block_t *)((void *)((unsigned char *)mem - (offsetof(H5MM_block_t, b) + H5MM_HEAD_GUARD_SIZE))))
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/******************/
/* Local Typedefs */
/******************/
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
-/* Memory allocation "block", wrapped around each allocation */
-struct H5MM_block_t; /* Forward declaration for typedef */
-typedef struct H5MM_block_t {
- unsigned char
- sig[H5MM_SIG_SIZE]; /* Signature for the block, to indicate it was allocated with H5MM* interface */
- struct H5MM_block_t *next; /* Pointer to next block in the list of allocated blocks */
- struct H5MM_block_t *prev; /* Pointer to previous block in the list of allocated blocks */
- union {
- struct {
- size_t size; /* Size of allocated block */
- hbool_t in_use; /* Whether the block is in use or is free */
- } info;
- double _align; /* Align following buffer (b) to double boundary (unused) */
- } u;
- unsigned char b[]; /* Buffer for caller (includes header and footer) */
-} H5MM_block_t;
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
-
/********************/
/* Local Prototypes */
/********************/
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
-static hbool_t H5MM__is_our_block(void *mem);
-static void H5MM__sanity_check_block(const H5MM_block_t *block);
-static void H5MM__sanity_check(void *mem);
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
/*********************/
/* Package Variables */
@@ -87,152 +54,6 @@ static void H5MM__sanity_check(void *mem);
/* Local Variables */
/*******************/
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
-/* Constant strings for block signature, head & tail guards */
-static const char H5MM_block_signature_s[H5MM_SIG_SIZE] = {'H', '5', 'M', 'M'};
-static const char H5MM_block_head_guard_s[H5MM_HEAD_GUARD_SIZE] = {'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F'};
-static const char H5MM_block_tail_guard_s[H5MM_TAIL_GUARD_SIZE] = {'B', 'E', 'E', 'F', 'D', 'E', 'A', 'D'};
-
-/* Flag to indicate the the interface has been initialized */
-static hbool_t H5MM_init_s = FALSE;
-
-/* Head of the list of allocated blocks */
-static H5MM_block_t H5MM_block_head_s;
-
-/* Statistics about block allocations */
-static unsigned long long H5MM_total_alloc_bytes_s = 0;
-static size_t H5MM_curr_alloc_bytes_s = 0;
-static size_t H5MM_peak_alloc_bytes_s = 0;
-static size_t H5MM_max_block_size_s = 0;
-static size_t H5MM_total_alloc_blocks_count_s = 0;
-static size_t H5MM_curr_alloc_blocks_count_s = 0;
-static size_t H5MM_peak_alloc_blocks_count_s = 0;
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
-
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
-
-/*-------------------------------------------------------------------------
- * Function: H5MM__is_our_block
- *
- * Purpose: Try to determine if a memory buffer has been allocated through
- * the H5MM* interface, instead of the system's malloc() routines.
- *
- * Return: Success: TRUE/FALSE
- * Failure: (Can't fail)
- *
- * Programmer: Quincey Koziol
- * Dec 30 2015
- *
- *-------------------------------------------------------------------------
- */
-static hbool_t
-H5MM__is_our_block(void *mem)
-{
- H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
-
- return (0 == HDmemcmp(block->sig, H5MM_block_signature_s, H5MM_SIG_SIZE));
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5MM__sanity_check_block
- *
- * Purpose: Check a block wrapper around a buffer to validate it.
- *
- * Return: N/A (void)
- *
- * Programmer: Quincey Koziol
- * Dec 30 2015
- *
- *-------------------------------------------------------------------------
- */
-static void
-H5MM__sanity_check_block(const H5MM_block_t *block)
-{
- HDassert(block->u.info.size > 0);
- HDassert(block->u.info.in_use);
- /* Check for head & tail guards, if not head of linked list */
- if (block->u.info.size != SIZE_MAX) {
- HDassert(0 == HDmemcmp(block->b, H5MM_block_head_guard_s, H5MM_HEAD_GUARD_SIZE));
- HDassert(0 == HDmemcmp(block->b + H5MM_HEAD_GUARD_SIZE + block->u.info.size, H5MM_block_tail_guard_s,
- H5MM_TAIL_GUARD_SIZE));
- }
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5MM__sanity_check
- *
- * Purpose: Check a buffer to validate it (just calls
- * H5MM__sanity_check_block after finding block for buffer)
- *
- * Return: N/A (void)
- *
- * Programmer: Quincey Koziol
- * Dec 30 2015
- *
- *-------------------------------------------------------------------------
- */
-static void
-H5MM__sanity_check(void *mem)
-{
- H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
-
- H5MM__sanity_check_block(block);
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5MM_sanity_check_all
- *
- * Purpose: Sanity check all current memory allocations.
- *
- * Return: N/A (void)
- *
- * Programmer: Quincey Koziol
- * Jan 5 2016
- *
- *-------------------------------------------------------------------------
- */
-void
-H5MM_sanity_check_all(void)
-{
- H5MM_block_t *curr = NULL;
-
- curr = H5MM_block_head_s.next;
- while (curr != &H5MM_block_head_s) {
- H5MM__sanity_check_block(curr);
- curr = curr->next;
- } /* end while */
-} /* end H5MM_sanity_check_all() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MM_final_sanity_check
- *
- * Purpose: Final sanity checks on memory allocation.
- *
- * Return: N/A (void)
- *
- * Programmer: Quincey Koziol
- * Jan 1 2016
- *
- *-------------------------------------------------------------------------
- */
-void
-H5MM_final_sanity_check(void)
-{
- HDassert(0 == H5MM_curr_alloc_bytes_s);
- HDassert(0 == H5MM_curr_alloc_blocks_count_s);
- HDassert(H5MM_block_head_s.next == &H5MM_block_head_s);
- HDassert(H5MM_block_head_s.prev == &H5MM_block_head_s);
-#ifdef H5MM_PRINT_MEMORY_STATS
- HDfprintf(stderr, "%s: H5MM_total_alloc_bytes_s = %llu\n", __func__, H5MM_total_alloc_bytes_s);
- HDfprintf(stderr, "%s: H5MM_peak_alloc_bytes_s = %zu\n", __func__, H5MM_peak_alloc_bytes_s);
- HDfprintf(stderr, "%s: H5MM_max_block_size_s = %zu\n", __func__, H5MM_max_block_size_s);
- HDfprintf(stderr, "%s: H5MM_total_alloc_blocks_count_s = %zu\n", __func__,
- H5MM_total_alloc_blocks_count_s);
- HDfprintf(stderr, "%s: H5MM_peak_alloc_blocks_count_s = %zu\n", __func__, H5MM_peak_alloc_blocks_count_s);
-#endif /* H5MM_PRINT_MEMORY_STATS */
-}
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
-
/*-------------------------------------------------------------------------
* Function: H5MM_malloc
*
@@ -246,10 +67,6 @@ H5MM_final_sanity_check(void)
*
* Return: Success: Pointer to new memory
* Failure: NULL
- *
- * Programmer: Quincey Koziol
- * Nov 8 2003
- *
*-------------------------------------------------------------------------
*/
void *
@@ -260,60 +77,7 @@ H5MM_malloc(size_t size)
/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- /* Initialize block list head singleton */
- if (!H5MM_init_s) {
- H5MM_memcpy(H5MM_block_head_s.sig, H5MM_block_signature_s, H5MM_SIG_SIZE);
- H5MM_block_head_s.next = &H5MM_block_head_s;
- H5MM_block_head_s.prev = &H5MM_block_head_s;
- H5MM_block_head_s.u.info.size = SIZE_MAX;
- H5MM_block_head_s.u.info.in_use = TRUE;
-
- H5MM_init_s = TRUE;
- } /* end if */
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
-
- if (size) {
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- H5MM_block_t *block;
- size_t alloc_size = sizeof(H5MM_block_t) + size + H5MM_HEAD_GUARD_SIZE + H5MM_TAIL_GUARD_SIZE;
-
- if (NULL != (block = (H5MM_block_t *)HDmalloc(alloc_size))) {
- /* Set up block */
- H5MM_memcpy(block->sig, H5MM_block_signature_s, H5MM_SIG_SIZE);
- block->next = H5MM_block_head_s.next;
- H5MM_block_head_s.next = block;
- block->next->prev = block;
- block->prev = &H5MM_block_head_s;
- block->u.info.size = size;
- block->u.info.in_use = TRUE;
- H5MM_memcpy(block->b, H5MM_block_head_guard_s, H5MM_HEAD_GUARD_SIZE);
- H5MM_memcpy(block->b + H5MM_HEAD_GUARD_SIZE + size, H5MM_block_tail_guard_s,
- H5MM_TAIL_GUARD_SIZE);
-
- /* Update statistics */
- H5MM_total_alloc_bytes_s += size;
- H5MM_curr_alloc_bytes_s += size;
- if (H5MM_curr_alloc_bytes_s > H5MM_peak_alloc_bytes_s)
- H5MM_peak_alloc_bytes_s = H5MM_curr_alloc_bytes_s;
- if (size > H5MM_max_block_size_s)
- H5MM_max_block_size_s = size;
- H5MM_total_alloc_blocks_count_s++;
- H5MM_curr_alloc_blocks_count_s++;
- if (H5MM_curr_alloc_blocks_count_s > H5MM_peak_alloc_blocks_count_s)
- H5MM_peak_alloc_blocks_count_s = H5MM_curr_alloc_blocks_count_s;
-
- /* Set buffer to return */
- ret_value = block->b + H5MM_HEAD_GUARD_SIZE;
- } /* end if */
- else
- ret_value = NULL;
-#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
- ret_value = HDmalloc(size);
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
- } /* end if */
- else
- ret_value = NULL;
+ ret_value = HDmalloc(size);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_malloc() */
@@ -330,13 +94,8 @@ H5MM_malloc(size_t size)
* considered an error condition since allocations of zero
* bytes usually indicate problems.
*
- *
* Return: Success: Pointer to new memory
* Failure: NULL
- *
- * Programmer: Quincey Koziol
- * Nov 8 2003
- *
*-------------------------------------------------------------------------
*/
void *
@@ -347,16 +106,7 @@ H5MM_calloc(size_t size)
/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (size) {
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- if (NULL != (ret_value = H5MM_malloc(size)))
- HDmemset(ret_value, 0, size);
-#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
- ret_value = HDcalloc((size_t)1, size);
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
- } /* end if */
- else
- ret_value = NULL;
+ ret_value = HDcalloc(1, size);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_calloc() */
@@ -377,10 +127,6 @@ H5MM_calloc(size_t size)
* Return: Success: Ptr to new memory if size > 0
* NULL if size is zero
* Failure: NULL (input buffer is unchanged on failure)
- *
- * Programmer: Robb Matzke
- * Jul 10 1997
- *
*-------------------------------------------------------------------------
*/
void *
@@ -395,35 +141,12 @@ H5MM_realloc(void *mem, size_t size)
/* Not defined in the standard, return NULL */
ret_value = NULL;
else {
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- if (size > 0) {
- if (mem) {
- if (H5MM__is_our_block(mem)) {
- H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
- size_t old_size = block->u.info.size;
-
- H5MM__sanity_check(mem);
-
- ret_value = H5MM_malloc(size);
- H5MM_memcpy(ret_value, mem, MIN(size, old_size));
- H5MM_xfree(mem);
- } /* end if */
- else
- ret_value = HDrealloc(mem, size);
- }
- else
- ret_value = H5MM_malloc(size);
- }
- else
- ret_value = H5MM_xfree(mem);
-#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
ret_value = HDrealloc(mem, size);
/* Some platforms do not return NULL if size is zero. */
if (0 == size)
ret_value = NULL;
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
- } /* end else */
+ }
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_realloc() */
@@ -436,9 +159,6 @@ H5MM_realloc(void *mem, size_t size)
*
* Return: Success: Pointer to a new string (NULL if s is NULL).
* Failure: NULL
- *
- * Programmer: Robb Matzke
- * Jul 10 1997
*-------------------------------------------------------------------------
*/
char *
@@ -448,18 +168,9 @@ H5MM_xstrdup(const char *s)
FUNC_ENTER_NOAPI(NULL)
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- if (s) {
- if (NULL == (ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDstrcpy(ret_value, s);
- }
-#else
if (s)
if (NULL == (ret_value = HDstrdup(s)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed")
-#endif
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MM_xstrdup() */
@@ -475,9 +186,6 @@ done:
*
* Return: Success: Pointer to a new string
* Failure: NULL
- *
- * Programmer: Robb Matzke
- * Jul 10 1997
*-------------------------------------------------------------------------
*/
char *
@@ -489,14 +197,8 @@ H5MM_strdup(const char *s)
if (!s)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL string not allowed")
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- if (NULL == (ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDstrcpy(ret_value, s);
-#else
if (NULL == (ret_value = HDstrdup(s)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed")
-#endif
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -521,9 +223,6 @@ done:
char *
H5MM_strndup(const char *s, size_t n)
{
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- size_t len;
-#endif
char *ret_value = NULL;
FUNC_ENTER_NOAPI(NULL)
@@ -531,19 +230,8 @@ H5MM_strndup(const char *s, size_t n)
if (!s)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL string not allowed")
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- for (len = 0; len < n && s[len] != '\0'; len++)
- ;
-
- if (NULL == (ret_value = H5MM_malloc(len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- H5MM_memcpy(ret_value, s, len);
- ret_value[len] = '\0';
-#else
if (NULL == (ret_value = HDstrndup(s, n)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "string duplication failed")
-#endif
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -552,18 +240,13 @@ done:
/*-------------------------------------------------------------------------
* Function: H5MM_xfree
*
- * Purpose: Just like free(3) except null pointers are allowed as
- * arguments, and the return value (always NULL) can be
- * assigned to the pointer whose memory was just freed:
+ * Purpose: Just like free(3) except the return value (always NULL) can
+ * be assigned to the pointer whose memory was just freed:
*
- * thing = H5MM_xfree (thing);
+ * thing = H5MM_xfree(thing);
*
* Return: Success: NULL
* Failure: never fails
- *
- * Programmer: Robb Matzke
- * Jul 10 1997
- *
*-------------------------------------------------------------------------
*/
void *
@@ -572,37 +255,7 @@ H5MM_xfree(void *mem)
/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (mem) {
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- if (H5MM__is_our_block(mem)) {
- H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem);
-
- /* Run sanity checks on this block and its neighbors */
- H5MM__sanity_check(mem);
- H5MM__sanity_check_block(block->next);
- H5MM__sanity_check_block(block->prev);
-
- /* Update statistics */
- H5MM_curr_alloc_bytes_s -= block->u.info.size;
- H5MM_curr_alloc_blocks_count_s--;
-
- /* Reset block info */
- HDmemset(block->sig, 0, H5MM_SIG_SIZE);
- block->next->prev = block->prev;
- block->prev->next = block->next;
- block->next = NULL;
- block->prev = NULL;
- block->u.info.in_use = FALSE;
-
- /* Free the block (finally!) */
- HDfree(block);
- }
- else
- HDfree(mem);
-#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
- HDfree(mem);
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
- } /* end if */
+ HDfree(mem);
FUNC_LEAVE_NOAPI(NULL)
} /* end H5MM_xfree() */
@@ -616,7 +269,6 @@ H5MM_xfree(void *mem)
*
* Return: Success: NULL
* Failure: never fails
- *
*-------------------------------------------------------------------------
*/
void *
@@ -639,10 +291,6 @@ H5MM_xfree_const(const void *mem)
*
* Return: Success: pointer to dest
* Failure: NULL
- *
- * Programmer: Dana Robinson
- * Spring 2019
- *
*-------------------------------------------------------------------------
*/
void *
@@ -665,45 +313,3 @@ H5MM_memcpy(void *dest, const void *src, size_t n)
FUNC_LEAVE_NOAPI(ret)
} /* end H5MM_memcpy() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MM_get_alloc_stats
- *
- * Purpose: Gets the memory allocation statistics for the library, if the
- * H5_MEMORY_ALLOC_SANITY_CHECK macro is defined. If the macro is not
- * defined, zeros are returned. These statistics are global for the
- * entire library.
- *
- * Parameters:
- * H5_alloc_stats_t *stats; OUT: Memory allocation statistics
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Saturday, March 7, 2020
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5MM_get_alloc_stats(H5_alloc_stats_t *stats)
-{
- FUNC_ENTER_NOAPI_NOERR
-
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
- if (stats) {
- stats->total_alloc_bytes = H5MM_total_alloc_bytes_s;
- stats->curr_alloc_bytes = H5MM_curr_alloc_bytes_s;
- stats->peak_alloc_bytes = H5MM_peak_alloc_bytes_s;
- stats->max_block_size = H5MM_max_block_size_s;
- stats->total_alloc_blocks_count = H5MM_total_alloc_blocks_count_s;
- stats->curr_alloc_blocks_count = H5MM_curr_alloc_blocks_count_s;
- stats->peak_alloc_blocks_count = H5MM_peak_alloc_blocks_count_s;
- } /* end if */
-#else /* H5_MEMORY_ALLOC_SANITY_CHECK */
- if (stats)
- HDmemset(stats, 0, sizeof(H5_alloc_stats_t));
-#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5MM_get_alloc_stats() */