diff options
31 files changed, 354 insertions, 766 deletions
@@ -187,7 +187,7 @@ ./config/gnu-warnings/general ./config/gnu-warnings/gfort-general ./config/gnu-warnings/gfort-4.8 -./config/gnu-warnings/gfort-5 +./config/gnu-warnings/developer-gfort-5 ./config/gnu-warnings/gfort-6 ./config/gnu-warnings/gfort-8 ./config/gnu-warnings/no-cxx-developer-4.8 diff --git a/c++/test/CMakeVFDTests.cmake b/c++/test/CMakeVFDTests.cmake index 4f3d137..ced9b0c 100644 --- a/c++/test/CMakeVFDTests.cmake +++ b/c++/test/CMakeVFDTests.cmake @@ -15,6 +15,7 @@ ### T E S T I N G ### ############################################################################## ############################################################################## +H5_CREATE_VFD_DIR() ############################################################################## ############################################################################## diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 263cedf..7b9d603 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -195,7 +195,7 @@ endif () # Header-check flags set in config/cmake_ext_mod/ConfigureChecks.cmake # ---------------------------------------------------------------------- option (HDF5_ENABLE_MIRROR_VFD "Build the Mirror Virtual File Driver" OFF) -if (H5FD_ENABLE_MIRROR_VFD) +if (HDF5_ENABLE_MIRROR_VFD) if ( ${HDF_PREFIX}_HAVE_NETINET_IN_H AND ${HDF_PREFIX}_HAVE_NETDB_H AND ${HDF_PREFIX}_HAVE_ARPA_INET_H AND diff --git a/config/cmake/HDF5Macros.cmake b/config/cmake/HDF5Macros.cmake index 1a0e8b3..8b8b334 100644 --- a/config/cmake/HDF5Macros.cmake +++ b/config/cmake/HDF5Macros.cmake @@ -93,7 +93,10 @@ macro (H5_SET_VFD_LIST) if (H5_HAVE_WINDOWS) set (VFD_LIST ${VFD_LIST} windows) endif () +endmacro () +# Initialize the list of VFDs to be used for testing and create a test folder for each VFD +macro (H5_CREATE_VFD_DIR) foreach (vfdtest ${VFD_LIST}) file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/${vfdtest}") endforeach () diff --git a/config/cmake/HDF5_Examples.cmake.in b/config/cmake/HDF5_Examples.cmake.in index 5b7262e..db638fd 100644 --- a/config/cmake/HDF5_Examples.cmake.in +++ b/config/cmake/HDF5_Examples.cmake.in @@ -94,6 +94,8 @@ else() set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${CTEST_SOURCE_NAME}") set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${CTEST_BINARY_NAME}") endif() +### default HDF5_PLUGIN_PATH to where the filter libraries are located +set(ENV{HDF5_PLUGIN_PATH} "${INSTALLDIR}/lib/plugin") if(${CDASH_LOCAL}) set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DCDASH_LOCAL:BOOL=ON") endif() diff --git a/config/cmake/HDFFortranCompilerFlags.cmake b/config/cmake/HDFFortranCompilerFlags.cmake index 94c40aa..754259e 100644 --- a/config/cmake/HDFFortranCompilerFlags.cmake +++ b/config/cmake/HDFFortranCompilerFlags.cmake @@ -79,7 +79,6 @@ if (NOT MSVC AND NOT MINGW) endif () if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - # Append more extra warning flags that only gcc 4.8+ knows about if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.8) ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-4.8") @@ -91,10 +90,11 @@ if (NOT MSVC AND NOT MINGW) #endif () # Append more extra warning flags that only gcc 5.x+ knows about - # do not include -Wuse-without-only - #if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) - # ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-5") - #endif () + if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-gfort-5") + endif () + endif () # Append more extra warning flags that only gcc 6.x+ knows about if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 6.0) diff --git a/config/gnu-fflags b/config/gnu-fflags index ce12561..1333ce5 100644 --- a/config/gnu-fflags +++ b/config/gnu-fflags @@ -161,10 +161,10 @@ if test "X-gfortran" = "X-$f9x_vendor"; then # gfortran 4.9 (nothing new) - # gfortran >= 5 (do not include -Wuse-without-only) - #if test $f9x_vers_major -ge 5; then - # H5_FCFLAGS="$H5_FCFLAGS $(load_gnu_arguments gfort-5)" - #fi + # gfortran >= 5 + if test $f9x_vers_major -ge 5; then + DEVELOPER_WARNING_FCFLAGS="$DEVELOPER_WARNING_FCFLAGS $(load_gnu_arguments developer-gfort-5)" + fi # gfortran >= 6 if test $f9x_vers_major -ge 6; then diff --git a/config/gnu-warnings/gfort-5 b/config/gnu-warnings/developer-gfort-5 index c5d3850..c5d3850 100644 --- a/config/gnu-warnings/gfort-5 +++ b/config/gnu-warnings/developer-gfort-5 diff --git a/configure.ac b/configure.ac index 7665f8e..98c3dbc 100644 --- a/configure.ac +++ b/configure.ac @@ -2302,6 +2302,7 @@ fi case "X-$DEV_WARNINGS" in X-yes) H5_CFLAGS="$H5_CFLAGS $DEVELOPER_WARNING_CFLAGS" + H5_FCFLAGS="$H5_FCFLAGS $DEVELOPER_WARNING_FCFLAGS" AC_MSG_RESULT([yes]) ;; X-no) diff --git a/fortran/test/tH5A.F90 b/fortran/test/tH5A.F90 index 4d56bed..d5ce9a2 100644 --- a/fortran/test/tH5A.F90 +++ b/fortran/test/tH5A.F90 @@ -408,13 +408,13 @@ CONTAINS !open the INTEGER attrbute by name ! CALL h5aopen_name_f(dset_id, aname5, attr5_id, error) - CALL check("h5aopen_idx_f",error,total_error) + CALL check("h5aopen_name_f",error,total_error) ! !open the NULL attrbute by name ! CALL h5aopen_name_f(dset_id, aname6, attr6_id, error) - CALL check("h5aopen_idx_f",error,total_error) + CALL check("h5aopen_name_f",error,total_error) ! !get the attrbute name diff --git a/hl/test/test_packet_vlen.c b/hl/test/test_packet_vlen.c index c668a07..6d6bf34 100644 --- a/hl/test/test_packet_vlen.c +++ b/hl/test/test_packet_vlen.c @@ -539,8 +539,8 @@ test_VLof_VLtype(void) HDfprintf(stderr, "Cannot allocate memory for VL data! uu=%u\n", uu); goto error; } - t1->len = vv * 1; - for (ww = 0; ww < (vv * 1); ww++) + t1->len = vv + 1; + for (ww = 0; ww < (vv + 1); ww++) ((unsigned int *)t1->p)[ww] = uu * 100 + vv * 10 + ww; } /* end for */ } /* end for */ diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index 5380bd1..bbe44f7 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -12808,8 +12808,11 @@ public class H5 implements java.io.Serializable { * IN: Field name of the field index to retrieve. * * @return if field is defined, the index; else negative. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. **/ - public synchronized static native int H5Tget_member_index(long type_id, String field_name); + public synchronized static native int H5Tget_member_index(long type_id, String field_name) throws HDF5LibraryException; /** * H5Tget_member_name retrieves the name of a field of a compound datatype or an element of an enumeration datatype. @@ -12820,8 +12823,11 @@ public class H5 implements java.io.Serializable { * IN: Field index (0-based) of the field name to retrieve. * * @return a valid pointer to the name if successful; otherwise null. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. **/ - public synchronized static native String H5Tget_member_name(long type_id, int field_idx); + public synchronized static native String H5Tget_member_name(long type_id, int field_idx) throws HDF5LibraryException; /** * H5Tget_member_offset returns the byte offset of the specified member of the compound datatype. This is the byte @@ -12833,11 +12839,8 @@ public class H5 implements java.io.Serializable { * IN: Field index (0-based) of the field type to retrieve. * * @return the offset of the member. - * - * @exception HDF5LibraryException - * - Error from the HDF-5 Library. **/ - public synchronized static native long H5Tget_member_offset(long type_id, int membno) throws HDF5LibraryException; + public synchronized static native long H5Tget_member_offset(long type_id, int membno); /** * H5Tget_member_type returns the datatype of the specified member. diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index d9a4e8e..247f182 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -66,7 +66,13 @@ New Features that default ON/enabled. Add configure options (autotools - CMake): - enable-hltools HDF5_BUILD_HL_TOOLS + --enable-hltools HDF5_BUILD_HL_TOOLS + + Disabling this option prevents building the gif tool which + contains the following CVEs: + HDFFV-10592 CVE-2018-17433 + HDFFV-10593 CVE-2018-17436 + HDFFV-11048 CVE-2020-10809 (ADB - 2021/09/16, HDFFV-11266) @@ -1100,6 +1106,14 @@ Bug Fixes since HDF5-1.12.0 release (ADB - 2021/03/03, #361) + - Fixed a segmentation fault + + A segmentation fault occurred with a Mathworks corrupted file. + + A detection of accessing a null pointer was added to prevent the problem. + + (BMR - 2021/02/19, HDFFV-11150) + - Fixed issue with MPI communicator and info object not being copied into new FAPL retrieved from H5F_get_access_plist @@ -1118,6 +1132,17 @@ Bug Fixes since HDF5-1.12.0 release (NAF - 2021/01/22) + - Fixed CVE-2018-17432 + + The tool h5repack produced a segfault on a corrupted file which had + invalid rank for scalar or NULL datatype. + + The problem was fixed by modifying the dataspace encode and decode + functions to detect and report invalid rank. h5repack now fails + with an error message for the corrupted file. + + (BMR - 2020/10/26, HDFFV-10590) + - Creation of dataset with optional filter When the combination of type, space, etc doesn't work for filter @@ -1447,7 +1472,11 @@ Bug Fixes since HDF5-1.12.0 release High-Level Library ------------------ - - + - Fixed HL_test_packet, test for packet table vlen of vlen. + + Incorrect length assignment. + + (ADB - 2021/10/14) Fortran High-Level APIs @@ -1653,3 +1682,11 @@ The share folder will have the most differences because CMake builds include a number of CMake specific files for support of CMake's find_package and support for the HDF5 Examples CMake project. +The issues with the gif tool are: + HDFFV-10592 CVE-2018-17433 + HDFFV-10593 CVE-2018-17436 + HDFFV-11048 CVE-2020-10809 +These CVE issues have not yet been addressed and can be avoided by not building +the gif tool. Disable building the High-Level tools with these options: + autotools: --disable-hltools + cmake: HDF5_BUILD_HL_TOOLS=OFF diff --git a/src/H5FDcore.c b/src/H5FDcore.c index ce96582..4b79de7 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -190,9 +190,9 @@ static const H5FD_class_t H5FD_core_g = { }; /* Default configurations, if none provided */ -static const H5FD_core_fapl_t H5FD_core_default_config_g = {H5_MB, TRUE, H5FD_CORE_WRITE_TRACKING_FLAG, - H5FD_CORE_WRITE_TRACKING_PAGE_SIZE}; -static const H5FD_core_fapl_t H5FD_core_default_paged_config_g = {H5_MB, TRUE, TRUE, (size_t)4096}; +static const H5FD_core_fapl_t H5FD_core_default_config_g = { + (size_t)H5_MB, TRUE, H5FD_CORE_WRITE_TRACKING_FLAG, H5FD_CORE_WRITE_TRACKING_PAGE_SIZE}; +static const H5FD_core_fapl_t H5FD_core_default_paged_config_g = {(size_t)H5_MB, TRUE, TRUE, (size_t)4096}; /* Define a free list to manage the region type */ H5FL_DEFINE(H5FD_core_region_t); @@ -398,7 +398,7 @@ H5FD__core_write_to_bstore(H5FD_core_t *file, haddr_t addr, size_t size) "write to backing store failed: time = %s, filename = '%s', file descriptor = %d, " "errno = %d, error message = '%s', ptr = %p, total write size = %llu, bytes this " "sub-write = %llu, bytes actually written = %llu, offset = %llu", - HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), ptr, + HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), (void *)ptr, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_wrote, (unsigned long long)offset); } /* end if */ @@ -952,8 +952,8 @@ H5FD__core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, " "error message = '%s', file->mem = %p, total read size = %llu, bytes this " "sub-read = %llu, bytes actually read = %llu, offset = %llu", - HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, - (unsigned long long)size, (unsigned long long)bytes_in, + HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), + (void *)file->mem, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_read, (unsigned long long)offset); } /* end if */ @@ -533,7 +533,7 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token /* Open the map */ if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map") - map = map_args.create.map; + map = map_args.open.map; /* Register an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) @@ -1360,6 +1360,7 @@ H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_SELF; map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(map_id); map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.key_mem_type_id = key_mem_type_id; map_args.specific.args.iterate.op = op; map_args.specific.args.iterate.op_data = op_data; vol_cb_args.op_type = H5VL_MAP_SPECIFIC; @@ -1450,6 +1451,7 @@ H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_m map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.name = map_name; map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.lapl_id = lapl_id; map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.key_mem_type_id = key_mem_type_id; map_args.specific.args.iterate.op = op; map_args.specific.args.iterate.op_data = op_data; vol_cb_args.op_type = H5VL_MAP_SPECIFIC; diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index f37cb74..70650ec 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -93,7 +93,7 @@ #define H5F_ACS_DATA_CACHE_BYTE_SIZE_DEC H5P__decode_size_t /* Definition for preemption read chunks first */ #define H5F_ACS_PREEMPT_READ_CHUNKS_SIZE sizeof(double) -#define H5F_ACS_PREEMPT_READ_CHUNKS_DEF 0.75f +#define H5F_ACS_PREEMPT_READ_CHUNKS_DEF 0.75 #define H5F_ACS_PREEMPT_READ_CHUNKS_ENC H5P__encode_double #define H5F_ACS_PREEMPT_READ_CHUNKS_DEC H5P__decode_double /* Definition for threshold for alignment */ @@ -36,13 +36,6 @@ * skip list. The implementation in that document hurts * performance, at least for integer keys. -NAF) * - * (Also, this implementation has a couple of home-grown - * optimizations, including setting the "update" vector to the - * actual 'forward' pointer to update, instead of the node - * containing the forward pointer -QAK - * -No longer uses update vector, as insertions/deletions are now - * always at level 0. -NAF) - * * (Note: This implementation does not have the information for * implementing the "Linear List Operations" (like insert/delete/ * search by position) in section 3.4 of "A Skip List Cookbook", @@ -71,25 +64,14 @@ /* Define the code template for searches for the "OP" in the H5SL_LOCATE macro */ #define H5SL_LOCATE_SEARCH_FOUND(SLIST, X, I) \ { \ - HDassert(!X->removed); \ - HGOTO_DONE(X->item); \ - } /* end block */ - -/* Define the code template for deferred removals for the "OP" in the - * H5SL_LOCATE macro */ -#define H5SL_LOCATE_SEARCH_DEFER_REMOVE_FOUND(SLIST, X, I) \ - { \ - HDassert(!X->removed); \ - X->removed = TRUE; \ HGOTO_DONE(X->item); \ - } /* end block */ + } /* Define the code template for finds for the "OP" in the H5SL_LOCATE macro */ #define H5SL_LOCATE_FIND_FOUND(SLIST, X, I) \ { \ - HDassert(!X->removed); \ HGOTO_DONE(X); \ - } /* end block */ + } /* Define a code template for comparing scalar keys for the "CMP" in the H5SL_LOCATE macro */ #define H5SL_LOCATE_SCALAR_CMP(SLIST, TYPE, PNODE, PKEY, HASHVAL) (*(TYPE *)((PNODE)->key) < *(TYPE *)PKEY) @@ -155,51 +137,19 @@ H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) { \ X = X->forward[_i]; \ _count++; \ - } /* end while */ \ - } /* end for */ \ + } \ + } \ X = X->forward[0]; \ if (X != NULL && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, X, KEY, HASHVAL)) { \ /* What to do when a node is found */ \ H5_GLUE3(H5SL_LOCATE_, OP, _FOUND)(SLIST, X, _i) \ - } /* end if */ \ - } - -/* Macro used to find node for operation, if there may be "removed" nodes in the - * list (whose keys cannot be read) */ -#define H5SL_LOCATE_SAFE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ - { \ - int _i; /* Local index variable */ \ - H5SL_node_t *_low = X; \ - H5SL_node_t *_high = NULL; \ - \ - H5_GLUE3(H5SL_LOCATE_, CMP, _HASHINIT) \ - (KEY, HASHVAL) for (_i = (int)SLIST->curr_level; _i >= 0; _i--) \ - { \ - X = _low->forward[_i]; \ - while (X != _high) { \ - if (!X->removed) { \ - if (H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X, KEY, HASHVAL)) \ - _low = X; \ - else \ - break; \ - } /* end if */ \ - X = X->forward[_i]; \ - } /* end while */ \ - _high = X; \ - if (X != NULL && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, X, KEY, HASHVAL)) { \ - /* What to do when a node is found */ \ - H5_GLUE3(H5SL_LOCATE_, OP, _FOUND)(SLIST, X, _i) break; \ - } /* end if */ \ - } /* end for */ \ + } \ } /* Macro used to find node for operation */ #define H5SL_LOCATE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ { \ - if ((SLIST)->safe_iterating) \ - H5SL_LOCATE_SAFE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ - else \ - H5SL_LOCATE_OPT(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ + H5SL_LOCATE_OPT(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ } /* Macro used to grow a node by 1. Does not update pointers. LVL is the current @@ -225,13 +175,13 @@ if (NULL == (H5SL_fac_g = (H5FL_fac_head_t **)H5MM_realloc( \ (void *)H5SL_fac_g, H5SL_fac_nalloc_g * sizeof(H5FL_fac_head_t *)))) \ HGOTO_ERROR(H5E_SLIST, H5E_CANTALLOC, ERR, "memory allocation failed") \ - } /* end if */ \ + } \ \ /* Create the new factory */ \ H5SL_fac_g[H5SL_fac_nused_g] = \ H5FL_fac_init((1u << H5SL_fac_nused_g) * sizeof(H5SL_node_t *)); \ H5SL_fac_nused_g++; \ - } /* end if */ \ + } \ \ /* Allocate space for new forward pointers */ \ if (NULL == (_tmp = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[X->log_nalloc]))) \ @@ -239,7 +189,7 @@ H5MM_memcpy((void *)_tmp, (const void *)X->forward, (LVL + 1) * sizeof(H5SL_node_t *)); \ X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc - 1], (void *)X->forward); \ X->forward = _tmp; \ - } /* end if */ \ + } \ \ X->level++; \ } @@ -260,7 +210,7 @@ H5MM_memcpy((void *)_tmp, (const void *)X->forward, (LVL) * sizeof(H5SL_node_t *)); \ X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc + 1], (void *)X->forward); \ X->forward = _tmp; \ - } /* end if */ \ + } \ \ X->level--; \ } @@ -284,7 +234,7 @@ else { \ HDassert(_lvl < (size_t)SLIST->curr_level); \ X->forward[_lvl + 1] = PREV->forward[_lvl + 1]; \ - } /* end else */ \ + } \ PREV->forward[_lvl + 1] = X; \ } @@ -322,7 +272,7 @@ if (!_drop) \ _drop = X; \ break; \ - } /* end if */ \ + } \ \ /* Check if this node is the start of the next gap */ \ if (!_drop && !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) \ @@ -337,7 +287,7 @@ break; \ } \ X = X->forward[_i]; \ - } /* end for */ \ + } \ HDassert(!_drop->forward[_i] || \ !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \ \ @@ -350,7 +300,7 @@ /* Prepare to drop down */ \ X = _last = _drop; \ _next = _drop->forward[_i]; \ - } /* end for */ \ + } \ \ if (_next && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) \ HGOTO_ERROR(H5E_SLIST, H5E_CANTINSERT, NULL, "can't insert duplicate key") \ @@ -359,172 +309,167 @@ /* Macro used to remove node */ #define H5SL_REMOVE(CMP, SLIST, X, TYPE, KEY, HASHVAL) \ { \ - /* Check for deferred removal */ \ - if (SLIST->safe_iterating) \ - H5SL_LOCATE(SEARCH_DEFER_REMOVE, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ - else { \ - H5SL_node_t *_last = X; /* Lowest node in the current gap */ \ - H5SL_node_t *_llast = X; /* Lowest node in the previous gap */ \ - H5SL_node_t *_next = NULL; /* Highest node in the currect gap */ \ - H5SL_node_t *_drop = NULL; /* Low node of the gap to drop into */ \ - H5SL_node_t *_ldrop = NULL; /* Low node of gap before the one to drop into */ \ - H5SL_node_t *_head = SLIST->header; /* Head of the skip list */ \ - int _count; /* Number of nodes in the current gap */ \ - int _i = (int)SLIST->curr_level; \ + H5SL_node_t *_last = X; /* Lowest node in the current gap */ \ + H5SL_node_t *_llast = X; /* Lowest node in the previous gap */ \ + H5SL_node_t *_next = NULL; /* Highest node in the currect gap */ \ + H5SL_node_t *_drop = NULL; /* Low node of the gap to drop into */ \ + H5SL_node_t *_ldrop = NULL; /* Low node of gap before the one to drop into */ \ + H5SL_node_t *_head = SLIST->header; /* Head of the skip list */ \ + int _count; /* Number of nodes in the current gap */ \ + int _i = (int)SLIST->curr_level; \ \ - if (_i < 0) \ - HGOTO_DONE(NULL); \ + if (_i < 0) \ + HGOTO_DONE(NULL); \ \ - H5_GLUE3(H5SL_LOCATE_, CMP, _HASHINIT) \ - (KEY, HASHVAL) \ + H5_GLUE3(H5SL_LOCATE_, CMP, _HASHINIT) \ + (KEY, HASHVAL) \ \ - /* Find the gap to drop in to at the highest level */ \ - while (X && (!X->key || H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X, KEY, HASHVAL))) \ - { \ - _llast = _last; \ - _last = X; \ - X = X->forward[_i]; \ - } \ - _next = X; \ + /* Find the gap to drop in to at the highest level */ \ + while (X && (!X->key || H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X, KEY, HASHVAL))) \ + { \ + _llast = _last; \ + _last = X; \ + X = X->forward[_i]; \ + } \ + _next = X; \ \ - /* Main loop */ \ - for (_i--; _i >= 0; _i--) { \ - /* Search for the node to drop into, also count the number of */ \ - /* nodes of height _i in this gap and keep track of of the node */ \ - /* before the one to drop into (_ldrop will become _llast, */ \ - /* _drop will become _last). */ \ - X = _ldrop = _last; \ - _drop = NULL; \ - for (_count = 0;; _count++) { \ - /* Terminate if this is the last node in the gap */ \ - if (X->forward[_i] == _next) { \ - if (!_drop) \ - _drop = X; \ - break; \ - } /* end if */ \ + /* Main loop */ \ + for (_i--; _i >= 0; _i--) { \ + /* Search for the node to drop into, also count the number of */ \ + /* nodes of height _i in this gap and keep track of of the node */ \ + /* before the one to drop into (_ldrop will become _llast, */ \ + /* _drop will become _last). */ \ + X = _ldrop = _last; \ + _drop = NULL; \ + for (_count = 0;; _count++) { \ + /* Terminate if this is the last node in the gap */ \ + if (X->forward[_i] == _next) { \ + if (!_drop) \ + _drop = X; \ + break; \ + } \ \ - /* If we have already found the node to drop into and there */ \ - /* is more than one node in this gap, we can stop searching */ \ - if (_drop) { \ - HDassert(_count >= 1); \ - _count = 2; \ - break; \ + /* If we have already found the node to drop into and there */ \ + /* is more than one node in this gap, we can stop searching */ \ + if (_drop) { \ + HDassert(_count >= 1); \ + _count = 2; \ + break; \ + } \ + else { /* !_drop */ \ + /* Check if this node is the start of the next gap */ \ + if (!H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) { \ + _drop = X; \ + /* Again check if we can stop searching */ \ + if (_count) { \ + _count = 2; \ + break; \ + } \ } \ - else { /* !_drop */ \ - /* Check if this node is the start of the next gap */ \ - if (!H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) { \ - _drop = X; \ - /* Again check if we can stop searching */ \ - if (_count) { \ - _count = 2; \ - break; \ - } /* end if */ \ - } /* end if */ \ - else \ - _ldrop = X; \ - } /* end else */ \ + else \ + _ldrop = X; \ + } \ \ - /* No need to check the last node in the gap if there are */ \ - /* 3, as there cannot be a fourth */ \ - if (_count == 2) { \ - if (!_drop) \ - _drop = X->forward[_i]; \ - break; \ - } /* end if */ \ - X = X->forward[_i]; \ - } /* end for */ \ - HDassert(_count >= 1 && _count <= 3); \ - HDassert(!_drop->forward[_i] || \ - !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \ + /* No need to check the last node in the gap if there are */ \ + /* 3, as there cannot be a fourth */ \ + if (_count == 2) { \ + if (!_drop) \ + _drop = X->forward[_i]; \ + break; \ + } \ + X = X->forward[_i]; \ + } \ + HDassert(_count >= 1 && _count <= 3); \ + HDassert(!_drop->forward[_i] || \ + !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \ \ - /* Check if we need to adjust node heights */ \ - if (_count == 1) { \ - /* Check if we are in the first gap */ \ - if (_llast == _last) { \ - /* We are in the first gap, count the number of nodes */ \ - /* of height _i in the next gap. We need only check */ \ - /* onenode to see if we should promote the first node */ \ - /* in the next gap */ \ - _llast = _next->forward[_i + 1]; \ + /* Check if we need to adjust node heights */ \ + if (_count == 1) { \ + /* Check if we are in the first gap */ \ + if (_llast == _last) { \ + /* We are in the first gap, count the number of nodes */ \ + /* of height _i in the next gap. We need only check */ \ + /* onenode to see if we should promote the first node */ \ + /* in the next gap */ \ + _llast = _next->forward[_i + 1]; \ \ - /* Demote the separator node */ \ - H5SL_DEMOTE(_next, _last) \ + /* Demote the separator node */ \ + H5SL_DEMOTE(_next, _last) \ \ - /* If there are 2 or more nodes, promote the first */ \ - if (_next->forward[_i]->forward[_i] != _llast) { \ - X = _next->forward[_i]; \ - H5SL_PROMOTE(SLIST, X, _last, NULL) \ - } \ - else if (!_head->forward[_i + 1]) { \ - /* shrink the header */ \ - HDassert(_i == SLIST->curr_level - 1); \ - HDassert((size_t)SLIST->curr_level == _head->level); \ + /* If there are 2 or more nodes, promote the first */ \ + if (_next->forward[_i]->forward[_i] != _llast) { \ + X = _next->forward[_i]; \ + H5SL_PROMOTE(SLIST, X, _last, NULL) \ + } \ + else if (!_head->forward[_i + 1]) { \ + /* shrink the header */ \ + HDassert(_i == SLIST->curr_level - 1); \ + HDassert((size_t)SLIST->curr_level == _head->level); \ \ - H5SL_SHRINK(_head, (size_t)(_i + 1)) \ - SLIST->curr_level--; \ - } /* end else */ \ + H5SL_SHRINK(_head, (size_t)(_i + 1)) \ + SLIST->curr_level--; \ } \ - else { \ - /* We are not in the first gap, count the number of */ \ - /* nodes of height _i in the previous gap. Note we */ \ - /* "look ahead" in this loop so X has the value of the */ \ - /* last node in the previous gap. */ \ - X = _llast->forward[_i]; \ - for (_count = 1; _count < 3 && X->forward[_i] != _last; _count++) \ - X = X->forward[_i]; \ - HDassert(X->forward[_i] == _last); \ + } \ + else { \ + /* We are not in the first gap, count the number of */ \ + /* nodes of height _i in the previous gap. Note we */ \ + /* "look ahead" in this loop so X has the value of the */ \ + /* last node in the previous gap. */ \ + X = _llast->forward[_i]; \ + for (_count = 1; _count < 3 && X->forward[_i] != _last; _count++) \ + X = X->forward[_i]; \ + HDassert(X->forward[_i] == _last); \ \ - /* Demote the separator node */ \ - H5SL_DEMOTE(_last, _llast) \ + /* Demote the separator node */ \ + H5SL_DEMOTE(_last, _llast) \ \ - /* If there are 2 or more nodes, promote the last */ \ - if (_count >= 2) \ - H5SL_PROMOTE(SLIST, X, _llast, NULL) \ - else if (!_head->forward[_i + 1]) { \ - /* shrink the header */ \ - HDassert(_i == SLIST->curr_level - 1); \ - HDassert((size_t)SLIST->curr_level == _head->level); \ + /* If there are 2 or more nodes, promote the last */ \ + if (_count >= 2) \ + H5SL_PROMOTE(SLIST, X, _llast, NULL) \ + else if (!_head->forward[_i + 1]) { \ + /* shrink the header */ \ + HDassert(_i == SLIST->curr_level - 1); \ + HDassert((size_t)SLIST->curr_level == _head->level); \ \ - H5SL_SHRINK(_head, (size_t)(_i + 1)) \ - SLIST->curr_level--; \ - } /* end else */ \ - } /* end else */ \ - } /* end if */ \ + H5SL_SHRINK(_head, (size_t)(_i + 1)) \ + SLIST->curr_level--; \ + } \ + } \ + } \ \ - /* Prepare to drop down */ \ - _llast = _ldrop; \ - _last = _drop; \ - _next = _drop->forward[_i]; \ - } /* end for */ \ + /* Prepare to drop down */ \ + _llast = _ldrop; \ + _last = _drop; \ + _next = _drop->forward[_i]; \ + } \ \ - /* Check if we've found the node */ \ - if (_next && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) { \ - void *tmp = _next->item; \ - X = _next; \ + /* Check if we've found the node */ \ + if (_next && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) { \ + void *tmp = _next->item; \ + X = _next; \ \ - /* If the node has a height > 0, swap it with its (lower) */ \ - /* neighbor */ \ - if (X->level) { \ - X = X->backward; \ - _next->key = X->key; \ - _next->item = X->item; \ - _next->hashval = X->hashval; \ - } /* end if */ \ - HDassert(!X->level); \ + /* If the node has a height > 0, swap it with its (lower) */ \ + /* neighbor */ \ + if (X->level) { \ + X = X->backward; \ + _next->key = X->key; \ + _next->item = X->item; \ + _next->hashval = X->hashval; \ + } \ + HDassert(!X->level); \ \ - /* Remove the node */ \ - X->backward->forward[0] = X->forward[0]; \ - if (SLIST->last == X) \ - SLIST->last = X->backward; \ - else \ - X->forward[0]->backward = X->backward; \ - SLIST->nobjs--; \ - X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[0], X->forward); \ - X = H5FL_FREE(H5SL_node_t, X); \ + /* Remove the node */ \ + X->backward->forward[0] = X->forward[0]; \ + if (SLIST->last == X) \ + SLIST->last = X->backward; \ + else \ + X->forward[0]->backward = X->backward; \ + SLIST->nobjs--; \ + X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[0], X->forward); \ + X = H5FL_FREE(H5SL_node_t, X); \ \ - HGOTO_DONE(tmp); \ - } /* end if */ \ - } /* end else */ \ + HGOTO_DONE(tmp); \ + } \ } /* Macro used to search for node */ @@ -542,7 +487,6 @@ struct H5SL_node_t { size_t level; /* The level of this node */ size_t log_nalloc; /* log2(Number of slots allocated in forward) */ uint32_t hashval; /* Hash value for key (only for strings, currently) */ - hbool_t removed; /* Whether the node is "removed" (actual removal deferred) */ struct H5SL_node_t **forward; /* Array of forward pointers from this node */ struct H5SL_node_t * backward; /* Backward pointer from this node */ }; @@ -558,8 +502,6 @@ struct H5SL_t { size_t nobjs; /* Number of active objects in skip list */ H5SL_node_t *header; /* Header for nodes in skip list */ H5SL_node_t *last; /* Pointer to last node in skip list */ - hbool_t safe_iterating; /* Whether a routine is "safely" iterating over the list and removals should be - deferred */ }; /* Static functions */ @@ -651,11 +593,11 @@ H5SL_term_package(void) for (i = 0; i < H5SL_fac_nused_g; i++) { ret = H5FL_fac_term(H5SL_fac_g[i]); HDassert(ret >= 0); - } /* end if */ + } H5SL_fac_nused_g = 0; n++; - } /* end if */ + } /* Free the list of factories */ if (H5SL_fac_g) { @@ -663,12 +605,12 @@ H5SL_term_package(void) H5SL_fac_nalloc_g = 0; n++; - } /* end if */ + } /* Mark the interface as uninitialized */ if (0 == n) H5_PKG_INIT_VAR = FALSE; - } /* end if */ + } FUNC_LEAVE_NOAPI(n) } /* H5SL_term_package() */ @@ -711,11 +653,10 @@ H5SL__new_node(void *item, const void *key, uint32_t hashval) ret_value->item = item; ret_value->level = 0; ret_value->hashval = hashval; - ret_value->removed = FALSE; if (NULL == (ret_value->forward = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[0]))) { ret_value = H5FL_FREE(H5SL_node_t, ret_value); HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed") - } /* end if */ + } ret_value->log_nalloc = 0; done: @@ -805,7 +746,7 @@ H5SL__insert_common(H5SL_t *slist, void *item, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* 'key' must not have been found in existing list, if we get here */ @@ -880,15 +821,22 @@ H5SL__release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data) while (node) { next_node = node->forward[0]; - /* Call callback, if one is given */ + /* Call callback, if one is given. + * + * Ignoring const here is fine as we only need the value to be const + * with respect to the list code, which should never modify the + * elements. The library code that is making use of the skip list + * container can do what it likes with the elements. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (op) - /* Casting away const OK -QAK */ (void)(op)(node->item, (void *)node->key, op_data); + H5_GCC_CLANG_DIAG_ON("cast-qual") node->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[node->log_nalloc], node->forward); node = H5FL_FREE(H5SL_node_t, node); node = next_node; - } /* end while */ + } /* Reset the header pointers */ slist->header->forward = @@ -1001,9 +949,8 @@ H5SL_create(H5SL_type_t type, H5SL_cmp_t cmp) new_slist->cmp = cmp; /* Set the dynamic internal fields */ - new_slist->curr_level = -1; - new_slist->nobjs = 0; - new_slist->safe_iterating = FALSE; + new_slist->curr_level = -1; + new_slist->nobjs = 0; /* Allocate the header node */ if (NULL == (header = H5SL__new_node(NULL, NULL, (uint32_t)ULONG_MAX))) @@ -1027,7 +974,7 @@ done: if (ret_value == NULL) { if (new_slist != NULL) new_slist = H5FL_FREE(H5SL_t, new_slist); - } /* end if */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5SL_create() */ @@ -1058,9 +1005,6 @@ H5SL_count(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1099,9 +1043,6 @@ H5SL_insert(H5SL_t *slist, void *item, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1148,9 +1089,6 @@ H5SL_add(H5SL_t *slist, void *item, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1242,7 +1180,7 @@ H5SL_remove(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1281,9 +1219,6 @@ H5SL_remove_first(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Assign level */ H5_CHECK_OVERFLOW(slist->curr_level, int, size_t); level = (size_t)slist->curr_level; @@ -1345,12 +1280,12 @@ H5SL_remove_first(H5SL_t *slist) H5SL_SHRINK(head, level) slist->curr_level--; - } /* end else */ + } } else break; - } /* end for */ - } /* end if */ + } + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1436,7 +1371,7 @@ H5SL_search(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* 'key' must not have been found in list, if we get here */ ret_value = NULL; @@ -1480,9 +1415,6 @@ H5SL_less(H5SL_t *slist, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1531,7 +1463,7 @@ H5SL_less(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* Check for a node with a key that is less than the given 'key' */ @@ -1541,13 +1473,13 @@ H5SL_less(H5SL_t *slist, const void *key) ret_value = slist->last->item; else ret_value = NULL; - } /* end if */ + } else { if (x->backward != slist->header) ret_value = x->backward->item; else ret_value = NULL; - } /* end else */ + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1588,9 +1520,6 @@ H5SL_greater(H5SL_t *slist, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1639,7 +1568,7 @@ H5SL_greater(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* ('x' must be the next node with a key greater than the 'key', or NULL) */ @@ -1734,7 +1663,7 @@ H5SL_find(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* 'key' must not have been found in list, if we get here */ ret_value = NULL; @@ -1826,7 +1755,7 @@ H5SL_below(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* Check for a node with a key that is less than the given 'key' */ @@ -1836,13 +1765,13 @@ H5SL_below(H5SL_t *slist, const void *key) ret_value = slist->last; else ret_value = NULL; - } /* end if */ + } else { if (x->backward != slist->header) ret_value = x->backward; else ret_value = NULL; - } /* end else */ + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1931,7 +1860,7 @@ H5SL_above(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* ('x' must be the next node with a key greater than the 'key', or NULL) */ @@ -1971,9 +1900,6 @@ H5SL_first(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2007,9 +1933,6 @@ H5SL_next(H5SL_node_t *slist_node) /* Check args */ HDassert(slist_node); - /* Not currently supported */ - HDassert(!slist_node->removed); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2043,9 +1966,6 @@ H5SL_prev(H5SL_node_t *slist_node) /* Check args */ HDassert(slist_node); - /* Not currently supported */ - HDassert(!slist_node->removed); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2080,9 +2000,6 @@ H5SL_last(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2116,9 +2033,6 @@ H5SL_item(H5SL_node_t *slist_node) /* Check args */ HDassert(slist_node); - /* Not currently supported */ - HDassert(!slist_node->removed); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2179,15 +2093,21 @@ H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data) /* Protect against the node being deleted by the callback */ next = node->forward[0]; - /* Call the iterator callback */ - /* Casting away const OK -QAK */ - if (!node->removed) - if ((ret_value = (op)(node->item, (void *)node->key, op_data)) != 0) - break; + /* Call the iterator callback + * + * Ignoring const here is fine as we only need the value to be const + * with respect to the list code, which should never modify the + * elements. The library code that is making use of the skip list + * container can do what it likes with the elements. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") + if ((ret_value = (op)(node->item, (void *)node->key, op_data)) != 0) + break; + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Advance to next node */ node = next; - } /* end while */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5SL_iterate() */ @@ -2222,9 +2142,6 @@ H5SL_release(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2274,9 +2191,6 @@ H5SL_free(H5SL_t *slist, H5SL_operator_t op, void *op_data) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2290,186 +2204,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5SL_try_free_safe - PURPOSE - Makes the supplied callback on all nodes in the skip list, freeing each - node that the callback returns TRUE for. - USAGE - herr_t PURPOSE(slist,op,opdata) - H5SL_t *slist; IN/OUT: Pointer to skip list to release nodes - H5SL_try_free_op_t op; IN: Callback function to try to free item & key - void *op_data; IN/OUT: Pointer to application data for callback - - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Makes the supplied callback on all nodes in the skip list, freeing each - node that the callback returns TRUE for. The iteration is performed in - a safe manner, such that the callback can call H5SL_remove(), - H5SL_search(), H5SL_find(), and H5SL_iterate() on nodes in this - skiplist, except H5SL_remove() may not be call on *this* node. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This function is written to be most efficient when most nodes are - removed from the skiplist, as it rebuilds the nodes afterwards. - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5SL_try_free_safe(H5SL_t *slist, H5SL_try_free_op_t op, void *op_data) -{ - H5SL_node_t *node, *next_node, *last_node; /* Pointers to skip list nodes */ - htri_t op_ret; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - /* Check args */ - HDassert(slist); - HDassert(op); - - /* Not currently supported */ - HDassert(!slist->safe_iterating); - - /* Check internal consistency */ - /* (Pre-condition) */ - - /* Mark skip list as safe iterating, so nodes aren't freed out from under - * us */ - slist->safe_iterating = TRUE; - - /* Iterate over skip list nodes, making the callback for each and marking - * them as removed if requested by the callback */ - node = slist->header->forward[0]; - while (node) { - /* Check if the node was already removed */ - if (!node->removed) { - /* Call callback */ - /* Casting away const OK -NAF */ - if ((op_ret = (op)(node->item, (void *)node->key, op_data)) < 0) - HGOTO_ERROR(H5E_SLIST, H5E_CALLBACK, FAIL, "callback operation failed") - - /* Check if op indicated that the node should be removed */ - if (op_ret) - /* Mark the node as removed */ - node->removed = TRUE; - } /* end if */ - - /* Advance node */ - node = node->forward[0]; - } /* end while */ - - /* Reset safe_iterating */ - slist->safe_iterating = FALSE; - - /* Iterate over nodes, freeing ones marked as removed */ - node = slist->header->forward[0]; - last_node = slist->header; - while (node) { - /* Save next node */ - next_node = node->forward[0]; - - /* Check if the node was marked as removed */ - if (node->removed) { - /* Remove the node */ - node->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[node->log_nalloc], node->forward); - node = H5FL_FREE(H5SL_node_t, node); - slist->nobjs--; - } /* end if */ - else { - /* Update backwards and forwards[0] pointers, and set the level to - * 0. Since the list is flattened we must rebuild the skiplist - * afterwards. */ - /* Set level to 0. Note there is no need to preserve - * node->forward[0] since it was cached above and will always be - * updated later. */ - if (node->level > 0) { - node->forward = - (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[node->log_nalloc], (void *)node->forward); - if (NULL == (node->forward = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[0]))) - HGOTO_ERROR(H5E_SLIST, H5E_CANTALLOC, FAIL, "memory allocation failed") - node->log_nalloc = 0; - node->level = 0; - } /* end if */ - - /* Update pointers */ - last_node->forward[0] = node; - node->backward = last_node; - last_node = node; - } /* end else */ - - /* Advance node */ - node = next_node; - } /* end while */ - - /* Final pointer update */ - last_node->forward[0] = NULL; - slist->last = last_node; - - /* Demote skip list to level 0 */ - if (slist->curr_level > 0) { - HDassert(slist->header->level == (size_t)slist->curr_level); - - node = slist->header->forward[0]; - slist->header->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[slist->header->log_nalloc], - (void *)slist->header->forward); - if (NULL == (slist->header->forward = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[0]))) - HGOTO_ERROR(H5E_SLIST, H5E_CANTALLOC, FAIL, "memory allocation failed") - slist->header->forward[0] = node; - slist->header->log_nalloc = 0; - slist->header->level = 0; - } /* end if */ - - /* Check if there are any nodes left */ - if (slist->nobjs > 0) { - int i; - - HDassert(slist->header->forward[0]); - - /* Set skiplist level to 0 */ - slist->curr_level = 0; - - /* Rebuild the forward arrays */ - for (i = 0; slist->curr_level >= i; i++) { - HDassert(slist->curr_level == i); - - /* Promote every third node this level until we run out of nodes */ - node = last_node = slist->header; - while (1) { - /* Check second node in gap, if not present, no need to promote - * further this level. */ - HDassert(node->forward[i]); - node = node->forward[i]->forward[i]; - if (!node) - break; - - /* Check third and fourth node in gap, if either is not present, - * no need to promote further this level. */ - node = node->forward[i]; - if (!node || !node->forward[i]) - break; - - /* Promote the third node in the gap */ - H5SL_PROMOTE(slist, node, last_node, FAIL) - last_node = node; - } /* end while */ - } /* end for */ - } /* end if */ - else { - HDassert(!slist->header->forward[0]); - HDassert(slist->last == slist->header); - HDassert(slist->nobjs == 0); - - /* Reset the skiplist level */ - slist->curr_level = -1; - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SL_try_free_safe() */ - -/*-------------------------------------------------------------------------- - NAME H5SL_destroy PURPOSE Close a skip list, deallocating it and freeing all its nodes. diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h index c9e1147..be6f7b6 100644 --- a/src/H5SLprivate.h +++ b/src/H5SLprivate.h @@ -60,9 +60,6 @@ typedef int (*H5SL_cmp_t)(const void *key1, const void *key2); /* Typedef for iteration operations */ typedef herr_t (*H5SL_operator_t)(void *item, void *key, void *operator_data /*in,out*/); -/* Typedef for H5SL_try_free_safe operation callback */ -typedef htri_t (*H5SL_try_free_op_t)(void *item, void *key, void *operator_data /*in,out*/); - /********************/ /* Private routines */ /********************/ @@ -86,7 +83,6 @@ H5_DLL void * H5SL_item(H5SL_node_t *slist_node); H5_DLL herr_t H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data); H5_DLL herr_t H5SL_release(H5SL_t *slist); H5_DLL herr_t H5SL_free(H5SL_t *slist, H5SL_operator_t op, void *op_data); -H5_DLL herr_t H5SL_try_free_safe(H5SL_t *slist, H5SL_try_free_op_t op, void *op_data); H5_DLL herr_t H5SL_close(H5SL_t *slist); H5_DLL herr_t H5SL_destroy(H5SL_t *slist, H5SL_operator_t op, void *op_data); H5_DLL int H5SL_term_interface(void); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 37e6af6..8afa7c4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -556,8 +556,8 @@ if (HDF5_ENABLE_FORMATTERS) endif () if (HDF5_BUILD_UTILS) -#-- Adding test for mirror_vfd -add_executable (mirror_vfd ${mirror_vfd_SOURCES}) + #-- Adding test for mirror_vfd (requires mirror server) + add_executable (mirror_vfd ${mirror_vfd_SOURCES}) target_include_directories (mirror_vfd PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (mirror_vfd STATIC) @@ -752,24 +752,26 @@ if (HDF5_ENABLE_FORMATTERS) clang_format (HDF5_TEST_use_append_chunk_FORMAT use_append_chunk) endif () -set (use_append_chunk_mirror_SOURCES ${HDF5_TEST_SOURCE_DIR}/use_append_chunk_mirror.c ${HDF5_TEST_SOURCE_DIR}/use_common.c ${HDF5_TEST_SOURCE_DIR}/use.h) -add_executable (use_append_chunk_mirror ${use_append_chunk_mirror_SOURCES}) -target_compile_options(use_append_chunk_mirror PRIVATE "${HDF5_CMAKE_C_FLAGS}") -target_include_directories (use_append_chunk_mirror PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") -if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (use_append_chunk_mirror STATIC) - target_link_libraries (use_append_chunk_mirror PRIVATE ${HDF5_TEST_LIB_TARGET}) -else () - TARGET_C_PROPERTIES (use_append_chunk_mirror SHARED) - target_link_libraries (use_append_chunk_mirror PRIVATE ${HDF5_TEST_LIBSH_TARGET}) -endif () -set_target_properties (use_append_chunk_mirror PROPERTIES FOLDER test) +if (HDF5_BUILD_UTILS) # requires mirror server + set (use_append_chunk_mirror_SOURCES ${HDF5_TEST_SOURCE_DIR}/use_append_chunk_mirror.c ${HDF5_TEST_SOURCE_DIR}/use_common.c ${HDF5_TEST_SOURCE_DIR}/use.h) + add_executable (use_append_chunk_mirror ${use_append_chunk_mirror_SOURCES}) + target_compile_options(use_append_chunk_mirror PRIVATE "${HDF5_CMAKE_C_FLAGS}") + target_include_directories (use_append_chunk_mirror PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + if (NOT BUILD_SHARED_LIBS) + TARGET_C_PROPERTIES (use_append_chunk_mirror STATIC) + target_link_libraries (use_append_chunk_mirror PRIVATE ${HDF5_TEST_LIB_TARGET}) + else () + TARGET_C_PROPERTIES (use_append_chunk_mirror SHARED) + target_link_libraries (use_append_chunk_mirror PRIVATE ${HDF5_TEST_LIBSH_TARGET}) + endif () + set_target_properties (use_append_chunk_mirror PROPERTIES FOLDER test) -#----------------------------------------------------------------------------- -# Add Target to clang-format -#----------------------------------------------------------------------------- -if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_TEST_use_append_chunk_mirror_FORMAT use_append_chunk_mirror) + #----------------------------------------------------------------------------- + # Add Target to clang-format + #----------------------------------------------------------------------------- + if (HDF5_ENABLE_FORMATTERS) + clang_format (HDF5_TEST_use_append_chunk_mirror_FORMAT use_append_chunk_mirror) + endif () endif () set (use_append_mchunks_SOURCES ${HDF5_TEST_SOURCE_DIR}/use_append_mchunks.c ${HDF5_TEST_SOURCE_DIR}/use_common.c ${HDF5_TEST_SOURCE_DIR}/use.h) diff --git a/test/CMakeVFDTests.cmake b/test/CMakeVFDTests.cmake index 130b0bf..e08e4d2 100644 --- a/test/CMakeVFDTests.cmake +++ b/test/CMakeVFDTests.cmake @@ -16,6 +16,7 @@ ############################################################################## ############################################################################## # included from CMakeTests.cmake +H5_CREATE_VFD_DIR() # create more test folders for each VFD foreach (vfdtest ${VFD_LIST}) diff --git a/test/dsets.c b/test/dsets.c index 5e80ef7..a4b5757 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -1399,7 +1399,7 @@ test_conv_buffer(hid_t fid) cf->b[j] = 100.0F * (float)(j + 1) + 0.01F * (float)j; for (j = 0; j < DIM3; j++) - cf->c[j] = 100.0F * (float)(j + 1) + 0.02F * (float)j; + cf->c[j] = 100.0 * (double)(j + 1) + 0.02 * (double)j; /* Create data space */ if ((space = H5Screate(H5S_SCALAR)) < 0) @@ -3442,11 +3442,11 @@ test_nbit_double(hid_t file) /* orig_data[] are initialized to be within the range that can be represented by * dataset datatype (no precision loss during datatype conversion) */ - double orig_data[2][5] = {{(double)1.6081706885101836e+60L, -255.32099170994480f, - (double)1.2677579992621376e-61L, 64568.289448797700f, + double orig_data[2][5] = {{(double)1.6081706885101836e+60L, -255.32099170994480, + (double)1.2677579992621376e-61L, 64568.289448797700, (double)-1.0619721778839084e-75L}, - {(double)2.1499497833454840e+56L, 6.6562295504670740e-3f, -1.5747263393432150f, - 1.0711093225222612f, -9.8971679387636870e-1f}}; + {(double)2.1499497833454840e+56L, 6.6562295504670740e-3, -1.5747263393432150, + 1.0711093225222612, -9.8971679387636870e-1}}; double new_data[2][5]; size_t precision, offset; size_t i, j; @@ -5201,7 +5201,7 @@ test_scaleoffset_float(hid_t file) /* Check that the values read are the same as the values written */ for (i = 0; i < (size_t)size[0]; i++) { for (j = 0; j < (size_t)size[1]; j++) { - if (HDfabs(new_data[i][j] - orig_data[i][j]) > HDpow(10.0, -3.0)) { + if (HDfabs((double)(new_data[i][j] - orig_data[i][j])) > HDpow(10.0, -3.0)) { H5_FAILED(); HDprintf(" Read different values than written.\n"); HDprintf(" At index %lu,%lu\n", (unsigned long)i, (unsigned long)j); @@ -5347,7 +5347,7 @@ test_scaleoffset_float_2(hid_t file) /* Check that the values read are the same as the values written */ for (j = 0; j < (size_t)size[1]; j++) { - if (HDfabs(new_data[0][j] - orig_data[0][j]) > HDpow(10.0, -3.0)) { + if (HDfabs((double)(new_data[0][j] - orig_data[0][j])) > HDpow(10.0, -3.0)) { H5_FAILED(); HDprintf(" Read different values than written.\n"); HDprintf(" At index %lu,%lu\n", (unsigned long)0, (unsigned long)j); @@ -5435,7 +5435,7 @@ test_scaleoffset_double(hid_t file) /* Initialize data */ for (i = 0; i < (size_t)size[0]; i++) for (j = 0; j < (size_t)size[1]; j++) { - orig_data[i][j] = (float)(HDrandom() % 10000000) / 10000000.0F; + orig_data[i][j] = (HDrandom() % 10000000) / 10000000.0; /* even-numbered values are negtive */ if ((i * size[1] + j + 1) % 2 == 0) @@ -5544,7 +5544,7 @@ test_scaleoffset_double_2(hid_t file) goto error; /* Set fill value */ - fillval = 10000.0F; + fillval = 10000.0; if (H5Pset_fill_value(dc, H5T_NATIVE_DOUBLE, &fillval) < 0) goto error; @@ -5581,7 +5581,7 @@ test_scaleoffset_double_2(hid_t file) /* Initialize data of hyperslab */ for (j = 0; j < (size_t)size[1]; j++) { - orig_data[0][j] = (float)(HDrandom() % 10000000) / 10000000.0F; + orig_data[0][j] = (HDrandom() % 10000000) / 10000000.0; /* even-numbered values are negtive */ if ((j + 1) % 2 == 0) @@ -5614,7 +5614,7 @@ test_scaleoffset_double_2(hid_t file) /* Check that the values read are the same as the values written */ for (j = 0; j < (size_t)size[1]; j++) { - if (HDfabs(new_data[0][j] - orig_data[0][j]) > HDpow(10.0, -7.0)) { + if (HDfabs((double)(new_data[0][j] - orig_data[0][j])) > HDpow(10.0, -7.0)) { H5_FAILED(); HDprintf(" Read different values than written.\n"); HDprintf(" At index %lu,%lu\n", (unsigned long)0, (unsigned long)j); @@ -6525,7 +6525,7 @@ test_set_local(hid_t fapl) h5_fixname(FILENAME[5], fapl, filename, sizeof filename); /* Initialize the integer & floating-point dataset */ - n = 1.0F; + n = 1.0; for (i = 0; i < DSET_DIM1; i++) for (j = 0; j < DSET_DIM2; j++) { points[i][j] = (int)n++; @@ -9085,7 +9085,7 @@ test_big_chunks_bypass_cache(hid_t fapl) /* Define cache size to be smaller than chunk size */ rdcc_nelmts = BYPASS_CHUNK_DIM / 5; rdcc_nbytes = sizeof(int) * BYPASS_CHUNK_DIM / 5; - if (H5Pset_cache(fapl_local, 0, rdcc_nelmts, rdcc_nbytes, 0.0F) < 0) + if (H5Pset_cache(fapl_local, 0, rdcc_nelmts, rdcc_nbytes, 0.0) < 0) FAIL_STACK_ERROR /* Create file */ diff --git a/test/dt_arith.c b/test/dt_arith.c index 91e31d5..4cdb020 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -2707,7 +2707,7 @@ my_isnan(dtype_t type, void *val) #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 } else if (FLT_LDOUBLE == type) { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, val, sizeof(long double)); retval = (x != x); #endif @@ -2735,7 +2735,7 @@ my_isnan(dtype_t type, void *val) #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 } else if (FLT_LDOUBLE == type) { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, val, sizeof(long double)); HDsnprintf(s, sizeof(s), "%Lg", x); @@ -3059,7 +3059,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) for (j = 0; j < nelmts; j++) { underflow = 0; hw_f = 911.0F; - hw_d = 911.0F; + hw_d = 911.0; #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE hw_ld = 911.0L; #endif @@ -3108,14 +3108,14 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) if (FLT_FLOAT == dst_type) { hw_f = (float)*((long double *)aligned); hw = (unsigned char *)&hw_f; - underflow = HDfabsl(*((long double *)aligned)) < FLT_MIN; - overflow = HDfabsl(*((long double *)aligned)) > FLT_MAX; + underflow = HDfabsl(*((long double *)aligned)) < (long double)FLT_MIN; + overflow = HDfabsl(*((long double *)aligned)) > (long double)FLT_MAX; } else if (FLT_DOUBLE == dst_type) { hw_d = (double)*((long double *)aligned); hw = (unsigned char *)&hw_d; - underflow = HDfabsl(*((long double *)aligned)) < DBL_MIN; - overflow = HDfabsl(*((long double *)aligned)) > DBL_MAX; + underflow = HDfabsl(*((long double *)aligned)) < (long double)DBL_MIN; + overflow = HDfabsl(*((long double *)aligned)) > (long double)DBL_MAX; } else { hw_ld = *((long double *)aligned); @@ -3204,8 +3204,8 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) if (overflow && my_isinf(dendian, buf + j * sizeof(float), dst_size, dst_mpos, dst_msize, dst_epos, dst_esize)) continue; /* all overflowed, no error */ - check_mant[0] = HDfrexpf(x, check_expo + 0); - check_mant[1] = HDfrexpf(hw_f, check_expo + 1); + check_mant[0] = (double)HDfrexpf(x, check_expo + 0); + check_mant[1] = (double)HDfrexpf(hw_f, check_expo + 1); } else if (FLT_DOUBLE == dst_type) { double x = 0.0; @@ -3220,7 +3220,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) #if H5_SIZEOF_LONG_DOUBLE != 0 && (H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE) } else { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, &buf[j * dst_size], sizeof(long double)); /* dst is largest float, no need to check underflow. */ check_mant[0] = (double)HDfrexpl(x, check_expo + 0); @@ -3278,7 +3278,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, &saved[j * src_size], sizeof(long double)); HDfprintf(stdout, " %29.20Le\n", x); #endif @@ -3300,7 +3300,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, &buf[j * dst_size], sizeof(long double)); HDfprintf(stdout, " %29.20Le\n", x); #endif diff --git a/test/testmeta.c b/test/testmeta.c index c59c6cb..7cb3000 100644 --- a/test/testmeta.c +++ b/test/testmeta.c @@ -195,7 +195,7 @@ main(void) start[0] = 0; status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, start, stride, count, NULL); - start[0] = (hssize_t)j; + start[0] = (hsize_t)j; status = H5Sselect_hyperslab(dataspace_id, H5S_SELECT_SET, start, stride, count, NULL); status = H5Dwrite(dataset_id, type_id, memspace_id, dataspace_id, H5P_DEFAULT, &floatval); if (status < 0) { diff --git a/test/tskiplist.c b/test/tskiplist.c index 4bf9b11..31b5cff 100644 --- a/test/tskiplist.c +++ b/test/tskiplist.c @@ -1165,213 +1165,6 @@ test_skiplist_free(void) /**************************************************************** ** -** test_skiplist_try_free_safe(): Test H5SL (skip list) code. -** Tests 'try_free_safe' operation in skip lists. -** -****************************************************************/ -/* Macro definitions */ -#define TEST_TFS_MAX_NOBJS 100 -#define TEST_TFS_MIN_NOBJS 5 -#define TEST_TFS_NITER 50 - -/* Structure to hold the list of objects */ -typedef struct { - H5SL_t * slist; /* Skiplist holding the objects */ - struct test_tfs_obj_t *list; /* Linear list of objects */ - int nobjs; /* Number of objects in list */ - int nobjs_rem; /* Number of objects in list that have not been freed */ -} test_tfs_list_t; - -/* Structure for an object */ -typedef struct test_tfs_obj_t { - int idx; /* Index (key) for this object */ - int nfrees; /* Number of times this object has been freed */ -} test_tfs_obj_t; - -/* op_data struct for H5SL_iterate() */ -typedef struct test_tfs_it_ud_t { - test_tfs_list_t *obj_list; /* List of objects */ - int last_idx; /* Index of last object visited in iteration */ - int ncalls; /* Number of times this callback was called */ -} test_tfs_it_ud_t; - -/* iterate callback */ -static herr_t -test_tfs_iter(void *_obj, void *key, void *_udata) -{ - test_tfs_obj_t * obj = (test_tfs_obj_t *)_obj; - test_tfs_it_ud_t *udata = (test_tfs_it_ud_t *)_udata; - - /* Check consistency */ - CHECK_PTR_EQ((void *)&obj->idx, key, "obj->idx"); - CHECK_PTR_EQ(obj, &udata->obj_list->list[obj->idx], "obj_list->list[obj->idx]"); - - /* Increment number of calls */ - udata->ncalls++; - - /* Verify we were given the correct object */ - do { - udata->last_idx++; - } while (udata->obj_list->list[udata->last_idx].nfrees != 0); - VERIFY(udata->last_idx, obj->idx, "H5SL_iterate"); - - return 0; -} /* end test_tfs_iter() */ - -/* try_free_safe callback */ -static htri_t -test_tfs_free(void *_obj, void *key, void *_obj_list) -{ - test_tfs_obj_t * obj = (test_tfs_obj_t *)_obj; - test_tfs_list_t *obj_list = (test_tfs_list_t *)_obj_list; - test_tfs_it_ud_t iter_ud; - int nrems, rem_idx, i, j; - test_tfs_obj_t * obj_ret; - herr_t ret; /* return value */ - htri_t ret_value; - - /* Check consistency */ - CHECK_PTR_EQ((void *)&obj->idx, key, "obj->idx"); - CHECK_PTR_EQ(obj, &obj_list->list[obj->idx], "obj_list->list[obj->idx]"); - - /* Mark this object as freed (to make sure it isn't recursively freed, that - * is not something we support, we will undo this if we decide later not to - * free the object) */ - obj->nfrees++; - obj_list->nobjs_rem--; - - /* Decide how many objects to remove */ - nrems = (int)(HDrandom() % (long)3); - - /* Remove objects */ - for (i = 0; i < nrems; i++) - /* Check nobjs_rem */ - if (obj_list->nobjs_rem > 0) { - /* Remove a random object from the list */ - rem_idx = (int)(HDrandom() % (long)obj_list->nobjs_rem); - - /* Scan the list, finding the rem_idx'th object that has not been - * freed */ - for (j = 0; j < obj_list->nobjs; j++) - if (obj_list->list[j].nfrees == 0) { - if (rem_idx == 0) - break; - else - rem_idx--; - } /* end if */ - if (j == obj_list->nobjs) - ERROR("invalid obj_list"); - else { - /* Remove the object */ - obj_ret = (test_tfs_obj_t *)H5SL_remove(obj_list->slist, &j); - CHECK_PTR(obj_ret, "H5SL_remove"); - obj_ret->nfrees++; - obj_list->nobjs_rem--; - } /* end else */ - } /* end if */ - - /* Mark this object as not freed so we know to expect it in the iterate call - */ - obj->nfrees--; - obj_list->nobjs_rem++; - - /* Iterate over skip list (maybe) */ - if (HDrandom() % (long)5) { - iter_ud.obj_list = obj_list; - iter_ud.last_idx = -1; - iter_ud.ncalls = 0; - ret = H5SL_iterate(obj_list->slist, test_tfs_iter, &iter_ud); - CHECK(ret, FAIL, "H5SL_iterate"); - VERIFY(iter_ud.ncalls, obj_list->nobjs_rem, "H5SL_iterate"); - } /* end if */ - - /* Verify nobjs_rem is non-negative */ - if (obj_list->nobjs_rem < 0) - ERROR("invalid nobjs_rem"); - - /* Decide whether this object should be freed */ - if (HDrandom() % (long)2) { - /* Free the object */ - ret_value = TRUE; - obj->nfrees++; - obj_list->nobjs_rem--; - } /* end if */ - else - /* Do not free the object */ - ret_value = FALSE; - - return ret_value; -} /* end test_tfs_free() */ - -/* Test function */ -static void -test_skiplist_try_free_safe(void) -{ - test_tfs_list_t obj_list; - test_tfs_obj_t list[TEST_TFS_MAX_NOBJS]; - int i, j; - int nobjs_found; - hsize_t count; - herr_t ret; /* Generic return value */ - - /* Output message about test being performed */ - MESSAGE(7, ("Testing Skip List 'Try Free Safe' Operation\n")); - - /* Create a skip list */ - obj_list.slist = H5SL_create(H5SL_TYPE_INT, NULL); - CHECK_PTR(obj_list.slist, "H5SL_create"); - - /* Init obj_list.list */ - obj_list.list = list; - for (j = 0; j < TEST_TFS_MAX_NOBJS; j++) - list[j].idx = j; - - for (i = 0; i < TEST_TFS_NITER; i++) { - /* Build object list */ - obj_list.nobjs = obj_list.nobjs_rem = - (int)(TEST_TFS_MIN_NOBJS + (HDrandom() % (long)(TEST_TFS_MAX_NOBJS - TEST_TFS_MIN_NOBJS + 1))); - for (j = 0; j < obj_list.nobjs; j++) { - list[j].nfrees = 0; - ret = H5SL_insert(obj_list.slist, &list[j], &list[j].idx); - CHECK(ret, FAIL, "H5SL_insert"); - } /* end for */ - - /* Call H5S_try_free_safe() - free most of the items in the skip list in - * a safe manner */ - ret = H5SL_try_free_safe(obj_list.slist, test_tfs_free, &obj_list); - CHECK(ret, FAIL, "H5SL_try_free_safe"); - - /* Verify list */ - nobjs_found = 0; - for (j = 0; j < obj_list.nobjs; j++) - if (list[j].nfrees == 0) - nobjs_found++; - else - VERIFY(list[j].nfrees, (long)1, "list[j].nfrees"); - - /* Verify number of objects */ - VERIFY(obj_list.nobjs_rem, nobjs_found, "obj_list.nobjs_rem"); - count = H5SL_count(obj_list.slist); - VERIFY(count, (size_t)nobjs_found, "H5SL_count"); - - /* Release the skip list, forcibly freeing all nodes (will not make - * callbacks) */ - ret = H5SL_release(obj_list.slist); - CHECK(ret, FAIL, "H5SL_release"); - - /* Verify number of objects is 0 */ - count = H5SL_count(obj_list.slist); - VERIFY(count, (size_t)0, "H5SL_count"); - } /* end for */ - - /* Close the skip list */ - ret = H5SL_close(obj_list.slist); - CHECK(ret, FAIL, "H5SL_close"); - -} /* end test_skiplist_try_free_safe() */ - -/**************************************************************** -** ** test_skiplist_less(): Test H5SL (skip list) code. ** Tests 'less' operation in skip lists. ** @@ -1796,7 +1589,6 @@ test_skiplist(void) test_skiplist_add(); /* Test 'add' operation */ test_skiplist_destroy(); /* Test 'destroy' operation */ test_skiplist_free(); /* Test 'free' operation */ - test_skiplist_try_free_safe(); /* Test 'try_free_safe' operation */ test_skiplist_less(); /* Test 'less' operation */ test_skiplist_greater(); /* Test 'greater' operation */ test_skiplist_below(); /* Test 'below' operation */ diff --git a/test/tvlstr.c b/test/tvlstr.c index 7e47c7b..68f6124 100644 --- a/test/tvlstr.c +++ b/test/tvlstr.c @@ -293,7 +293,7 @@ test_vlstrings_special(void) /* Check data read in */ for (i = 0; i < SPACE1_DIM1; i++) if (rdata[i] != NULL) - TestErrPrintf("VL doesn't match!, rdata[%d]=%p\n", (int)i, rdata[i]); + TestErrPrintf("VL doesn't match!, rdata[%d]=%s\n", (int)i, rdata[i]); /* Write dataset to disk */ ret = H5Dwrite(dataset, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); @@ -352,7 +352,7 @@ test_vlstrings_special(void) /* Check data read in */ for (i = 0; i < SPACE1_DIM1; i++) if (rdata[i] != NULL) - TestErrPrintf("VL doesn't match!, rdata[%d]=%p\n", (int)i, rdata[i]); + TestErrPrintf("VL doesn't match!, rdata[%d]=%s\n", (int)i, rdata[i]); /* Try to write nil strings to disk. */ ret = H5Dwrite(dataset, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata2); @@ -365,7 +365,7 @@ test_vlstrings_special(void) /* Check data read in */ for (i = 0; i < SPACE1_DIM1; i++) if (rdata[i] != NULL) - TestErrPrintf("VL doesn't match!, rdata[%d]=%p\n", (int)i, rdata[i]); + TestErrPrintf("VL doesn't match!, rdata[%d]=%s\n", (int)i, rdata[i]); /* Close Dataset */ ret = H5Dclose(dataset); diff --git a/testpar/CMakeVFDTests.cmake b/testpar/CMakeVFDTests.cmake index 12df1e9..d6a4025 100644 --- a/testpar/CMakeVFDTests.cmake +++ b/testpar/CMakeVFDTests.cmake @@ -15,6 +15,7 @@ ### T E S T I N G ### ############################################################################## ############################################################################## +H5_CREATE_VFD_DIR() set (H5P_VFD_TESTS t_pflush1 diff --git a/tools/test/h5dump/CMakeVFDTests.cmake b/tools/test/h5dump/CMakeVFDTests.cmake index b6e0bea..7ab8c1f 100644 --- a/tools/test/h5dump/CMakeVFDTests.cmake +++ b/tools/test/h5dump/CMakeVFDTests.cmake @@ -15,6 +15,7 @@ ### T E S T I N G ### ############################################################################## ############################################################################## +H5_CREATE_VFD_DIR() # -------------------------------------------------------------------- # Copy all the HDF5 files from the source directory into the test directory diff --git a/tools/test/h5repack/CMakeTests.cmake b/tools/test/h5repack/CMakeTests.cmake index 037287d..397c3ac 100644 --- a/tools/test/h5repack/CMakeTests.cmake +++ b/tools/test/h5repack/CMakeTests.cmake @@ -1544,7 +1544,7 @@ # the references in attribute of compund or vlen datatype ADD_H5_TEST (HDFFV-5932 "TEST" ${FILE_ATTR_REF}) -# Add test for memory leak in attirbute. This test is verified by CTEST. +# Add test for memory leak in attribute. This test is verified by CTEST. # 1. leak from vlen string # 2. leak from compound type without reference member # (HDFFV-7840, ) @@ -1552,12 +1552,12 @@ ADD_H5_TEST (HDFFV-7840 "TEST" h5diff_attr1.h5) # test CVE-2018-17432 fix - set (arg h5repack_CVE-2018-17432.h5 h5repack__CVE-2018-17432_out.h5 --low=1 --high=2 -f GZIP=8 -l dset1:CHUNK=5x6) + set (arg h5repack_CVE-2018-17432.h5 --low=1 --high=2 -f GZIP=8 -l dset1:CHUNK=5x6) set (TESTTYPE "TEST") ADD_H5_FILTER_TEST (HDFFV-10590 "" ${TESTTYPE} 1 ${arg}) # test CVE-2018-14460 fix - set (arg h5repack_CVE-2018-14460.h5 h5repack_CVE-2018-14460_out.h5) + set (arg h5repack_CVE-2018-14460.h5) set (TESTTYPE "TEST") ADD_H5_FILTER_TEST (HDFFV-11223 "" ${TESTTYPE} 1 ${arg}) diff --git a/tools/test/h5repack/CMakeVFDTests.cmake b/tools/test/h5repack/CMakeVFDTests.cmake index e50414f..f8ac10b 100644 --- a/tools/test/h5repack/CMakeVFDTests.cmake +++ b/tools/test/h5repack/CMakeVFDTests.cmake @@ -15,6 +15,7 @@ ### T E S T I N G ### ############################################################################## ############################################################################## +H5_CREATE_VFD_DIR() ############################################################################## ############################################################################## diff --git a/tools/test/h5repack/h5repack.sh.in b/tools/test/h5repack/h5repack.sh.in index ef89899..e74bb4f 100644 --- a/tools/test/h5repack/h5repack.sh.in +++ b/tools/test/h5repack/h5repack.sh.in @@ -908,13 +908,24 @@ TOOLTEST_FAIL() ( cd $TESTDIR $ENVCMD $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile - ) >$actual + ) >&$actual RET=$? - if [ $RET == 0 ] ; then + + # Normally h5repack of files tested with this function are expected + # to return not 0, but if the command results in "Segmentation fault" + # or "core dumped" it is a failure regardless of the return value. + failure=`grep -e 'Segmentation fault' -e 'core dumped' $actual` + if [ "$failure" != "" ]; then nerrors="`expr $nerrors + 1`" echo " FAILED" + echo " $failure" else - echo " PASSED" + if [ $RET == 0 ] ; then + nerrors="`expr $nerrors + 1`" + echo " FAILED" + else + echo " PASSED" + fi fi rm -f $outfile } diff --git a/utils/test/CMakeLists.txt b/utils/test/CMakeLists.txt index 64d5563..f0612c1 100644 --- a/utils/test/CMakeLists.txt +++ b/utils/test/CMakeLists.txt @@ -26,9 +26,9 @@ set (H5_UTIL_TESTS) if (HDF5_TEST_SWMR) set (H5_UTIL_TESTS ${H5_UTIL_TESTS} - swmr_check_compat_vfd - vds_elink_compat_vol -) + swmr_check_compat_vfd + vds_elink_compat_vol + ) endif () if (H5_UTIL_TESTS) |