diff options
author | Quincey Koziol <koziol@koziol.gov> | 2020-06-26 23:57:38 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@koziol.gov> | 2020-06-26 23:57:38 (GMT) |
commit | e767f44e953047297fece364218147c908e8b585 (patch) | |
tree | d4b6909f14b78bb732b6947adc46ac3cd3ca54f6 /src/H5MM.c | |
parent | 949649a2b6e00297cbdc49437e70a27e455e92d2 (diff) | |
parent | a08ab621febde7b09e4d86eab80cb029c123e9f6 (diff) | |
download | hdf5-e767f44e953047297fece364218147c908e8b585.zip hdf5-e767f44e953047297fece364218147c908e8b585.tar.gz hdf5-e767f44e953047297fece364218147c908e8b585.tar.bz2 |
Merge remote-tracking branch 'origin/develop' into monotonic_timer
Diffstat (limited to 'src/H5MM.c')
-rw-r--r-- | src/H5MM.c | 140 |
1 files changed, 119 insertions, 21 deletions
@@ -43,7 +43,7 @@ #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 *)((unsigned char *)mem - (offsetof(H5MM_block_t, b) + H5MM_HEAD_GUARD_SIZE))) +#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 */ @@ -108,8 +108,8 @@ static H5MM_block_t H5MM_block_head_s; /* Statistics about block allocations */ static unsigned long long H5MM_total_alloc_bytes_s = 0; -static unsigned long long H5MM_curr_alloc_bytes_s = 0; -static unsigned long long H5MM_peak_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; @@ -154,7 +154,7 @@ H5MM__is_our_block(void *mem) * *------------------------------------------------------------------------- */ -H5_ATTR_PURE static void +static void H5MM__sanity_check_block(const H5MM_block_t *block) { HDassert(block->u.info.size > 0); @@ -180,7 +180,7 @@ H5MM__sanity_check_block(const H5MM_block_t *block) * *------------------------------------------------------------------------- */ -H5_ATTR_PURE static void +static void H5MM__sanity_check(void *mem) { H5MM_block_t *block = H5MM_BLOCK_FROM_BUF(mem); @@ -201,7 +201,7 @@ H5MM__sanity_check(void *mem) * *------------------------------------------------------------------------- */ -H5_ATTR_PURE void +void H5MM_sanity_check_all(void) { H5MM_block_t *curr = NULL; @@ -226,7 +226,7 @@ H5MM_sanity_check_all(void) * *------------------------------------------------------------------------- */ -H5_ATTR_PURE void +void H5MM_final_sanity_check(void) { HDassert(0 == H5MM_curr_alloc_bytes_s); @@ -235,7 +235,7 @@ H5MM_final_sanity_check(void) 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 = %llu\n", __func__, H5MM_peak_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); @@ -254,7 +254,7 @@ H5MM_final_sanity_check(void) * difficult to check as a return value. This is still * considered an error condition since allocations of zero * bytes usually indicate problems. - * + * * Return: Success: Pointer to new memory * Failure: NULL * @@ -268,15 +268,13 @@ H5MM_malloc(size_t size) { void *ret_value = NULL; - HDassert(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) { - HDmemcpy(H5MM_block_head_s.sig, H5MM_block_signature_s, H5MM_SIG_SIZE); + 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 = SIZET_MAX; @@ -293,15 +291,15 @@ H5MM_malloc(size_t size) if(NULL != (block = (H5MM_block_t *)HDmalloc(alloc_size))) { /* Set up block */ - HDmemcpy(block->sig, H5MM_block_signature_s, H5MM_SIG_SIZE); + 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; - HDmemcpy(block->b, H5MM_block_head_guard_s, H5MM_HEAD_GUARD_SIZE); - HDmemcpy(block->b + H5MM_HEAD_GUARD_SIZE + size, H5MM_block_tail_guard_s, H5MM_TAIL_GUARD_SIZE); + 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; @@ -357,8 +355,6 @@ H5MM_calloc(size_t size) { void *ret_value = NULL; - HDassert(size); - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -407,8 +403,6 @@ H5MM_realloc(void *mem, size_t size) /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOERR - HDassert(mem || size); - if(NULL == mem && 0 == size) /* Not defined in the standard, return NULL */ ret_value = NULL; @@ -423,7 +417,7 @@ H5MM_realloc(void *mem, size_t size) H5MM__sanity_check(mem); ret_value = H5MM_malloc(size); - HDmemcpy(ret_value, mem, MIN(size, old_size)); + H5MM_memcpy(ret_value, mem, MIN(size, old_size)); H5MM_xfree(mem); } /* end if */ else @@ -454,7 +448,7 @@ H5MM_realloc(void *mem, size_t size) * NULL is an acceptable value for the input string. * * Return: Success: Pointer to a new string (NULL if s is NULL). - * Failure: abort() + * Failure: NULL * * Programmer: Robb Matzke * Jul 10 1997 @@ -570,3 +564,107 @@ H5MM_xfree(void *mem) FUNC_LEAVE_NOAPI(NULL) } /* end H5MM_xfree() */ + +/*------------------------------------------------------------------------- + * Function: H5MM_xfree_const + * + * Purpose: H5MM_xfree() wrapper that handles const pointers without + * warnings. Used for freeing buffers that should be regarded + * as const in use but need to be freed when no longer needed. + * + * Return: Success: NULL + * Failure: never fails + * + *------------------------------------------------------------------------- + */ +void * +H5MM_xfree_const(const void *mem) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Cast through uintptr_t to de-const memory */ + H5MM_xfree((void *)(uintptr_t)mem); + + FUNC_LEAVE_NOAPI(NULL) +} /* end H5MM_xfree_const() */ + + +/*------------------------------------------------------------------------- + * Function: H5MM_memcpy + * + * Purpose: Like memcpy(3) but with sanity checks on the parameters, + * particularly buffer overlap. + * + * Return: Success: pointer to dest + * Failure: NULL + * + * Programmer: Dana Robinson + * Spring 2019 + * + *------------------------------------------------------------------------- + */ +void * +H5MM_memcpy(void *dest, const void *src, size_t n) +{ + void *ret = NULL; + + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(dest); + HDassert(src); + + /* Check for buffer overlap */ + HDassert((char *)dest >= (const char *)src + n || (const char *)src >= (char *)dest + n); + + /* Copy */ + ret = HDmemcpy(dest, src, 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() */ + |