diff options
author | Dana Robinson <derobins@hdfgroup.org> | 2021-04-07 18:25:39 (GMT) |
---|---|---|
committer | Dana Robinson <derobins@hdfgroup.org> | 2021-04-07 18:25:39 (GMT) |
commit | dfc2a0993c076387d96f08e812e6eb9a84e4b778 (patch) | |
tree | 694520f115c6807d21b21096e89fc9e2b1742877 /src | |
parent | b7dc1ef6f4c9e8a3e1dd4ee18f2dafcd763c21c1 (diff) | |
download | hdf5-dfc2a0993c076387d96f08e812e6eb9a84e4b778.zip hdf5-dfc2a0993c076387d96f08e812e6eb9a84e4b778.tar.gz hdf5-dfc2a0993c076387d96f08e812e6eb9a84e4b778.tar.bz2 |
Brings H5module.h from develop and fixes Autotools badness
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 47 | ||||
-rw-r--r-- | src/H5.c | 201 | ||||
-rw-r--r-- | src/H5checksum.c | 37 | ||||
-rw-r--r-- | src/H5dbg.c | 26 | ||||
-rw-r--r-- | src/H5err.txt | 2 | ||||
-rw-r--r-- | src/H5module.h | 34 | ||||
-rw-r--r-- | src/H5public.h | 567 | ||||
-rw-r--r-- | src/H5system.c | 1 | ||||
-rw-r--r-- | src/H5timer.c | 1 |
9 files changed, 811 insertions, 105 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a189f1b..1cceb87 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -651,6 +651,7 @@ set (H5TS_SOURCES ${HDF5_SRC_DIR}/H5TS.c ) set (H5TS_HDRS + ${HDF5_SRC_DIR}/H5TSpublic.h ) IDE_GENERATED_PROPERTIES ("H5TS" "${H5TS_HDRS}" "${H5TS_SOURCES}" ) @@ -726,6 +727,47 @@ set (H5Z_HDRS ) IDE_GENERATED_PROPERTIES ("H5Z" "${H5Z_HDRS}" "${H5Z_SOURCES}" ) +set (H5_MODULE_HEADERS + ${HDF5_SRC_DIR}/H5module.h + ${HDF5_SRC_DIR}/H5Amodule.h + ${HDF5_SRC_DIR}/H5ACmodule.h + ${HDF5_SRC_DIR}/H5Bmodule.h + ${HDF5_SRC_DIR}/H5B2module.h + ${HDF5_SRC_DIR}/H5Cmodule.h + ${HDF5_SRC_DIR}/H5CXmodule.h + ${HDF5_SRC_DIR}/H5Dmodule.h + ${HDF5_SRC_DIR}/H5Emodule.h + ${HDF5_SRC_DIR}/H5EAmodule.h + ${HDF5_SRC_DIR}/H5ESmodule.h + ${HDF5_SRC_DIR}/H5Fmodule.h + ${HDF5_SRC_DIR}/H5FAmodule.h + ${HDF5_SRC_DIR}/H5FDdrvr_module.h + ${HDF5_SRC_DIR}/H5FDmodule.h + ${HDF5_SRC_DIR}/H5FLmodule.h + ${HDF5_SRC_DIR}/H5FSmodule.h + ${HDF5_SRC_DIR}/H5Gmodule.h + ${HDF5_SRC_DIR}/H5HFmodule.h + ${HDF5_SRC_DIR}/H5HGmodule.h + ${HDF5_SRC_DIR}/H5HLmodule.h + ${HDF5_SRC_DIR}/H5Imodule.h + ${HDF5_SRC_DIR}/H5Lmodule.h + ${HDF5_SRC_DIR}/H5Mmodule.h + ${HDF5_SRC_DIR}/H5MFmodule.h + ${HDF5_SRC_DIR}/H5MPmodule.h + ${HDF5_SRC_DIR}/H5Omodule.h + ${HDF5_SRC_DIR}/H5Pmodule.h + ${HDF5_SRC_DIR}/H5PBmodule.h + ${HDF5_SRC_DIR}/H5PLmodule.h + ${HDF5_SRC_DIR}/H5Rmodule.h + ${HDF5_SRC_DIR}/H5RSmodule.h + ${HDF5_SRC_DIR}/H5Smodule.h + ${HDF5_SRC_DIR}/H5SLmodule.h + ${HDF5_SRC_DIR}/H5SMmodule.h + ${HDF5_SRC_DIR}/H5Tmodule.h + ${HDF5_SRC_DIR}/H5VLmodule.h + ${HDF5_SRC_DIR}/H5Zmodule.h +) + set (common_SRCS ${H5_SOURCES} ${H5A_SOURCES} @@ -809,6 +851,7 @@ set (H5_PUBLIC_HEADERS ${H5S_HDRS} ${H5SM_HDRS} ${H5T_HDRS} + ${H5TS_HDRS} ${H5VL_HDRS} ${H5Z_HDRS} ) @@ -982,7 +1025,7 @@ if (HDF5_GENERATE_HEADERS) ) message(STATUS ${SCRIPT_OUTPUT}) else () - message (STATUS "Cannot generate headers - perl not found") + message (WARNING "Cannot generate headers - perl not found") endif () endif () @@ -1157,7 +1200,7 @@ if (NOT ONLY_SHARED_LIBS) set (gen_SRCS ${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c ${HDF5_BINARY_DIR}/H5lib_settings.c) add_custom_target (gen_${HDF5_LIB_TARGET} ALL DEPENDS ${HDF5_GENERATED_SOURCE_DIR}/gen_SRCS.stamp1 ${HDF5_GENERATED_SOURCE_DIR}/gen_SRCS.stamp2) - add_library (${HDF5_LIB_TARGET} STATIC ${common_SRCS} ${gen_SRCS} ${H5_PUBLIC_HEADERS} ${H5_PRIVATE_HEADERS} ${H5_GENERATED_HEADERS}) + add_library (${HDF5_LIB_TARGET} STATIC ${common_SRCS} ${gen_SRCS} ${H5_PUBLIC_HEADERS} ${H5_PRIVATE_HEADERS} ${H5_GENERATED_HEADERS} ${H5_MODULE_HEADERS}) target_include_directories (${HDF5_LIB_TARGET} PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>" INTERFACE "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>;$<BUILD_INTERFACE:${HDF5_BINARY_DIR}>" @@ -14,6 +14,7 @@ /****************/ /* Module Setup */ /****************/ +#include "H5module.h" /* This source code file is part of the H5 module */ /***********/ /* Headers */ @@ -43,18 +44,28 @@ /* Package Typedefs */ /********************/ +/* Node for list of 'atclose' routines to invoke at library shutdown */ +typedef struct H5_atclose_node_t { + H5_atclose_func_t func; /* Function to invoke */ + void * ctx; /* Context to pass to function */ + struct H5_atclose_node_t *next; /* Pointer to next node in list */ +} H5_atclose_node_t; + /********************/ /* Local Prototypes */ /********************/ -static void H5_debug_mask(const char *); +static void H5__debug_mask(const char *); #ifdef H5_HAVE_PARALLEL -static int H5_mpi_delete_cb(MPI_Comm comm, int keyval, void *attr_val, int *flag); +static int H5__mpi_delete_cb(MPI_Comm comm, int keyval, void *attr_val, int *flag); #endif /*H5_HAVE_PARALLEL*/ /*********************/ /* Package Variables */ /*********************/ +/* Package initialization variable */ +hbool_t H5_PKG_INIT_VAR = FALSE; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -84,6 +95,39 @@ H5_debug_t H5_debug_g; /* debugging info */ /* Local Variables */ /*******************/ +/* Linked list of registered 'atclose' functions to invoke at library shutdown */ +static H5_atclose_node_t *H5_atclose_head = NULL; + +/* Declare a free list to manage the H5_atclose_node_t struct */ +H5FL_DEFINE_STATIC(H5_atclose_node_t); + +/*-------------------------------------------------------------------------- +NAME + H5__init_package -- Initialize interface-specific information +USAGE + herr_t H5__init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------*/ +herr_t +H5__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Run the library initialization routine, if it hasn't already ran */ + if (!H5_INIT_GLOBAL && !H5_TERM_GLOBAL) { + if (H5_init_library() < 0) + HGOTO_ERROR(H5E_LIB, H5E_CANTINIT, FAIL, "unable to initialize library") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5__init_package() */ + /*-------------------------------------------------------------------------- * NAME * H5_init_library -- Initialize library-global information @@ -103,6 +147,11 @@ H5_init_library(void) { herr_t ret_value = SUCCEED; + /* Set the 'library initialized' flag as early as possible, to avoid + * possible re-entrancy. + */ + H5_INIT_GLOBAL = TRUE; + FUNC_ENTER_NOAPI(FAIL) #ifdef H5_HAVE_PARALLEL @@ -132,7 +181,7 @@ H5_init_library(void) int key_val; if (MPI_SUCCESS != (mpi_code = MPI_Comm_create_keyval( - MPI_COMM_NULL_COPY_FN, (MPI_Comm_delete_attr_function *)H5_mpi_delete_cb, + MPI_COMM_NULL_COPY_FN, (MPI_Comm_delete_attr_function *)H5__mpi_delete_cb, &key_val, NULL))) HMPI_GOTO_ERROR(FAIL, "MPI_Comm_create_keyval failed", mpi_code) @@ -228,8 +277,8 @@ H5_init_library(void) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface") /* Debugging? */ - H5_debug_mask("-all"); - H5_debug_mask(HDgetenv("HDF5_DEBUG")); + H5__debug_mask("-all"); + H5__debug_mask(HDgetenv("HDF5_DEBUG")); done: FUNC_LEAVE_NOAPI(ret_value) @@ -273,6 +322,28 @@ H5_term_library(void) /* Check if we should display error output */ (void)H5Eget_auto2(H5E_DEFAULT, &func, NULL); + /* Iterate over the list of 'atclose' callbacks that have been registered */ + if (H5_atclose_head) { + H5_atclose_node_t *curr_atclose; /* Current 'atclose' node */ + + /* Iterate over all 'atclose' nodes, making callbacks */ + curr_atclose = H5_atclose_head; + while (curr_atclose) { + H5_atclose_node_t *tmp_atclose; /* Temporary pointer to 'atclose' node */ + + /* Invoke callback, providing context */ + (*curr_atclose->func)(curr_atclose->ctx); + + /* Advance to next node and free this one */ + tmp_atclose = curr_atclose; + curr_atclose = curr_atclose->next; + H5FL_FREE(H5_atclose_node_t, tmp_atclose); + } /* end while */ + + /* Reset list head, in case library is re-initialized */ + H5_atclose_head = NULL; + } /* end if */ + /* * Terminate each interface. The termination functions return a positive * value if they do something that might affect some other interface in a @@ -564,12 +635,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5get_free_list_sizes(size_t *reg_size, size_t *arr_size, size_t *blk_size, size_t *fac_size) +H5get_free_list_sizes(size_t *reg_size /*out*/, size_t *arr_size /*out*/, size_t *blk_size /*out*/, + size_t *fac_size /*out*/) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE4("e", "*z*z*z*z", reg_size, arr_size, blk_size, fac_size); + H5TRACE4("e", "xxxx", reg_size, arr_size, blk_size, fac_size); /* Call the free list function to actually get the sizes */ if (H5FL_get_free_list_sizes(reg_size, arr_size, blk_size, fac_size) < 0) @@ -604,12 +676,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5get_alloc_stats(H5_alloc_stats_t *stats) +H5get_alloc_stats(H5_alloc_stats_t *stats /*out*/) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE1("e", "*Ha", stats); + H5TRACE1("e", "x", stats); /* Call the internal allocation stat routine to get the values */ if (H5MM_get_alloc_stats(stats) < 0) @@ -620,7 +692,7 @@ done: } /* end H5get_alloc_stats() */ /*------------------------------------------------------------------------- - * Function: H5_debug_mask + * Function: H5__debug_mask * * Purpose: Set runtime debugging flags according to the string S. The * string should contain file numbers and package names @@ -643,7 +715,7 @@ done: *------------------------------------------------------------------------- */ static void -H5_debug_mask(const char *s) +H5__debug_mask(const char *s) { FILE * stream = stderr; char pkg_name[32], *rest; @@ -724,15 +796,12 @@ H5_debug_mask(const char *s) s++; } /* end if-else */ } /* end while */ - - return; - -} /* end H5_debug_mask() */ +} /* end H5__debug_mask() */ #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- - * Function: H5_mpi_delete_cb + * Function: H5__mpi_delete_cb * * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5 * library when the communicator is destroyed, i.e. on MPI_Finalize. @@ -742,8 +811,8 @@ H5_debug_mask(const char *s) *------------------------------------------------------------------------- */ static int -H5_mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void H5_ATTR_UNUSED *attr_val, - int H5_ATTR_UNUSED *flag) +H5__mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void H5_ATTR_UNUSED *attr_val, + int H5_ATTR_UNUSED *flag) { H5_term_library(); return MPI_SUCCESS; @@ -767,12 +836,12 @@ H5_mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void H *------------------------------------------------------------------------- */ herr_t -H5get_libversion(unsigned *majnum, unsigned *minnum, unsigned *relnum) +H5get_libversion(unsigned *majnum /*out*/, unsigned *minnum /*out*/, unsigned *relnum /*out*/) { herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) - H5TRACE3("e", "*Iu*Iu*Iu", majnum, minnum, relnum); + H5TRACE3("e", "xxx", majnum, minnum, relnum); /* Set the version information */ if (majnum) @@ -890,7 +959,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) HDstrncat(lib_str, "-", (size_t)1); HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1); } /* end if */ - if (HDstrcmp(lib_str, H5_lib_vers_info_g)) { + if (HDstrcmp(lib_str, H5_lib_vers_info_g) != 0) { HDfputs("Warning! Library version information error.\n" "The HDF5 library version information are not " "consistent in its source code.\nThis is NOT a fatal error " @@ -937,6 +1006,45 @@ done: } /* end H5open() */ /*------------------------------------------------------------------------- + * Function: H5atclose + * + * Purpose: Register a callback for the library to invoke when it's + * closing. Callbacks are invoked in LIFO order. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5atclose(H5_atclose_func_t func, void *ctx) +{ + H5_atclose_node_t *new_atclose; /* New 'atclose' node */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "Hc*x", func, ctx); + + /* Check arguments */ + if (NULL == func) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL func pointer") + + /* Allocate space for the 'atclose' node */ + if (NULL == (new_atclose = H5FL_MALLOC(H5_atclose_node_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate 'atclose' node") + + /* Set up 'atclose' node */ + new_atclose->func = func; + new_atclose->ctx = ctx; + + /* Connector to linked-list of 'atclose' nodes */ + new_atclose->next = H5_atclose_head; + H5_atclose_head = new_atclose; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5atclose() */ + +/*------------------------------------------------------------------------- * Function: H5close * * Purpose: Terminate the library and release all resources. @@ -1073,23 +1181,58 @@ H5free_memory(void *mem) *------------------------------------------------------------------------- */ herr_t -H5is_library_threadsafe(hbool_t *is_ts) +H5is_library_threadsafe(hbool_t *is_ts /*out*/) { - FUNC_ENTER_API_NOINIT - H5TRACE1("e", "*b", is_ts); + herr_t ret_value = SUCCEED; /* Return value */ - HDassert(is_ts); + FUNC_ENTER_API_NOINIT + H5TRACE1("e", "x", is_ts); - /* At this time, it is impossible for this to fail. */ + if (is_ts) { #ifdef H5_HAVE_THREADSAFE - *is_ts = TRUE; + *is_ts = TRUE; #else /* H5_HAVE_THREADSAFE */ - *is_ts = FALSE; + *is_ts = FALSE; #endif /* H5_HAVE_THREADSAFE */ + } + else + ret_value = FAIL; - FUNC_LEAVE_API_NOINIT(SUCCEED) + FUNC_LEAVE_API_NOINIT(ret_value) } /* end H5is_library_threadsafe() */ +/*------------------------------------------------------------------------- + * Function: H5is_library_terminating + * + * Purpose: Checks to see if the library is shutting down. + * + * Note: Useful for plugins to detect when the library is terminating. + * For example, a VOL connector could check if a "file close" + * callback was the result of the library shutdown process, or + * an API action from the application. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5is_library_terminating(hbool_t *is_terminating /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE1("e", "x", is_terminating); + + HDassert(is_terminating); + + if (is_terminating) + *is_terminating = H5_TERM_GLOBAL; + else + ret_value = FAIL; + + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5is_library_terminating() */ + #if defined(H5_HAVE_THREADSAFE) && defined(H5_BUILT_AS_DYNAMIC_LIB) && defined(H5_HAVE_WIN32_API) && \ defined(H5_HAVE_WIN_THREADS) /*------------------------------------------------------------------------- diff --git a/src/H5checksum.c b/src/H5checksum.c index 7daf8b8..0cd7745 100644 --- a/src/H5checksum.c +++ b/src/H5checksum.c @@ -15,7 +15,7 @@ * * Created: H5checksum.c * Aug 21 2006 - * Quincey Koziol <koziol@hdfgroup.org> + * Quincey Koziol * * Purpose: Internal code for computing fletcher32 checksums * @@ -25,6 +25,7 @@ /****************/ /* Module Setup */ /****************/ +#include "H5module.h" /* This source code file is part of the H5 module */ /***********/ /* Headers */ @@ -141,7 +142,7 @@ H5_checksum_fletcher32(const void *_data, size_t _len) } /* end H5_checksum_fletcher32() */ /*------------------------------------------------------------------------- - * Function: H5_checksum_crc_make_table + * Function: H5__checksum_crc_make_table * * Purpose: Compute the CRC table for the CRC checksum algorithm * @@ -153,12 +154,12 @@ H5_checksum_fletcher32(const void *_data, size_t _len) *------------------------------------------------------------------------- */ static void -H5_checksum_crc_make_table(void) +H5__checksum_crc_make_table(void) { uint32_t c; /* Checksum for each byte value */ unsigned n, k; /* Local index variables */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Compute the checksum for each possible byte value */ for (n = 0; n < 256; n++) { @@ -173,10 +174,10 @@ H5_checksum_crc_make_table(void) H5_crc_table_computed = TRUE; FUNC_LEAVE_NOAPI_VOID -} /* end H5_checksum_crc_make_table() */ +} /* end H5__checksum_crc_make_table() */ /*------------------------------------------------------------------------- - * Function: H5_checksum_crc_make_table + * Function: H5__checksum_crc_update * * Purpose: Update a running CRC with the bytes buf[0..len-1]--the CRC * should be initialized to all 1's, and the transmitted value @@ -191,22 +192,22 @@ H5_checksum_crc_make_table(void) *------------------------------------------------------------------------- */ static uint32_t -H5_checksum_crc_update(uint32_t crc, const uint8_t *buf, size_t len) +H5__checksum_crc_update(uint32_t crc, const uint8_t *buf, size_t len) { size_t n; /* Local index variable */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Initialize the CRC table if necessary */ if (!H5_crc_table_computed) - H5_checksum_crc_make_table(); + H5__checksum_crc_make_table(); /* Update the CRC with the results from this buffer */ for (n = 0; n < len; n++) crc = H5_crc_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8); FUNC_LEAVE_NOAPI(crc) -} /* end H5_checksum_crc_update() */ +} /* end H5__checksum_crc_update() */ /*------------------------------------------------------------------------- * Function: H5_checksum_crc @@ -234,7 +235,8 @@ H5_checksum_crc(const void *_data, size_t len) HDassert(_data); HDassert(len > 0); - FUNC_LEAVE_NOAPI(H5_checksum_crc_update((uint32_t)0xffffffffL, (const uint8_t *)_data, len) ^ 0xffffffffL) + FUNC_LEAVE_NOAPI(H5__checksum_crc_update((uint32_t)0xffffffffL, (const uint8_t *)_data, len) ^ + 0xffffffffL) } /* end H5_checksum_crc() */ /* @@ -378,7 +380,7 @@ uint32_t H5_checksum_lookup3(const void *key, size_t length, uint32_t initval) { const uint8_t *k = (const uint8_t *)key; - uint32_t a, b, c; /* internal state */ + uint32_t a, b, c = 0; /* internal state */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -413,36 +415,47 @@ H5_checksum_lookup3(const void *key, size_t length, uint32_t initval) { case 12: c += ((uint32_t)k[11]) << 24; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 11: c += ((uint32_t)k[10]) << 16; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 10: c += ((uint32_t)k[9]) << 8; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 9: c += k[8]; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 8: b += ((uint32_t)k[7]) << 24; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 7: b += ((uint32_t)k[6]) << 16; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 6: b += ((uint32_t)k[5]) << 8; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 5: b += k[4]; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 4: a += ((uint32_t)k[3]) << 24; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 3: a += ((uint32_t)k[2]) << 16; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 2: a += ((uint32_t)k[1]) << 8; + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case 1: a += k[0]; diff --git a/src/H5dbg.c b/src/H5dbg.c index b332fd1..5af6525 100644 --- a/src/H5dbg.c +++ b/src/H5dbg.c @@ -13,11 +13,11 @@ /*------------------------------------------------------------------------- * - * Created: H5dbg.c - * Mar 4 2006 - * Quincey Koziol + * Created: H5dbg.c + * Mar 4 2006 + * Quincey Koziol * - * Purpose: Generic debugging routines + * Purpose: Generic debugging routines * *------------------------------------------------------------------------- */ @@ -25,11 +25,12 @@ /****************/ /* Module Setup */ /****************/ +#include "H5module.h" /* This source code file is part of the H5 module */ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ +#include "H5private.h" /* Generic Functions */ /****************/ /* Local Macros */ @@ -56,14 +57,14 @@ /*******************/ /*------------------------------------------------------------------------- - * Function: H5_buffer_dump + * Function: H5_buffer_dump * - * Purpose: Dumps a buffer of memory in an octal dump form + * Purpose: Dumps a buffer of memory in an octal dump form * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Mar 4 2006 + * Programmer: Quincey Koziol + * Mar 4 2006 * *------------------------------------------------------------------------- */ @@ -91,7 +92,7 @@ H5_buffer_dump(FILE *stream, int indent, const uint8_t *buf, const uint8_t *mark for (u = 0; u < buf_size; u += 16) { uint8_t c; - HDfprintf(stream, "%*s %8d: ", indent, "", u + buf_offset); + HDfprintf(stream, "%*s %8zu: ", indent, "", u + buf_offset); /* Print the hex values */ for (v = 0; v < 16; v++) { @@ -105,6 +106,7 @@ H5_buffer_dump(FILE *stream, int indent, const uint8_t *buf, const uint8_t *mark } /* end if */ else HDfprintf(stream, " "); + if (7 == v) HDfputc(' ', stream); } /* end for */ @@ -117,12 +119,14 @@ H5_buffer_dump(FILE *stream, int indent, const uint8_t *buf, const uint8_t *mark HDfputc(' ', stream); else { c = buf[buf_offset + u + v]; + if (HDisprint(c)) HDfputc(c, stream); else HDfputc('.', stream); } /* end else */ } /* end if */ + if (7 == v) HDfputc(' ', stream); } /* end for */ diff --git a/src/H5err.txt b/src/H5err.txt index a902991..24e9b2a 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -46,6 +46,7 @@ MAJOR, H5E_ARGS, Invalid arguments to routine MAJOR, H5E_RESOURCE, Resource unavailable MAJOR, H5E_INTERNAL, Internal error (too specific to document in detail) +MAJOR, H5E_LIB, General library infrastructure MAJOR, H5E_FILE, File accessibility MAJOR, H5E_IO, Low-level I/O MAJOR, H5E_FUNC, Function entry/exit @@ -102,6 +103,7 @@ SECTION, FSPACE, Free space errors SECTION, PIPELINE, I/O pipeline errors SECTION, SYSTEM, System level errors SECTION, PLUGIN, Plugin errors +SECTION, MAP, Map related errors SECTION, NONE, No error # Minor errors diff --git a/src/H5module.h b/src/H5module.h new file mode 100644 index 0000000..64081bf --- /dev/null +++ b/src/H5module.h @@ -0,0 +1,34 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: This file contains declarations which define macros for the + * H5 package. Including this header means that the source file + * is part of the H5 package. + */ +#ifndef H5module_H +#define H5module_H + +/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error + * reporting macros. + */ +#define H5_MODULE +#define H5_MY_PKG H5 +#define H5_MY_PKG_ERR H5E_LIB +#define H5_MY_PKG_INIT YES + +/**\defgroup H5 H5 + * \brief General Library Functions + * \todo Describe concisely what the functions in this module are about. + */ + +#endif /* H5module_H */ diff --git a/src/H5public.h b/src/H5public.h index 206fdc9..2fb4407 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -20,34 +20,34 @@ /* Include files for public use... */ /* * Since H5pubconf.h is a generated header file, it is messy to try - * to put a #ifndef _H5pubconf_H ... #endif guard in it. + * to put a #ifndef H5pubconf_H ... #endif guard in it. * HDF5 has set an internal rule that it is being included here. * Source files should NOT include H5pubconf.h directly but include - * it via H5public.h. The #ifndef _H5public_H guard above would + * it via H5public.h. The #ifndef H5public_H guard above would * prevent repeated include. */ -#include "H5pubconf.h" /*from configure */ +#include "H5pubconf.h" /* From configure */ /* API Version macro wrapper definitions */ #include "H5version.h" #ifdef H5_HAVE_FEATURES_H -#include <features.h> /*for setting POSIX, BSD, etc. compatibility */ +#include <features.h> /* For setting POSIX, BSD, etc. compatibility */ #endif #ifdef H5_HAVE_SYS_TYPES_H #include <sys/types.h> #endif #ifdef H5_STDC_HEADERS -#include <limits.h> /*for H5T_NATIVE_CHAR defn in H5Tpublic.h */ -#include <stdarg.h> /*for variadic functions in H5VLpublic.h */ +#include <limits.h> /* For H5T_NATIVE_CHAR defn in H5Tpublic.h */ +#include <stdarg.h> /* For variadic functions in H5VLpublic.h */ #endif #ifndef __cplusplus #ifdef H5_HAVE_STDINT_H -#include <stdint.h> /*for C9x types */ +#include <stdint.h> /* For C9x types */ #endif #else #ifdef H5_HAVE_STDINT_H_CXX -#include <stdint.h> /*for C9x types when include from C++ */ +#include <stdint.h> /* For C9x types (when included from C++) */ #endif #endif #ifdef H5_HAVE_INTTYPES_H @@ -61,7 +61,7 @@ #define MPICH_SKIP_MPICXX 1 #define OMPI_SKIP_MPICXX 1 #include <mpi.h> -#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ +#ifndef MPI_FILE_NULL /* MPIO may be defined in mpi.h already */ #include <mpio.h> #endif #endif @@ -91,12 +91,15 @@ extern "C" { #define H5_GCC_DIAG_ON(x) #endif +/* Macro to hide a symbol from further preprocessor substitutions */ +#define H5_NO_EXPAND(x) (x) + /* Version numbers */ -#define H5_VERS_MAJOR 1 /* For major interface/format changes */ -#define H5_VERS_MINOR 13 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 0 /* For tweaks, bug-fixes, or development */ -#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ - /* Empty string for real releases. */ +#define H5_VERS_MAJOR 1 /* For major interface/format changes */ +#define H5_VERS_MINOR 13 /* For minor interface/format changes */ +#define H5_VERS_RELEASE 0 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ +/* Empty string for real releases. */ #define H5_VERS_INFO "HDF5 library version: 1.13.0" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE) @@ -117,8 +120,8 @@ extern "C" { * The negative failure value is most commonly -1, but don't bet on it. The * proper way to detect failure is something like: * - * if((dset = H5Dopen2(file, name)) < 0) - * fprintf(stderr, "unable to open the requested dataset\n"); + * if((dset = H5Dopen2(file, name)) < 0) + * fprintf(stderr, "unable to open the requested dataset\n"); */ typedef int herr_t; @@ -129,13 +132,13 @@ typedef int herr_t; * (false), positive (true), or negative (failure). The proper way to test * for truth from a htri_t function is: * - * if ((retval = H5Tcommitted(type))>0) { - * printf("data type is committed\n"); - * } else if (!retval) { - * printf("data type is not committed\n"); - * } else { - * printf("error determining whether data type is committed\n"); - * } + * if ((retval = H5Tcommitted(type)) > 0) { + * printf("data type is committed\n"); + * } else if (!retval) { + * printf("data type is not committed\n"); + * } else { + * printf("error determining whether data type is committed\n"); + * } */ #ifdef H5_HAVE_STDBOOL_H #include <stdbool.h> @@ -295,15 +298,21 @@ typedef unsigned long uint32_t; #error "nothing appropriate for uint32_t" #endif -/* Common iteration orders */ +//! [H5_iter_order_t_snip] + +/** + * Common iteration orders + */ typedef enum { - H5_ITER_UNKNOWN = -1, /* Unknown order */ - H5_ITER_INC, /* Increasing order */ - H5_ITER_DEC, /* Decreasing order */ - H5_ITER_NATIVE, /* No particular order, whatever is fastest */ - H5_ITER_N /* Number of iteration orders */ + H5_ITER_UNKNOWN = -1, /**< Unknown order */ + H5_ITER_INC, /**< Increasing order */ + H5_ITER_DEC, /**< Decreasing order */ + H5_ITER_NATIVE, /**< No particular order, whatever is fastest */ + H5_ITER_N /**< Number of iteration orders */ } H5_iter_order_t; +//! [H5_iter_order_t_snip] + /* Iteration callback values */ /* (Actually, any positive value will cause the iterator to stop and pass back * that positive value to the function that called the iterator) @@ -312,25 +321,39 @@ typedef enum { #define H5_ITER_CONT (0) #define H5_ITER_STOP (1) -/* +//! [H5_index_t_snip] + +/** * The types of indices on links in groups/attributes on objects. * Primarily used for "<do> <foo> by index" routines and for iterating over * links in groups/attributes on objects. */ typedef enum H5_index_t { - H5_INDEX_UNKNOWN = -1, /* Unknown index type */ - H5_INDEX_NAME, /* Index on names */ - H5_INDEX_CRT_ORDER, /* Index on creation order */ - H5_INDEX_N /* Number of indices defined */ + H5_INDEX_UNKNOWN = -1, /**< Unknown index type */ + H5_INDEX_NAME, /**< Index on names */ + H5_INDEX_CRT_ORDER, /**< Index on creation order */ + H5_INDEX_N /**< Number of indices defined */ } H5_index_t; -/* +//! [H5_index_t_snip] + +/** * Storage info struct used by H5O_info_t and H5F_info_t */ +//! [H5_ih_info_t_snip] typedef struct H5_ih_info_t { - hsize_t index_size; /* btree and/or list */ + hsize_t index_size; /**< btree and/or list */ hsize_t heap_size; } H5_ih_info_t; +//! [H5_ih_info_t_snip] + +/** + * The maximum size allowed for tokens + * \details Tokens are unique and permanent identifiers that are + * used to reference HDF5 objects in a container. This allows + * for 128-bit tokens + */ +#define H5O_MAX_TOKEN_SIZE (16) static inline const char * htri_to_string(htri_t v) @@ -343,46 +366,488 @@ htri_to_string(htri_t v) return "true"; } -/* Tokens are unique and permanent identifiers that are - * used to reference HDF5 objects in a container. */ - -/* The maximum size allowed for tokens */ -#define H5O_MAX_TOKEN_SIZE (16) /* Allows for 128-bit tokens */ +//! [H5O_token_t_snip] +/** + * \internal (Hoisted here, since it's used by both the + * H5Lpublic.h and H5Opublic.h headers) */ /* Type for object tokens */ /* (Hoisted here, since it's used by both the H5Lpublic.h and H5Opublic.h headers) */ typedef struct H5O_token_t { uint8_t __data[H5O_MAX_TOKEN_SIZE]; } H5O_token_t; -/* +//! [H5O_token_t_snip] + +/** * Allocation statistics info struct */ typedef struct H5_alloc_stats_t { - unsigned long long total_alloc_bytes; /* Running count of total # of bytes allocated */ - size_t curr_alloc_bytes; /* Current # of bytes allocated */ - size_t peak_alloc_bytes; /* Peak # of bytes allocated */ - size_t max_block_size; /* Largest block allocated */ - size_t total_alloc_blocks_count; /* Running count of total # of blocks allocated */ - size_t curr_alloc_blocks_count; /* Current # of blocks allocated */ - size_t peak_alloc_blocks_count; /* Peak # of blocks allocated */ + unsigned long long total_alloc_bytes; /**< Running count of total # of bytes allocated */ + size_t curr_alloc_bytes; /**< Current # of bytes allocated */ + size_t peak_alloc_bytes; /**< Peak # of bytes allocated */ + size_t max_block_size; /**< Largest block allocated */ + size_t total_alloc_blocks_count; /**< Running count of total # of blocks allocated */ + size_t curr_alloc_blocks_count; /**< Current # of blocks allocated */ + size_t peak_alloc_blocks_count; /**< Peak # of blocks allocated */ } H5_alloc_stats_t; +/** + * Library shutdown callback, used by H5atclose(). + */ +typedef void (*H5_atclose_func_t)(void *ctx); + /* Functions in H5.c */ +/** + * \ingroup H5 + * \brief Initializes the HDF5 library + * \return \herr_t + * + * \details H5open() initializes the HDF5 library. + * + * \details When the HDF5 library is used in a C application, the library is + * automatically initialized when the first HDf5 function call is + * issued. If one finds that an HDF5 library function is failing + * inexplicably, H5open() can be called first. It is safe to call + * H5open() before an application issues any other function calls to + * the HDF5 library as there are no damaging side effects in calling + * it more than once. + */ H5_DLL herr_t H5open(void); +/** + * \ingroup H5 + * \brief Registers a callback for the library to invoke when it's closing. + * \param[in] func The function pointer to invoke + * \param[in] ctx Context to pass to \p func when invoked + * \return \herr_t + * + * \details H5atclose() registers a callback that the HDF5 library will invoke + * when closing. The full capabilities of the HDF5 library are + * available to callbacks invoked through this mechanism, library + * shutdown will only begin in earnest when all callbacks have been + * invoked and have returned. + * + * Registered callbacks are invoked in LIFO order, similar to the + * Standard C 'atexit' routine. For example, if 'func1' is registered, + * then 'func2', when the library is closing 'func2' will + * be invoked first, then 'func1'. + * + * The \p ctx pointer will be passed to \p func when it's invoked. + * NULL is allowed for \p ctx. + * + * If the HDF5 library is initialized and closed more than once, the + * \p func callback must be registered within each open/close cycle. + * + * \since 1.12.1 + */ +H5_DLL herr_t H5atclose(H5_atclose_func_t func, void *ctx); +/** + * \ingroup H5 + * \brief Flushes all data to disk, closes all open objects, and releases memory + * \return \herr_t + * + * \details H5close() flushes all data to disk, closes all open HDF5 objects, + * and cleans up all memory used by the HDF5 library. This function is + * generally called when the application calls exit(), but may be + * called earlier in the event of an emergency shutdown or out of a + * desire to free all resources used by the HDF5 library. + */ H5_DLL herr_t H5close(void); +/** + * \ingroup H5 + * \brief Instructs library not to install atexit() cleanup routine + * \return \herr_t + * + * \details H5dont_atexit() indicates to the library that an atexit() cleanup + * routine should not be installed. The major purpose for using this + * function is in situations where the library is dynamically linked + * into an application and is un-linked from the application before + * exit() gets called. In those situations, a routine installed with + * atexit() would jump to a routine which was no longer in memory, + * causing errors. + * + * \attention In order to be effective, this routine \Emph{must} be called + * before any other HDF5 function calls, and must be called each + * time the library is loaded/linked into the application (the first + * time and after it's been un-loaded). + */ H5_DLL herr_t H5dont_atexit(void); +/** + * \ingroup H5 + * \brief Garbage collects on all free-lists of all types + * \return \herr_t + * + * \details H5garbage_collect() walks through all garbage collection routines + * of the library, freeing any unused memory. + * + * It is not required that H5garbage_collect() be called at any + * particular time; it is only necessary in certain situations where + * the application has performed actions that cause the library to + * allocate many objects. The application should call + * H5garbage_collect() if it eventually releases those objects and + * wants to reduce the memory used by the library from the peak usage + * required. + * + * \note The library automatically garbage collects all the free lists when the + * application ends. + */ H5_DLL herr_t H5garbage_collect(void); +/** + * \ingroup H5 + * \brief Sets free-list size limits + * + * \param[in] reg_global_lim The cumulative limit, in bytes, on memory used for + * all regular free lists (Default: 1MB) + * \param[in] reg_list_lim The limit, in bytes, on memory used for each regular + * free list (Default: 64KB) + * \param[in] arr_global_lim The cumulative limit, in bytes, on memory used for + * all array free lists (Default: 4MB) + * \param[in] arr_list_lim The limit, in bytes, on memory used for each array + * free list (Default: 256KB) + * \param[in] blk_global_lim The cumulative limit, in bytes, on memory used for + * all block free lists and, separately, for all + * factory free lists (Default: 16MB) + * \param[in] blk_list_lim The limit, in bytes, on memory used for each block + * or factory free list (Default: 1MB) + * \return \herr_t + * + * \details H5set_free_list_limits() sets size limits on all types of free + * lists. The HDF5 library uses free lists internally to manage + * memory. The types of free lists used are as follows: + * \li Regular free lists manage memory for single internal data + * structures. + * \li Array free lists manage memory for arrays of internal + * data structures. + * \li Block free lists manage memory for arbitrarily-sized blocks + * of bytes. + * \li Factory free lists manage memory for fixed-size blocks of + * bytes. + * + * The parameters specify global and per-list limits; for example, \p + * reg_global_limit and \p reg_list_limit limit the accumulated size + * of all regular free lists and the size of each individual regular + * free list, respectively. Therefore, if an application sets a 1Mb + * limit on each of the global lists, up to 4Mb of total storage might + * be allocated, 1Mb for each of the regular, array, block, and + * factory type lists. + * + * The settings specified for block free lists are duplicated for + * factory free lists. Therefore, increasing the global limit on block + * free lists by x bytes will increase the potential free list memory + * usage by 2x bytes. + * + * Using a value of -1 for a limit means that no limit is set for the + * specified type of free list. + * + * \version 1.8.3 Function changed in this release to set factory free list + * memory limits. + * + * \since 1.6.0 + */ H5_DLL herr_t H5set_free_list_limits(int reg_global_lim, int reg_list_lim, int arr_global_lim, int arr_list_lim, int blk_global_lim, int blk_list_lim); +/** + * \ingroup H5 + * \brief Gets the current size of the free lists used to manage memory + * + * \param[out] reg_size The current size of all "regular" free list memory used + * \param[out] arr_size The current size of all "array" free list memory used + * \param[out] blk_size The current size of all "block" free list memory used + * \param[out] fac_size The current size of all "factory" free list memory used + * \return \herr_t + * + * \details H5get_free_list_sizes() obtains the current size of the different + * kinds of free lists that the library uses to manage memory. The + * free list sizes can be set with H5set_free_list_limits() and + * garbage collected with H5garbage_collect(). These lists are global + * for the entire library. + * + * \since 1.12.1 + */ H5_DLL herr_t H5get_free_list_sizes(size_t *reg_size, size_t *arr_size, size_t *blk_size, size_t *fac_size); +/** + * \ingroup H5 + * \brief Gets the memory allocation statistics for the library + * + * \param[out] stats Memory allocation statistics + * \return \herr_t + * + * \details H5get_alloc_stats() gets the memory allocation statistics for the + * library, if the \c --enable-memory-alloc-sanity-check option was + * given when building the library. Applications can check whether + * this option was enabled detecting if the + * \c H5_MEMORY_ALLOC_SANITY_CHECK macro is defined. This option is + * enabled by default for debug builds of the library and disabled by + * default for non-debug builds. If the option is not enabled, all the + * values returned with be 0. These statistics are global for the + * entire library, but do not include allocations from chunked dataset + * I/O filters or non-native VOL connectors. + * + * \since 1.12.1 + */ H5_DLL herr_t H5get_alloc_stats(H5_alloc_stats_t *stats); +/** + * \ingroup H5 + * \brief Returns the HDF library release number + * + * \param[out] majnum The major version number of the library + * \param[out] minnum The minor version number of the library + * \param[out] relnum The release version number of the library + * \return \herr_t + * + * \details H5get_libversion() retrieves the major, minor, and release numbers + * of the version of the HDF5 library which is linked to the + * application. + * + */ H5_DLL herr_t H5get_libversion(unsigned *majnum, unsigned *minnum, unsigned *relnum); +/** + * \ingroup H5 + * \brief Verifies that HDF5 library versions are consistent + * + * \param[in] majnum HDF5 library major version number + * \param[in] minnum HDF5 library minor version number + * \param[in] relnum HDF5 library release number + * \return \herr_t + * + * \details H5check_version() verifies that the version of the HDF5 library + * with which an application was compiled, as indicated by the passed + * parameters, matches the version of the HDF5 library against which + * the application is currently linked. + * + * \p majnum is the major version number of the HDF library with which + * the application was compiled, \p minnum is the minor version + * number, and \p relnum is the release number. Consider the following + * example: + * + * An official HDF5 release is labelled as follows: + * HDF5 Release \Code{\<majnum\>.\<minnum\>.\<relnum\>}\n + * For example, in HDF5 Release 1.8.5: + * \li 1 is the major version number, \p majnum. + * \li 8 is the minor version number, \p minnum. + * \li 5 is the release number, \p relnum. + * + * As stated above, H5check_version() first verifies that the version + * of the HDF5 library with which an application was compiled matches + * the version of the HDF5 library against which the application is + * currently linked. If this check fails, H5check_version() causes the + * application to abort (by means of a standard C abort() call) and + * prints information that is usually useful for debugging. This + * precaution is is taken to avoid the risks of data corruption or + * segmentation faults. + * + * The most common cause of this failure is that an application was + * compiled with one version of HDF5 and is dynamically linked with a + * different version different version. + * + * If the above test passes, H5check_version() proceeds to verify the + * consistency of additional library version information. This is + * designed to catch source code inconsistencies that do not normally + * cause failures; if this check reveals an inconsistency, an + * informational warning is printed but the application is allowed to + * run. + * + */ H5_DLL herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum); +/** + * \ingroup H5 + * \brief Checks whether the HDF5 library is closing. + * \param[out] is_terminating Flag indicating whether library is shutting down + * \return \herr_t + * + * \details H5is_library_terminating() queries whether the HDF5 library is in + * the process of shutting down. The \p is_terminating flag will only + * be set to TRUE after shutdown starts, it will be FALSE before the + * library has been initialized, while the library is initialized, and + * after it has been closed. The value of \p is_terminating is + * undefined if this routine fails. + * + * \since 1.12.1 + */ +H5_DLL herr_t H5is_library_terminating(hbool_t *is_terminating); +/** + * \ingroup H5 + * \brief Determines whether the HDF5 library was built with the thread-safety + * feature enabled + * + * \param[out] is_ts Boolean value indicating whether the library was built + * with thread-safety enabled + * \return \herr_t + * + * \details The HDF5 library, although not internally multi-threaded, can be + * built with a thread-safety feature enabled that protects internal + * data structures with a mutex. In certain circumstances, it may be + * useful to determine, at run-time, whether the linked HDF5 library + * was built with the thread-safety feature enabled. + */ H5_DLL herr_t H5is_library_threadsafe(hbool_t *is_ts); +/** + * \ingroup H5 + * \brief Frees memory allocated by the HDF5 library + * + * \param[in] mem Buffer to be freed. Can be NULL + * \return \herr_t + * + * \details H5free_memory() frees memory that has been allocated by the caller + * with H5allocate_memory() or by the HDF5 library on behalf of the + * caller. + * + * H5Tget_member_name() provides an example of memory allocation on + * behalf of the caller: The function returns a buffer containing the + * name of a compound datatype member. It is the caller’s + * responsibility to eventually free that buffer with H5free_memory(). + * + * \attention It is especially important to use this function to free memory + * allocated by the library on Windows. The C standard library is + * implemented in dynamic link libraries (DLLs) known as the C + * run-time (CRT). Each version of Visual Studio comes with two CRT + * DLLs (debug and release) and allocating and freeing across DLL + * boundaries can cause resource leaks and subtle bugs due to heap + * corruption.\n + * Only use this function to free memory allocated by the HDF5 + * Library. It will generally not be safe to use this function to + * free memory allocated by any other means.\n + * Even when using this function, it is still best to ensure that + * all components of a C application are built with the same version + * of Visual Studio and build (debug or release) and thus linked + * against the same CRT. + * + * \see H5allocate_memory(), H5resize_memory() + * + * \since 1.8.13 + * + */ H5_DLL herr_t H5free_memory(void *mem); -H5_DLL void * H5allocate_memory(size_t size, hbool_t clear); -H5_DLL void * H5resize_memory(void *mem, size_t size); +/** + * \ingroup H5 + * \brief Frees memory allocated by the HDF5 library + * + * \param[in] size The size in bytes of the buffer to be allocated + * \param[in] clear Flag whether the new buffer is to be initialized with 0 + * + * \return On success, returns pointer to newly allocated buffer or returns + * NULL if size is 0 (zero).\n + * Returns NULL on failure. + * + * \details H5allocate_memory() allocates a memory buffer of size bytes that + * will later be freed internally by the HDF5 library. + * + * The boolean \p clear parameter specifies whether the buffer should + * be initialized. If clear is \c TRUE, all bits in the buffer are to be + * set to 0 (zero); if clear is \c FALSE, the buffer will not be + * initialized. + * + * This function is intended to have the semantics of malloc() and + * calloc(). However, unlike malloc() and calloc() which allow for a + * "special" pointer to be returned instead of NULL, this function + * always returns NULL on failure or when size is set to 0 (zero). + * + * \note At this time, the only intended use for this function is to allocate + * memory that will be returned to the library as a data buffer from a + * third-party filter. + * + * \attention To avoid heap corruption, allocated memory should be freed using + * the same library that initially allocated it. In most cases, the + * HDF5 API uses resources that are allocated and freed either + * entirely by the user or entirely by the library, so this is not a + * problem. In rare cases, however, HDF5 API calls will free memory + * that the user allocated. This function allows the user to safely + * allocate this memory.\n + * It is particularly important to use this function to allocate + * memory in Microsoft Windows environments. In Windows, the C + * standard library is implemented in dynamic link libraries (DLLs) + * known as the C run-time (CRT). Each version of Visual Studio + * comes with multiple versions of the CRT DLLs (debug, release, et + * cetera) and allocating and freeing memory across DLL boundaries + * can cause resource leaks and subtle bugs due to heap corruption.\n + * Even when using this function, it is best where possible to + * ensure that all components of a C application are built with the + * same version of Visual Studio and configuration (Debug or + * Release), and thus linked against the same CRT.\n + * Use this function only to allocate memory inside third-party HDF5 + * filters. It will generally not be safe to use this function to + * allocate memory for any other purpose. + * + * \see H5free_memory(), H5resize_memory() + * + * \since 1.8.15 + * + */ +H5_DLL void *H5allocate_memory(size_t size, hbool_t clear); +/** + * \ingroup H5 + * \brief Resizes and, if required, re-allocates memory that will later be + * freed internally by the HDF5 library + * + * \param[in] mem Pointer to a buffer to be resized. May be NULL + * \param[in] size New size of the buffer, in bytes + + * + * \return On success, returns pointer to resized or reallocated buffer + * or returns NULL if size is 0 (zero).\n + * Returns NULL on failure. + * + * \details H5resize_memory() takes a pointer to an existing buffer and resizes + * the buffer to match the value in \p size. If necessary, the buffer + * is reallocated. If \p size is 0, the buffer is released. + * + * The input buffer must either be NULL or have been allocated by + * H5allocate_memory() since the input buffer may be freed by the + * library. + * + * For certain behaviors, the pointer \p mem may be passed in as NULL. + * + * This function is intended to have the semantics of realloc(): + * + * <table> + * <tr><td>\Code{H5resize_memory(buffer, size)}</td> + * <td>Resizes buffer. Returns pointer to resized buffer.</td></tr> + * <tr><td>\Code{H5resize_memory(NULL, size)}</td> + * <td>Allocates memory using HDF5 Library allocator. + * Returns pointer to new buffer</td></tr> + * <tr><td>\Code{H5resize_memory(buffer, 0)}</td> + * <td>Frees memory using HDF5 Library allocator. + * Returns NULL.</td></tr> + * <tr><td>\Code{H5resize_memory(NULL, 0)}</td> + * <td>Returns NULL (undefined in C standard).</td></tr> + * </table> + * + * Unlike realloc(), which allows for a "special pointer to be + * returned instead of NULL, this function always returns NULL on + * failure or when size is 0 (zero). + * + * \note At this time, the only intended use for this function is to resize or + * reallocate memory that will be returned to the library (and eventually + * to the user) as a data buffer from a third-party HDF5 filter. + * + * \attention To avoid heap corruption, allocated memory should be freed using + * the same library that initially allocated it. In most cases, the + * HDF5 API uses resources that are allocated and freed either + * entirely by the user or entirely by the library, so this is not a + * problem. In rare cases, however, HDF5 API calls will free memory + * that the user allocated. This function allows the user to safely + * allocate this memory.\n + * It is particularly important to use this function to resize + * memory on Microsoft Windows systems. In Windows, the C standard + * library is implemented in dynamic link libraries (DLLs) known as + * the C run-time (CRT). Each version of Visual Studio comes with + * multiple versions of the CRT DLLs (debug, release, et cetera) and + * allocating and freeing memory across DLL boundaries can cause + * resource leaks and subtle bugs due to heap corruption.\n + * Even when using this function, it is still best to ensure that + * all components of a C application are built with the same version + * of Visual Studio and the same configuration (Debug or Release), + * and thus linked against the same CRT.\n + * Only use this function to resize memory inside third-party HDF5 + * filters. It will generally not be safe to use this function to + * resize memory for any other purpose. + * + * \see H5allocate_memory(), H5free_memory() + * + * \since 1.8.15 + * + */ +H5_DLL void *H5resize_memory(void *mem, size_t size); #ifdef __cplusplus } diff --git a/src/H5system.c b/src/H5system.c index 65053ab..e7fe422 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -25,6 +25,7 @@ /****************/ /* Module Setup */ /****************/ +#include "H5module.h" /* This source code file is part of the H5 module */ /***********/ /* Headers */ diff --git a/src/H5timer.c b/src/H5timer.c index ac3a01e..54a3365 100644 --- a/src/H5timer.c +++ b/src/H5timer.c @@ -24,6 +24,7 @@ /****************/ /* Module Setup */ /****************/ +#include "H5module.h" /* This source code file is part of the H5 module */ /***********/ /* Headers */ |