summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorvchoi-hdfgroup <55293060+vchoi-hdfgroup@users.noreply.github.com>2022-04-04 19:40:16 (GMT)
committerGitHub <noreply@github.com>2022-04-04 19:40:16 (GMT)
commitff7fe9e9af404591d3d50f3b33d190679529bb10 (patch)
treed2bd03b84b8e97d21dbcdfaa04199c898b6ae291 /src
parente3ff70f44a4360b26e569f6047a906f522fb28ed (diff)
parentbc62da7eb911727497475d1cc90991230f33fa3d (diff)
downloadhdf5-ff7fe9e9af404591d3d50f3b33d190679529bb10.zip
hdf5-ff7fe9e9af404591d3d50f3b33d190679529bb10.tar.gz
hdf5-ff7fe9e9af404591d3d50f3b33d190679529bb10.tar.bz2
Merge pull request #60 from HDFGroup/feature/vfd_swmr
Feature/vfd swmr
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt98
-rw-r--r--src/H5.c332
-rw-r--r--src/H5A.c8
-rw-r--r--src/H5AC.c170
-rw-r--r--src/H5ACdbg.c4
-rw-r--r--src/H5ACmpio.c111
-rw-r--r--src/H5ACpkg.h2
-rw-r--r--src/H5ACprivate.h4
-rw-r--r--src/H5ACproxy_entry.c3
-rw-r--r--src/H5ACpublic.h19
-rw-r--r--src/H5Adense.c32
-rw-r--r--src/H5Adeprec.c2
-rw-r--r--src/H5Aint.c76
-rw-r--r--src/H5Apublic.h4
-rw-r--r--src/H5B.c3
-rw-r--r--src/H5B2.c3
-rw-r--r--src/H5C.c543
-rw-r--r--src/H5CS.c4
-rw-r--r--src/H5CSprivate.h4
-rw-r--r--src/H5CX.c94
-rw-r--r--src/H5CXprivate.h7
-rw-r--r--src/H5Cdbg.c4
-rw-r--r--src/H5Cimage.c59
-rw-r--r--src/H5Cmpio.c2
-rw-r--r--src/H5Cpkg.h215
-rw-r--r--src/H5Cprefetched.c2
-rw-r--r--src/H5Cprivate.h29
-rw-r--r--src/H5Cpublic.h7
-rw-r--r--src/H5Cquery.c2
-rw-r--r--src/H5Ctag.c88
-rw-r--r--src/H5D.c7
-rw-r--r--src/H5Dchunk.c475
-rw-r--r--src/H5Dcompact.c136
-rw-r--r--src/H5Dcontig.c51
-rw-r--r--src/H5Dearray.c4
-rw-r--r--src/H5Defl.c28
-rw-r--r--src/H5Dfarray.c2
-rw-r--r--src/H5Dfill.c2
-rw-r--r--src/H5Dint.c175
-rw-r--r--src/H5Dio.c124
-rw-r--r--src/H5Dlayout.c2
-rw-r--r--src/H5Dmpio.c5394
-rw-r--r--src/H5Dpkg.h66
-rw-r--r--src/H5Dpublic.h17
-rw-r--r--src/H5Dscatgath.c4
-rw-r--r--src/H5Dselect.c199
-rw-r--r--src/H5Dsingle.c8
-rw-r--r--src/H5Dvirtual.c94
-rw-r--r--src/H5E.c147
-rw-r--r--src/H5EA.c3
-rw-r--r--src/H5EAdbg.c6
-rw-r--r--src/H5EApkg.h2
-rw-r--r--src/H5EAprivate.h5
-rw-r--r--src/H5EAtest.c2
-rw-r--r--src/H5ES.c55
-rw-r--r--src/H5ESdevelop.h2
-rw-r--r--src/H5ESint.c138
-rw-r--r--src/H5ESlist.c13
-rw-r--r--src/H5ESpkg.h5
-rw-r--r--src/H5ESprivate.h1
-rw-r--r--src/H5ESpublic.h13
-rw-r--r--src/H5Eint.c3
-rw-r--r--src/H5Epkg.h2
-rw-r--r--src/H5F.c10
-rw-r--r--src/H5FA.c5
-rw-r--r--src/H5FAcache.c2
-rw-r--r--src/H5FAdblkpage.c2
-rw-r--r--src/H5FApkg.h4
-rw-r--r--src/H5FAprivate.h9
-rw-r--r--src/H5FAtest.c2
-rw-r--r--src/H5FD.c230
-rw-r--r--src/H5FDcore.c80
-rw-r--r--src/H5FDcore.h3
-rw-r--r--src/H5FDdevelop.h9
-rw-r--r--src/H5FDdirect.c136
-rw-r--r--src/H5FDdirect.h6
-rw-r--r--src/H5FDfamily.c246
-rw-r--r--src/H5FDfamily.h3
-rw-r--r--src/H5FDhdfs.c35
-rw-r--r--src/H5FDhdfs.h6
-rw-r--r--src/H5FDint.c388
-rw-r--r--src/H5FDlog.c138
-rw-r--r--src/H5FDlog.h3
-rw-r--r--src/H5FDmirror.c36
-rw-r--r--src/H5FDmirror.h5
-rw-r--r--src/H5FDmirror_priv.h10
-rw-r--r--src/H5FDmpi.c90
-rw-r--r--src/H5FDmpio.c471
-rw-r--r--src/H5FDmpio.h8
-rw-r--r--src/H5FDmulti.c483
-rw-r--r--src/H5FDmulti.h2
-rw-r--r--src/H5FDperform.c59
-rw-r--r--src/H5FDprivate.h56
-rw-r--r--src/H5FDpublic.h139
-rw-r--r--src/H5FDros3.c45
-rw-r--r--src/H5FDros3.h6
-rw-r--r--src/H5FDs3comms.h6
-rw-r--r--src/H5FDsec2.c98
-rw-r--r--src/H5FDsec2.h3
-rw-r--r--src/H5FDspace.c15
-rw-r--r--src/H5FDsplitter.c441
-rw-r--r--src/H5FDsplitter.h5
-rw-r--r--src/H5FDstdio.c4
-rw-r--r--src/H5FDstdio.h2
-rw-r--r--src/H5FDvfd_swmr.c115
-rw-r--r--src/H5FDvfd_swmr.h3
-rw-r--r--src/H5FDvfd_swmr_instr.c58
-rw-r--r--src/H5FDvfd_swmr_private.h87
-rw-r--r--src/H5FDwindows.c2
-rw-r--r--src/H5FL.c169
-rw-r--r--src/H5FLprivate.h26
-rw-r--r--src/H5FS.c41
-rw-r--r--src/H5FSint.c25
-rw-r--r--src/H5FSprivate.h5
-rw-r--r--src/H5FSsection.c65
-rw-r--r--src/H5Fcwfs.c6
-rw-r--r--src/H5Fefc.c2
-rw-r--r--src/H5Fint.c242
-rw-r--r--src/H5Fmount.c2
-rw-r--r--src/H5Fmpi.c196
-rw-r--r--src/H5Fpkg.h142
-rw-r--r--src/H5Fprivate.h128
-rw-r--r--src/H5Fpublic.h15
-rw-r--r--src/H5Fquery.c34
-rw-r--r--src/H5Fsuper.c6
-rw-r--r--src/H5Fsuper_cache.c4
-rw-r--r--src/H5Ftest.c22
-rw-r--r--src/H5Fvfd_swmr.c825
-rw-r--r--src/H5Gcache.c4
-rw-r--r--src/H5Gcompact.c2
-rw-r--r--src/H5Gint.c72
-rw-r--r--src/H5Gnode.c2
-rw-r--r--src/H5Gpublic.h2
-rw-r--r--src/H5HF.c5
-rw-r--r--src/H5HFcache.c4
-rw-r--r--src/H5HFdbg.c4
-rw-r--r--src/H5HFdblock.c2
-rw-r--r--src/H5HFspace.c2
-rw-r--r--src/H5HG.c7
-rw-r--r--src/H5HL.c3
-rw-r--r--src/H5HP.c904
-rw-r--r--src/H5HPprivate.h68
-rw-r--r--src/H5I.c2
-rw-r--r--src/H5Iint.c41
-rw-r--r--src/H5Ipublic.h2
-rw-r--r--src/H5Lint.c47
-rw-r--r--src/H5Lpublic.h16
-rw-r--r--src/H5M.c64
-rw-r--r--src/H5MF.c113
-rw-r--r--src/H5MFaggr.c41
-rw-r--r--src/H5MFdbg.c2
-rw-r--r--src/H5MFsection.c44
-rw-r--r--src/H5MP.c446
-rw-r--r--src/H5MPmodule.h32
-rw-r--r--src/H5MPpkg.h99
-rw-r--r--src/H5MPprivate.h57
-rw-r--r--src/H5MPtest.c213
-rw-r--r--src/H5MV.c3
-rw-r--r--src/H5MVprivate.h2
-rw-r--r--src/H5Oainfo.c2
-rw-r--r--src/H5Oattr.c2
-rw-r--r--src/H5Oattribute.c14
-rw-r--r--src/H5Obogus.c4
-rw-r--r--src/H5Obtreek.c2
-rw-r--r--src/H5Ocache.c10
-rw-r--r--src/H5Ocache_image.c2
-rw-r--r--src/H5Ocont.c2
-rw-r--r--src/H5Ocopy.c4
-rw-r--r--src/H5Ocopy_ref.c200
-rw-r--r--src/H5Odrvinfo.c2
-rw-r--r--src/H5Odtype.c40
-rw-r--r--src/H5Oefl.c2
-rw-r--r--src/H5Ofill.c4
-rw-r--r--src/H5Oflush.c3
-rw-r--r--src/H5Ofsinfo.c4
-rw-r--r--src/H5Oginfo.c2
-rw-r--r--src/H5Oint.c39
-rw-r--r--src/H5Olayout.c2
-rw-r--r--src/H5Olinfo.c2
-rw-r--r--src/H5Olink.c2
-rw-r--r--src/H5Omessage.c8
-rw-r--r--src/H5Omtime.c4
-rw-r--r--src/H5Oname.c2
-rw-r--r--src/H5Onull.c2
-rw-r--r--src/H5Opkg.h4
-rw-r--r--src/H5Opline.c4
-rw-r--r--src/H5Oprivate.h2
-rw-r--r--src/H5Opublic.h26
-rw-r--r--src/H5Orefcount.c2
-rw-r--r--src/H5Osdspace.c2
-rw-r--r--src/H5Oshmesg.c2
-rw-r--r--src/H5Ostab.c2
-rw-r--r--src/H5Ounknown.c2
-rw-r--r--src/H5P.c11
-rw-r--r--src/H5PB.c100
-rw-r--r--src/H5PBpkg.h16
-rw-r--r--src/H5PBprivate.h8
-rw-r--r--src/H5PL.c14
-rw-r--r--src/H5PLint.c113
-rw-r--r--src/H5PLpath.c35
-rw-r--r--src/H5PLplugin_cache.c140
-rw-r--r--src/H5PLprivate.h32
-rw-r--r--src/H5PLpublic.h6
-rw-r--r--src/H5Pdxpl.c16
-rw-r--r--src/H5Pencdec.c2
-rw-r--r--src/H5Pfapl.c601
-rw-r--r--src/H5Pint.c369
-rw-r--r--src/H5Pmodule.h3
-rw-r--r--src/H5Pocpl.c14
-rw-r--r--src/H5Ppkg.h3
-rw-r--r--src/H5Pprivate.h13
-rw-r--r--src/H5Ppublic.h366
-rw-r--r--src/H5RS.c5
-rw-r--r--src/H5Rint.c110
-rw-r--r--src/H5Rprivate.h2
-rw-r--r--src/H5S.c85
-rw-r--r--src/H5SL.c82
-rw-r--r--src/H5SLprivate.h1
-rw-r--r--src/H5SM.c27
-rw-r--r--src/H5Sall.c34
-rw-r--r--src/H5Shyper.c146
-rw-r--r--src/H5Smpio.c2
-rw-r--r--src/H5Snone.c34
-rw-r--r--src/H5Spkg.h20
-rw-r--r--src/H5Spoint.c38
-rw-r--r--src/H5Sprivate.h62
-rw-r--r--src/H5Spublic.h16
-rw-r--r--src/H5Sselect.c34
-rw-r--r--src/H5Stest.c12
-rw-r--r--src/H5T.c441
-rw-r--r--src/H5TS.c86
-rw-r--r--src/H5TSprivate.h6
-rw-r--r--src/H5Tbit.c10
-rw-r--r--src/H5Tcommit.c2
-rw-r--r--src/H5Tconv.c48
-rw-r--r--src/H5Tfields.c2
-rw-r--r--src/H5Tnative.c6
-rw-r--r--src/H5Topaque.c2
-rw-r--r--src/H5Tpkg.h2
-rw-r--r--src/H5Tpublic.h8
-rw-r--r--src/H5VLcallback.c80
-rw-r--r--src/H5VLint.c201
-rw-r--r--src/H5VLnative.c6
-rw-r--r--src/H5VLnative_introspect.c2
-rw-r--r--src/H5VLnative_token.c4
-rw-r--r--src/H5VLpassthru.c15
-rw-r--r--src/H5VM.c2
-rw-r--r--src/H5VMprivate.h4
-rw-r--r--src/H5WB.c2
-rw-r--r--src/H5Z.c160
-rw-r--r--src/H5Znbit.c31
-rw-r--r--src/H5Zscaleoffset.c12
-rw-r--r--src/H5Ztrans.c6
-rw-r--r--src/H5detect.c4
-rw-r--r--src/H5module.h6
-rw-r--r--src/H5mpi.c235
-rw-r--r--src/H5private.h253
-rw-r--r--src/H5public.h65
-rw-r--r--src/H5retry_private.h34
-rw-r--r--src/H5system.c6
-rw-r--r--src/H5timer.c15
-rw-r--r--src/H5trace.c66
-rw-r--r--src/Makefile.am8
263 files changed, 12590 insertions, 9160 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 33d31fb..538655b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -241,6 +241,7 @@ set (H5FD_SOURCES
${HDF5_SRC_DIR}/H5FDmpi.c
${HDF5_SRC_DIR}/H5FDmpio.c
${HDF5_SRC_DIR}/H5FDmulti.c
+ ${HDF5_SRC_DIR}/H5FDperform.c
${HDF5_SRC_DIR}/H5FDros3.c
${HDF5_SRC_DIR}/H5FDs3comms.c
${HDF5_SRC_DIR}/H5FDsec2.c
@@ -249,7 +250,6 @@ set (H5FD_SOURCES
${HDF5_SRC_DIR}/H5FDstdio.c
${HDF5_SRC_DIR}/H5FDtest.c
${HDF5_SRC_DIR}/H5FDvfd_swmr.c
- ${HDF5_SRC_DIR}/H5FDvfd_swmr_instr.c
${HDF5_SRC_DIR}/H5FDwindows.c
)
@@ -380,14 +380,6 @@ set (H5HL_HDRS
IDE_GENERATED_PROPERTIES ("H5HL" "${H5HL_HDRS}" "${H5HL_SOURCES}" )
-set (H5HP_SOURCES
- ${HDF5_SRC_DIR}/H5HP.c
-)
-set (H5HP_HDRS
-)
-IDE_GENERATED_PROPERTIES ("H5HP" "${H5HP_HDRS}" "${H5HP_SOURCES}" )
-
-
set (H5I_SOURCES
${HDF5_SRC_DIR}/H5I.c
${HDF5_SRC_DIR}/H5Idbg.c
@@ -444,15 +436,6 @@ set (H5MM_HDRS
IDE_GENERATED_PROPERTIES ("H5MM" "${H5MM_HDRS}" "${H5MM_SOURCES}" )
-set (H5MP_SOURCES
- ${HDF5_SRC_DIR}/H5MP.c
- ${HDF5_SRC_DIR}/H5MPtest.c
-)
-
-set (H5MP_HDRS
-)
-IDE_GENERATED_PROPERTIES ("H5MP" "${H5MP_HDRS}" "${H5MP_SOURCES}" )
-
set (H5MV_SOURCES
${HDF5_SRC_DIR}/H5MV.c
${HDF5_SRC_DIR}/H5MVsection.c
@@ -461,6 +444,7 @@ set (H5MV_HDRS
)
IDE_GENERATED_PROPERTIES ("H5MV" "${H5MV_HDRS}" "${H5MV_SOURCES}" )
+
set (H5O_SOURCES
${HDF5_SRC_DIR}/H5O.c
${HDF5_SRC_DIR}/H5Oainfo.c
@@ -759,7 +743,6 @@ set (H5_MODULE_HEADERS
${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
@@ -797,13 +780,11 @@ set (common_SRCS
${H5HF_SOURCES}
${H5HG_SOURCES}
${H5HL_SOURCES}
- ${H5HP_SOURCES}
${H5I_SOURCES}
${H5L_SOURCES}
${H5M_SOURCES}
${H5MF_SOURCES}
${H5MM_SOURCES}
- ${H5MP_SOURCES}
${H5MV_SOURCES}
${H5O_SOURCES}
${H5P_SOURCES}
@@ -847,7 +828,6 @@ set (H5_PUBLIC_HEADERS
${H5M_HDRS}
${H5MF_HDRS}
${H5MM_HDRS}
- ${H5MP_HDRS}
${H5MV_HDRS}
${H5O_HDRS}
${H5P_HDRS}
@@ -911,7 +891,6 @@ set (H5_PRIVATE_HEADERS
${HDF5_SRC_DIR}/H5FDmirror_priv.h
${HDF5_SRC_DIR}/H5FDpkg.h
${HDF5_SRC_DIR}/H5FDprivate.h
- ${HDF5_SRC_DIR}/H5FDvfd_swmr_private.h
${HDF5_SRC_DIR}/H5FLprivate.h
@@ -932,8 +911,6 @@ set (H5_PRIVATE_HEADERS
${HDF5_SRC_DIR}/H5HLpkg.h
${HDF5_SRC_DIR}/H5HLprivate.h
- ${HDF5_SRC_DIR}/H5HPprivate.h
-
${HDF5_SRC_DIR}/H5Ipkg.h
${HDF5_SRC_DIR}/H5Iprivate.h
@@ -948,9 +925,6 @@ set (H5_PRIVATE_HEADERS
${HDF5_SRC_DIR}/H5MMprivate.h
- ${HDF5_SRC_DIR}/H5MPpkg.h
- ${HDF5_SRC_DIR}/H5MPprivate.h
-
${HDF5_SRC_DIR}/H5MVpkg.h
${HDF5_SRC_DIR}/H5MVprivate.h
@@ -1074,20 +1048,23 @@ if (LOCAL_BATCH_TEST)
endif ()
endif ()
+#### make the H5detect program
set (lib_prog_deps)
-if (NOT EXISTS "${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c")
- add_executable (H5detect ${HDF5_SRC_DIR}/H5detect.c)
- target_include_directories (H5detect PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
- target_compile_definitions(H5detect PUBLIC ${HDF_EXTRA_C_FLAGS} ${HDF_EXTRA_FLAGS})
- TARGET_C_PROPERTIES (H5detect STATIC)
- target_link_libraries (H5detect
- PRIVATE "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>" $<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:MinGW>>:ws2_32.lib>
- )
- target_compile_options(H5detect
- PRIVATE "$<$<PLATFORM_ID:Emscripten>:-O0>"
- )
- set (lib_prog_deps ${lib_prog_deps} H5detect)
+add_executable (H5detect ${HDF5_SRC_DIR}/H5detect.c)
+target_include_directories (H5detect PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+target_compile_definitions(H5detect PUBLIC ${HDF_EXTRA_C_FLAGS} ${HDF_EXTRA_FLAGS})
+TARGET_C_PROPERTIES (H5detect STATIC)
+target_link_libraries (H5detect
+ PRIVATE "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>" $<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:MinGW>>:ws2_32.lib>
+)
+target_compile_options(H5detect
+ PRIVATE "$<$<PLATFORM_ID:Emscripten>:-O0>"
+)
+set (lib_prog_deps ${lib_prog_deps} H5detect)
+# check if a pregenerated H5Tinit.c file is present
+if (NOT EXISTS "${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c")
+ # execute the H5detect program
if (HDF5_BATCH_H5DETECT)
configure_file (
${HDF5_SOURCE_DIR}/bin/batch/${HDF5_BATCH_H5DETECT_SCRIPT}.in.cmake
@@ -1095,9 +1072,9 @@ if (NOT EXISTS "${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c")
)
add_custom_command (
OUTPUT gen_SRCS.stamp1
+ BYPRODUCTS H5Tinit.c
COMMAND ${HDF5_BATCH_CMD}
ARGS ${HDF5_BINARY_DIR}/${HDF5_BATCH_H5DETECT_SCRIPT}
- BYPRODUCTS H5Tinit.c gen_SRCS.stamp1
COMMAND ${CMAKE_COMMAND}
ARGS -E echo "Executed batch command to create H5Tinit.c"
COMMAND ${CMAKE_COMMAND}
@@ -1108,31 +1085,30 @@ if (NOT EXISTS "${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c")
add_custom_target (gen_H5Tinit
COMMAND ${CMAKE_COMMAND} -P ${HDF5_SOURCE_DIR}/config/cmake/wait_H5Tinit.cmake
)
- set_source_files_properties (${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c PROPERTIES GENERATED TRUE)
else ()
- add_custom_command (TARGET H5detect POST_BUILD
+ add_custom_command (
+ OUTPUT gen_SRCS.stamp1
+ BYPRODUCTS H5Tinit.c
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:H5detect>
ARGS H5Tinit.c
- BYPRODUCTS H5Tinit.c gen_SRCS.stamp1
COMMAND ${CMAKE_COMMAND}
ARGS -E touch gen_SRCS.stamp1
DEPENDS H5detect
WORKING_DIRECTORY ${HDF5_GENERATED_SOURCE_DIR}
COMMENT "Create H5Tinit.c"
)
- set_source_files_properties (${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c PROPERTIES GENERATED TRUE)
if (BUILD_SHARED_LIBS)
- add_custom_command (TARGET H5detect POST_BUILD
+ add_custom_command (
+ OUTPUT shared/shared_gen_SRCS.stamp1
+ BYPRODUCTS shared/H5Tinit.c
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different H5Tinit.c shared/H5Tinit.c
- BYPRODUCTS shared/H5Tinit.c shared/shared_gen_SRCS.stamp1
COMMAND ${CMAKE_COMMAND}
ARGS -E touch shared/shared_gen_SRCS.stamp1
- DEPENDS H5detect H5Tinit.c
+ DEPENDS H5detect gen_SRCS.stamp1
WORKING_DIRECTORY ${HDF5_GENERATED_SOURCE_DIR}
COMMENT "Copy H5Tinit.c to shared folder"
)
- set_source_files_properties (${HDF5_GENERATED_SOURCE_DIR}/shared/H5Tinit.c PROPERTIES GENERATED TRUE)
endif ()
endif ()
else ()
@@ -1148,16 +1124,15 @@ else ()
if (BUILD_SHARED_LIBS)
add_custom_command (
OUTPUT shared/shared_gen_SRCS.stamp1
+ BYPRODUCTS shared/H5Tinit.c
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different H5Tinit.c shared/H5Tinit.c
- BYPRODUCTS shared/H5Tinit.c shared/shared_gen_SRCS.stamp1
COMMAND ${CMAKE_COMMAND}
ARGS -E touch shared/shared_gen_SRCS.stamp1
- DEPENDS H5Tinit.c
+ DEPENDS H5Tinit.c gen_SRCS.stamp1
WORKING_DIRECTORY ${HDF5_GENERATED_SOURCE_DIR}
COMMENT "Copy existing H5Tinit.c to shared folder"
)
- set_source_files_properties (${HDF5_GENERATED_SOURCE_DIR}/shared/H5Tinit.c PROPERTIES GENERATED TRUE)
endif ()
endif ()
@@ -1168,6 +1143,7 @@ if (HDF5_ENABLE_FORMATTERS)
clang_format (HDF5_SRC_DETECT_FORMAT ${HDF5_SRC_DIR}/H5detect.c)
endif ()
+# make the H5make_libsettings program
add_executable (H5make_libsettings ${HDF5_SRC_DIR}/H5make_libsettings.c)
target_include_directories (H5make_libsettings PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
target_compile_definitions(H5make_libsettings PUBLIC ${HDF_EXTRA_C_FLAGS} ${HDF_EXTRA_FLAGS})
@@ -1187,10 +1163,12 @@ if (HDF5_ENABLE_FORMATTERS)
clang_format (HDF5_SRC_LIBSETTINGS_FORMAT H5make_libsettings)
endif ()
-add_custom_command (TARGET H5make_libsettings POST_BUILD
+# execute the H5make_libsettings program
+add_custom_command (
+ OUTPUT gen_SRCS.stamp2
+ BYPRODUCTS H5lib_settings.c
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:H5make_libsettings>
ARGS H5lib_settings.c
- BYPRODUCTS H5lib_settings.c gen_SRCS.stamp2
COMMAND ${CMAKE_COMMAND}
ARGS -E touch gen_SRCS.stamp2
DEPENDS H5make_libsettings
@@ -1199,17 +1177,17 @@ add_custom_command (TARGET H5make_libsettings POST_BUILD
)
set_source_files_properties (${HDF5_SRC_BINARY_DIR}/H5lib_settings.c PROPERTIES GENERATED TRUE)
if (BUILD_SHARED_LIBS)
- add_custom_command (TARGET H5make_libsettings POST_BUILD
+ add_custom_command (
+ OUTPUT shared/shared_gen_SRCS.stamp2
+ BYPRODUCTS shared/H5lib_settings.c
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different H5lib_settings.c shared/H5lib_settings.c
- BYPRODUCTS shared/H5lib_settings.c shared/shared_gen_SRCS.stamp2
COMMAND ${CMAKE_COMMAND}
ARGS -E touch shared/shared_gen_SRCS.stamp2
- DEPENDS H5make_libsettings H5lib_settings.c
+ DEPENDS H5make_libsettings gen_SRCS.stamp2
WORKING_DIRECTORY ${HDF5_SRC_BINARY_DIR}
COMMENT "Copy H5lib_settings.c to shared folder"
)
- set_source_files_properties (${HDF5_SRC_BINARY_DIR}/shared/H5lib_settings.c PROPERTIES GENERATED TRUE)
endif ()
## all_packages="AC,B,B2,D,F,FA,FL,FS,HL,I,O,S,ST,T,Z"
@@ -1222,7 +1200,7 @@ option (HDF5_ENABLE_DEBUG_APIS "Turn on extra debug output in all packages" OFF)
if (NOT ONLY_SHARED_LIBS)
set (gen_SRCS ${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c ${HDF5_SRC_BINARY_DIR}/H5lib_settings.c)
add_custom_target (gen_${HDF5_LIB_TARGET} ALL
- DEPENDS ${lib_prog_deps} ${gen_SRCS} ${HDF5_GENERATED_SOURCE_DIR}/gen_SRCS.stamp1 ${HDF5_SRC_BINARY_DIR}/gen_SRCS.stamp2
+ DEPENDS ${lib_prog_deps} ${HDF5_GENERATED_SOURCE_DIR}/gen_SRCS.stamp1 ${HDF5_SRC_BINARY_DIR}/gen_SRCS.stamp2
COMMENT "Generation target files"
)
@@ -1261,7 +1239,7 @@ endif ()
if (BUILD_SHARED_LIBS)
set (shared_gen_SRCS ${HDF5_GENERATED_SOURCE_DIR}/shared/H5Tinit.c ${HDF5_SRC_BINARY_DIR}/shared/H5lib_settings.c)
add_custom_target (gen_${HDF5_LIBSH_TARGET} ALL
- DEPENDS ${lib_prog_deps} ${shared_gen_SRCS} ${HDF5_GENERATED_SOURCE_DIR}/shared/shared_gen_SRCS.stamp1 ${HDF5_SRC_BINARY_DIR}/shared/shared_gen_SRCS.stamp2
+ DEPENDS ${lib_prog_deps} ${HDF5_GENERATED_SOURCE_DIR}/shared/shared_gen_SRCS.stamp1 ${HDF5_SRC_BINARY_DIR}/shared/shared_gen_SRCS.stamp2
COMMENT "Shared generation target files"
)
diff --git a/src/H5.c b/src/H5.c
index 69c81ea..1585dd3 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -29,9 +29,12 @@
#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
+#include "H5PLprivate.h" /* Plugins */
#include "H5SLprivate.h" /* Skip lists */
#include "H5Tprivate.h" /* Datatypes */
+#include "H5FDsec2.h" /* for H5FD_sec2_init() */
+
/****************/
/* Local Macros */
/****************/
@@ -63,16 +66,13 @@ static int H5__mpi_delete_cb(MPI_Comm comm, int keyval, void *attr_val, int *fla
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
-/* Library incompatible release versions */
-const unsigned VERS_RELEASE_EXCEPTIONS[] = {0};
-const unsigned VERS_RELEASE_EXCEPTIONS_SIZE = 0;
+/* Library incompatible release versions, develop releases are incompatible by design */
+const unsigned VERS_RELEASE_EXCEPTIONS[] = {0, 1, 2};
+const unsigned VERS_RELEASE_EXCEPTIONS_SIZE = 3;
/* statically initialize block for pthread_once call used in initializing */
/* the first global mutex */
@@ -101,32 +101,30 @@ 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)
+/*-------------------------------------------------------------------------
+ * Function: H5_default_vfd_init
+ *
+ * Purpose: Initialize the default VFD.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5_default_vfd_init(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 */
+ herr_t ret_value = SUCCEED;
+ FUNC_ENTER_NOAPI(FAIL)
+ /* Load the hid_t for the default VFD for the side effect
+ * it has of initializing the default VFD.
+ */
+ if (H5FD_sec2_init() == H5I_INVALID_HID) {
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to load default VFD ID")
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5__init_package() */
+}
/*--------------------------------------------------------------------------
* NAME
@@ -145,15 +143,20 @@ done:
herr_t
H5_init_library(void)
{
+ size_t i;
herr_t ret_value = SUCCEED;
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Run the library initialization routine, if it hasn't already run */
+ if (H5_INIT_GLOBAL || H5_TERM_GLOBAL)
+ HGOTO_DONE(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
{
int mpi_initialized;
@@ -257,28 +260,33 @@ H5_init_library(void)
* The dataspace interface needs to be initialized so that future IDs for
* dataspaces work.
*/
- if (H5E_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface")
- if (H5VL_init_phase1() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface")
- if (H5P_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize property list interface")
- if (H5T_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize datatype interface")
- if (H5D_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize dataset interface")
- if (H5AC_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize metadata caching interface")
- if (H5L_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize link interface")
- if (H5FS_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize FS interface")
- if (H5S_init() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize dataspace interface")
-
+ /* clang-format off */
+ struct {
+ herr_t (*func)(void);
+ const char *descr;
+ } initializer[] = {
+ {H5E_init, "error"}
+ , {H5VL_init_phase1, "VOL"}
+ , {H5SL_init, "skip lists"}
+ , {H5FD_init, "VFD"}
+ , {H5_default_vfd_init, "default VFD"}
+ , {H5P_init_phase1, "property list"}
+ , {H5AC_init, "metadata caching"}
+ , {H5L_init, "link"}
+ , {H5S_init, "dataspace"}
+ , {H5PL_init, "plugins"}
/* Finish initializing interfaces that depend on the interfaces above */
- if (H5VL_init_phase2() < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface")
+ , {H5P_init_phase2, "property list"}
+ , {H5VL_init_phase2, "VOL"}
+ };
+
+ for (i = 0; i < NELMTS(initializer); i++) {
+ if (initializer[i].func() < 0) {
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL,
+ "unable to initialize %s interface", initializer[i].descr)
+ }
+ }
+ /* clang-format on */
/* Debugging? */
H5__debug_mask("-all");
@@ -302,9 +310,11 @@ done:
void
H5_term_library(void)
{
- int pending, ntries = 0, n;
- size_t at = 0;
- char loop[1024];
+ int pending, ntries = 0;
+ char loop[1024], *next = loop;
+ size_t i;
+ size_t nleft = sizeof(loop);
+ int nprinted;
H5E_auto2_t func;
#ifdef H5_HAVE_THREADSAFE
@@ -348,108 +358,137 @@ H5_term_library(void)
H5_atclose_head = NULL;
} /* end if */
+ /* clang-format off */
+
/*
* Terminate each interface. The termination functions return a positive
* value if they do something that might affect some other interface in a
* way that would necessitate some cleanup work in the other interface.
*/
-#define DOWN(F) \
- (((n = H5##F##_term_package()) && (at + 8) < sizeof loop) \
- ? (HDsprintf(loop + at, "%s%s", (at ? "," : ""), #F), at += HDstrlen(loop + at), n) \
- : ((n > 0 && (at + 5) < sizeof loop) ? (HDsprintf(loop + at, "..."), at += HDstrlen(loop + at), n) \
- : n))
- do {
- pending = 0;
-
- /* Try to organize these so the "higher" level components get shut
- * down before "lower" level components that they might rely on. -QAK
- */
+#define TERMINATOR(module, wait) { \
+ .func = H5##module##_term_package \
+ , .name = #module \
+ , .completed = false \
+ , .await_prior = wait \
+ }
+ /*
+ * Termination is ordered by the `terminator` table so the "higher" level
+ * packages are shut down before "lower" level packages that they
+ * rely on:
+ */
+ struct {
+ int (*func)(void); /* function to terminate the module; returns 0
+ * on success, >0 if termination was not
+ * completed and we should try to terminate
+ * some dependent modules, first.
+ */
+ const char *name; /* name of the module */
+ hbool_t completed; /* true iff this terminator was already
+ * completed
+ */
+ const hbool_t await_prior; /* true iff all prior terminators in the
+ * list must complete before this
+ * terminator is attempted
+ */
+ } terminator[] = {
/* Close the event sets first, so that all asynchronous operations
- * complete before anything else attempts to shut down.
+ * complete before anything else attempts to shut down.
*/
- pending += DOWN(ES);
-
- /* Close down the user-facing interfaces, after the event sets */
- if (pending == 0) {
- /* Close the interfaces dependent on others */
- pending += DOWN(L);
-
- /* Close the "top" of various interfaces (IDs, etc) but don't shut
- * down the whole interface yet, so that the object header messages
- * get serialized correctly for entries in the metadata cache and the
- * symbol table entry in the superblock gets serialized correctly, etc.
- * all of which is performed in the 'F' shutdown.
- */
- pending += DOWN(A_top);
- pending += DOWN(D_top);
- pending += DOWN(G_top);
- pending += DOWN(M_top);
- pending += DOWN(R_top);
- pending += DOWN(S_top);
- pending += DOWN(T_top);
- } /* end if */
-
+ TERMINATOR(ES, false)
+ /* Do not attempt to close down package L until after event sets
+ * have finished closing down.
+ */
+ , TERMINATOR(L, true)
+ /* Close the "top" of various interfaces (IDs, etc) but don't shut
+ * down the whole interface yet, so that the object header messages
+ * get serialized correctly for entries in the metadata cache and the
+ * symbol table entry in the superblock gets serialized correctly, etc.
+ * all of which is performed in the 'F' shutdown.
+ *
+ * The tops of packages A, D, G, M, S, T do not need to wait for L
+ * or previous packages to finish closing down.
+ */
+ , TERMINATOR(A_top, false)
+ , TERMINATOR(D_top, false)
+ , TERMINATOR(G_top, false)
+ , TERMINATOR(M_top, false)
+ , TERMINATOR(S_top, false)
+ , TERMINATOR(T_top, false)
/* Don't shut down the file code until objects in files are shut down */
- if (pending == 0)
- pending += DOWN(F);
-
+ , TERMINATOR(F, true)
/* Don't shut down the property list code until all objects that might
- * use property lists are shut down */
- if (pending == 0)
- pending += DOWN(P);
-
+ * use property lists are shut down
+ */
+ , TERMINATOR(P, true)
/* Wait to shut down the "bottom" of various interfaces until the
- * files are closed, so pieces of the file can be serialized
- * correctly.
+ * files are closed, so pieces of the file can be serialized
+ * correctly.
+ *
+ * Shut down the "bottom" of the attribute, dataset, group,
+ * reference, dataspace, and datatype interfaces, fully closing
+ * out the interfaces now.
*/
- if (pending == 0) {
- /* Shut down the "bottom" of the attribute, dataset, group,
- * reference, dataspace, and datatype interfaces, fully closing
- * out the interfaces now.
- */
- pending += DOWN(A);
- pending += DOWN(D);
- pending += DOWN(G);
- pending += DOWN(M);
- pending += DOWN(R);
- pending += DOWN(S);
- pending += DOWN(T);
- } /* end if */
-
- /* Don't shut down "low-level" components until "high-level" components
- * have successfully shut down. This prevents property lists and IDs
- * from being closed "out from underneath" of the high-level objects
- * that depend on them. -QAK
+ , TERMINATOR(A, true)
+ , TERMINATOR(D, false)
+ , TERMINATOR(G, false)
+ , TERMINATOR(M, false)
+ , TERMINATOR(S, false)
+ , TERMINATOR(T, false)
+ /* Wait to shut down low-level packages like AC until after
+ * the preceding high-level packages have shut down. This prevents
+ * low-level objects from closing "out from underneath" their
+ * reliant high-level objects.
*/
- if (pending == 0) {
- pending += DOWN(AC);
- /* Shut down the "pluggable" interfaces, before the plugin framework */
- pending += DOWN(Z);
- pending += DOWN(FD);
- pending += DOWN(VL);
- /* Don't shut down the plugin code until all "pluggable" interfaces (Z, FD, PL) are shut down */
- if (pending == 0)
- pending += DOWN(PL);
- /* Don't shut down the error code until other APIs which use it are shut down */
- if (pending == 0)
- pending += DOWN(E);
- /* Don't shut down the ID code until other APIs which use them are shut down */
- if (pending == 0)
- pending += DOWN(I);
- /* Don't shut down the skip list code until everything that uses it is down */
- if (pending == 0)
- pending += DOWN(SL);
- /* Don't shut down the free list code until everything that uses it is down */
- if (pending == 0)
- pending += DOWN(FL);
- /* Don't shut down the API context code until _everything_ else is down */
- if (pending == 0)
- pending += DOWN(CX);
- } /* end if */
+ , TERMINATOR(AC, true)
+ /* Shut down the "pluggable" interfaces, before the plugin framework */
+ , TERMINATOR(Z, false)
+ , TERMINATOR(FD, false)
+ , TERMINATOR(VL, false)
+ /* Don't shut down the plugin code until all "pluggable" interfaces
+ * (Z, FD, PL) are shut down
+ */
+ , TERMINATOR(PL, true)
+ /* Shut down the following packages in strictly the order given
+ * by the table.
+ */
+ , TERMINATOR(E, true)
+ , TERMINATOR(I, true)
+ , TERMINATOR(SL, true)
+ , TERMINATOR(FL, true)
+ , TERMINATOR(CX, true)
+ };
+
+ do {
+ pending = 0;
+ for (i = 0; i < NELMTS(terminator); i++) {
+ if (terminator[i].completed)
+ continue;
+ if (pending != 0 && terminator[i].await_prior)
+ break;
+ if (terminator[i].func() == 0) {
+ terminator[i].completed = true;
+ continue;
+ }
+
+ /* log a package when its terminator needs to be retried */
+ pending++;
+ nprinted = HDsnprintf(next, nleft, "%s%s",
+ (next != loop) ? "," : "", terminator[i].name);
+ if (nprinted < 0)
+ continue;
+ if ((size_t)nprinted >= nleft)
+ nprinted = HDsnprintf(next, nleft, "...");
+ if (nprinted < 0 || (size_t)nprinted >= nleft)
+ continue;
+ nleft -= (size_t)nprinted;
+ next += nprinted;
+ }
} while (pending && ntries++ < 100);
+ /* clang-format on */
+
if (pending) {
/* Only display the error message if the user is interested in them. */
if (func) {
@@ -915,6 +954,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
static int checked = 0; /* If we've already checked the version info */
static unsigned int disable_version_check = 0; /* Set if the version check should be disabled */
static const char * version_mismatch_warning = VERSION_MISMATCH_WARNING;
+ static const char * release_mismatch_warning = RELEASE_MISMATCH_WARNING;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API_NOINIT_NOERR_NOFS
@@ -935,10 +975,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
}
/* H5_VERS_MAJOR and H5_VERS_MINOR must match */
- /* Cast relnum to int to avoid warning for unsigned < 0 comparison
- * in first release versions */
- if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > (int)relnum) {
-
+ if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum) {
switch (disable_version_check) {
case 0:
HDfprintf(stderr, "%s%s", version_mismatch_warning,
@@ -973,9 +1010,10 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
break;
} /* end switch */
- } /* end if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > relnum) */
+ } /* end if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum) */
/* H5_VERS_RELEASE should be compatible, we will only add checks for exceptions */
+ /* Library develop release versions are incompatible by design */
if (H5_VERS_RELEASE != relnum) {
for (unsigned i = 0; i < VERS_RELEASE_EXCEPTIONS_SIZE; i++) {
/* Check for incompatible headers or incompatible library */
@@ -983,7 +1021,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
switch (disable_version_check) {
case 0:
HDfprintf(
- stderr, "%s%s", version_mismatch_warning,
+ stderr, "%s%s", release_mismatch_warning,
"You can, at your own risk, disable this warning by setting the environment\n"
"variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.\n"
"Setting it to 2 or higher will suppress the warning messages totally.\n");
@@ -1002,7 +1040,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
"%s'HDF5_DISABLE_VERSION_CHECK' "
"environment variable is set to %d, application will\n"
"continue at your own risk.\n",
- version_mismatch_warning, disable_version_check);
+ release_mismatch_warning, disable_version_check);
/* Mention the versions we are referring to */
HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum,
relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR,
diff --git a/src/H5A.c b/src/H5A.c
index c986d1f..b5cc77a 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -1868,7 +1868,7 @@ done:
if all attributes were processed.
DESCRIPTION
- This function interates over the attributes of dataset or group
+ This function iterates over the attributes of dataset or group
specified with 'loc_id' & 'obj_name'. For each attribute of the object,
the 'op_data' and some additional information (specified below) are passed
to the 'op' function. The iteration begins with the '*idx'
@@ -1956,7 +1956,7 @@ done:
if all attributes were processed.
DESCRIPTION
- This function interates over the attributes of dataset or group
+ This function iterates over the attributes of dataset or group
specified with 'loc_id' & 'obj_name'. For each attribute of the object,
the 'op_data' and some additional information (specified below) are passed
to the 'op' function. The iteration begins with the '*idx'
@@ -2410,7 +2410,7 @@ done:
htri_t
H5Aexists(hid_t obj_id, const char *attr_name)
{
- hbool_t exists; /* Flag for attribute existance */
+ hbool_t exists; /* Flag for attribute existence */
htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -2526,7 +2526,7 @@ done:
htri_t
H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id)
{
- hbool_t exists; /* Flag for attribute existance */
+ hbool_t exists; /* Flag for attribute existence */
htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_API(FAIL)
diff --git a/src/H5AC.c b/src/H5AC.c
index e89c22d..0171956 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -70,9 +70,6 @@ static herr_t H5AC__verify_tag(const H5AC_class_t *type);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -143,29 +140,7 @@ H5AC_init(void)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5AC_init() */
-
-/*-------------------------------------------------------------------------
- * Function: H5AC__init_package
- *
- * Purpose: Initialize interface-specific information
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, July 18, 2002
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5AC__init_package(void)
-{
- FUNC_ENTER_PACKAGE_NOERR
+ FUNC_ENTER_NOAPI_NOERR
#ifdef H5_HAVE_PARALLEL
/* check whether to enable strict collective function calling
@@ -182,8 +157,8 @@ H5AC__init_package(void)
}
#endif /* H5_HAVE_PARALLEL */
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5AC__init_package() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5AC_init() */
/*-------------------------------------------------------------------------
* Function: H5AC_term_package
@@ -204,10 +179,6 @@ H5AC_term_package(void)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR)
- /* Reset interface initialization flag */
- H5_PKG_INIT_VAR = FALSE;
-
FUNC_LEAVE_NOAPI(0)
} /* end H5AC_term_package() */
@@ -263,7 +234,7 @@ H5AC_cache_image_pending(const H5F_t *f)
* Programmer: Robb Matzke
* Jul 9 1997
*
- * Changes: Added code to configrue the metadata cache for VFD SWMR
+ * Changes: Added code to configure the metadata cache for VFD SWMR
* reader operations when indicated.
*
* JRM -- 1/15/19
@@ -339,7 +310,7 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_co
aux_ptr->sync_point_done = NULL;
aux_ptr->p0_image_len = 0;
- HDsprintf(prefix, "%d:", mpi_rank);
+ HDsnprintf(prefix, sizeof(prefix), "%d:", mpi_rank);
if (mpi_rank == 0) {
if (NULL == (aux_ptr->d_slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
@@ -1248,7 +1219,7 @@ done:
* metadata cache flush.
*
* Initially, this means setting up the slist prior to the
- * flush. We do this in a seperate call because
+ * flush. We do this in a separate call because
* H5F__flush_phase2() make repeated calls to H5AC_flush().
* Handling this detail in separate calls allows us to avoid
* the overhead of setting up and taking down the skip list
@@ -1300,7 +1271,7 @@ done:
* flush.
*
* Initially, this means taking down the slist after the
- * flush. We do this in a seperate call because
+ * flush. We do this in a separate call because
* H5F__flush_phase2() make repeated calls to H5AC_flush().
* Handling this detail in separate calls allows us to avoid
* the overhead of setting up and taking down the skip list
@@ -1489,21 +1460,82 @@ H5AC_resize_entry(void *thing, size_t new_size)
cache_ptr = entry_ptr->cache_ptr;
HDassert(cache_ptr);
- /* Resize the entry */
- if (H5C_resize_entry(thing, new_size) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, "can't resize entry")
-
#ifdef H5_HAVE_PARALLEL
- {
+ /* Log the generation of dirty bytes of metadata iff:
+ *
+ * 1) The entry is clean on entry, and this resize will dirty it
+ * (i.e. the current and new sizes are different), and
+ *
+ * 2) This is a parallel computation -- which it is if the aux_ptr
+ * is non-null.
+ *
+ * A few points to note about this section of the code:
+ *
+ * 1) This call must occur before the call to H5C_resize_entry() since
+ * H5AC__log_dirtied_entry() expects the target entry to be clean
+ * on entry.
+ *
+ * 2) This code has some basic issues in terms of the number of bytes
+ * added to the dirty bytes count.
+ *
+ * First, it adds the initial entry size to aux_ptr->dirty_bytes,
+ * not the final size. Note that this code used to use the final
+ * size, but code to support this has been removed from
+ * H5AC__log_dirtied_entry() for reasons unknown since I wrote this
+ * code.
+ *
+ * As long as all ranks do the same thing here, this probably doesn't
+ * matter much, although it will delay initiation of sync points.
+ *
+ * A more interesting point is that this code will not increment
+ * aux_ptr->dirty_bytes if a dirty entry is resized. At first glance
+ * this seems major, as particularly with the older file formats,
+ * resizes can be quite large. However, this is probably not an
+ * issue either, since such resizes will be accompanied by large
+ * amounts of dirty metadata creation in other areas -- which will
+ * cause aux_ptr->dirty_bytes to be incremented.
+ *
+ * The bottom line is that this code is probably OK, but the above
+ * points should be kept in mind.
+ *
+ * One final observation: This comment is occasioned by a bug caused
+ * by moving the call to H5AC__log_dirtied_entry() after the call to
+ * H5C_resize_entry(), and then only calling H5AC__log_dirtied_entry()
+ * if entry_ptr->is_dirty was false.
+ *
+ * Since H5C_resize_entry() marks the target entry dirty unless there
+ * is not change in size, this had the effect of not calling
+ * H5AC__log_dirtied_entry() when it should be, and corrupting
+ * the cleaned and dirtied lists used by rank 0 in the parallel
+ * version of the metadata cache.
+ *
+ * The point here is that you should be very careful when working with
+ * this code, and not modify it unless you fully understand it.
+ *
+ * JRM -- 2/28/22
+ */
+
+ if ((!entry_ptr->is_dirty) && (entry_ptr->size != new_size)) {
+
+ /* the entry is clean, and will be marked dirty in the resize
+ * operation.
+ */
H5AC_aux_t *aux_ptr;
aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
- if ((!entry_ptr->is_dirty) && (NULL != aux_ptr))
+
+ if (NULL != aux_ptr) {
+
if (H5AC__log_dirtied_entry(entry_ptr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "can't log dirtied entry")
+ }
}
#endif /* H5_HAVE_PARALLEL */
+ /* Resize the entry */
+ if (H5C_resize_entry(thing, new_size) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, "can't resize entry")
+
done:
/* If currently logging, generate a message */
if (cache_ptr != NULL && cache_ptr->log_info != NULL)
@@ -1685,9 +1717,14 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing, un
if (H5AC__log_dirtied_entry((H5AC_info_t *)thing) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "can't log dirtied entry")
- if (deleted && aux_ptr->mpi_rank == 0)
- if (H5AC__log_deleted_entry((H5AC_info_t *)thing) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "H5AC__log_deleted_entry() failed")
+ if (deleted && aux_ptr->mpi_rank == 0) {
+ if (H5AC__log_deleted_entry((H5AC_info_t *)thing) < 0) {
+ /* If we fail to log the deleted entry, push an error but still
+ * participate in a possible sync point ahead
+ */
+ HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "H5AC__log_deleted_entry() failed")
+ }
+ }
} /* end if */
#endif /* H5_HAVE_PARALLEL */
@@ -2415,7 +2452,7 @@ done:
/*------------------------------------------------------------------------------
* Function: H5AC_expunge_tag_type_metadata()
*
- * Purpose: Wrapper for cache level function which expunge entries with
+ * Purpose: Wrapper for cache level function which expunges entries with
* a specific tag and type id.
*
* Return: SUCCEED on success, FAIL otherwise.
@@ -2425,7 +2462,7 @@ done:
*------------------------------------------------------------------------------
*/
herr_t
-H5AC_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags, hbool_t type_match)
+H5AC_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags)
{
/* Variable Declarations */
herr_t ret_value = SUCCEED;
@@ -2438,7 +2475,7 @@ H5AC_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flag
HDassert(f->shared);
/* Call cache level function to expunge entries with specified tag and type id */
- if (H5C_expunge_tag_type_metadata(f, tag, type_id, flags, type_match) < 0)
+ if (H5C_expunge_tag_type_metadata(f, tag, type_id, flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot expunge tagged type entries")
done:
@@ -2446,6 +2483,40 @@ done:
} /* H5AC_expunge_tag_type_metadata*/
/*------------------------------------------------------------------------------
+ * Function: H5AC_expunge_all_tagged_metadata()
+ *
+ * Purpose: Wrapper for cache level function which expunges all tagged
+ * entries
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Dana Robinson
+ * Spring 2022
+ *
+ *------------------------------------------------------------------------------
+ */
+herr_t
+H5AC_expunge_all_tagged_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags)
+{
+ /* Variable Declarations */
+ herr_t ret_value = SUCCEED;
+
+ /* Function Enter Macro */
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Assertions */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Call cache-level function to expunge all tagged entries */
+ if (H5C_expunge_all_tagged_metadata(f, tag, type_id, flags) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot expunge all entries")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5AC_expunge_all_tagged_metadata*/
+
+/*------------------------------------------------------------------------------
* Function: H5AC_get_tag()
*
* Purpose: Get the tag for a metadata cache entry.
@@ -2785,7 +2856,8 @@ done:
*
* Return: SUCCEED on success, and FAIL on failure.
*
- * Programmer: Vailin Choi; Dec 2021
+ * Programmer: Vailin Choi
+ * Dec 2021
*
*-------------------------------------------------------------------------
*/
diff --git a/src/H5ACdbg.c b/src/H5ACdbg.c
index 2d24adb..5e24517 100644
--- a/src/H5ACdbg.c
+++ b/src/H5ACdbg.c
@@ -197,9 +197,9 @@ done:
* If either the parent or the child is not in the metadata
* cache, the function sets *fd_exists_ptr to FALSE.
*
- * If both are in the cache, the childs list of parents is
+ * If both are in the cache, the child's list of parents is
* searched for the proposed parent. If the proposed parent
- * is found in the childs parent list, the function sets
+ * is found in the child's parent list, the function sets
* *fd_exists_ptr to TRUE. In all other non-error cases,
* the function sets *fd_exists_ptr FALSE.
*
diff --git a/src/H5ACmpio.c b/src/H5ACmpio.c
index 7d2ba25..7eaf751 100644
--- a/src/H5ACmpio.c
+++ b/src/H5ACmpio.c
@@ -304,8 +304,10 @@ H5AC__broadcast_candidate_list(H5AC_t *cache_ptr, unsigned *num_entries_ptr, had
* are used to receiving from process 0, and also load it
* into a buffer for transmission.
*/
- if (H5AC__copy_candidate_list_to_buffer(cache_ptr, &chk_num_entries, &haddr_buf_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't construct candidate buffer.")
+ if (H5AC__copy_candidate_list_to_buffer(cache_ptr, &chk_num_entries, &haddr_buf_ptr) < 0) {
+ /* Push an error, but still participate in following MPI_Bcast */
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't construct candidate buffer.")
+ }
HDassert(chk_num_entries == num_entries);
HDassert(haddr_buf_ptr != NULL);
@@ -428,18 +430,23 @@ H5AC__broadcast_clean_list(H5AC_t *cache_ptr)
/* allocate a buffer to store the list of entry base addresses in */
buf_size = sizeof(haddr_t) * num_entries;
- if (NULL == (addr_buf_ptr = (haddr_t *)H5MM_malloc(buf_size)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for addr buffer")
-
- /* Set up user data for callback */
- udata.aux_ptr = aux_ptr;
- udata.addr_buf_ptr = addr_buf_ptr;
- udata.u = 0;
-
- /* Free all the clean list entries, building the address list in the callback */
- /* (Callback also removes the matching entries from the dirtied list) */
- if (H5SL_free(aux_ptr->c_slist_ptr, H5AC__broadcast_clean_list_cb, &udata) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "Can't build address list for clean entries")
+ if (NULL == (addr_buf_ptr = (haddr_t *)H5MM_malloc(buf_size))) {
+ /* Push an error, but still participate in following MPI_Bcast */
+ HDONE_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for addr buffer")
+ }
+ else {
+ /* Set up user data for callback */
+ udata.aux_ptr = aux_ptr;
+ udata.addr_buf_ptr = addr_buf_ptr;
+ udata.u = 0;
+
+ /* Free all the clean list entries, building the address list in the callback */
+ /* (Callback also removes the matching entries from the dirtied list) */
+ if (H5SL_free(aux_ptr->c_slist_ptr, H5AC__broadcast_clean_list_cb, &udata) < 0) {
+ /* Push an error, but still participate in following MPI_Bcast */
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "Can't build address list for clean entries")
+ }
+ }
/* Now broadcast the list of cleaned entries */
if (MPI_SUCCESS !=
@@ -1132,7 +1139,7 @@ done:
*
* While the list of candidate cache entries is prepared
* elsewhere, this function is the main routine for distributing
- * and applying the list. It must be run simultaniously on
+ * and applying the list. It must be run simultaneously on
* all processes that have the relevant file open. To ensure
* proper synchronization, there is a barrier at the beginning
* of this function.
@@ -1311,7 +1318,7 @@ done:
*
* This function is the main routine for handling this
* notification procedure. It must be called
- * simultaniously on all processes that have the relevant
+ * simultaneously on all processes that have the relevant
* file open. To this end, it is called only during a
* sync point, with a barrier prior to the call.
*
@@ -1448,8 +1455,10 @@ H5AC__receive_haddr_list(MPI_Comm mpi_comm, unsigned *num_entries_ptr, haddr_t *
/* allocate buffers to store the list of entry base addresses in */
buf_size = sizeof(haddr_t) * num_entries;
- if (NULL == (haddr_buf_ptr = (haddr_t *)H5MM_malloc(buf_size)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for haddr buffer")
+ if (NULL == (haddr_buf_ptr = (haddr_t *)H5MM_malloc(buf_size))) {
+ /* Push an error, but still participate in following MPI_Bcast */
+ HDONE_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for haddr buffer")
+ }
/* Now receive the list of candidate entries */
if (MPI_SUCCESS !=
@@ -1800,10 +1809,14 @@ H5AC__rsp__dist_md_write__flush_to_min_clean(H5F_t *f)
if (evictions_enabled) {
/* construct candidate list -- process 0 only */
- if (aux_ptr->mpi_rank == 0)
+ if (aux_ptr->mpi_rank == 0) {
+ /* If constructing candidate list fails, push an error but still participate
+ * in collective operations during following candidate list propagation
+ */
if (H5AC__construct_candidate_list(cache_ptr, aux_ptr, H5AC_SYNC_POINT_OP__FLUSH_TO_MIN_CLEAN) <
0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't construct candidate list.")
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't construct candidate list.")
+ }
/* propagate and apply candidate list -- all processes */
if (H5AC__propagate_and_apply_candidate_list(f) < 0)
@@ -1899,15 +1912,21 @@ H5AC__rsp__p0_only__flush(H5F_t *f)
aux_ptr->write_permitted = FALSE;
/* Check for error on the write operation */
- if (result < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
-
- /* this code exists primarily for the test bed -- it allows us to
- * enforce POSIX semantics on the server that pretends to be a
- * file system in our parallel tests.
- */
- if (aux_ptr->write_done)
- (aux_ptr->write_done)();
+ if (result < 0) {
+ /* If write operation fails, push an error but still participate
+ * in collective operations during following cache entry
+ * propagation
+ */
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
+ }
+ else {
+ /* this code exists primarily for the test bed -- it allows us to
+ * enforce POSIX semantics on the server that pretends to be a
+ * file system in our parallel tests.
+ */
+ if (aux_ptr->write_done)
+ (aux_ptr->write_done)();
+ }
} /* end if */
/* Propagate cleaned entries to other ranks. */
@@ -2019,15 +2038,21 @@ H5AC__rsp__p0_only__flush_to_min_clean(H5F_t *f)
aux_ptr->write_permitted = FALSE;
/* Check for error on the write operation */
- if (result < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_flush_to_min_clean() failed.")
-
- /* this call exists primarily for the test code -- it is used
- * to enforce POSIX semantics on the process used to simulate
- * reads and writes in t_cache.c.
- */
- if (aux_ptr->write_done)
- (aux_ptr->write_done)();
+ if (result < 0) {
+ /* If write operation fails, push an error but still participate
+ * in collective operations during following cache entry
+ * propagation
+ */
+ HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_flush_to_min_clean() failed.")
+ }
+ else {
+ /* this call exists primarily for the test code -- it is used
+ * to enforce POSIX semantics on the process used to simulate
+ * reads and writes in t_cache.c.
+ */
+ if (aux_ptr->write_done)
+ (aux_ptr->write_done)();
+ }
} /* end if */
if (H5AC__propagate_flushed_and_still_clean_entries_list(f) < 0)
@@ -2093,11 +2118,11 @@ H5AC__run_sync_point(H5F_t *f, int sync_point_op)
(sync_point_op == H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED));
#if H5AC_DEBUG_DIRTY_BYTES_CREATION
- HDfprintf(stdout, "%d:H5AC_propagate...:%u: (u/uu/i/iu/r/ru) = %zu/%u/%zu/%u/%zu/%u\n", aux_ptr->mpi_rank,
+ HDfprintf(stdout, "%d:H5AC_propagate...:%u: (u/uu/i/iu/m/mu) = %zu/%u/%zu/%u/%zu/%u\n", aux_ptr->mpi_rank,
aux_ptr->dirty_bytes_propagations, aux_ptr->unprotect_dirty_bytes,
aux_ptr->unprotect_dirty_bytes_updates, aux_ptr->insert_dirty_bytes,
- aux_ptr->insert_dirty_bytes_updates, aux_ptr->rename_dirty_bytes,
- aux_ptr->rename_dirty_bytes_updates);
+ aux_ptr->insert_dirty_bytes_updates, aux_ptr->move_dirty_bytes,
+ aux_ptr->move_dirty_bytes_updates);
#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
/* clear collective access flag on half of the entries in the
@@ -2161,8 +2186,8 @@ H5AC__run_sync_point(H5F_t *f, int sync_point_op)
aux_ptr->unprotect_dirty_bytes_updates = 0;
aux_ptr->insert_dirty_bytes = 0;
aux_ptr->insert_dirty_bytes_updates = 0;
- aux_ptr->rename_dirty_bytes = 0;
- aux_ptr->rename_dirty_bytes_updates = 0;
+ aux_ptr->move_dirty_bytes = 0;
+ aux_ptr->move_dirty_bytes_updates = 0;
#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
done:
diff --git a/src/H5ACpkg.h b/src/H5ACpkg.h
index 521f85a..9b75034 100644
--- a/src/H5ACpkg.h
+++ b/src/H5ACpkg.h
@@ -346,7 +346,7 @@ H5FL_EXTERN(H5AC_aux_t);
*
* The following field supports the metadata cache image feature.
*
- * p0_image_len: unsiged integer containing the length of the metadata cache
+ * p0_image_len: unsigned integer containing the length of the metadata cache
* image constructed by MPI process 0. This field should be 0
* if the value is unknown, or if cache image is not enabled.
*
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index ff632d0..758f63d 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -430,8 +430,8 @@ H5_DLL herr_t H5AC_get_entry_ring(const H5F_t *f, haddr_t addr, H5AC_ring_t *rin
H5_DLL void H5AC_set_ring(H5AC_ring_t ring, H5AC_ring_t *orig_ring);
H5_DLL herr_t H5AC_unsettle_entry_ring(void *entry);
H5_DLL herr_t H5AC_unsettle_ring(H5F_t *f, H5AC_ring_t ring);
-H5_DLL herr_t H5AC_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags,
- hbool_t type_match);
+H5_DLL herr_t H5AC_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags);
+H5_DLL herr_t H5AC_expunge_all_tagged_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags);
H5_DLL herr_t H5AC_get_tag(const void *thing, /*OUT*/ haddr_t *tag);
H5_DLL herr_t H5AC_set_vfd_swmr_reader(H5AC_t *cache_ptr, hbool_t vfd_swmr_reader, hsize_t page_size);
diff --git a/src/H5ACproxy_entry.c b/src/H5ACproxy_entry.c
index d310a2b..25e7e9a 100644
--- a/src/H5ACproxy_entry.c
+++ b/src/H5ACproxy_entry.c
@@ -422,7 +422,7 @@ H5AC_proxy_entry_dest(H5AC_proxy_entry_t *pentry)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(pentry);
@@ -434,7 +434,6 @@ H5AC_proxy_entry_dest(H5AC_proxy_entry_t *pentry)
/* Free the proxy entry object */
pentry = H5FL_FREE(H5AC_proxy_entry_t, pentry);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5AC_proxy_entry_dest() */
diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h
index f8f4f28..42bc090 100644
--- a/src/H5ACpublic.h
+++ b/src/H5ACpublic.h
@@ -28,10 +28,6 @@
#include "H5public.h"
#include "H5Cpublic.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/****************************************************************************
*
* structure H5AC_cache_config_t
@@ -76,7 +72,7 @@ extern "C" {
*
* *** DEPRECATED *** Use H5Fstart/stop logging functions instead
*
- * The trace file is a debuging feature that allow the capture of
+ * The trace file is a debugging feature that allow the capture of
* top level metadata cache requests for purposes of debugging and/or
* optimization. This field should normally be set to FALSE, as
* trace file collection imposes considerable overhead.
@@ -123,7 +119,7 @@ extern "C" {
* H5C_incr__off ) && ( decr_mode == H5C_decr__off )). There
* is no logical reason why this should be so, but it simplifies
* implementation and testing, and I can't think of any reason
- * why it would be desireable. If you can think of one, I'll
+ * why it would be desirable. If you can think of one, I'll
* revisit the issue.
*
* set_initial_size: Boolean flag indicating whether the size of the
@@ -396,7 +392,7 @@ extern "C" {
*
* When the sync point is reached (or when there is a user generated
* flush), process zero flushes sufficient entries to bring it into
- * complience with its min clean size (or flushes all dirty entries in
+ * compliance with its min clean size (or flushes all dirty entries in
* the case of a user generated flush), broad casts the list of
* entries just cleaned to all the other processes, and then exits
* the sync point.
@@ -576,7 +572,7 @@ typedef struct H5AC_cache_config_t {
size_t min_size;
/**< Lower bound (in bytes) on the range of values that the
- * adaptive cache resize code can select as the mininum cache * size. */
+ * adaptive cache resize code can select as the minimum cache * size. */
long int epoch_length;
/**< Number of cache accesses between runs of the adaptive cache resize
@@ -708,13 +704,13 @@ typedef struct H5AC_cache_config_t {
* of bytes of dirty metadata created since the last synchronization exceeds
* this limit.\n This field only applies to the parallel case. While it is
* ignored elsewhere, it can still draw a value out of bounds error.\n It
- * must be consistant across all caches on any given file.\n By default,
+ * must be consistent across all caches on any given file.\n By default,
* this field is set to 256 KB. It shouldn't be more than half the current
* max cache size times the min clean fraction. */
int metadata_write_strategy;
/**< Desired metadata write strategy. The valid values for this field
- * are:\n #H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY: Specifies tha only
+ * are:\n #H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY: Specifies the only
* process zero is allowed to write dirty metadata to disk.\n
* #H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED: Specifies that process zero
* still makes the decisions as to what entries should be flushed, but the
@@ -783,7 +779,4 @@ typedef struct H5AC_cache_image_config_t {
//! <!-- [H5AC_cache_image_config_t_snip] -->
-#ifdef __cplusplus
-}
-#endif
#endif
diff --git a/src/H5Adense.c b/src/H5Adense.c
index b0d793c..fa51f9d 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -337,7 +337,7 @@ H5A__dense_open(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
H5HF_t * fheap = NULL; /* Fractal heap handle */
H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
hbool_t attr_exists; /* Attribute exists in v2 B-tree */
H5A_t * ret_value = NULL; /* Return value */
@@ -356,7 +356,7 @@ H5A__dense_open(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
@@ -429,7 +429,7 @@ H5A__dense_insert(H5F_t *f, const H5O_ainfo_t *ainfo, H5A_t *attr)
H5WB_t * wb = NULL; /* Wrapped buffer for attribute data */
uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */
unsigned mesg_flags = 0; /* Flags for storing message */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -443,7 +443,7 @@ H5A__dense_insert(H5F_t *f, const H5O_ainfo_t *ainfo, H5A_t *attr)
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
@@ -727,7 +727,7 @@ H5A__dense_write(H5F_t *f, const H5O_ainfo_t *ainfo, H5A_t *attr)
H5HF_t * fheap = NULL; /* Fractal heap handle */
H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -743,7 +743,7 @@ H5A__dense_write(H5F_t *f, const H5O_ainfo_t *ainfo, H5A_t *attr)
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
@@ -865,7 +865,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
H5B2_t * bt2_corder = NULL; /* v2 B-tree handle for creation order ndex */
H5A_t * attr_copy = NULL; /* Copy of attribute to rename */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
hbool_t attr_exists; /* Attribute exists in v2 B-tree */
herr_t ret_value = SUCCEED; /* Return value */
@@ -882,7 +882,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
@@ -1181,7 +1181,7 @@ H5A__dense_iterate(H5F_t *f, hid_t loc_id, const H5O_ainfo_t *ainfo, H5_index_t
/* Check on iteration order */
if (order == H5_ITER_NATIVE && H5F_addr_defined(bt2_addr)) {
H5A_bt2_ud_it_t udata; /* User data for iterator callback */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
/* Open the fractal heap */
if (NULL == (fheap = H5HF_open(f, ainfo->fheap_addr)))
@@ -1191,7 +1191,7 @@ H5A__dense_iterate(H5F_t *f, hid_t loc_id, const H5O_ainfo_t *ainfo, H5_index_t
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
@@ -1338,7 +1338,7 @@ H5A__dense_remove(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
H5A_t * attr_copy = NULL; /* Copy of attribute to remove */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -1356,7 +1356,7 @@ H5A__dense_remove(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
@@ -1585,7 +1585,7 @@ H5A__dense_remove_by_idx(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type
/* If there is an index defined for the field, use it */
if (H5F_addr_defined(bt2_addr)) {
H5A_bt2_ud_rmbi_t udata; /* User data for v2 B-tree record removal */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
/* Open the fractal heap */
if (NULL == (fheap = H5HF_open(f, ainfo->fheap_addr)))
@@ -1595,7 +1595,7 @@ H5A__dense_remove_by_idx(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
@@ -1675,7 +1675,7 @@ H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name, hbool_t
H5HF_t * fheap = NULL; /* Fractal heap handle */
H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
- htri_t attr_sharable; /* Flag indicating attributes are sharable */
+ htri_t attr_sharable; /* Flag indicating attributes are shareable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -1694,7 +1694,7 @@ H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name, hbool_t
if ((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
- /* Get handle for shared message heap, if attributes are sharable */
+ /* Get handle for shared message heap, if attributes are shareable */
if (attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c
index 8ae4e41..05e4eed 100644
--- a/src/H5Adeprec.c
+++ b/src/H5Adeprec.c
@@ -356,7 +356,7 @@ done:
last operator if it was non-zero, or zero if all attributes were processed.
DESCRIPTION
- This function interates over the attributes of dataset or group
+ This function iterates over the attributes of dataset or group
specified with 'loc_id'. For each attribute of the object, the
'op_data' and some additional information (specified below) are passed
to the 'op' function. The iteration begins with the '*attr_number'
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 300d686..b0b91d0 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -99,9 +99,6 @@ static herr_t H5A__iterate_common(hid_t loc_id, H5_index_t idx_type, H5_iter_ord
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Format version bounds for attribute */
const unsigned H5O_attr_ver_bounds[] = {
H5O_ATTR_VERSION_1, /* H5F_LIBVER_EARLIEST */
@@ -139,9 +136,6 @@ static const H5I_class_t H5I_ATTR_CLS[1] = {{
(H5I_free_t)H5A__close_cb /* Callback routine for closing objects of this class */
}};
-/* Flag indicating "top" of interface has been initialized */
-static hbool_t H5A_top_package_initialize_s = FALSE;
-
/*-------------------------------------------------------------------------
* Function: H5A_init
*
@@ -158,30 +152,6 @@ H5A_init(void)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A_init() */
-
-/*--------------------------------------------------------------------------
-NAME
- H5A__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5A__init_package()
-
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
-
---------------------------------------------------------------------------*/
-herr_t
-H5A__init_package(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
/*
* Create attribute ID type.
@@ -189,12 +159,9 @@ H5A__init_package(void)
if (H5I_register_type(H5I_ATTR_CLS) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize interface")
- /* Mark "top" of interface as initialized, too */
- H5A_top_package_initialize_s = TRUE;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A__init_package() */
+} /* end H5A_init() */
/*--------------------------------------------------------------------------
NAME
@@ -220,16 +187,10 @@ H5A_top_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5A_top_package_initialize_s) {
- if (H5I_nmembers(H5I_ATTR) > 0) {
- (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
-
- /* Mark closed */
- if (0 == n)
- H5A_top_package_initialize_s = FALSE;
- } /* end if */
+ if (H5I_nmembers(H5I_ATTR) > 0) {
+ (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE);
+ n++; /*H5I*/
+ } /* end if */
FUNC_LEAVE_NOAPI(n)
} /* H5A_top_term_package() */
@@ -260,18 +221,11 @@ H5A_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Sanity checks */
- HDassert(0 == H5I_nmembers(H5I_ATTR));
- HDassert(FALSE == H5A_top_package_initialize_s);
-
- /* Destroy the attribute object id group */
- n += (H5I_dec_type_ref(H5I_ATTR) > 0);
+ /* Sanity checks */
+ HDassert(0 == H5I_nmembers(H5I_ATTR));
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Destroy the attribute object id group */
+ n += (H5I_dec_type_ref(H5I_ATTR) > 0);
FUNC_LEAVE_NOAPI(n)
} /* H5A_term_package() */
@@ -1148,7 +1102,7 @@ H5A__get_info(const H5A_t *attr, H5A_info_t *ainfo)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Check args */
HDassert(attr);
@@ -1166,7 +1120,6 @@ H5A__get_info(const H5A_t *attr, H5A_info_t *ainfo)
ainfo->corder = attr->shared->crt_idx;
} /* end else */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A__get_info() */
@@ -1383,14 +1336,13 @@ H5A_oloc(H5A_t *attr)
{
H5O_loc_t *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(attr);
/* Set return value */
ret_value = &(attr->oloc);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_oloc() */
@@ -1414,14 +1366,13 @@ H5A_nameof(H5A_t *attr)
{
H5G_name_t *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(attr);
/* Set return value */
ret_value = &(attr->path);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_nameof() */
@@ -1443,14 +1394,13 @@ H5A_type(const H5A_t *attr)
{
H5T_t *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(attr);
/* Set return value */
ret_value = attr->shared->dt;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_type() */
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index b78ae05..4ac6a53 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -622,7 +622,7 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id);
* For example, if \p idx_type, \p order, and \p idx are set to
* #H5_INDEX_NAME, #H5_ITER_INC, and 5, respectively, the attribute
* in question is the fifth attribute from the beginning of the
- * alpha-numeric index of attribute names. If \p order were set to
+ * alphanumeric index of attribute names. If \p order were set to
* #H5_ITER_DEC, it would be the fifth attribute from the end of
* the index.
*
@@ -677,7 +677,7 @@ H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t ord
* For example, if \p idx_type, \p order, and \p idx are set to
* #H5_INDEX_NAME, #H5_ITER_INC, and 5, respectively, the attribute
* in question is the fifth attribute from the beginning of the
- * alpha-numeric index of attribute names. If \p order were set to
+ * alphanumeric index of attribute names. If \p order were set to
* #H5_ITER_DEC, it would be the fifth attribute from the end of
* the index.
*
diff --git a/src/H5B.c b/src/H5B.c
index fa6284c..a9aa312 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -157,9 +157,6 @@ static H5B_t *H5B__copy(const H5B_t *old_bt);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declare a free list to manage the haddr_t sequence information */
H5FL_SEQ_DEFINE(haddr_t);
diff --git a/src/H5B2.c b/src/H5B2.c
index cc6a664..b64f253 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -61,9 +61,6 @@
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* v2 B-tree client ID to class mapping */
/* Remember to add client ID to H5B2_subid_t in H5B2private.h when adding a new
diff --git a/src/H5C.c b/src/H5C.c
index 802b4e3..8052b3d 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -11,9 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/* TEMPORARY (during VFD SWMR sync with develop - reduces churn) */
-/* clang-format off */
-
/*-------------------------------------------------------------------------
*
* Created: H5C.c
@@ -36,7 +33,7 @@
*
* Code Changes:
*
- * - Remove extra functionality in H5C__flush_single_entry()?
+ * - Remove extra functionality in H5C__flush_single_entry()?
*
* - Change protect/unprotect to lock/unlock.
*
@@ -54,18 +51,18 @@
* the LRU list, eliminating skip list lookups when evicting objects
* from the cache.
*
- * - Create MPI type for dirty objects when flushing in parallel.
+ * - Create MPI type for dirty objects when flushing in parallel.
*
- * - Now that TBBT routines aren't used, fix nodes in memory to
+ * - Now that TBBT routines aren't used, fix nodes in memory to
* point directly to the skip list node from the LRU list, eliminating
* skip list lookups when evicting objects from the cache.
*
- * Tests:
+ * Tests:
*
- * - Trim execution time. (This is no longer a major issue with the
- * shift from the TBBT to a hash table for indexing.)
+ * - Trim execution time. (This is no longer a major issue with the
+ * shift from the TBBT to a hash table for indexing.)
*
- * - Add random tests.
+ * - Add random tests.
*
**************************************************************************/
@@ -79,17 +76,18 @@
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5retry_private.h" /* Retry loops. */
-#include "H5Cpkg.h" /* Cache */
-#include "H5CXprivate.h" /* API Contexts */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fpkg.h" /* Files */
-#include "H5FLprivate.h" /* Free Lists */
-#include "H5Iprivate.h" /* IDs */
-#include "H5MFprivate.h" /* File memory management */
-#include "H5MMprivate.h" /* Memory management */
-#include "H5Pprivate.h" /* Property lists */
+#include "H5private.h" /* Generic Functions */
+#include "H5Cpkg.h" /* Cache */
+#include "H5CXprivate.h" /* API Contexts */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* Files */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
+
+#include "H5retry_private.h" /* Retry loops */
/****************/
/* Local Macros */
@@ -153,19 +151,10 @@ static herr_t H5C__mark_flush_dep_clean(H5C_cache_entry_t *entry);
static herr_t H5C__serialize_ring(H5F_t *f, H5C_ring_t ring);
static herr_t H5C__serialize_single_entry(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr);
+static herr_t H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr);
static herr_t H5C__verify_len_eoa(H5F_t *f, const H5C_class_t *type, haddr_t addr, size_t *len,
hbool_t actual);
-#if H5C_DO_SLIST_SANITY_CHECKS
-static hbool_t H5C__entry_in_skip_list(H5C_t *cache_ptr, H5C_cache_entry_t *target_ptr);
-#endif /* H5C_DO_SLIST_SANITY_CHECKS */
-
-#if H5C_DO_EXTREME_SANITY_CHECKS
-static herr_t H5C__validate_lru_list(H5C_t *cache_ptr);
-static herr_t H5C__validate_pinned_entry_list(H5C_t *cache_ptr);
-static herr_t H5C__validate_protected_entry_list(H5C_t *cache_ptr);
-#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
-
#ifndef NDEBUG
static void H5C__assert_flush_dep_nocycle(const H5C_cache_entry_t *entry,
const H5C_cache_entry_t *base_entry);
@@ -175,9 +164,6 @@ static void H5C__assert_flush_dep_nocycle(const H5C_cache_entry_t *entry,
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declare a free list to manage the tag info struct */
H5FL_DEFINE(H5C_tag_info_t);
@@ -397,7 +383,7 @@ H5C_create(size_t max_cache_size, size_t min_clean_size, int max_type_id,
cache_ptr->slist_size = (size_t)0;
/* slist_ring_len, slist_ring_size, and
- * slist_ptr initialized above.
+ * slist_ptr initializaed above.
*/
#if H5C_DO_SANITY_CHECKS
@@ -811,7 +797,7 @@ H5C_prep_for_file_close(H5F_t *f)
*
* 2) Since the FSM settle routines are only invoked once during
* file close, invoking them now will prevent their invocation
- * during a flush, and thus avoid any resulting entrie dirties,
+ * during a flush, and thus avoid any resulting entry dirties,
* deletions, insertion, or moves during the flush.
*/
if (H5C__serialize_cache(f) < 0)
@@ -890,6 +876,9 @@ H5C_dest(H5F_t *f)
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "Can't generate metadata cache image")
}
+ /* Question: Is it possible for cache_ptr->slist be non-null at this
+ * point? If no, shouldn't this if statement be an assert?
+ */
if (cache_ptr->slist_ptr != NULL) {
HDassert(cache_ptr->slist_len == 0);
@@ -1073,12 +1062,6 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t *f, uint64_t page, uint32_t lengt
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(cache_ptr->vfd_swmr_reader);
-#if 0 /* JRM */
- HDfprintf(stderr,
- "H5C_evict_or_refresh_all_entries_in_page() entering. page = %lld\n",
- page);
-#endif /* JRM */
-
/* since file must be opened R/O for a VFD SWMR reader, the skip
* list must be empty. Verify this.
*/
@@ -1126,11 +1109,6 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t *f, uint64_t page, uint32_t lengt
tag = entry_ptr->tag_info->tag;
HDassert(!(entry_ptr->tag_info->corked));
-#if 0 /* JRM */
- HDfprintf(stderr,
- "evicting tagged entries addr/page/tag == %lld/%lld/%lld\n",
- entry_ptr->addr, entry_ptr->page, tag);
-#endif /* JRM */
/* passing TRUE for the match_global parameter. Look
* into this and verify that it is the right thing to
@@ -1146,10 +1124,7 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t *f, uint64_t page, uint32_t lengt
follow_ptr = entry_ptr = NULL;
}
else if (entry_ptr->type->refresh) {
-#if 0 /* JRM */
- HDfprintf(stderr, "refreshing addr/page/tag == %lld/%lld\n",
- entry_ptr->addr, entry_ptr->page);
-#endif /* JRM */
+
/* If there is a refresh callback, use it to minimize
* overhead.
*
@@ -1178,10 +1153,10 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t *f, uint64_t page, uint32_t lengt
* Note that this will be satisfied from the metadata
* file via the VFD SWMR reade VFD.
*
- * For this reason, we don't nead to check for reads
+ * For this reason, we don't need to check for reads
* past the EOA. Torn reads and checksums are also
* not an issue, since pages in the metadata file
- * are checksumed and re-tried if necessary in the
+ * are checksummed and re-tried if necessary in the
* VFD SWMR reader VFD.
*/
if (NULL == (image_ptr = (uint8_t *)H5MM_malloc(image_len + H5C_IMAGE_EXTRA_SPACE)))
@@ -1290,19 +1265,6 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t *f, uint64_t page, uint32_t lengt
* skip list -- thus no need for the
* H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG.
*/
-#if 0 /* JRM */
- if ( entry_ptr->tag_info ) {
-
- HDfprintf(stderr,
- "evicting entry addr/page/tag == %lld/%lld/%lld\n",
- entry_ptr->addr, entry_ptr->page,
- entry_ptr->tag_info->tag);
- } else {
- HDfprintf(stderr,
- "evicting entry addr/page == %lld/%lld no tag\n",
- entry_ptr->addr, entry_ptr->page);
- }
-#endif /* JRM */
if (H5C__flush_single_entry(f, entry_ptr, flush_flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "can't evict unpinned entry")
@@ -1357,10 +1319,7 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t *f, uint64_t page, uint32_t lengt
entry_ptr = (cache_ptr->page_index)[i];
while (entry_ptr) {
-
HDassert((entry_ptr->page != page) || (entry_ptr->refreshed_in_tick == tick));
- ;
-
entry_ptr = entry_ptr->pi_next;
}
@@ -1402,7 +1361,7 @@ H5C_expunge_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, unsigned flag
HDassert(H5F_addr_defined(addr));
#if H5C_DO_EXTREME_SANITY_CHECKS
- if (H5C__validate_lru_list(cache_ptr) < 0)
+ if (H5C_validate_lru_list(cache_ptr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "LRU extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -1437,7 +1396,7 @@ H5C_expunge_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, unsigned flag
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if (H5C__validate_lru_list(cache_ptr) < 0)
+ if (H5C_validate_lru_list(cache_ptr) < 0)
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "LRU extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -1544,8 +1503,8 @@ H5C_flush_cache(H5F_t *f, unsigned flags)
#endif /* H5C_DO_SANITY_CHECKS */
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -1712,7 +1671,7 @@ H5C_insert_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *thing, u
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- /* if this is a VFD SWMR reader, verify that the page size is defined */
+ /* If this is a VFD SWMR reader, verify that the page size is defined */
HDassert((!cache_ptr->vfd_swmr_reader) || (cache_ptr->page_size > 0));
HDassert(type);
@@ -1724,8 +1683,8 @@ H5C_insert_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *thing, u
#if H5C_DO_EXTREME_SANITY_CHECKS
/* no need to verify that entry is not already in the index as */
/* we already make that check below. */
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -1840,14 +1799,10 @@ H5C_insert_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *thing, u
entry_ptr->tag_info = NULL;
/* initialize fields supporting VFD SWMR */
- if (cache_ptr->vfd_swmr_reader) {
-
+ if (cache_ptr->vfd_swmr_reader)
entry_ptr->page = (addr / cache_ptr->page_size);
- }
- else {
-
+ else
entry_ptr->page = 0;
- }
entry_ptr->refreshed_in_tick = 0;
entry_ptr->pi_next = NULL;
entry_ptr->pi_prev = NULL;
@@ -1908,7 +1863,7 @@ H5C_insert_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *thing, u
* Finally, we usually don't check to see if the cache is
* oversized at the end of an unprotect. As a result, it is
* possible to have a vastly oversized cache with no protected
- * entries as long as all the protects preceed the unprotects.
+ * entries as long as all the protects precede the unprotects.
*
* Since items 1 and 2 are not changing any time soon, I see
* no point in worrying about the third.
@@ -1927,8 +1882,8 @@ H5C_insert_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *thing, u
H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, FAIL)
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed just before done")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -1942,23 +1897,32 @@ H5C_insert_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *thing, u
#ifdef H5_HAVE_PARALLEL
if (H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI))
- coll_access = H5CX_get_coll_metadata_read();
+ coll_access = H5F_get_coll_metadata_reads(f);
entry_ptr->coll_access = coll_access;
if (coll_access) {
H5C__INSERT_IN_COLL_LIST(cache_ptr, entry_ptr, FAIL)
/* Make sure the size of the collective entries in the cache remain in check */
- if (cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100)
- if (H5C_clear_coll_entries(cache_ptr, TRUE) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't clear collective metadata entries")
- } /* end if */
+ if (H5P_USER_TRUE == H5F_COLL_MD_READ(f)) {
+ if (cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100) {
+ if (H5C_clear_coll_entries(cache_ptr, TRUE) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't clear collective metadata entries")
+ } /* end if */
+ } /* end if */
+ else {
+ if (cache_ptr->max_cache_size * 40 < cache_ptr->coll_list_size * 100) {
+ if (H5C_clear_coll_entries(cache_ptr, TRUE) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't clear collective metadata entries")
+ } /* end if */
+ } /* end else */
+ } /* end if */
#endif
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2281,7 +2245,7 @@ H5C_move_entry(H5C_t *cache_ptr, const H5C_class_t *type, haddr_t old_addr, hadd
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- /* if this is a VFD SWMR reader, verify that the page size is defined */
+ /* If this is a VFD SWMR reader, verify that the page size is defined */
HDassert((!cache_ptr->vfd_swmr_reader) || (cache_ptr->page_size > 0));
HDassert(type);
@@ -2290,8 +2254,8 @@ H5C_move_entry(H5C_t *cache_ptr, const H5C_class_t *type, haddr_t old_addr, hadd
HDassert(H5F_addr_ne(old_addr, new_addr));
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2346,13 +2310,11 @@ H5C_move_entry(H5C_t *cache_ptr, const H5C_class_t *type, haddr_t old_addr, hadd
entry_ptr->addr = new_addr;
- /* update the page in which the entry resides if the file is opened
- * as a VFD SWMR reader.
+ /* Update the page in which the entry resides if the file is opened
+ * as a VFD SWMR reader
*/
- if (cache_ptr->vfd_swmr_reader) {
-
+ if (cache_ptr->vfd_swmr_reader)
entry_ptr->page = (new_addr / cache_ptr->page_size);
- }
if (!entry_ptr->destroy_in_progress) {
hbool_t was_dirty; /* Whether the entry was previously dirty */
@@ -2404,8 +2366,8 @@ H5C_move_entry(H5C_t *cache_ptr, const H5C_class_t *type, haddr_t old_addr, hadd
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2451,8 +2413,7 @@ H5C_resize_entry(void *thing, size_t new_size)
HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, FAIL, "Entry isn't pinned or protected??")
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) || (H5C_validate_pinned_entry_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2548,8 +2509,7 @@ H5C_resize_entry(void *thing, size_t new_size)
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) || (H5C_validate_pinned_entry_list(cache_ptr) < 0))
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2589,8 +2549,8 @@ H5C_pin_protected_entry(void *thing)
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2604,8 +2564,8 @@ H5C_pin_protected_entry(void *thing)
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2668,8 +2628,8 @@ H5C_protect(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *udata, unsign
HDassert(H5F_addr_defined(addr));
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2688,7 +2648,7 @@ H5C_protect(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *udata, unsign
#ifdef H5_HAVE_PARALLEL
if (H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI))
- coll_access = H5CX_get_coll_metadata_read();
+ coll_access = H5F_get_coll_metadata_reads(f);
#endif /* H5_HAVE_PARALLEL */
/* first check to see if the target is in cache */
@@ -2747,9 +2707,14 @@ H5C_protect(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *udata, unsign
H5MM_memcpy(((uint8_t *)entry_ptr->image_ptr) + entry_ptr->size, H5C_IMAGE_SANITY_VALUE,
H5C_IMAGE_EXTRA_SPACE);
#endif /* H5C_DO_MEMORY_SANITY_CHECKS */
- if (0 == mpi_rank)
- if (H5C__generate_image(f, cache_ptr, entry_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "can't generate entry's image")
+ if (0 == mpi_rank) {
+ if (H5C__generate_image(f, cache_ptr, entry_ptr) < 0) {
+ /* If image generation fails, push an error but
+ * still participate in the following MPI_Bcast
+ */
+ HDONE_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "can't generate entry's image")
+ }
+ }
} /* end if */
HDassert(entry_ptr->image_ptr);
@@ -2803,15 +2768,16 @@ H5C_protect(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *udata, unsign
#endif /* H5_HAVE_PARALLEL */
type, addr, udata))) {
/* Print out meaningful message for VFD SWMR reader */
- if(f->shared->vfd_swmr && !f->shared->vfd_swmr_writer) {
- uint64_t tmp_tick_num = 0;
+ if (f->shared->vfd_swmr && !f->shared->vfd_swmr_writer) {
+ uint64_t tmp_tick_num = 0;
if (H5FD_vfd_swmr_get_tick_and_idx(f->shared->lf, TRUE, &tmp_tick_num, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, NULL, "error in retrieving tick_num from driver");
if (tmp_tick_num >= f->shared->tick_num + f->shared->vfd_swmr_config.max_lag)
- HDONE_ERROR(H5E_FILE, H5E_SYSTEM, NULL,
- "Reader's API time exceeds max_lag ticks, suggest to increase the value of max_lag.");
+ HDONE_ERROR(
+ H5E_FILE, H5E_SYSTEM, NULL,
+ "Reader's API time exceeds max_lag ticks, suggest to increase the value of max_lag.");
}
HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "can't load entry")
@@ -2897,7 +2863,7 @@ H5C_protect(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *udata, unsign
* Finally, we usually don't check to see if the cache is
* oversized at the end of an unprotect. As a result, it is
* possible to have a vastly oversized cache with no protected
- * entries as long as all the protects preceed the unprotects.
+ * entries as long as all the protects precede the unprotects.
*
* Since items 1, 2, and 3 are not changing any time soon, I
* see no point in worrying about the fourth.
@@ -3012,7 +2978,7 @@ H5C_protect(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *udata, unsign
*
* Also, if the min_clean_size requirement is not met, we
* should also call H5C__make_space_in_cache() to bring us
- * into complience.
+ * into compliance.
*/
if (cache_ptr->index_size >= cache_ptr->max_cache_size)
@@ -3048,16 +3014,24 @@ H5C_protect(H5F_t *f, const H5C_class_t *type, haddr_t addr, void *udata, unsign
#ifdef H5_HAVE_PARALLEL
/* Make sure the size of the collective entries in the cache remain in check */
- if (coll_access)
- if (cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100)
- if (H5C_clear_coll_entries(cache_ptr, TRUE) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "can't clear collective metadata entries")
-#endif /* H5_HAVE_PARALLEL */
+ if (coll_access) {
+ if (H5P_USER_TRUE == H5F_COLL_MD_READ(f)) {
+ if (cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100)
+ if (H5C_clear_coll_entries(cache_ptr, TRUE) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "can't clear collective metadata entries")
+ } /* end if */
+ else {
+ if (cache_ptr->max_cache_size * 40 < cache_ptr->coll_list_size * 100)
+ if (H5C_clear_coll_entries(cache_ptr, TRUE) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "can't clear collective metadata entries")
+ } /* end else */
+ } /* end if */
+#endif /* H5_HAVE_PARALLEL */
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "an extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -3509,7 +3483,7 @@ done:
* Programmer: John Mainzer
* 1/15/19
*
- * Changes: None.
+ * Changes: None
*
*-------------------------------------------------------------------------
*/
@@ -3521,7 +3495,6 @@ H5C_set_vfd_swmr_reader(H5C_t *cache_ptr, hbool_t vfd_swmr_reader, hsize_t page_
FUNC_ENTER_NOAPI(FAIL)
if ((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
-
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry")
cache_ptr->vfd_swmr_reader = vfd_swmr_reader;
@@ -3565,8 +3538,8 @@ H5C_unpin_entry(void *_entry_ptr)
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -3576,8 +3549,8 @@ H5C_unpin_entry(void *_entry_ptr)
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -3744,8 +3717,8 @@ H5C_unprotect(H5F_t *f, haddr_t addr, void *thing, unsigned flags)
was_clean = !(entry_ptr->is_dirty);
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -4011,8 +3984,8 @@ H5C_unprotect(H5F_t *f, haddr_t addr, void *thing, unsigned flags)
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -5336,7 +5309,7 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t *f, hbool_t write_permitte
/* for now at least, don't bother to maintain the minimum clean size,
* as the cache should now be less than its maximum size. Due to
- * the vaguries of the cache size reduction algorthim, we may not
+ * the vaguries of the cache size reduction algorithm, we may not
* reduce the size of the cache.
*
* If we do, we will calculate a new minimum clean size, which will
@@ -6348,7 +6321,7 @@ H5C__flush_invalidate_ring(H5F_t *f, H5C_ring_t ring, unsigned flags)
* If either of these happen, and one of the target
* or proxy entries happens to be the next entry in
* the hash bucket, we could either find ourselves
- * either scanning a non-existant entry, scanning
+ * either scanning a non-existent entry, scanning
* through a different bucket, or skipping an entry.
*
* Neither of these are good, so restart the
@@ -6546,8 +6519,8 @@ H5C__flush_ring(H5F_t *f, H5C_ring_t ring, unsigned flags)
HDassert(ring < H5C_RING_NTYPES);
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -6806,12 +6779,6 @@ done:
* be cleared and not flushed, and the call can't be part of a
* sequence of flushes.
*
- * If the caller knows the address of the skip list node at
- * which the target entry resides, it can avoid a lookup
- * by supplying that address in the tgt_node_ptr parameter.
- * If this parameter is NULL, the function will do a skip list
- * search for the entry instead.
- *
* The function does nothing silently if there is no entry
* at the supplied address, or if the entry found has the
* wrong type.
@@ -7123,7 +7090,8 @@ H5C__flush_single_entry(H5F_t *f, H5C_cache_entry_t *entry_ptr, unsigned flags)
H5C__SET_PB_WRITE_HINTS(cache_ptr, entry_ptr->type)
- if (H5F_block_write(f, mem_type, entry_ptr->addr, entry_ptr->size, entry_ptr->image_ptr) < 0) {
+ if (H5F_block_write(f, mem_type, entry_ptr->addr, entry_ptr->size, entry_ptr->image_ptr) <
+ 0) {
H5C__RESET_PB_WRITE_HINTS(cache_ptr)
@@ -7477,7 +7445,7 @@ H5C__flush_single_entry(H5F_t *f, H5C_cache_entry_t *entry_ptr, unsigned flags)
*/
/* VFD SWMR TODO: Think on this, and decide if we need to extend
- * this for multi page metadata entries.
+ * this for multi-page metadata entries.
*/
if (update_page_buffer) {
@@ -7590,10 +7558,7 @@ done:
*
* Programmer: John Mainzer, 5/18/04
*
- * Changes: Please maintain the change list and do not delete entries
- * unless the have been folded into the header comment.
- *
- * Reverted optimization that avoided re-reading the prefix
+ * Changes: Reverted optimization that avoided re-reading the prefix
* of a metadata entry when a speculative read proved too
* small.
* JRM -- 3/25/20
@@ -7611,22 +7576,17 @@ H5C__load_entry(H5F_t *f,
#endif /* H5_HAVE_PARALLEL */
const H5C_class_t *type, haddr_t addr, void *udata)
{
- hbool_t dirty = FALSE; /* Flag indicating whether thing */
- /* was dirtied during deserialize */
- uint8_t * image = NULL; /* Buffer for disk image */
- void * thing = NULL; /* Pointer to thing loaded */
- H5C_cache_entry_t *entry = NULL; /* Alias for thing loaded, as */
- /* cache entry */
-#if 0
-size_t init_len;
-#endif
- size_t len; /* Size of image in file */
+ hbool_t dirty = FALSE; /* Flag indicating whether thing was dirtied during deserialize */
+ uint8_t * image = NULL; /* Buffer for disk image */
+ void * thing = NULL; /* Pointer to thing loaded */
+ H5C_cache_entry_t *entry = NULL; /* Alias for thing loaded, as cache entry */
+ size_t len; /* Size of image in file */
#ifdef H5_HAVE_PARALLEL
- int mpi_rank = 0; /* MPI process rank */
- MPI_Comm comm = MPI_COMM_NULL; /* File MPI Communicator */
- int mpi_code; /* MPI error code */
-#endif /* H5_HAVE_PARALLEL */
- void *ret_value = NULL; /* Return value */
+ int mpi_rank = 0; /* MPI process rank */
+ MPI_Comm comm = MPI_COMM_NULL; /* File MPI Communicator */
+ int mpi_code; /* MPI error code */
+#endif /* H5_HAVE_PARALLEL */
+ void *ret_value = NULL; /* Return value */
FUNC_ENTER_STATIC
@@ -7658,10 +7618,6 @@ size_t init_len;
HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "can't retrieve image size")
HDassert(len > 0);
-#if 0
-init_len = len;
-#endif
-
/* Check for possible speculative read off the end of the file */
if (type->flags & H5C__CLASS_SPECULATIVE_LOAD_FLAG)
if (H5C__verify_len_eoa(f, type, addr, &len, FALSE) < 0)
@@ -7696,14 +7652,14 @@ init_len = len;
h5_retry_t retry;
/*
- * This do/while loop performs the following till the metadata checksum
+ * This for loop performs the following till the metadata checksum
* is correct or the file's number of allowed read attempts are reached.
* --read the metadata
* --determine the actual size of the metadata
* --perform checksum verification
*/
- for (do_try = h5_retry_init(&retry, H5F_GET_READ_ATTEMPTS(f), 1, H5_RETRY_ONE_HOUR / 3600 / 100);
- do_try; do_try = h5_retry_next(&retry)) {
+ for (do_try = H5_retry_init(&retry, H5F_GET_READ_ATTEMPTS(f), 1, H5_RETRY_ONE_HOUR / 3600 / 100);
+ do_try; do_try = H5_retry_next(&retry)) {
if (actual_len != len) {
if (NULL == (new_image = H5MM_realloc(image, len + H5C_IMAGE_EXTRA_SPACE)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "image null after H5MM_realloc()")
@@ -7746,15 +7702,11 @@ init_len = len;
/* If the entry could be read speculatively and the length is still
* changing, check for updating the actual size
*/
- if ((type->flags & H5C__CLASS_SPECULATIVE_LOAD_FLAG) && (len_changed)) {
-
+ if ((type->flags & H5C__CLASS_SPECULATIVE_LOAD_FLAG) && len_changed) {
/* Retrieve the actual length */
actual_len = len;
- if (type->get_final_load_size(image, len, udata, &actual_len) < 0) {
-
- /* Transfer control to while() and count towards retries */
- continue;
- }
+ if (type->get_final_load_size(image, len, udata, &actual_len) < 0)
+ continue; /* Transfer control to while() and count towards retries */
/* Check for the length changing */
if (actual_len != len) {
@@ -7774,61 +7726,50 @@ init_len = len;
#ifdef H5_HAVE_PARALLEL
if (!coll_access || 0 == mpi_rank) {
#endif /* H5_HAVE_PARALLEL */
-#if 0 /* JRM */
- /* If the thing's image needs to be bigger for
- * a speculatively loaded thing, go get the
- * on-disk image again (the extra portion).
- */
- if ( H5F_block_read(f, type->mem_type, addr + len,
- actual_len - len, image + len) < 0)
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, \
- "can't read image")
-#else /* JRM */
-
- /* the original version of this code re-read
- * the entire buffer. At some point, someone
- * reworked this code to avoid re-reading the
- * initial portion of the buffer.
- *
- * In addition to being of questionable utility,
- * this optimization changed the invarient that
- * that metadata is read and written atomically.
- * While this didn't cause immediate problems,
- * the page buffer in VFD SWMR depends on this
- * invarient in its management of multi-page
- * metadata entries.
- *
- * To repair this issue, I have reverted to
- * the original algorithm for managing the
- * speculative load case. Note that I have
- * done so crudely -- before merge, we should
- * remove the infrastructure that supports the
- * optimization.
- *
- * We should also verify my impression that the
- * that the optimization is of no measurable
- * value. If it is, we will put it back, but
- * disable it in the VFD SWMR case.
- *
- * While this issue was detected in the global
- * heap case, note that the super bloc, the
- * local heap, and the fractal heap also use
- * speculative loads.
- *
- * JRM -- 3/24/20
- */
-
- H5C__SET_PB_READ_HINTS(f->shared->cache, type, FALSE);
-
- if (H5F_block_read(f, type->mem_type, addr, actual_len, image) < 0) {
- H5C__RESET_PB_READ_HINTS(f->shared->cache)
+ /* the original version of this code re-read
+ * the entire buffer. At some point, someone
+ * reworked this code to avoid re-reading the
+ * initial portion of the buffer.
+ *
+ * In addition to being of questionable utility,
+ * this optimization changed the invariant that
+ * that metadata is read and written atomically.
+ * While this didn't cause immediate problems,
+ * the page buffer in VFD SWMR depends on this
+ * invariant in its management of multi-page
+ * metadata entries.
+ *
+ * To repair this issue, I have reverted to
+ * the original algorithm for managing the
+ * speculative load case. Note that I have
+ * done so crudely -- before merge, we should
+ * remove the infrastructure that supports the
+ * optimization.
+ *
+ * We should also verify my impression that the
+ * that the optimization is of no measurable
+ * value. If it is, we will put it back, but
+ * disable it in the VFD SWMR case.
+ *
+ * While this issue was detected in the global
+ * heap case, note that the super block, the
+ * local heap, and the fractal heap also use
+ * speculative loads.
+ *
+ * JRM -- 3/24/20
+ */
+
+ H5C__SET_PB_READ_HINTS(f->shared->cache, type, FALSE);
+
+ if (H5F_block_read(f, type->mem_type, addr, actual_len, image) < 0) {
+
+ H5C__RESET_PB_READ_HINTS(f->shared->cache)
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "can't read image")
+ }
+ H5C__RESET_PB_READ_HINTS(f->shared->cache)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "can't read image")
- }
- H5C__RESET_PB_READ_HINTS(f->shared->cache)
-#endif /* JRM */
#ifdef H5_HAVE_PARALLEL
}
/* If the collective metadata read optimization is turned on,
@@ -7868,34 +7809,15 @@ init_len = len;
}
/* Check for too many tries */
- if (!do_try) {
-#if 0 /* JRM */
- haddr_t eoa;
- int64_t page = (int64_t)(addr / f->shared->cache->page_size);
-
- eoa = H5F_get_eoa(f, type->mem_type);
-
- HDfprintf(stderr, "addr = 0x%llx, init_len = %lld, len = %lld\n",
- (int64_t)addr, (int64_t)init_len, (int64_t)len);
- HDfprintf(stderr, "type = %s, eoa = 0x%llx, tick = %lld\n",
- type->name, (int64_t)eoa, f->shared->tick_num);
- HDfprintf(stderr, "page = %lld, index_len = %d\n",
- page, f->shared->mdf_idx_entries_used);
- H5FD_vfd_swmr_dump_status(f->shared->lf, page);
-#endif /* JRM */
+ if (!do_try)
HGOTO_ERROR(H5E_CACHE, H5E_READERROR, NULL,
- "incorrect metadata checksum after all read attempts addr %" PRIuHADDR
- " size %zu",
- addr, len);
- }
+ "incorrect metadata checksum after all read attempts addr %" PRIuHADDR " size %zu",
+ addr, len)
- /* Calculate and track the # of retries */
- if ((tries = h5_retry_tries(&retry)) > 1) { /* Does not track 0 retry */
-
- if (H5F_track_metadata_read_retries(f, (unsigned)type->mem_type, tries - 1) < 0)
-
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "cannot track read tries = %u ", tries)
- }
+ /* Calculate and track the # of retries (does not track 0 retries) */
+ if ((tries = H5_retry_tries(&retry)) > 1)
+ if (H5F_track_metadata_read_retries(f, (unsigned)type->mem_type, tries - 1) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "cannot track read tries = %u ", tries)
/* Set the final length (in case it wasn't set earlier) */
len = actual_len;
@@ -8002,14 +7924,10 @@ init_len = len;
entry->tag_info = NULL;
/* initialize fields supporting VFD SWMR */
- if (f->shared->cache->vfd_swmr_reader) {
-
+ if (f->shared->cache->vfd_swmr_reader)
entry->page = (addr / f->shared->cache->page_size);
- }
- else {
-
+ else
entry->page = 0;
- }
entry->refreshed_in_tick = 0;
entry->pi_next = NULL;
entry->pi_prev = NULL;
@@ -8338,7 +8256,7 @@ done:
/*-------------------------------------------------------------------------
*
- * Function: H5C__validate_lru_list
+ * Function: H5C_validate_lru_list
*
* Purpose: Debugging function that scans the LRU list for errors.
*
@@ -8350,23 +8268,21 @@ done:
*
* Programmer: John Mainzer, 7/14/05
*
- * Changes:
- *
- * Added code to verify that the LRU contains no pinned
- * entries. JRM -- 4/25/14
+ * Changes: Added code to verify that the LRU contains no pinned
+ * entries. JRM -- 4/25/14
*
*-------------------------------------------------------------------------
*/
#if H5C_DO_EXTREME_SANITY_CHECKS
-static herr_t
-H5C__validate_lru_list(H5C_t *cache_ptr)
+herr_t
+H5C_validate_lru_list(H5C_t *cache_ptr)
{
int32_t len = 0;
size_t size = 0;
H5C_cache_entry_t *entry_ptr = NULL;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_NOAPI(FAIL)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
@@ -8406,7 +8322,7 @@ H5C__validate_lru_list(H5C_t *cache_ptr)
entry_ptr = entry_ptr->next;
}
- if ((cache_ptr->LRU_list_len != len) || (cache_ptr->LRU_list_size != size))
+ if ((cache_ptr->LRU_list_len != (uint32_t)len) || (cache_ptr->LRU_list_size != size))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 8 failed")
done:
@@ -8414,12 +8330,12 @@ done:
HDassert(0);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__validate_lru_list() */
+} /* H5C_validate_lru_list() */
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/*-------------------------------------------------------------------------
*
- * Function: H5C__validate_pinned_entry_list
+ * Function: H5C_validate_pinned_entry_list
*
* Purpose: Debugging function that scans the pinned entry list for
* errors.
@@ -8432,22 +8348,20 @@ done:
*
* Programmer: John Mainzer, 4/25/14
*
- * Changes:
- *
- * None.
+ * Changes: None
*
*-------------------------------------------------------------------------
*/
#if H5C_DO_EXTREME_SANITY_CHECKS
-static herr_t
-H5C__validate_pinned_entry_list(H5C_t *cache_ptr)
+herr_t
+H5C_validate_pinned_entry_list(H5C_t *cache_ptr)
{
int32_t len = 0;
size_t size = 0;
H5C_cache_entry_t *entry_ptr = NULL;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_NOAPI(FAIL)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
@@ -8490,7 +8404,7 @@ H5C__validate_pinned_entry_list(H5C_t *cache_ptr)
entry_ptr = entry_ptr->next;
}
- if ((cache_ptr->pel_len != len) || (cache_ptr->pel_size != size))
+ if ((cache_ptr->pel_len != (uint32_t)len) || (cache_ptr->pel_size != size))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 9 failed")
done:
@@ -8498,12 +8412,12 @@ done:
HDassert(0);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__validate_pinned_entry_list() */
+} /* H5C_validate_pinned_entry_list() */
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/*-------------------------------------------------------------------------
*
- * Function: H5C__validate_protected_entry_list
+ * Function: H5C_validate_protected_entry_list
*
* Purpose: Debugging function that scans the protected entry list for
* errors.
@@ -8516,22 +8430,20 @@ done:
*
* Programmer: John Mainzer, 4/25/14
*
- * Changes:
- *
- * None.
+ * Changes: None
*
*-------------------------------------------------------------------------
*/
#if H5C_DO_EXTREME_SANITY_CHECKS
-static herr_t
-H5C__validate_protected_entry_list(H5C_t *cache_ptr)
+herr_t
+H5C_validate_protected_entry_list(H5C_t *cache_ptr)
{
int32_t len = 0;
size_t size = 0;
H5C_cache_entry_t *entry_ptr = NULL;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_NOAPI(FAIL)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
@@ -8574,7 +8486,7 @@ H5C__validate_protected_entry_list(H5C_t *cache_ptr)
entry_ptr = entry_ptr->next;
}
- if ((cache_ptr->pl_len != len) || (cache_ptr->pl_size != size))
+ if ((cache_ptr->pl_len != (uint32_t)len) || (cache_ptr->pl_size != size))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 9 failed")
done:
@@ -8582,12 +8494,12 @@ done:
HDassert(0);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__validate_protected_entry_list() */
+} /* H5C_validate_protected_entry_list() */
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/*-------------------------------------------------------------------------
*
- * Function: H5C__entry_in_skip_list
+ * Function: H5C_entry_in_skip_list
*
* Purpose: Debugging function that scans skip list to see if it
* is in present. We need this, as it is possible for
@@ -8598,15 +8510,13 @@ done:
*
* Programmer: John Mainzer, 11/1/14
*
- * Changes:
- *
- * None.
+ * Changes: None
*
*-------------------------------------------------------------------------
*/
#if H5C_DO_SLIST_SANITY_CHECKS
-static hbool_t
-H5C__entry_in_skip_list(H5C_t *cache_ptr, H5C_cache_entry_t *target_ptr)
+hbool_t
+H5C_entry_in_skip_list(H5C_t *cache_ptr, H5C_cache_entry_t *target_ptr)
{
H5SL_node_t *node_ptr;
hbool_t in_slist;
@@ -8634,7 +8544,7 @@ H5C__entry_in_skip_list(H5C_t *cache_ptr, H5C_cache_entry_t *target_ptr)
}
return (in_slist);
-} /* H5C__entry_in_skip_list() */
+} /* H5C_entry_in_skip_list() */
#endif /* H5C_DO_SLIST_SANITY_CHECKS */
/*-------------------------------------------------------------------------
@@ -8703,7 +8613,7 @@ done:
* To cork the object
* Return error if the object is already corked
* H5C__UNCORK:
- * To uncork the obejct
+ * To uncork the object
* Return error if the object is not corked
* H5C__GET_CORKED:
* To retrieve the cork status of an object in
@@ -9124,8 +9034,8 @@ H5C__serialize_cache(H5F_t *f)
#endif /* H5C_DO_SANITY_CHECKS */
#if H5C_DO_EXTREME_SANITY_CHECKS
- if ((H5C__validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C__validate_pinned_entry_list(cache_ptr) < 0) || (H5C__validate_lru_list(cache_ptr) < 0))
+ if ((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
+ (H5C_validate_pinned_entry_list(cache_ptr) < 0) || (H5C_validate_lru_list(cache_ptr) < 0))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -9134,7 +9044,7 @@ H5C__serialize_cache(H5F_t *f)
* each entry in the cache to zero before we start the serialization.
* This allows us to detect the case in which any entry is serialized
* more than once (a performance issues), and more importantly, the
- * case is which any flush depencency parent is serializes more than
+ * case is which any flush dependency parent is serializes more than
* once (a correctness issue).
*/
{
@@ -9291,8 +9201,8 @@ H5C__serialize_ring(H5F_t *f, H5C_ring_t ring)
* are serialized correctly, it doesn't matter if we have to go back
* and serialize an entry a second time.
*
- * These possible actions result in the following modfications to
- * tha basic algorithm:
+ * These possible actions result in the following modifications to
+ * the basic algorithm:
*
* 1) In the event of an entry expunge, eviction or removal, we must
* restart the scan as it is possible that the next entry in our
@@ -9342,7 +9252,7 @@ H5C__serialize_ring(H5F_t *f, H5C_ring_t ring)
* condition appears.
*
* Observe that either eviction or removal of entries as a result of
- * a serialization is not a problem as long as the flush depencency
+ * a serialization is not a problem as long as the flush dependency
* tree does not change beyond the removal of a leaf.
*/
while (!done) {
@@ -9569,7 +9479,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr)
{
haddr_t new_addr = HADDR_UNDEF;
@@ -9578,7 +9488,7 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr)
unsigned serialize_flags = H5C__SERIALIZE_NO_FLAGS_SET;
herr_t ret_value = SUCCEED;
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(f);
@@ -9714,10 +9624,8 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr)
entry_ptr->addr = new_addr;
/* In the VFD SWMR reader case, update the entry page field */
- if (cache_ptr->vfd_swmr_reader) {
-
+ if (cache_ptr->vfd_swmr_reader)
entry_ptr->page = (new_addr / cache_ptr->page_size);
- }
/* And then reinsert in the index and slist */
H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL);
@@ -9896,6 +9804,3 @@ H5C_remove_entry(void *_entry)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__remove_entry() */
-
-/* TEMPORARY (during VFD SWMR sync with develop - reduces churn) */
-/* clang-format on */
diff --git a/src/H5CS.c b/src/H5CS.c
index d7cb6f1..0fabc0d 100644
--- a/src/H5CS.c
+++ b/src/H5CS.c
@@ -47,7 +47,7 @@ typedef struct H5CS_t {
* each thread individually. The association of stacks to threads will
* be handled by the pthread library.
*
- * In order for this macro to work, H5CS_get_my_stack() must be preceeded
+ * In order for this macro to work, H5CS_get_my_stack() must be preceded
* by "H5CS_t *fstack =".
*/
static H5CS_t *H5CS__get_stack(void);
@@ -127,7 +127,7 @@ H5CS__get_stack(void)
herr_t
H5CS_print_stack(const H5CS_t *fstack, FILE *stream)
{
- const int indent = 2; /* Indention level */
+ const int indent = 2; /* Indentation level */
int i; /* Local index ariable */
/* Don't push this function on the function stack... :-) */
diff --git a/src/H5CSprivate.h b/src/H5CSprivate.h
index a238ec7..2dc28f5 100644
--- a/src/H5CSprivate.h
+++ b/src/H5CSprivate.h
@@ -17,10 +17,6 @@
#ifndef H5CSprivate_H
#define H5CSprivate_H
-#ifdef NOT_YET
-#include "H5CSpublic.h"
-#endif /* NOT_YET */
-
/* Private headers needed by this file */
#include "H5private.h"
diff --git a/src/H5CX.c b/src/H5CX.c
index 01bf435..c5bb8e4 100644
--- a/src/H5CX.c
+++ b/src/H5CX.c
@@ -50,7 +50,7 @@
* each thread individually. The association of contexts to threads will
* be handled by the pthread library.
*
- * In order for this macro to work, H5CX_get_my_context() must be preceeded
+ * In order for this macro to work, H5CX_get_my_context() must be preceded
* by "H5CX_node_t *ctx =".
*/
#define H5CX_get_my_context() H5CX__get_context()
@@ -428,9 +428,6 @@ static H5CX_node_t *H5CX__pop_common(hbool_t update_dxpl_props);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*******************/
/* Local Variables */
/*******************/
@@ -463,18 +460,17 @@ H5FL_DEFINE_STATIC(H5CX_node_t);
/* Declare a static free list to manage H5CX_state_t structs */
H5FL_DEFINE_STATIC(H5CX_state_t);
-/*--------------------------------------------------------------------------
-NAME
- H5CX__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5CX__init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
---------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------
+ * Function: H5CX_init
+ *
+ * Purpose: Initialize the interface from some other layer.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5CX__init_package(void)
+H5CX_init(void)
{
H5P_genplist_t *dx_plist; /* Data transfer property list */
H5P_genplist_t *lc_plist; /* Link creation property list */
@@ -484,7 +480,7 @@ H5CX__init_package(void)
H5P_genplist_t *fa_plist; /* File access property list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_NOAPI(FAIL)
/* Reset the "default DXPL cache" information */
HDmemset(&H5CX_def_dxpl_cache, 0, sizeof(H5CX_dxpl_cache_t));
@@ -649,10 +645,9 @@ H5CX__init_package(void)
if (H5P_get(fa_plist, H5F_ACS_LIBVER_HIGH_BOUND_NAME, &H5CX_def_fapl_cache.high_bound) < 0)
HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve dataset minimize flag")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5CX__init_package() */
+}
/*-------------------------------------------------------------------------
* Function: H5CX_term_package
@@ -673,24 +668,20 @@ H5CX_term_package(void)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- H5CX_node_t *cnode; /* Context node */
+ H5CX_node_t *cnode; /* Context node */
- /* Pop the top context node from the stack */
- /* (Can't check for errors, as rest of library is shut down) */
- cnode = H5CX__pop_common(FALSE);
+ /* Pop the top context node from the stack */
+ /* (Can't check for errors, as rest of library is shut down) */
+ cnode = H5CX__pop_common(FALSE);
- /* Free the context node */
- /* (Allocated with HDmalloc() in H5CX_push_special() ) */
- HDfree(cnode);
+ /* Free the context node */
+ /* (Allocated with HDmalloc() in H5CX_push_special() ) */
+ HDfree(cnode);
#ifndef H5_HAVE_THREADSAFE
- H5CX_head_g = NULL;
+ H5CX_head_g = NULL;
#endif /* H5_HAVE_THREADSAFE */
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
-
FUNC_LEAVE_NOAPI(0)
} /* end H5CX_term_package() */
@@ -1227,7 +1218,7 @@ H5CX_set_libver_bounds(H5F_t *f)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -1241,7 +1232,6 @@ H5CX_set_libver_bounds(H5F_t *f)
(*head)->ctx.low_bound_valid = TRUE;
(*head)->ctx.high_bound_valid = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_libver_bounds() */
@@ -1407,9 +1397,7 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass,
/* If parallel is enabled and the file driver used is the MPI-IO
* VFD, issue an MPI barrier for easier debugging if the API function
- * calling this is supposed to be called collectively. Note that this
- * happens only when the environment variable H5_COLL_BARRIER is set
- * to non 0.
+ * calling this is supposed to be called collectively.
*/
if (H5_coll_api_sanity_check_g) {
MPI_Comm mpi_comm; /* File communicator */
@@ -1435,7 +1423,7 @@ done:
* Purpose: Sanity checks and sets up collective operations.
*
* Note: Should be called for all API routines that modify file
- * file metadata but don't pass in an access property list.
+ * metadata but don't pass in an access property list.
*
* Return: Non-negative on success / Negative on failure
*
@@ -1466,9 +1454,7 @@ H5CX_set_loc(hid_t
/* If parallel is enabled and the file driver used is the MPI-IO
* VFD, issue an MPI barrier for easier debugging if the API function
- * calling this is supposed to be called collectively. Note that this
- * happens only when the environment variable H5_COLL_BARRIER is set
- * to non 0.
+ * calling this is supposed to be called collectively.
*/
if (H5_coll_api_sanity_check_g) {
MPI_Comm mpi_comm; /* File communicator */
@@ -1509,7 +1495,7 @@ H5CX_set_vol_wrap_ctx(void *vol_wrap_ctx)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -1521,7 +1507,6 @@ H5CX_set_vol_wrap_ctx(void *vol_wrap_ctx)
/* Mark the value as valid */
(*head)->ctx.vol_wrap_ctx_valid = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_vol_wrap_ctx() */
@@ -1543,7 +1528,7 @@ H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -1555,7 +1540,6 @@ H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop)
/* Mark the value as valid */
(*head)->ctx.vol_connector_prop_valid = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_vol_connector_prop() */
@@ -1637,7 +1621,7 @@ H5CX_get_vol_wrap_ctx(void **vol_wrap_ctx)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
HDassert(vol_wrap_ctx);
@@ -1651,7 +1635,6 @@ H5CX_get_vol_wrap_ctx(void **vol_wrap_ctx)
else
*vol_wrap_ctx = NULL;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_get_vol_wrap_ctx() */
@@ -1673,7 +1656,7 @@ H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
HDassert(vol_connector_prop);
@@ -1687,7 +1670,6 @@ H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop)
else
HDmemset(vol_connector_prop, 0, sizeof(H5VL_connector_prop_t));
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_get_vol_connector_prop() */
@@ -1803,7 +1785,7 @@ H5CX_get_mpi_coll_datatypes(MPI_Datatype *btype, MPI_Datatype *ftype)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
HDassert(btype);
@@ -1815,7 +1797,6 @@ H5CX_get_mpi_coll_datatypes(MPI_Datatype *btype, MPI_Datatype *ftype)
*btype = (*head)->ctx.btype;
*ftype = (*head)->ctx.ftype;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_get_mpi_coll_datatypes() */
@@ -2977,7 +2958,7 @@ H5CX_set_mpi_coll_datatypes(MPI_Datatype btype, MPI_Datatype ftype)
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -2987,7 +2968,6 @@ H5CX_set_mpi_coll_datatypes(MPI_Datatype btype, MPI_Datatype ftype)
(*head)->ctx.btype = btype;
(*head)->ctx.ftype = ftype;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_mpi_coll_datatypes() */
@@ -3009,7 +2989,7 @@ H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -3021,7 +3001,6 @@ H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode)
/* Mark the value as valid */
(*head)->ctx.io_xfer_mode_valid = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_io_xfer_mode() */
@@ -3043,7 +3022,7 @@ H5CX_set_mpio_coll_opt(H5FD_mpio_collective_opt_t mpio_coll_opt)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -3055,7 +3034,6 @@ H5CX_set_mpio_coll_opt(H5FD_mpio_collective_opt_t mpio_coll_opt)
/* Mark the value as valid */
(*head)->ctx.mpio_coll_opt_valid = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_mpio_coll_opt() */
@@ -3135,7 +3113,7 @@ H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -3150,7 +3128,6 @@ H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free
/* Mark the value as valid */
(*head)->ctx.vl_alloc_info_valid = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_vlen_alloc_info() */
@@ -3172,7 +3149,7 @@ H5CX_set_nlinks(size_t nlinks)
H5CX_node_t **head = NULL; /* Pointer to head of API context list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
@@ -3184,7 +3161,6 @@ H5CX_set_nlinks(size_t nlinks)
/* Mark the value as valid */
(*head)->ctx.nlinks_valid = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5CX_set_nlinks() */
diff --git a/src/H5CXprivate.h b/src/H5CXprivate.h
index c500356..878bcf6 100644
--- a/src/H5CXprivate.h
+++ b/src/H5CXprivate.h
@@ -16,11 +16,6 @@
#ifndef H5CXprivate_H
#define H5CXprivate_H
-/* Include package's public header */
-#ifdef NOT_YET
-#include "H5CXpublic.h"
-#endif /* NOT_YET */
-
/* Private headers needed by this file */
#include "H5private.h" /* Generic Functions */
#include "H5ACprivate.h" /* Metadata cache */
@@ -160,6 +155,8 @@ H5_DLL herr_t H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_i
/* "Setter" routines for LAPL properties cached in API context */
H5_DLL herr_t H5CX_set_nlinks(size_t nlinks);
+H5_DLL herr_t H5CX_init(void);
+
/* "Setter" routines for cached DXPL properties that must be returned to application */
#ifdef H5_HAVE_PARALLEL
H5_DLL void H5CX_set_mpio_actual_chunk_opt(H5D_mpio_actual_chunk_opt_mode_t chunk_opt);
diff --git a/src/H5Cdbg.c b/src/H5Cdbg.c
index 7784c3b..58b6bbe 100644
--- a/src/H5Cdbg.c
+++ b/src/H5Cdbg.c
@@ -1012,9 +1012,9 @@ H5C__dump_entry(H5C_t *cache_ptr, const H5C_cache_entry_t *entry_ptr, hbool_t du
* If either the parent or the child is not in the metadata
* cache, the function sets *fd_exists_ptr to FALSE.
*
- * If both are in the cache, the childs list of parents is
+ * If both are in the cache, the child's list of parents is
* searched for the proposed parent. If the proposed parent
- * is found in the childs parent list, the function sets
+ * is found in the child's parent list, the function sets
* *fd_exists_ptr to TRUE. In all other non-error cases,
* the function sets *fd_exists_ptr FALSE.
*
diff --git a/src/H5Cimage.c b/src/H5Cimage.c
index 659382b..bec337b 100644
--- a/src/H5Cimage.c
+++ b/src/H5Cimage.c
@@ -591,7 +591,7 @@ H5C__deserialize_prefetched_entry(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t
*
* Note that at present, dirty can't be set to true with prefetched
* entries. However this may change, so include this functionality
- * against that posibility.
+ * against that possibility.
*
* Also, note that it is possible for a prefetched entry to be dirty --
* hence the value assigned to ds_entry_ptr->is_dirty below.
@@ -862,53 +862,6 @@ H5C__free_image_entries_array(H5C_t *cache_ptr)
} /* H5C__free_image_entries_array() */
/*-------------------------------------------------------------------------
- * Function: H5C_force_cache_image_load()
- *
- * Purpose: On rare occasions, it is necessary to run
- * H5MF_tidy_self_referential_fsm_hack() prior to the first
- * metadata cache access. This is a problem as if there is a
- * cache image at the end of the file, that routine will
- * discard it.
- *
- * We solve this issue by calling this function, which will
- * load the cache image and then call
- * H5MF_tidy_self_referential_fsm_hack() to discard it.
- *
- * Return: SUCCEED on success, and FAIL on failure.
- *
- * Programmer: John Mainzer
- * 1/11/17
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5C_force_cache_image_load(H5F_t *f)
-{
- H5C_t *cache_ptr;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Sanity checks */
- HDassert(f);
- HDassert(f->shared);
- cache_ptr = f->shared->cache;
- HDassert(cache_ptr);
- HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- HDassert(cache_ptr->load_image);
-
- /* Load the cache image, if requested */
- if (cache_ptr->load_image) {
- cache_ptr->load_image = FALSE;
- if (H5C__load_cache_image(f) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, FAIL, "can't load cache image")
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C_force_cache_image_load() */
-
-/*-------------------------------------------------------------------------
* Function: H5C_get_cache_image_config
*
* Purpose: Copy the current configuration for cache image generation
@@ -1192,7 +1145,7 @@ done:
* image superblock extension message must be deleted from
* the superblock extension and the image block freed
*
- * Contrawise, if the file is openened R/O, the metadata
+ * Contrawise, if the file is opened R/O, the metadata
* cache image superblock extension message and image block
* must be left as is. Further, any dirty entries in the
* cache image block must be marked as clean to avoid
@@ -1884,7 +1837,7 @@ done:
* Purpose: Decode the metadata cache image entry from the supplied
* buffer into the supplied instance of H5C_image_entry_t.
* This includes allocating a buffer for the entry image,
- * loading it, and seting ie_ptr->image_ptr to point to
+ * loading it, and setting ie_ptr->image_ptr to point to
* the buffer.
*
* Advances the buffer pointer to the first byte
@@ -2401,7 +2354,7 @@ done:
* also be a flush dependency child.
*
* Finally, note that for purposes of the cache image, flush
- * dependency height ends when a flush dependecy relation
+ * dependency height ends when a flush dependency relation
* passes off the cache image.
*
* On exit, the flush dependency height of each entry in the
@@ -2563,7 +2516,7 @@ H5C__prep_for_file_close__compute_fd_heights(const H5C_t *cache_ptr)
entry_ptr = entry_ptr->il_next;
} /* while (entry_ptr != NULL) */
- /* At present, no extenal parent or child flush dependency links
+ /* At present, no external parent or child flush dependency links
* should exist -- hence the following assertions. This will change
* if we support ageout of entries in the cache image.
*/
@@ -3444,7 +3397,7 @@ done:
* creating if specified.
*
* In general, the size and location of the cache image block
- * will be unknow at the time that the cache image superblock
+ * will be unknown at the time that the cache image superblock
* message is created. A subsequent call to this routine will
* be used to write the correct data.
*
diff --git a/src/H5Cmpio.c b/src/H5Cmpio.c
index 35d8dd0..d127961 100644
--- a/src/H5Cmpio.c
+++ b/src/H5Cmpio.c
@@ -1097,7 +1097,7 @@ done:
*
* Note that this function is a modified version of
* H5C_flush_cache() -- any changes there may need to be
- * reflected here and vise versa.
+ * reflected here and vice versa.
*
* Return: Non-negative on success/Negative on failure.
*
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index 5fc255f..405d03a 100644
--- a/src/H5Cpkg.h
+++ b/src/H5Cpkg.h
@@ -53,7 +53,7 @@
/* Cache configuration settings */
#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */
-#define H5C__PAGE_HASH_TABLE_LEN (4 * 1024) /* must be a poser of 2 */
+#define H5C__PAGE_HASH_TABLE_LEN (4 * 1024) /* must be a power of 2 */
#define H5C__H5C_T_MAGIC 0x005CAC0E
/* Initial allocated size of the "flush_dep_parent" array */
@@ -999,7 +999,7 @@ if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \
*
***********************************************************************/
-/* H5C__HASH_TABLE_LEN is defined in H5Cpkg.h. It must be a power of two. */
+/* H5C__HASH_TABLE_LEN is defined in H5Cpkg.h. It mut be a power of two. */
#define H5C__HASH_MASK ((size_t)(H5C__HASH_TABLE_LEN - 1) << 3)
@@ -1235,7 +1235,7 @@ if ( ( (cache_ptr) == NULL ) || \
( ( !((entry_ptr)->is_dirty ) || \
( (cache_ptr)->dirty_index_size < (new_size) ) ) && \
( ( ((entry_ptr)->is_dirty) ) || \
- ( (cache_ptr)->clean_index_size < (new_size) ) ) ) || \
+ ( (cache_ptr)->clean_index_size < (new_size) ) ) ) || \
( ( (cache_ptr)->index_len == 1 ) && \
( (cache_ptr)->index_size != (new_size) ) ) || \
( (cache_ptr)->index_ring_len[(entry_ptr)->ring] > \
@@ -1510,10 +1510,10 @@ if ( ( (cache_ptr)->index_size != \
H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \
(cache_ptr)->dirty_index_size -= (entry_ptr)->size; \
((cache_ptr)->dirty_index_ring_size[entry_ptr->ring]) \
- -= (entry_ptr)->size; \
+ -= (entry_ptr)->size; \
(cache_ptr)->clean_index_size += (entry_ptr)->size; \
((cache_ptr)->clean_index_ring_size[entry_ptr->ring]) \
- += (entry_ptr)->size; \
+ += (entry_ptr)->size; \
H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \
}
@@ -1522,18 +1522,18 @@ if ( ( (cache_ptr)->index_size != \
H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \
(cache_ptr)->clean_index_size -= (entry_ptr)->size; \
((cache_ptr)->clean_index_ring_size[entry_ptr->ring]) \
- -= (entry_ptr)->size; \
+ -= (entry_ptr)->size; \
(cache_ptr)->dirty_index_size += (entry_ptr)->size; \
((cache_ptr)->dirty_index_ring_size[entry_ptr->ring]) \
- += (entry_ptr)->size; \
+ += (entry_ptr)->size; \
H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \
}
#define H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size, \
- entry_ptr, was_clean) \
+ entry_ptr, was_clean) \
{ \
H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \
- entry_ptr, was_clean) \
+ entry_ptr, was_clean) \
(cache_ptr)->index_size -= (old_size); \
(cache_ptr)->index_size += (new_size); \
((cache_ptr)->index_ring_size[entry_ptr->ring]) -= (old_size); \
@@ -1542,14 +1542,14 @@ if ( ( (cache_ptr)->index_size != \
(cache_ptr)->clean_index_size -= (old_size); \
((cache_ptr)->clean_index_ring_size[entry_ptr->ring])-= (old_size); \
} else { \
- (cache_ptr)->dirty_index_size -= (old_size); \
+ (cache_ptr)->dirty_index_size -= (old_size); \
((cache_ptr)->dirty_index_ring_size[entry_ptr->ring])-= (old_size); \
} \
if((entry_ptr)->is_dirty) { \
(cache_ptr)->dirty_index_size += (new_size); \
((cache_ptr)->dirty_index_ring_size[entry_ptr->ring])+= (new_size); \
} else { \
- (cache_ptr)->clean_index_size += (new_size); \
+ (cache_ptr)->clean_index_size += (new_size); \
((cache_ptr)->clean_index_ring_size[entry_ptr->ring])+= (new_size); \
} \
H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->il_len, \
@@ -1642,7 +1642,7 @@ if ( ( (cache_ptr)->index_size != \
*
* H5C_DO_SLIST_SANITY_CHECKS
*
- * can be selected independantly. This is easy to miss as the
+ * can be selected independently. This is easy to miss as the
* two #defines are easy to confuse.
*/
@@ -1836,7 +1836,7 @@ if ( ( (cache_ptr)->index_size != \
} else { /* slist disabled */ \
\
HDassert( (cache_ptr)->slist_len == 0 ); \
- HDassert( (cache_ptr)->slist_size == 0 ); \
+ HDassert( (cache_ptr)->slist_size == 0 ); \
} \
} /* H5C__REMOVE_ENTRY_FROM_SLIST */
@@ -2078,16 +2078,16 @@ if ( ( (cache_ptr)->index_size != \
/* modified LRU specific code */ \
\
/* remove the entry from the LRU list, and re-insert it at the head.\
- */ \
+ */ \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* Use the dirty flag to infer whether the entry is on the clean or \
@@ -2141,16 +2141,16 @@ if ( ( (cache_ptr)->index_size != \
/* modified LRU specific code */ \
\
/* remove the entry from the LRU list, and re-insert it at the head \
- */ \
+ */ \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* End modified LRU specific code. */ \
@@ -2333,28 +2333,28 @@ if ( ( (cache_ptr)->index_size != \
/* modified LRU specific code */ \
\
/* remove the entry from the LRU list, and re-insert it at the \
- * head. \
- */ \
+ * head. \
+ */ \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* since the entry is being flushed or cleared, one would think \
- * that it must be dirty -- but that need not be the case. Use the \
- * dirty flag to infer whether the entry is on the clean or dirty \
- * LRU list, and remove it. Then insert it at the head of the \
- * clean LRU list. \
+ * that it must be dirty -- but that need not be the case. Use the \
+ * dirty flag to infer whether the entry is on the clean or dirty \
+ * LRU list, and remove it. Then insert it at the head of the \
+ * clean LRU list. \
* \
* The function presumes that a dirty entry will be either cleared \
- * or flushed shortly, so it is OK if we put a dirty entry on the \
- * clean LRU list. \
+ * or flushed shortly, so it is OK if we put a dirty entry on the \
+ * clean LRU list. \
*/ \
\
if ( (entry_ptr)->is_dirty ) { \
@@ -2395,17 +2395,17 @@ if ( ( (cache_ptr)->index_size != \
/* modified LRU specific code */ \
\
/* remove the entry from the LRU list, and re-insert it at the \
- * head. \
- */ \
+ * head. \
+ */ \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* End modified LRU specific code. */ \
@@ -2469,7 +2469,7 @@ if ( ( (cache_ptr)->index_size != \
\
H5C__DLL_APPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* insert the entry at the tail of the clean or dirty LRU list as \
@@ -2510,7 +2510,7 @@ if ( ( (cache_ptr)->index_size != \
(cache_ptr)->pel_tail_ptr, \
(cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
- \
+ \
} else { \
\
/* modified LRU specific code */ \
@@ -2519,7 +2519,7 @@ if ( ( (cache_ptr)->index_size != \
\
H5C__DLL_APPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* End modified LRU specific code. */ \
@@ -2603,7 +2603,7 @@ if ( ( (cache_ptr)->index_size != \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* insert the entry at the head of the clean or dirty LRU list as \
@@ -2644,7 +2644,7 @@ if ( ( (cache_ptr)->index_size != \
(cache_ptr)->pel_tail_ptr, \
(cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
- \
+ \
} else { \
\
/* modified LRU specific code */ \
@@ -2653,7 +2653,7 @@ if ( ( (cache_ptr)->index_size != \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* End modified LRU specific code. */ \
@@ -2722,12 +2722,12 @@ if ( ( (cache_ptr)->index_size != \
HDassert( !((entry_ptr)->is_read_only) ); \
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
HDassert( (entry_ptr)->size > 0 ); \
- \
+ \
if ( (entry_ptr)->is_pinned ) { \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \
- (cache_ptr)->pel_tail_ptr, \
- (cache_ptr)->pel_len, \
+ (cache_ptr)->pel_tail_ptr, \
+ (cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
\
} else { \
@@ -2738,7 +2738,7 @@ if ( ( (cache_ptr)->index_size != \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* Similarly, remove the entry from the clean or dirty LRU list \
@@ -2784,12 +2784,12 @@ if ( ( (cache_ptr)->index_size != \
HDassert( !((entry_ptr)->is_read_only) ); \
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
HDassert( (entry_ptr)->size > 0 ); \
- \
+ \
if ( (entry_ptr)->is_pinned ) { \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \
- (cache_ptr)->pel_tail_ptr, \
- (cache_ptr)->pel_len, \
+ (cache_ptr)->pel_tail_ptr, \
+ (cache_ptr)->pel_len, \
(cache_ptr)->pel_size, (fail_val)) \
\
} else { \
@@ -2800,7 +2800,7 @@ if ( ( (cache_ptr)->index_size != \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* End modified LRU specific code. */ \
@@ -2849,21 +2849,21 @@ if ( ( (cache_ptr)->index_size != \
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
HDassert( (entry_ptr)->size > 0 ); \
\
- if ( ! ( (entry_ptr)->is_pinned ) && ! ( (entry_ptr->is_protected ) ) ) { \
- \
+ if ( ! ( (entry_ptr)->is_pinned ) && ! ( (entry_ptr->is_protected ) ) ) {\
+ \
/* modified LRU specific code */ \
\
/* remove the entry from the LRU list, and re-insert it at the head. \
- */ \
+ */ \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* remove the entry from either the clean or dirty LUR list as \
@@ -2872,7 +2872,7 @@ if ( ( (cache_ptr)->index_size != \
if ( was_dirty ) { \
\
H5C__AUX_DLL_REMOVE((entry_ptr), \
- (cache_ptr)->dLRU_head_ptr, \
+ (cache_ptr)->dLRU_head_ptr, \
(cache_ptr)->dLRU_tail_ptr, \
(cache_ptr)->dLRU_list_len, \
(cache_ptr)->dLRU_list_size, \
@@ -2881,34 +2881,34 @@ if ( ( (cache_ptr)->index_size != \
} else { \
\
H5C__AUX_DLL_REMOVE((entry_ptr), \
- (cache_ptr)->cLRU_head_ptr, \
+ (cache_ptr)->cLRU_head_ptr, \
(cache_ptr)->cLRU_tail_ptr, \
(cache_ptr)->cLRU_list_len, \
(cache_ptr)->cLRU_list_size, \
- (fail_val)) \
+ (fail_val)) \
} \
\
/* insert the entry at the head of either the clean or dirty \
- * LRU list as appropriate. \
+ * LRU list as appropriate. \
*/ \
\
if ( (entry_ptr)->is_dirty ) { \
\
H5C__AUX_DLL_PREPEND((entry_ptr), \
- (cache_ptr)->dLRU_head_ptr, \
+ (cache_ptr)->dLRU_head_ptr, \
(cache_ptr)->dLRU_tail_ptr, \
(cache_ptr)->dLRU_list_len, \
(cache_ptr)->dLRU_list_size, \
- (fail_val)) \
+ (fail_val)) \
\
} else { \
\
H5C__AUX_DLL_PREPEND((entry_ptr), \
- (cache_ptr)->cLRU_head_ptr, \
+ (cache_ptr)->cLRU_head_ptr, \
(cache_ptr)->cLRU_tail_ptr, \
(cache_ptr)->cLRU_list_len, \
(cache_ptr)->cLRU_list_size, \
- (fail_val)) \
+ (fail_val)) \
} \
\
/* End modified LRU specific code. */ \
@@ -2917,7 +2917,7 @@ if ( ( (cache_ptr)->index_size != \
#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */
-#define H5C__UPDATE_RP_FOR_MOVE(cache_ptr, entry_ptr, was_dirty, fail_val) \
+#define H5C__UPDATE_RP_FOR_MOVE(cache_ptr, entry_ptr, was_dirty, fail_val) \
{ \
HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
@@ -2926,21 +2926,21 @@ if ( ( (cache_ptr)->index_size != \
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
HDassert( (entry_ptr)->size > 0 ); \
\
- if ( ! ( (entry_ptr)->is_pinned ) && ! ( (entry_ptr->is_protected ) ) ) { \
- \
+ if ( ! ( (entry_ptr)->is_pinned ) && ! ( (entry_ptr->is_protected ) ) ) {\
+ \
/* modified LRU specific code */ \
\
/* remove the entry from the LRU list, and re-insert it at the head. \
- */ \
+ */ \
\
H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
(cache_ptr)->LRU_tail_ptr, \
- (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_len, \
(cache_ptr)->LRU_list_size, (fail_val)) \
\
/* End modified LRU specific code. */ \
@@ -2997,49 +2997,49 @@ if ( ( (cache_ptr)->index_size != \
\
if ( (entry_ptr)->coll_access ) { \
\
- H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->coll_list_len, \
- (cache_ptr)->coll_list_size, \
- (entry_ptr)->size, \
- (new_size)); \
- \
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->coll_list_len, \
+ (cache_ptr)->coll_list_size, \
+ (entry_ptr)->size, \
+ (new_size)); \
+ \
} \
\
if ( (entry_ptr)->is_pinned ) { \
\
- H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \
- (cache_ptr)->pel_size, \
- (entry_ptr)->size, \
- (new_size)); \
- \
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \
+ (cache_ptr)->pel_size, \
+ (entry_ptr)->size, \
+ (new_size)); \
+ \
} else { \
\
/* modified LRU specific code */ \
\
- /* Update the size of the LRU list */ \
+ /* Update the size of the LRU list */ \
\
- H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \
- (cache_ptr)->LRU_list_size, \
- (entry_ptr)->size, \
- (new_size)); \
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_size, \
+ (entry_ptr)->size, \
+ (new_size)); \
\
/* Similarly, update the size of the clean or dirty LRU list as \
- * appropriate. At present, the entry must be clean, but that \
- * could change. \
+ * appropriate. At present, the entry must be clean, but that \
+ * could change. \
*/ \
\
if ( (entry_ptr)->is_dirty ) { \
\
- H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->dLRU_list_len, \
- (cache_ptr)->dLRU_list_size, \
- (entry_ptr)->size, \
- (new_size)); \
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->dLRU_list_len, \
+ (cache_ptr)->dLRU_list_size, \
+ (entry_ptr)->size, \
+ (new_size)); \
\
} else { \
\
- H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->cLRU_list_len, \
- (cache_ptr)->cLRU_list_size, \
- (entry_ptr)->size, \
- (new_size)); \
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->cLRU_list_len, \
+ (cache_ptr)->cLRU_list_size, \
+ (entry_ptr)->size, \
+ (new_size)); \
} \
\
/* End modified LRU specific code. */ \
@@ -3062,21 +3062,21 @@ if ( ( (cache_ptr)->index_size != \
\
if ( (entry_ptr)->is_pinned ) { \
\
- H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \
- (cache_ptr)->pel_size, \
- (entry_ptr)->size, \
- (new_size)); \
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \
+ (cache_ptr)->pel_size, \
+ (entry_ptr)->size, \
+ (new_size)); \
\
} else { \
\
/* modified LRU specific code */ \
\
- /* Update the size of the LRU list */ \
+ /* Update the size of the LRU list */ \
\
- H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \
- (cache_ptr)->LRU_list_size, \
- (entry_ptr)->size, \
- (new_size)); \
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_size, \
+ (entry_ptr)->size, \
+ (new_size)); \
\
/* End modified LRU specific code. */ \
} \
@@ -3363,7 +3363,7 @@ if ( ( (hd_ptr) == NULL ) || \
( (Size) < (entry_ptr)->size ) || \
( ( (Size) == (entry_ptr)->size ) && ( ! ( (len) == 1 ) ) ) || \
( ( (entry_ptr)->coll_prev == NULL ) && ( (hd_ptr) != (entry_ptr) ) ) || \
- ( ( (entry_ptr)->coll_next == NULL ) && ( (tail_ptr) != (entry_ptr) ) ) || \
+ ( ( (entry_ptr)->coll_next == NULL ) && ( (tail_ptr) != (entry_ptr) ) ) ||\
( ( (len) == 1 ) && \
( ! ( ( (hd_ptr) == (entry_ptr) ) && ( (tail_ptr) == (entry_ptr) ) && \
( (entry_ptr)->coll_next == NULL ) && \
@@ -3395,10 +3395,10 @@ if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \
) \
) { \
HDassert(0 && "COLL DLL sanity check failed"); \
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "COLL DLL sanity check failed") \
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "COLL DLL sanity check failed")\
}
-#define H5C__COLL_DLL_PRE_INSERT_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) \
+#define H5C__COLL_DLL_PRE_INSERT_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv)\
if ( ( (entry_ptr) == NULL ) || \
( (entry_ptr)->coll_next != NULL ) || \
( (entry_ptr)->coll_prev != NULL ) || \
@@ -4664,7 +4664,7 @@ typedef struct H5C_tag_info_t {
* This field exists because the fixed and variable length
* array cache clients allocate numerous entries in a single
* block, and sub-allocate metadata cache entries out of this
- * block. The effect of this is to break the invarient,
+ * block. The effect of this is to break the invariant,
* normally maintained by the free space managers in paged
* allocation mode, that no entry of less than a page in
* size crosses page boundaries, and that entries of page
@@ -4674,7 +4674,7 @@ typedef struct H5C_tag_info_t {
*
* The correct solution is to modify the fixed and variable
* length array cache client to repair this. However, in
- * the interrim, this field exists to detect similar
+ * the interim, this field exists to detect similar
* behaviour elsewhere.
*
* To complicate matters, speculative reads for metadata
@@ -5029,7 +5029,7 @@ typedef struct H5C_tag_info_t {
* This field exists because the fixed and variable length
* array cache clients allocate numerous entries in a single
* block, and sub-allocate metadata cache entries out of this
- * block. The effect of this is to break the invarient,
+ * block. The effect of this is to break the invariant,
* normally maintained by the free space managers in paged
* allocation mode, that no entry of less than a page in
* size crosses page boundaries, and that entries of page
@@ -5039,7 +5039,7 @@ typedef struct H5C_tag_info_t {
*
* The correct solution is to modify the fixed and variable
* length array cache client to repair this. However, in
- * the interrim, this field exists to detect similar
+ * the interim, this field exists to detect similar
* behaviour elsewhere.
*
****************************************************************************/
@@ -5317,7 +5317,6 @@ H5_DLL herr_t H5C__mark_flush_dep_unserialized(H5C_cache_entry_t * entry_ptr);
H5_DLL herr_t H5C__make_space_in_cache(H5F_t * f, size_t space_needed,
hbool_t write_permitted);
H5_DLL herr_t H5C__flush_marked_entries(H5F_t * f);
-H5_DLL herr_t H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr);
H5_DLL herr_t H5C__serialize_cache(H5F_t *f);
H5_DLL herr_t H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global,
H5C_tag_iter_cb_t cb, void *cb_ctx);
diff --git a/src/H5Cprefetched.c b/src/H5Cprefetched.c
index 74573d0..fd5153d 100644
--- a/src/H5Cprefetched.c
+++ b/src/H5Cprefetched.c
@@ -303,7 +303,7 @@ H5C__prefetched_entry_free_icr(void *_thing)
HDassert(entry_ptr->fd_parent_count == 0);
if (entry_ptr->image_ptr != NULL)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "prefetched entry image buffer still attatched?")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "prefetched entry image buffer still attached?")
entry_ptr = H5FL_FREE(H5C_cache_entry_t, entry_ptr);
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index cbc34b2..dad5029 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -213,7 +213,7 @@
#define H5C_DO_TAGGING_SANITY_CHECKS 1
#define H5C_DO_EXTREME_SANITY_CHECKS 0
#else /* NDEBUG */
-/* With rare execptions, the following defines should be set
+/* With rare exceptions, the following defines should be set
* to 0 if NDEBUG is defined
*/
#define H5C_DO_SANITY_CHECKS 0
@@ -879,7 +879,7 @@ typedef struct H5C_t H5C_t;
* managers.
*
* The refresh entry callback exists to address this issue. As
- * indicated above, it is essential for the superblock, and desireable
+ * indicated above, it is essential for the superblock, and desirable
* whenever it is not possible to simply evict an entry that resides
* in a modified page cache page.
*
@@ -1528,7 +1528,7 @@ typedef int H5C_ring_t;
* with no flush dependency children.
*
* Since the image_fd_height is used to order entries in the
- * cache image so that fd parents preceed fd children, for
+ * cache image so that fd parents precede fd children, for
* purposes of this field, and entry is at flush dependency
* level 0 if it either has no children, or if all of its
* children are not in the cache image.
@@ -1643,7 +1643,7 @@ typedef int H5C_ring_t;
* number of times each entry is serialized during cache
* serialization. While no entry should be serialized more than
* once in any serialization call, throw an assertion if any
- * flush depencency parent is serialized more than once during
+ * flush dependency parent is serialized more than once during
* a single cache serialization.
*
* This is a debugging field, and thus is maintained only if
@@ -1680,7 +1680,7 @@ typedef int H5C_ring_t;
*
* refreshed_in_tick: When an entry is refreshed as part of the VFD SWMR
* reader end of tick processing, this field is used to
- * record the tick in which this occured. The field is
+ * record the tick in which this occurred. The field is
* used primarily for sanity checking.
*
* pi_next: Next pointer used by the page index hash table that maps
@@ -1869,7 +1869,7 @@ typedef struct H5C_cache_entry_t {
* with no flush dependency children.
*
* Since the image_fd_height is used to order entries in the
- * cache image so that fd parents preceed fd children, for
+ * cache image so that fd parents precede fd children, for
* purposes of this field, an entry is at flush dependency
* level 0 if it either has no children, or if all of its
* children are not in the cache image.
@@ -2312,7 +2312,7 @@ typedef struct H5C_auto_size_ctl_t {
* equivalent of H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE.
*
* flags: Unsigned integer containing flags controlling which aspects of the
- * cache image functinality is actually executed. The primary impetus
+ * cache image functionality is actually executed. The primary impetus
* behind this field is to allow development of tests for partial
* implementations that will require little if any modification to run
* with the full implementation. In normal operation, all flags should
@@ -2370,10 +2370,9 @@ H5_DLL herr_t H5C_evict_or_refresh_all_entries_in_page(H5F_t *f, uint64_t page,
H5_DLL herr_t H5C_expunge_entry(H5F_t *f, const H5C_class_t *type, haddr_t addr, unsigned flags);
H5_DLL herr_t H5C_flush_cache(H5F_t *f, unsigned flags);
H5_DLL herr_t H5C_flush_tagged_entries(H5F_t *f, haddr_t tag);
-H5_DLL herr_t H5C_force_cache_image_load(H5F_t *f);
H5_DLL herr_t H5C_evict_tagged_entries(H5F_t *f, haddr_t tag, hbool_t match_global);
-H5_DLL herr_t H5C_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags,
- hbool_t type_match);
+H5_DLL herr_t H5C_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags);
+H5_DLL herr_t H5C_expunge_all_tagged_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags);
H5_DLL herr_t H5C_get_tag(const void *thing, /*OUT*/ haddr_t *tag);
#if H5C_DO_TAGGING_SANITY_CHECKS
herr_t H5C_verify_tag(int id, haddr_t tag);
@@ -2434,6 +2433,16 @@ H5_DLL herr_t H5C_cache_image_status(H5F_t *f, hbool_t *load_ci_ptr, hbool_t *
H5_DLL hbool_t H5C_cache_image_pending(const H5C_t *cache_ptr);
H5_DLL herr_t H5C_get_mdc_image_info(const H5C_t *cache_ptr, haddr_t *image_addr, hsize_t *image_len);
+#if H5C_DO_SLIST_SANITY_CHECKS
+H5_DLL hbool_t H5C_entry_in_skip_list(H5C_t *cache_ptr, H5C_cache_entry_t *target_ptr);
+#endif
+
+#if H5C_DO_EXTREME_SANITY_CHECKS
+H5_DLL herr_t H5C_validate_lru_list(H5C_t *cache_ptr);
+H5_DLL herr_t H5C_validate_pinned_entry_list(H5C_t *cache_ptr);
+H5_DLL herr_t H5C_validate_protected_entry_list(H5C_t *cache_ptr);
+#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
+
/* Logging functions */
H5_DLL herr_t H5C_start_logging(H5C_t *cache);
H5_DLL herr_t H5C_stop_logging(H5C_t *cache);
diff --git a/src/H5Cpublic.h b/src/H5Cpublic.h
index 79ece10..c65dc7c 100644
--- a/src/H5Cpublic.h
+++ b/src/H5Cpublic.h
@@ -27,10 +27,6 @@
/* Public headers needed by this file */
#include "H5public.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
enum H5C_cache_incr_mode {
H5C_incr__off,
/**<Automatic cache size increase is disabled, and the remaining increment fields are ignored.*/
@@ -61,7 +57,4 @@ enum H5C_cache_decr_mode {
/**<Automatic cache size decrease is enabled using the ageout with hit rate threshold algorithm.*/
};
-#ifdef __cplusplus
-}
-#endif
#endif
diff --git a/src/H5Cquery.c b/src/H5Cquery.c
index d95dd87..d62c61a 100644
--- a/src/H5Cquery.c
+++ b/src/H5Cquery.c
@@ -201,7 +201,7 @@ H5C_get_cache_hit_rate(const H5C_t *cache_ptr, double *hit_rate_ptr)
if (cache_ptr->cache_accesses > 0)
*hit_rate_ptr = ((double)(cache_ptr->cache_hits)) / ((double)(cache_ptr->cache_accesses));
else
- *hit_rate_ptr = 0.0f;
+ *hit_rate_ptr = 0.0;
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Ctag.c b/src/H5Ctag.c
index a3f04e8..2095cf8 100644
--- a/src/H5Ctag.c
+++ b/src/H5Ctag.c
@@ -72,7 +72,6 @@ typedef struct {
H5F_t * f; /* File pointer for evicting entry */
int type_id; /* Cache entry type to expunge */
unsigned flags; /* Flags for expunging entry */
- hbool_t type_match;
} H5C_tag_iter_ettm_ctx_t;
/* Typedef for tagged entry iterator callback context - mark corked */
@@ -818,7 +817,7 @@ H5C__expunge_tag_type_metadata_cb(H5C_cache_entry_t *entry, void *_ctx)
HDassert(ctx);
/* Found one with the same tag and type id */
- if (entry->type->id == ctx->type_id || !ctx->type_match)
+ if (entry->type->id == ctx->type_id)
if (H5C_expunge_entry(ctx->f, entry->type, entry->addr, ctx->flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, H5_ITER_ERROR, "can't expunge entry")
@@ -841,7 +840,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5C_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags, hbool_t type_match)
+H5C_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags)
{
H5C_t * cache; /* Pointer to cache structure */
H5C_tag_iter_ettm_ctx_t ctx; /* Context for iterator callback */
@@ -858,10 +857,9 @@ H5C_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags
HDassert(cache->magic == H5C__H5C_T_MAGIC);
/* Construct context for iterator callbacks */
- ctx.f = f;
- ctx.type_id = type_id;
- ctx.flags = flags;
- ctx.type_match = type_match;
+ ctx.f = f;
+ ctx.type_id = type_id;
+ ctx.flags = flags;
/* Iterate through hash table entries, expunge those with specified tag and type id */
if (H5C__iter_tagged_entries(cache, tag, FALSE, H5C__expunge_tag_type_metadata_cb, &ctx) < 0)
@@ -873,6 +871,82 @@ done:
/*-------------------------------------------------------------------------
*
+ * Function: H5C__expunge_all_tagged_metadata_cb
+ *
+ * Purpose: Callback for expunging all tagged cache entries
+ *
+ * Return: H5_ITER_ERROR if error is detected, H5_ITER_CONT otherwise.
+ *
+ * Programmer: Dana Robinson
+ * Spring 2022
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5C__expunge_all_tagged_metadata_cb(H5C_cache_entry_t *entry, void *_ctx)
+{
+ H5C_tag_iter_ettm_ctx_t *ctx = (H5C_tag_iter_ettm_ctx_t *)_ctx; /* Get pointer to iterator context */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ /* Function enter macro */
+ FUNC_ENTER_STATIC
+
+ /* Santify checks */
+ HDassert(entry);
+ HDassert(ctx);
+
+ if (H5C_expunge_entry(ctx->f, entry->type, entry->addr, ctx->flags) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, H5_ITER_ERROR, "can't expunge entry")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C__expunge_all_tagged_metadata_cb() */
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5C_expunge_all_tagged_metadata
+ *
+ * Purpose: Expunge all cache entries
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Dana Robinson
+ * Spring 2022
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_expunge_all_tagged_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags)
+{
+ H5C_t * cache; /* Pointer to cache structure */
+ H5C_tag_iter_ettm_ctx_t ctx; /* Context for iterator callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ /* Function enter macro */
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(f);
+ HDassert(f->shared);
+ cache = f->shared->cache; /* Get cache pointer */
+ HDassert(cache != NULL);
+ HDassert(cache->magic == H5C__H5C_T_MAGIC);
+
+ /* Construct context for iterator callbacks */
+ ctx.f = f;
+ ctx.type_id = type_id;
+ ctx.flags = flags;
+
+ /* Iterate through all tagged entries, expunging them */
+ if (H5C__iter_tagged_entries(cache, tag, FALSE, H5C__expunge_all_tagged_metadata_cb, &ctx) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iterated expunging of tagged entries failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_expunge_all_tagged_metadata() */
+
+/*-------------------------------------------------------------------------
+ *
* Function: H5C_get_tag()
*
* Purpose: Get the tag for a metadata cache entry.
diff --git a/src/H5D.c b/src/H5D.c
index 7153c7d..c10b079 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -62,9 +62,6 @@ static herr_t H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], vo
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -1805,7 +1802,7 @@ H5Dset_extent(hid_t dset_id, const hsize_t size[])
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "i*h", dset_id, size);
- /* Change a datset's dimenions synchronously */
+ /* Change a datset's dimensions synchronously */
if ((ret_value = H5D__set_extent_api_common(dset_id, size, NULL, NULL)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to synchronously change a dataset's dimensions")
@@ -1838,7 +1835,7 @@ H5Dset_extent_async(const char *app_file, const char *app_func, unsigned app_lin
if (H5ES_NONE != es_id)
token_ptr = &token; /* Point at token for VOL connector to set up */
- /* Change a datset's dimenions asynchronously */
+ /* Change a datset's dimensions asynchronously */
if (H5D__set_extent_api_common(dset_id, size, token_ptr, &vol_obj) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to asynchronously change a dataset's dimensions")
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index cd54c3a..35916d2 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -239,10 +239,14 @@ typedef struct H5D_chunk_file_iter_ud_t {
#ifdef H5_HAVE_PARALLEL
/* information to construct a collective I/O operation for filling chunks */
-typedef struct H5D_chunk_coll_info_t {
- size_t num_io; /* Number of write operations */
- haddr_t *addr; /* array of the file addresses of the write operation */
-} H5D_chunk_coll_info_t;
+typedef struct H5D_chunk_coll_fill_info_t {
+ size_t num_chunks; /* Number of chunks in the write operation */
+ struct chunk_coll_fill_info {
+ haddr_t addr; /* File address of the chunk */
+ size_t chunk_size; /* Size of the chunk in the file */
+ hbool_t unfiltered_partial_chunk;
+ } * chunk_info;
+} H5D_chunk_coll_fill_info_t;
#endif /* H5_HAVE_PARALLEL */
typedef struct H5D_chunk_iter_ud_t {
@@ -258,14 +262,13 @@ typedef struct H5D_chunk_iter_ud_t {
static herr_t H5D__chunk_construct(H5F_t *f, H5D_t *dset);
static herr_t H5D__chunk_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
static herr_t H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
- H5D_chunk_map_t *fm);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
static herr_t H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_map_t *fm);
static herr_t H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm);
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
static herr_t H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm);
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
static herr_t H5D__chunk_flush(H5D_t *dset);
static herr_t H5D__chunk_io_term(const H5D_chunk_map_t *fm);
static herr_t H5D__chunk_dest(H5D_t *dset);
@@ -290,9 +293,6 @@ static int H5D__chunk_format_convert_cb(const H5D_chunk_rec_t *chunk_rec, void *
/* Helper routines */
static herr_t H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize_t *curr_dims,
const hsize_t *max_dims);
-static void * H5D__chunk_mem_alloc(size_t size, const H5O_pline_t *pline);
-static void * H5D__chunk_mem_xfree(void *chk, const void *pline);
-static void * H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline);
static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last);
static herr_t H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *udata);
static hbool_t H5D__chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_chunk_ud_t *udata);
@@ -309,8 +309,6 @@ static herr_t H5D__chunk_mem_cb(void *elem, const H5T_t *type, unsigned ndims,
static unsigned H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled);
static herr_t H5D__chunk_flush_entry(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t reset);
static herr_t H5D__chunk_cache_evict(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t flush);
-static hbool_t H5D__chunk_is_partial_edge_chunk(unsigned dset_ndims, const uint32_t *chunk_dims,
- const hsize_t *chunk_scaled, const hsize_t *dset_dims);
static void * H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax,
hbool_t prev_unfilt_chunk);
static herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbool_t dirty,
@@ -318,9 +316,9 @@ static herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_
static herr_t H5D__chunk_cache_prune(const H5D_t *dset, size_t size);
static herr_t H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk);
#ifdef H5_HAVE_PARALLEL
-static herr_t H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_info_t *chunk_info,
- size_t chunk_size, const void *fill_buf);
-static int H5D__chunk_cmp_addr(const void *addr1, const void *addr2);
+static herr_t H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_fill_info_t *chunk_fill_info,
+ const void *fill_buf, const void *partial_chunk_fill_buf);
+static int H5D__chunk_cmp_coll_fill_info(const void *_entry1, const void *_entry2);
#endif /* H5_HAVE_PARALLEL */
/* Debugging helper routine callback */
@@ -331,13 +329,24 @@ static int H5D__chunk_dump_index_cb(const H5D_chunk_rec_t *chunk_rec, void *_uda
/*********************/
/* Chunked storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {
- {H5D__chunk_construct, H5D__chunk_init, H5D__chunk_is_space_alloc, H5D__chunk_is_data_cached,
- H5D__chunk_io_init, H5D__chunk_read, H5D__chunk_write,
+const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
+ H5D__chunk_construct, /* construct */
+ H5D__chunk_init, /* init */
+ H5D__chunk_is_space_alloc, /* is_space_alloc */
+ H5D__chunk_is_data_cached, /* is_data_cached */
+ H5D__chunk_io_init, /* io_init */
+ H5D__chunk_read, /* ser_read */
+ H5D__chunk_write, /* ser_write */
#ifdef H5_HAVE_PARALLEL
- H5D__chunk_collective_read, H5D__chunk_collective_write,
-#endif /* H5_HAVE_PARALLEL */
- NULL, NULL, H5D__chunk_flush, H5D__chunk_io_term, H5D__chunk_dest}};
+ H5D__chunk_collective_read, /* par_read */
+ H5D__chunk_collective_write, /* par_write */
+#endif
+ NULL, /* readvv */
+ NULL, /* writevv */
+ H5D__chunk_flush, /* flush */
+ H5D__chunk_io_term, /* io_term */
+ H5D__chunk_dest /* dest */
+}};
/*******************/
/* Local Variables */
@@ -966,7 +975,7 @@ H5D__chunk_init(H5F_t *f, const H5D_t *const dset, hid_t dapl_id)
if (!(scaled_power2up = H5VM_power2up(rdcc->scaled_dims[u])))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
- /* Inital 'power2up' values for scaled dimensions */
+ /* Initial 'power2up' values for scaled dimensions */
rdcc->scaled_power2up[u] = scaled_power2up;
/* Number of bits required to encode scaled dimension size */
@@ -1059,7 +1068,7 @@ H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset)
*/
static herr_t
H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm)
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm)
{
const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
@@ -1090,7 +1099,7 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
* speed up hyperslab calculations by removing the extra checks and/or
* additions involving the offset and the hyperslab selection -QAK)
*/
- if ((file_space_normalized = H5S_hyper_normalize_offset((H5S_t *)file_space, old_offset)) < 0)
+ if ((file_space_normalized = H5S_hyper_normalize_offset(file_space, old_offset)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to normalize selection")
/* Decide the number of chunks in each dimension */
@@ -1354,7 +1363,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static void *
+void *
H5D__chunk_mem_alloc(size_t size, const H5O_pline_t *pline)
{
void *ret_value = NULL; /* Return value */
@@ -1385,7 +1394,7 @@ H5D__chunk_mem_alloc(size_t size, const H5O_pline_t *pline)
*
*-------------------------------------------------------------------------
*/
-static void *
+void *
H5D__chunk_mem_xfree(void *chk, const void *_pline)
{
const H5O_pline_t *pline = (const H5O_pline_t *)_pline;
@@ -1409,7 +1418,7 @@ H5D__chunk_mem_xfree(void *chk, const void *_pline)
* calls H5D__chunk_mem_xfree and discards the return value.
*-------------------------------------------------------------------------
*/
-static void
+void
H5D__chunk_mem_free(void *chk, const void *_pline)
{
(void)H5D__chunk_mem_xfree(chk, _pline);
@@ -1429,7 +1438,7 @@ H5D__chunk_mem_free(void *chk, const void *_pline)
*
*-------------------------------------------------------------------------
*/
-static void *
+void *
H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline)
{
void *ret_value = NULL; /* Return value */
@@ -2251,7 +2260,6 @@ H5D__chunk_file_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type,
/* Set the chunk's scaled coordinates */
H5MM_memcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
chunk_info->scaled[fm->f_ndims] = 0;
- H5MM_memcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
/* Insert the new chunk into the skip list */
if (H5SL_insert(fm->sel_chunks, chunk_info, &chunk_info->index) < 0) {
@@ -2466,8 +2474,7 @@ done:
*/
static herr_t
H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
- const H5S_t H5_ATTR_UNUSED *file_space, const H5S_t H5_ATTR_UNUSED *mem_space,
- H5D_chunk_map_t *fm)
+ H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
{
H5SL_node_t * chunk_node; /* Current node in chunk skip list */
H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */
@@ -2543,7 +2550,7 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
HDassert((H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length > 0) ||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
- /* Check for non-existant chunk & skip it if appropriate */
+ /* Check for non-existent chunk & skip it if appropriate */
if (H5F_addr_defined(udata.chunk_block.offset) || UINT_MAX != udata.idx_hint ||
!skip_missing_chunks) {
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
@@ -2629,8 +2636,7 @@ done:
*/
static herr_t
H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
- const H5S_t H5_ATTR_UNUSED *file_space, const H5S_t H5_ATTR_UNUSED *mem_space,
- H5D_chunk_map_t *fm)
+ H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
{
H5SL_node_t * chunk_node; /* Current node in chunk skip list */
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
@@ -2868,20 +2874,29 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__chunk_io_term() */
-/* Close the given dataset's chunk index, or destroy it if `destroy`
- * is true. A closed index merely releases holds on metadata cache
- * entries; the index can be reopened. Once a dataset's index is
- * destroyed, however, the dataset must not try to use the index, again.
+/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_index_close
+ *
+ * Purpose: Close the given dataset's chunk index, or destroy it if
+ * `destroy` is true. A closed index merely releases holds
+ * on metadata cache entries; the index can be reopened. Once
+ * a dataset's index is
+ * destroyed, however, the dataset must not try to use the
+ * index, again.
+ *
+ * A useful side-effect of closing the chunk index is the
+ * release of pinned/tagged metadata cache entries connected
+ * with the index.
*
- * A useful side-effect of closing the chunk index is the release
- * pinned/tagged metadata cache entries connected with the index.
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
*/
static herr_t
H5D__chunk_index_close(const H5D_t *dset, bool destroy)
{
H5D_chk_idx_info_t idx_info;
H5O_storage_chunk_t * sc = &(dset->shared->layout.storage.u.chunk);
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED;
H5D_chunk_close_func_t fn;
FUNC_ENTER_STATIC
@@ -3211,7 +3226,9 @@ H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udat
unsigned idx = 0; /* Index of chunk in cache, if present */
hbool_t found = FALSE; /* In cache? */
#ifdef H5_HAVE_PARALLEL
- hbool_t reenable_coll_md_reads = FALSE;
+ H5P_coll_md_read_flag_t md_reads_file_flag;
+ hbool_t md_reads_context_flag;
+ hbool_t restore_md_reads_state = FALSE;
#endif
herr_t ret_value = SUCCEED; /* Return value */
@@ -3285,11 +3302,10 @@ H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udat
* processes.
*/
if (H5F_HAS_FEATURE(idx_info.f, H5FD_FEAT_HAS_MPI)) {
- hbool_t do_coll_md_reads = H5CX_get_coll_metadata_read();
- if (do_coll_md_reads) {
- H5CX_set_coll_metadata_read(FALSE);
- reenable_coll_md_reads = TRUE;
- }
+ md_reads_file_flag = H5P_FORCE_FALSE;
+ md_reads_context_flag = FALSE;
+ H5F_set_coll_metadata_reads(idx_info.f, &md_reads_file_flag, &md_reads_context_flag);
+ restore_md_reads_state = TRUE;
}
#endif /* H5_HAVE_PARALLEL */
@@ -3335,8 +3351,8 @@ H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udat
done:
#ifdef H5_HAVE_PARALLEL
/* Re-enable collective metadata reads if we disabled them */
- if (reenable_coll_md_reads)
- H5CX_set_coll_metadata_read(TRUE);
+ if (restore_md_reads_state)
+ H5F_set_coll_metadata_reads(dset->oloc.file, &md_reads_file_flag, &md_reads_context_flag);
#endif /* H5_HAVE_PARALLEL */
FUNC_LEAVE_NOAPI(ret_value)
@@ -3648,7 +3664,7 @@ H5D__chunk_cache_prune(const H5D_t *dset, size_t size)
* traversing the list when pointer pN reaches wN percent of the original
* list. In other words, preemption method N gets to consider entries in
* approximate least recently used order w0 percent before method N+1
- * where 100% means tha method N will run to completion before method N+1
+ * where 100% means the method N will run to completion before method N+1
* begins. The pointers participating in the list traversal are each
* given a chance at preemption before any of the pointers are advanced.
*/
@@ -4352,8 +4368,8 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const
hbool_t blocks_written = FALSE; /* Flag to indicate that chunk was actually written */
hbool_t using_mpi =
FALSE; /* Flag to indicate that the file is being accessed with an MPI-capable file driver */
- H5D_chunk_coll_info_t chunk_info; /* chunk address information for doing I/O */
-#endif /* H5_HAVE_PARALLEL */
+ H5D_chunk_coll_fill_info_t chunk_fill_info; /* chunk address information for doing I/O */
+#endif /* H5_HAVE_PARALLEL */
hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
unsigned space_ndims; /* Dataset's space rank */
const hsize_t * space_dim; /* Dataset's dataspace dimensions */
@@ -4400,8 +4416,8 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const
using_mpi = TRUE;
/* init chunk info stuff for collective I/O */
- chunk_info.num_io = 0;
- chunk_info.addr = NULL;
+ chunk_fill_info.num_chunks = 0;
+ chunk_fill_info.chunk_info = NULL;
} /* end if */
#endif /* H5_HAVE_PARALLEL */
@@ -4673,19 +4689,26 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const
if (using_mpi) {
/* collect all chunk addresses to be written to
write collectively at the end */
- /* allocate/resize address array if no more space left */
- /* Note that if we add support for parallel filters we must
- * also store an array of chunk sizes and pass it to the
- * apporpriate collective write function */
- if (0 == chunk_info.num_io % 1024)
- if (NULL == (chunk_info.addr = (haddr_t *)H5MM_realloc(
- chunk_info.addr, (chunk_info.num_io + 1024) * sizeof(haddr_t))))
+
+ /* allocate/resize chunk info array if no more space left */
+ if (0 == chunk_fill_info.num_chunks % 1024) {
+ void *tmp_realloc;
+
+ if (NULL == (tmp_realloc = H5MM_realloc(chunk_fill_info.chunk_info,
+ (chunk_fill_info.num_chunks + 1024) *
+ sizeof(struct chunk_coll_fill_info))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
- "memory allocation failed for chunk addresses")
+ "memory allocation failed for chunk fill info")
+
+ chunk_fill_info.chunk_info = tmp_realloc;
+ }
- /* Store the chunk's address for later */
- chunk_info.addr[chunk_info.num_io] = udata.chunk_block.offset;
- chunk_info.num_io++;
+ /* Store info about the chunk for later */
+ chunk_fill_info.chunk_info[chunk_fill_info.num_chunks].addr = udata.chunk_block.offset;
+ chunk_fill_info.chunk_info[chunk_fill_info.num_chunks].chunk_size = chunk_size;
+ chunk_fill_info.chunk_info[chunk_fill_info.num_chunks].unfiltered_partial_chunk =
+ (*fill_buf == unfilt_fill_buf);
+ chunk_fill_info.num_chunks++;
/* Indicate that blocks will be written */
blocks_written = TRUE;
@@ -4758,7 +4781,7 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const
#ifdef H5_HAVE_PARALLEL
/* do final collective I/O */
if (using_mpi && blocks_written)
- if (H5D__chunk_collective_fill(dset, &chunk_info, chunk_size, fb_info.fill_buf) < 0)
+ if (H5D__chunk_collective_fill(dset, &chunk_fill_info, fb_info.fill_buf, unfilt_fill_buf) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
#endif /* H5_HAVE_PARALLEL */
@@ -4774,8 +4797,8 @@ done:
unfilt_fill_buf = H5D__chunk_mem_xfree(unfilt_fill_buf, &def_pline);
#ifdef H5_HAVE_PARALLEL
- if (using_mpi && chunk_info.addr)
- H5MM_free(chunk_info.addr);
+ if (using_mpi && chunk_fill_info.chunk_info)
+ H5MM_free(chunk_fill_info.chunk_info);
#endif
FUNC_LEAVE_NOAPI(ret_value)
@@ -4969,27 +4992,35 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_info_t *chunk_info, size_t chunk_size,
- const void *fill_buf)
+H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_fill_info_t *chunk_fill_info,
+ const void *fill_buf, const void *partial_chunk_fill_buf)
{
- MPI_Comm mpi_comm = MPI_COMM_NULL; /* MPI communicator for file */
- int mpi_rank = (-1); /* This process's rank */
- int mpi_size = (-1); /* MPI Comm size */
- int mpi_code; /* MPI return code */
- size_t num_blocks; /* Number of blocks between processes. */
- size_t leftover_blocks; /* Number of leftover blocks to handle */
- int blocks, leftover, block_len; /* converted to int for MPI */
+ MPI_Comm mpi_comm = MPI_COMM_NULL; /* MPI communicator for file */
+ int mpi_rank = (-1); /* This process's rank */
+ int mpi_size = (-1); /* MPI Comm size */
+ int mpi_code; /* MPI return code */
+ size_t num_blocks; /* Number of blocks between processes. */
+ size_t leftover_blocks; /* Number of leftover blocks to handle */
+ int blocks, leftover; /* converted to int for MPI */
MPI_Aint * chunk_disp_array = NULL;
+ MPI_Aint * block_disps = NULL;
int * block_lens = NULL;
MPI_Datatype mem_type = MPI_BYTE, file_type = MPI_BYTE;
H5FD_mpio_xfer_t prev_xfer_mode; /* Previous data xfer mode */
hbool_t have_xfer_mode = FALSE; /* Whether the previous xffer mode has been retrieved */
- hbool_t need_addr_sort = FALSE;
- int i; /* Local index variable */
+ hbool_t need_sort = FALSE;
+ size_t i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
+ /*
+ * If a separate fill buffer is provided for partial chunks, ensure
+ * that the "don't filter partial edge chunks" flag is set.
+ */
+ if (partial_chunk_fill_buf)
+ HDassert(dset->shared->layout.u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS);
+
/* Get the MPI communicator */
if (MPI_COMM_NULL == (mpi_comm = H5F_mpi_get_comm(dset->oloc.file)))
HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI communicator")
@@ -5005,39 +5036,89 @@ H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_info_t *chunk_info,
/* Distribute evenly the number of blocks between processes. */
if (mpi_size == 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "Resulted in division by zero")
- num_blocks = (size_t)(chunk_info->num_io / (size_t)mpi_size); /* value should be the same on all procs */
+ num_blocks =
+ (size_t)(chunk_fill_info->num_chunks / (size_t)mpi_size); /* value should be the same on all procs */
/* After evenly distributing the blocks between processes, are there any
* leftover blocks for each individual process (round-robin)?
*/
- leftover_blocks = (size_t)(chunk_info->num_io % (size_t)mpi_size);
+ leftover_blocks = (size_t)(chunk_fill_info->num_chunks % (size_t)mpi_size);
/* Cast values to types needed by MPI */
H5_CHECKED_ASSIGN(blocks, int, num_blocks, size_t);
H5_CHECKED_ASSIGN(leftover, int, leftover_blocks, size_t);
- H5_CHECKED_ASSIGN(block_len, int, chunk_size, size_t);
/* Check if we have any chunks to write on this rank */
if (num_blocks > 0 || (leftover && leftover > mpi_rank)) {
+ MPI_Aint partial_fill_buf_disp = 0;
+ hbool_t all_same_block_len = TRUE;
+
/* Allocate buffers */
- /* (MSC - should not need block_lens if MPI_type_create_hindexed_block is working) */
- if (NULL == (block_lens = (int *)H5MM_malloc((size_t)(blocks + 1) * sizeof(int))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk lengths buffer")
if (NULL == (chunk_disp_array = (MPI_Aint *)H5MM_malloc((size_t)(blocks + 1) * sizeof(MPI_Aint))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk file displacement buffer")
- for (i = 0; i < blocks; i++) {
- /* store the chunk address as an MPI_Aint */
- chunk_disp_array[i] = (MPI_Aint)(chunk_info->addr[i + (mpi_rank * blocks)]);
+ if (partial_chunk_fill_buf) {
+ MPI_Aint fill_buf_addr;
+ MPI_Aint partial_fill_buf_addr;
+
+ /* Calculate the displacement between the fill buffer and partial chunk fill buffer */
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_address(fill_buf, &fill_buf_addr)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_address failed", mpi_code)
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_address(partial_chunk_fill_buf, &partial_fill_buf_addr)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_address failed", mpi_code)
- /* MSC - should not need this if MPI_type_create_hindexed_block is working */
- block_lens[i] = block_len;
+#if MPI_VERSION >= 3 && MPI_SUBVERSION >= 1
+ partial_fill_buf_disp = MPI_Aint_diff(partial_fill_buf_addr, fill_buf_addr);
+#else
+ partial_fill_buf_disp = partial_fill_buf_addr - fill_buf_addr;
+#endif
- /* Make sure that the addresses in the datatype are
- * monotonically non-decreasing
+ /*
+ * Allocate all-zero block displacements array. If a block's displacement
+ * is left as zero, that block will be written to from the regular fill
+ * buffer. If a block represents an unfiltered partial edge chunk, its
+ * displacement will be set so that the block is written to from the
+ * unfiltered fill buffer.
*/
- if (i && (chunk_disp_array[i] < chunk_disp_array[i - 1]))
- need_addr_sort = TRUE;
+ if (NULL == (block_disps = (MPI_Aint *)H5MM_calloc((size_t)(blocks + 1) * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate block displacements buffer")
+ }
+
+ /*
+ * Perform initial scan of chunk info list to:
+ * - make sure that chunk addresses are monotonically non-decreasing
+ * - check if all blocks have the same length
+ */
+ for (i = 1; i < chunk_fill_info->num_chunks; i++) {
+ if (chunk_fill_info->chunk_info[i].addr < chunk_fill_info->chunk_info[i - 1].addr)
+ need_sort = TRUE;
+
+ if (chunk_fill_info->chunk_info[i].chunk_size != chunk_fill_info->chunk_info[i - 1].chunk_size)
+ all_same_block_len = FALSE;
+ }
+
+ if (need_sort)
+ HDqsort(chunk_fill_info->chunk_info, chunk_fill_info->num_chunks,
+ sizeof(struct chunk_coll_fill_info), H5D__chunk_cmp_coll_fill_info);
+
+ /* Allocate buffer for block lengths if necessary */
+ if (!all_same_block_len)
+ if (NULL == (block_lens = (int *)H5MM_malloc((size_t)(blocks + 1) * sizeof(int))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk lengths buffer")
+
+ for (i = 0; i < (size_t)blocks; i++) {
+ size_t idx = i + (size_t)(mpi_rank * blocks);
+
+ /* store the chunk address as an MPI_Aint */
+ chunk_disp_array[i] = (MPI_Aint)(chunk_fill_info->chunk_info[idx].addr);
+
+ if (!all_same_block_len)
+ H5_CHECKED_ASSIGN(block_lens[i], int, chunk_fill_info->chunk_info[idx].chunk_size, size_t);
+
+ if (chunk_fill_info->chunk_info[idx].unfiltered_partial_chunk) {
+ HDassert(partial_chunk_fill_buf);
+ block_disps[i] = partial_fill_buf_disp;
+ }
} /* end for */
/* Calculate if there are any leftover blocks after evenly
@@ -5045,32 +5126,71 @@ H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_info_t *chunk_info,
* to processes 0 -> leftover.
*/
if (leftover && leftover > mpi_rank) {
- chunk_disp_array[blocks] = (MPI_Aint)chunk_info->addr[(blocks * mpi_size) + mpi_rank];
- if (blocks && (chunk_disp_array[blocks] < chunk_disp_array[blocks - 1]))
- need_addr_sort = TRUE;
- block_lens[blocks] = block_len;
+ chunk_disp_array[blocks] =
+ (MPI_Aint)chunk_fill_info->chunk_info[(blocks * mpi_size) + mpi_rank].addr;
+
+ if (!all_same_block_len)
+ H5_CHECKED_ASSIGN(block_lens[blocks], int,
+ chunk_fill_info->chunk_info[(blocks * mpi_size) + mpi_rank].chunk_size,
+ size_t);
+
+ if (chunk_fill_info->chunk_info[(blocks * mpi_size) + mpi_rank].unfiltered_partial_chunk) {
+ HDassert(partial_chunk_fill_buf);
+ block_disps[blocks] = partial_fill_buf_disp;
+ }
+
blocks++;
}
- /* Ensure that the blocks are sorted in monotonically non-decreasing
- * order of offset in the file.
- */
- if (need_addr_sort)
- HDqsort(chunk_disp_array, (size_t)blocks, sizeof(MPI_Aint), H5D__chunk_cmp_addr);
+ /* Create file and memory types for the write operation */
+ if (all_same_block_len) {
+ int block_len;
+
+ H5_CHECKED_ASSIGN(block_len, int, chunk_fill_info->chunk_info[0].chunk_size, size_t);
+
+ mpi_code =
+ MPI_Type_create_hindexed_block(blocks, block_len, chunk_disp_array, MPI_BYTE, &file_type);
+ if (mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code)
+
+ if (partial_chunk_fill_buf) {
+ /*
+ * If filters are disabled for partial edge chunks, those chunks could
+ * potentially have the same block length as the other chunks, but still
+ * need to be written to using the unfiltered fill buffer. Use an hindexed
+ * block type rather than an hvector.
+ */
+ mpi_code =
+ MPI_Type_create_hindexed_block(blocks, block_len, block_disps, MPI_BYTE, &mem_type);
+ if (mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code)
+ }
+ else {
+ mpi_code = MPI_Type_create_hvector(blocks, block_len, 0, MPI_BYTE, &mem_type);
+ if (mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code)
+ }
+ }
+ else {
+ /*
+ * Currently, different block lengths implies that there are partial
+ * edge chunks and the "don't filter partial edge chunks" flag is set.
+ */
+ HDassert(partial_chunk_fill_buf);
+ HDassert(block_lens);
+ HDassert(block_disps);
+
+ mpi_code = MPI_Type_create_hindexed(blocks, block_lens, chunk_disp_array, MPI_BYTE, &file_type);
+ if (mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
+
+ mpi_code = MPI_Type_create_hindexed(blocks, block_lens, block_disps, MPI_BYTE, &mem_type);
+ if (mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
+ }
- /* MSC - should use this if MPI_type_create_hindexed block is working:
- * mpi_code = MPI_Type_create_hindexed_block(blocks, block_len, chunk_disp_array, MPI_BYTE,
- * &file_type);
- */
- mpi_code = MPI_Type_create_hindexed(blocks, block_lens, chunk_disp_array, MPI_BYTE, &file_type);
- if (mpi_code != MPI_SUCCESS)
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&file_type)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
-
- mpi_code = MPI_Type_create_hvector(blocks, block_len, 0, MPI_BYTE, &mem_type);
- if (mpi_code != MPI_SUCCESS)
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code)
if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&mem_type)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
} /* end if */
@@ -5113,39 +5233,25 @@ done:
if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&mem_type)))
HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
H5MM_xfree(chunk_disp_array);
+ H5MM_xfree(block_disps);
H5MM_xfree(block_lens);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__chunk_collective_fill() */
static int
-H5D__chunk_cmp_addr(const void *addr1, const void *addr2)
+H5D__chunk_cmp_coll_fill_info(const void *_entry1, const void *_entry2)
{
- MPI_Aint _addr1 = (MPI_Aint)0, _addr2 = (MPI_Aint)0;
- int ret_value = 0;
+ const struct chunk_coll_fill_info *entry1;
+ const struct chunk_coll_fill_info *entry2;
FUNC_ENTER_STATIC_NOERR
- _addr1 = *((const MPI_Aint *)addr1);
- _addr2 = *((const MPI_Aint *)addr2);
-
-#if MPI_VERSION >= 3 && MPI_SUBVERSION >= 1
- {
- MPI_Aint diff = MPI_Aint_diff(_addr1, _addr2);
+ entry1 = (const struct chunk_coll_fill_info *)_entry1;
+ entry2 = (const struct chunk_coll_fill_info *)_entry2;
- if (diff < (MPI_Aint)0)
- ret_value = -1;
- else if (diff > (MPI_Aint)0)
- ret_value = 1;
- else
- ret_value = 0;
- }
-#else
- ret_value = (_addr1 > _addr2) - (_addr1 < _addr2);
-#endif
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__chunk_cmp_addr() */
+ FUNC_LEAVE_NOAPI(H5F_addr_cmp(entry1->addr, entry2->addr))
+} /* end H5D__chunk_cmp_coll_fill_info() */
#endif /* H5_HAVE_PARALLEL */
/*-------------------------------------------------------------------------
@@ -5253,7 +5359,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
/* The number of bytes accessed in the chunk */
/* (i.e. the bytes replaced with fill values) */
- H5_CHECK_OVERFLOW(sel_nelmts, hssize_t, uint32_t);
+ H5_CHECK_OVERFLOW(sel_nelmts, hsize_t, uint32_t);
bytes_accessed = (uint32_t)sel_nelmts * layout->u.chunk.dim[rank];
/* Release lock on chunk */
@@ -5998,7 +6104,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
size_t buf_size = udata->buf_size; /* Size of chunk buffer */
const H5O_pline_t *pline = udata->pline; /* I/O pipeline for applying filters */
- /* needed for commpressed variable length data */
+ /* needed for compressed variable length data */
hbool_t must_filter = FALSE; /* Whether chunk must be filtered during copy */
size_t nbytes; /* Size of chunk in file (in bytes) */
H5Z_cb_t filter_cb; /* Filter failure callback struct */
@@ -6729,10 +6835,10 @@ H5D__chunk_stats(const H5D_t *dset, hbool_t headers)
miss_rate = 0.0;
}
if (miss_rate > 100) {
- HDsprintf(ascii, "%7d%%", (int)(miss_rate + 0.5));
+ HDsnprintf(ascii, sizeof(ascii), "%7d%%", (int)(miss_rate + 0.5));
}
else {
- HDsprintf(ascii, "%7.2f%%", miss_rate);
+ HDsnprintf(ascii, sizeof(ascii), "%7.2f%%", miss_rate);
}
HDfprintf(H5DEBUG(AC), " %-18s %8u %8u %7s %8d+%-9ld\n", "raw data chunks", rdcc->stats.nhits,
@@ -6859,7 +6965,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static hbool_t
+hbool_t
H5D__chunk_is_partial_edge_chunk(unsigned dset_ndims, const uint32_t *chunk_dims, const hsize_t scaled[],
const hsize_t *dset_dims)
{
@@ -7154,6 +7260,89 @@ done:
} /* end H5D__chunk_format_convert() */
/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_index_empty_cb
+ *
+ * Purpose: Callback function that simply stops iteration and sets the
+ * `empty` parameter to FALSE if called. If this callback is
+ * entered, it means that the chunk index contains at least
+ * one chunk, so is not empty.
+ *
+ * Return: H5_ITER_STOP
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5D__chunk_index_empty_cb(const H5D_chunk_rec_t H5_ATTR_UNUSED *chunk_rec, void *_udata)
+{
+ hbool_t *empty = (hbool_t *)_udata;
+ int ret_value = H5_ITER_STOP;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ *empty = FALSE;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__chunk_index_empty_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_index_empty
+ *
+ * Purpose: Determines whether a chunk index is empty (has no chunks
+ * inserted into it yet).
+ *
+ * Note: This routine is meant to be a little more performant than
+ * just counting the number of chunks in the index. In the
+ * future, this is probably a callback that the chunk index
+ * ops structure should provide.
+ *
+ * Return: Non-negative on Success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D__chunk_index_empty(const H5D_t *dset, hbool_t *empty)
+{
+ H5D_chk_idx_info_t idx_info; /* Chunked index info */
+ H5D_rdcc_ent_t * ent; /* Cache entry */
+ const H5D_rdcc_t * rdcc = NULL; /* Raw data chunk cache */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr)
+
+ HDassert(dset);
+ HDassert(dset->shared);
+ HDassert(empty);
+
+ rdcc = &(dset->shared->cache.chunk); /* raw data chunk cache */
+ HDassert(rdcc);
+
+ /* Search for cached chunks that haven't been written out */
+ for (ent = rdcc->head; ent; ent = ent->next)
+ /* Flush the chunk out to disk, to make certain the size is correct later */
+ if (H5D__chunk_flush_entry(dset, ent, FALSE) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer")
+
+ /* Compose chunked index info struct */
+ idx_info.f = dset->oloc.file;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
+
+ *empty = TRUE;
+
+ if (H5F_addr_defined(idx_info.storage->idx_addr)) {
+ /* Iterate over the allocated chunks */
+ if ((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__chunk_index_empty_cb, empty) <
+ 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "unable to retrieve allocated chunk information from index")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI_TAG(ret_value)
+} /* end H5D__chunk_index_empty() */
+
+/*-------------------------------------------------------------------------
* Function: H5D__get_num_chunks_cb
*
* Purpose: Callback function that increments the number of written
@@ -7558,7 +7747,7 @@ H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata)
/*-------------------------------------------------------------------------
* Function: H5D__chunk_iter
*
- * Purpose: Iterate over all the chunks in the dataset with given callbak.
+ * Purpose: Iterate over all the chunks in the dataset with given callback.
*
* Return: Success: Non-negative
* Failure: Negative
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index fe41298..356a54e 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -47,6 +47,15 @@
/* Local Typedefs */
/******************/
+/* Callback info for I/O operation when file driver
+ * wishes to do its own memory management
+ */
+typedef struct H5D_compact_iovv_memmanage_ud_t {
+ H5F_shared_t *f_sh; /* Shared file for dataset */
+ void * dstbuf; /* Pointer to buffer to be read into/written into */
+ const void * srcbuf; /* Pointer to buffer to be read from/written from */
+} H5D_compact_iovv_memmanage_ud_t;
+
/********************/
/* Local Prototypes */
/********************/
@@ -55,8 +64,8 @@
static herr_t H5D__compact_construct(H5F_t *f, H5D_t *dset);
static hbool_t H5D__compact_is_space_alloc(const H5O_storage_t *storage);
static herr_t H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
- H5D_chunk_map_t *cm);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
+static herr_t H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata);
static ssize_t H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
@@ -71,13 +80,24 @@ static herr_t H5D__compact_dest(H5D_t *dset);
/*********************/
/* Compact storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {
- {H5D__compact_construct, NULL, H5D__compact_is_space_alloc, NULL, H5D__compact_io_init, H5D__contig_read,
- H5D__contig_write,
+const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{
+ H5D__compact_construct, /* construct */
+ NULL, /* init */
+ H5D__compact_is_space_alloc, /* is_space_alloc */
+ NULL, /* is_data_cached */
+ H5D__compact_io_init, /* io_init */
+ H5D__contig_read, /* ser_read */
+ H5D__contig_write, /* ser_write */
#ifdef H5_HAVE_PARALLEL
- NULL, NULL,
-#endif /* H5_HAVE_PARALLEL */
- H5D__compact_readvv, H5D__compact_writevv, H5D__compact_flush, NULL, H5D__compact_dest}};
+ NULL, /* par_read */
+ NULL, /* par_write */
+#endif
+ H5D__compact_readvv, /* readvv */
+ H5D__compact_writevv, /* writevv */
+ H5D__compact_flush, /* flush */
+ NULL, /* io_term */
+ H5D__compact_dest /* dest */
+}};
/*******************/
/* Local Variables */
@@ -228,8 +248,8 @@ H5D__compact_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
*/
static herr_t
H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
- hsize_t H5_ATTR_UNUSED nelmts, const H5S_t H5_ATTR_UNUSED *file_space,
- const H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
+ hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
+ H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
{
FUNC_ENTER_STATIC_NOERR
@@ -240,6 +260,48 @@ H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR
} /* end H5D__compact_io_init() */
/*-------------------------------------------------------------------------
+ * Function: H5D__compact_iovv_memmanage_cb
+ *
+ * Purpose: Callback operator for H5D__compact_readvv()/_writevv() to
+ * send a memory copy request to the underlying file driver.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata)
+{
+ H5D_compact_iovv_memmanage_ud_t *udata = (H5D_compact_iovv_memmanage_ud_t *)_udata;
+ H5FD_ctl_memcpy_args_t op_args;
+ uint64_t op_flags;
+ H5FD_t * file_handle = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Retrieve pointer to file driver structure for ctl call */
+ if (H5F_shared_get_file_driver(udata->f_sh, &file_handle) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get file handle")
+
+ /* Setup operation flags and arguments */
+ op_flags = H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG | H5FD_CTL__FAIL_IF_UNKNOWN_FLAG;
+
+ op_args.dstbuf = udata->dstbuf;
+ op_args.dst_off = dst_off;
+ op_args.srcbuf = udata->srcbuf;
+ op_args.src_off = src_off;
+ op_args.len = len;
+
+ /* Make request to file driver */
+ if (H5FD_ctl(file_handle, H5FD_CTL__MEM_COPY, op_flags, &op_args, NULL) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_FCNTL, FAIL, "VFD memcpy request failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__compact_iovv_memmanage_cb() */
+
+/*-------------------------------------------------------------------------
* Function: H5D__compact_readvv
*
* Purpose: Reads some data vectors from a dataset into a buffer.
@@ -268,11 +330,28 @@ H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *
HDassert(io_info);
- /* Use the vectorized memory copy routine to do actual work */
- if ((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr,
- io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr,
- dset_offset_arr)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ /* Check if file driver wishes to do its own memory management */
+ if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
+ H5D_compact_iovv_memmanage_ud_t udata;
+
+ /* Set up udata for memory copy operation */
+ udata.f_sh = io_info->f_sh;
+ udata.dstbuf = io_info->u.rbuf;
+ udata.srcbuf = io_info->store->compact.buf;
+
+ /* Request that file driver does the memory copy */
+ if ((ret_value = H5VM_opvv(mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr, dset_max_nseq,
+ dset_curr_seq, dset_size_arr, dset_offset_arr,
+ H5D__compact_iovv_memmanage_cb, &udata)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
+ else {
+ /* Use the vectorized memory copy routine to do actual work */
+ if ((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr,
+ mem_offset_arr, io_info->store->compact.buf, dset_max_nseq,
+ dset_curr_seq, dset_size_arr, dset_offset_arr)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -310,11 +389,28 @@ H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t
HDassert(io_info);
- /* Use the vectorized memory copy routine to do actual work */
- if ((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr,
- dset_offset_arr, io_info->u.wbuf, mem_max_nseq, mem_curr_seq, mem_size_arr,
- mem_offset_arr)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ /* Check if file driver wishes to do its own memory management */
+ if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
+ H5D_compact_iovv_memmanage_ud_t udata;
+
+ /* Set up udata for memory copy operation */
+ udata.f_sh = io_info->f_sh;
+ udata.dstbuf = io_info->store->compact.buf;
+ udata.srcbuf = io_info->u.wbuf;
+
+ /* Request that file driver does the memory copy */
+ if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr, mem_max_nseq,
+ mem_curr_seq, mem_size_arr, mem_offset_arr, H5D__compact_iovv_memmanage_cb,
+ &udata)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
+ else {
+ /* Use the vectorized memory copy routine to do actual work */
+ if ((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq,
+ dset_size_arr, dset_offset_arr, io_info->u.wbuf, mem_max_nseq,
+ mem_curr_seq, mem_size_arr, mem_offset_arr)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+ }
/* Mark the compact dataset's buffer as dirty */
*io_info->store->compact.dirty = TRUE;
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 4dc6f72..3828e8e 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -91,8 +91,7 @@ typedef struct H5D_contig_writevv_ud_t {
static herr_t H5D__contig_construct(H5F_t *f, H5D_t *dset);
static herr_t H5D__contig_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
static herr_t H5D__contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
- H5D_chunk_map_t *cm);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
static ssize_t H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
@@ -109,13 +108,24 @@ static herr_t H5D__contig_write_one(H5D_io_info_t *io_info, hsize_t offset, size
/*********************/
/* Contiguous storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {
- {H5D__contig_construct, H5D__contig_init, H5D__contig_is_space_alloc, H5D__contig_is_data_cached,
- H5D__contig_io_init, H5D__contig_read, H5D__contig_write,
+const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{
+ H5D__contig_construct, /* construct */
+ H5D__contig_init, /* init */
+ H5D__contig_is_space_alloc, /* is_space_alloc */
+ H5D__contig_is_data_cached, /* is_data_cached */
+ H5D__contig_io_init, /* io_init */
+ H5D__contig_read, /* ser_read */
+ H5D__contig_write, /* ser_write */
#ifdef H5_HAVE_PARALLEL
- H5D__contig_collective_read, H5D__contig_collective_write,
-#endif /* H5_HAVE_PARALLEL */
- H5D__contig_readvv, H5D__contig_writevv, H5D__contig_flush, NULL, NULL}};
+ H5D__contig_collective_read, /* par_read */
+ H5D__contig_collective_write, /* par_write */
+#endif
+ H5D__contig_readvv, /* readvv */
+ H5D__contig_writevv, /* writevv */
+ H5D__contig_flush, /* flush */
+ NULL, /* io_term */
+ NULL /* dest */
+}};
/*******************/
/* Local Variables */
@@ -268,9 +278,16 @@ H5D__contig_fill(const H5D_io_info_t *io_info)
if (using_mpi) {
/* Write the chunks out from only one process */
/* !! Use the internal "independent" DXPL!! -QAK */
- if (H5_PAR_META_WRITE == mpi_rank)
- if (H5D__contig_write_one(&ioinfo, offset, size) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset")
+ if (H5_PAR_META_WRITE == mpi_rank) {
+ if (H5D__contig_write_one(&ioinfo, offset, size) < 0) {
+ /* If writing fails, push an error and stop writing, but
+ * still participate in following MPI_Barrier.
+ */
+ blocks_written = TRUE;
+ HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset")
+ break;
+ }
+ }
/* Indicate that blocks are being written */
blocks_written = TRUE;
@@ -550,8 +567,8 @@ H5D__contig_is_data_cached(const H5D_shared_t *shared_dset)
*/
static herr_t
H5D__contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
- hsize_t H5_ATTR_UNUSED nelmts, const H5S_t H5_ATTR_UNUSED *file_space,
- const H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
+ hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
+ H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
{
FUNC_ENTER_STATIC_NOERR
@@ -574,8 +591,8 @@ H5D__contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_
*-------------------------------------------------------------------------
*/
herr_t
-H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
+H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
+ H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
{
herr_t ret_value = SUCCEED; /*return value */
@@ -609,8 +626,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
+H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
+ H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
{
herr_t ret_value = SUCCEED; /*return value */
diff --git a/src/H5Dearray.c b/src/H5Dearray.c
index bef453d..0174a76 100644
--- a/src/H5Dearray.c
+++ b/src/H5Dearray.c
@@ -418,7 +418,7 @@ H5D__earray_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void
HDassert(elmt);
/* Print element */
- HDsprintf(temp_str, "Element #%" PRIuHSIZE ":", idx);
+ HDsnprintf(temp_str, sizeof(temp_str), "Element #%" PRIuHSIZE ":", idx);
HDfprintf(stream, "%*s%-*s %" PRIuHADDR "\n", indent, "", fwidth, temp_str, *(const haddr_t *)elmt);
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -574,7 +574,7 @@ H5D__earray_filt_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const
HDassert(elmt);
/* Print element */
- HDsprintf(temp_str, "Element #%" PRIuHSIZE ":", idx);
+ HDsnprintf(temp_str, sizeof(temp_str), "Element #%" PRIuHSIZE ":", idx);
HDfprintf(stream, "%*s%-*s {%" PRIuHADDR ", %u, %0x}\n", indent, "", fwidth, temp_str, elmt->addr,
elmt->nbytes, elmt->filter_mask);
diff --git a/src/H5Defl.c b/src/H5Defl.c
index 85c9dba..a30955b 100644
--- a/src/H5Defl.c
+++ b/src/H5Defl.c
@@ -62,7 +62,7 @@ typedef struct H5D_efl_writevv_ud_t {
/* Layout operation callbacks */
static herr_t H5D__efl_construct(H5F_t *f, H5D_t *dset);
static herr_t H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *cm);
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
static ssize_t H5D__efl_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
@@ -80,12 +80,24 @@ static herr_t H5D__efl_write(const H5O_efl_t *efl, const H5D_t *dset, haddr_t ad
/*********************/
/* External File List (EFL) storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{H5D__efl_construct, NULL, H5D__efl_is_space_alloc, NULL,
- H5D__efl_io_init, H5D__contig_read, H5D__contig_write,
+const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
+ H5D__efl_construct, /* construct */
+ NULL, /* init */
+ H5D__efl_is_space_alloc, /* is_space_alloc */
+ NULL, /* is_data_cached */
+ H5D__efl_io_init, /* io_init */
+ H5D__contig_read, /* ser_read */
+ H5D__contig_write, /* ser_write */
#ifdef H5_HAVE_PARALLEL
- NULL, NULL,
-#endif /* H5_HAVE_PARALLEL */
- H5D__efl_readvv, H5D__efl_writevv, NULL, NULL, NULL}};
+ NULL, /* par_read */
+ NULL, /* par_write */
+#endif
+ H5D__efl_readvv, /* readvv */
+ H5D__efl_writevv, /* writevv */
+ NULL, /* flush */
+ NULL, /* io_term */
+ NULL /* dest */
+}};
/*******************/
/* Local Variables */
@@ -198,8 +210,8 @@ H5D__efl_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
*/
static herr_t
H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
- hsize_t H5_ATTR_UNUSED nelmts, const H5S_t H5_ATTR_UNUSED *file_space,
- const H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
+ hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
+ H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
{
FUNC_ENTER_STATIC_NOERR
diff --git a/src/H5Dfarray.c b/src/H5Dfarray.c
index 8293ec4..8c031e4 100644
--- a/src/H5Dfarray.c
+++ b/src/H5Dfarray.c
@@ -416,7 +416,7 @@ H5D__farray_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void
HDassert(elmt);
/* Print element */
- HDsprintf(temp_str, "Element #%" PRIuHSIZE ":", idx);
+ HDsnprintf(temp_str, sizeof(temp_str), "Element #%" PRIuHSIZE ":", idx);
HDfprintf(stream, "%*s%-*s %" PRIuHADDR "\n", indent, "", fwidth, temp_str, *(const haddr_t *)elmt);
FUNC_LEAVE_NOAPI(SUCCEED)
diff --git a/src/H5Dfill.c b/src/H5Dfill.c
index fe98487..cec7e8b 100644
--- a/src/H5Dfill.c
+++ b/src/H5Dfill.c
@@ -112,7 +112,7 @@ H5FL_EXTERN(H5S_sel_iter_t);
on each element so that each of them has a copy of the VL data.
--------------------------------------------------------------------------*/
herr_t
-H5D__fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, const H5S_t *space)
+H5D__fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, H5S_t *space)
{
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info */
hbool_t mem_iter_init = FALSE; /* Whether the memory selection iterator has been initialized */
diff --git a/src/H5Dint.c b/src/H5Dint.c
index a287ae8..cc17265 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -139,9 +139,6 @@ static const H5I_class_t H5I_DATASET_CLS[1] = {{
(H5I_free_t)H5D__close_cb /* Callback routine for closing objects of this class */
}};
-/* Flag indicating "top" of interface has been initialized */
-static hbool_t H5D_top_package_initialize_s = FALSE;
-
/* Prefixes of VDS and external file from the environment variables
* HDF5_EXTFILE_PREFIX and HDF5_VDS_PREFIX */
static const char *H5D_prefix_ext_env = NULL;
@@ -160,37 +157,10 @@ static const char *H5D_prefix_vds_env = NULL;
herr_t
H5D_init(void)
{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_init() */
-
-/*--------------------------------------------------------------------------
-NAME
- H5D__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5D__init_package()
-
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
-NOTES
- Care must be taken when using the H5P functions, since they can cause
- a deadlock in the library when the library is attempting to terminate -QAK
-
---------------------------------------------------------------------------*/
-herr_t
-H5D__init_package(void)
-{
H5P_genplist_t *def_dcpl; /* Default Dataset Creation Property list */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI(FAIL)
/* Initialize the ID group for the dataset IDs */
if (H5I_register_type(H5I_DATASET_CLS) < 0)
@@ -220,16 +190,13 @@ H5D__init_package(void)
if (H5P_get(def_dcpl, H5O_CRT_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter")
- /* Mark "top" of interface as initialized, too */
- H5D_top_package_initialize_s = TRUE;
-
/* Retrieve the prefixes of VDS and external file from the environment variable */
H5D_prefix_vds_env = HDgetenv("HDF5_VDS_PREFIX");
H5D_prefix_ext_env = HDgetenv("HDF5_EXTFILE_PREFIX");
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__init_package() */
+} /* end H5D_init() */
/*-------------------------------------------------------------------------
* Function: H5D_top_term_package
@@ -248,38 +215,32 @@ H5D_top_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5D_top_package_initialize_s) {
- if (H5I_nmembers(H5I_DATASET) > 0) {
- /* The dataset API uses the "force" flag set to true because it
- * is using the "file objects" (H5FO) API functions to track open
- * objects in the file. Using the H5FO code means that dataset
- * IDs can have reference counts >1, when an existing dataset is
- * opened more than once. However, the H5I code does not attempt
- * to close objects with reference counts>1 unless the "force" flag
- * is set to true.
- *
- * At some point (probably after the group and datatypes use the
- * the H5FO code), the H5FO code might need to be switched around
- * to storing pointers to the objects being tracked (H5D_t, H5G_t,
- * etc) and reference count those itself instead of relying on the
- * reference counting in the H5I layer. Then, the "force" flag can
- * be put back to false.
- *
- * Setting the "force" flag to true for all the interfaces won't
- * work because the "file driver" (H5FD) APIs use the H5I reference
- * counting to avoid closing a file driver out from underneath an
- * open file...
- *
- * QAK - 5/13/03
- */
- (void)H5I_clear_type(H5I_DATASET, TRUE, FALSE);
- n++; /*H5I*/
- } /* end if */
-
- /* Mark closed */
- if (0 == n)
- H5D_top_package_initialize_s = FALSE;
- } /* end if */
+ if (H5I_nmembers(H5I_DATASET) > 0) {
+ /* The dataset API uses the "force" flag set to true because it
+ * is using the "file objects" (H5FO) API functions to track open
+ * objects in the file. Using the H5FO code means that dataset
+ * IDs can have reference counts >1, when an existing dataset is
+ * opened more than once. However, the H5I code does not attempt
+ * to close objects with reference counts>1 unless the "force" flag
+ * is set to true.
+ *
+ * At some point (probably after the group and datatypes use the
+ * the H5FO code), the H5FO code might need to be switched around
+ * to storing pointers to the objects being tracked (H5D_t, H5G_t,
+ * etc) and reference count those itself instead of relying on the
+ * reference counting in the H5I layer. Then, the "force" flag can
+ * be put back to false.
+ *
+ * Setting the "force" flag to true for all the interfaces won't
+ * work because the "file driver" (H5FD) APIs use the H5I reference
+ * counting to avoid closing a file driver out from underneath an
+ * open file...
+ *
+ * QAK - 5/13/03
+ */
+ (void)H5I_clear_type(H5I_DATASET, TRUE, FALSE);
+ n++; /*H5I*/
+ }
FUNC_LEAVE_NOAPI(n)
} /* end H5D_top_term_package() */
@@ -304,18 +265,11 @@ H5D_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Sanity checks */
- HDassert(0 == H5I_nmembers(H5I_DATASET));
- HDassert(FALSE == H5D_top_package_initialize_s);
-
- /* Destroy the dataset object id group */
- n += (H5I_dec_type_ref(H5I_DATASET) > 0);
+ /* Sanity checks */
+ HDassert(0 == H5I_nmembers(H5I_DATASET));
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Destroy the dataset object id group */
+ n += (H5I_dec_type_ref(H5I_DATASET) > 0);
FUNC_LEAVE_NOAPI(n)
} /* end H5D_term_package() */
@@ -410,7 +364,7 @@ done:
*
* Return:
* Success: Non-negative
- * Failture: Negative
+ * Failure: Negative
*-------------------------------------------------------------------------
*/
herr_t
@@ -424,40 +378,18 @@ H5D__get_space_status(const H5D_t *dset, H5D_space_status_t *allocation)
/* Check for chunked layout */
if (dset->shared->layout.type == H5D_CHUNKED) {
- hsize_t space_allocated; /* The number of bytes allocated for chunks */
- hssize_t snelmts; /* Temporary holder for number of elements in dataspace */
- hsize_t nelmts; /* Number of elements in dataspace */
- size_t dt_size; /* Size of datatype */
- hsize_t full_size; /* The number of bytes in the dataset when fully populated */
-
- /* For chunked layout set the space status by the storage size */
- /* Get the dataset's dataspace */
- HDassert(dset->shared->space);
-
- /* Get the total number of elements in dataset's dataspace */
- if ((snelmts = H5S_GET_EXTENT_NPOINTS(dset->shared->space)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve number of elements in dataspace")
- nelmts = (hsize_t)snelmts;
-
- /* Get the size of the dataset's datatype */
- if (0 == (dt_size = H5T_GET_SIZE(dset->shared->type)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve size of datatype")
-
- /* Compute the maximum size of the dataset in bytes */
- full_size = nelmts * dt_size;
-
- /* Check for overflow during multiplication */
- if (nelmts != (full_size / dt_size))
- HGOTO_ERROR(H5E_DATASET, H5E_OVERFLOW, FAIL, "size of dataset's storage overflowed")
-
- /* Difficult to error check, since the error value is 0 and 0 is a valid value... :-/ */
- if (H5D__get_storage_size(dset, &space_allocated) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get size of dataset's storage")
-
- /* Decide on how much of the space is allocated */
- if (space_allocated == 0)
+ hsize_t n_chunks_total = dset->shared->layout.u.chunk.nchunks;
+ hsize_t n_chunks_alloc = 0;
+
+ if (H5D__get_num_chunks(dset, dset->shared->space, &n_chunks_alloc) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "unable to retrieve number of allocated chunks in dataset")
+
+ HDassert(n_chunks_alloc <= n_chunks_total);
+
+ if (n_chunks_alloc == 0)
*allocation = H5D_SPACE_STATUS_NOT_ALLOCATED;
- else if (space_allocated == full_size)
+ else if (n_chunks_alloc == n_chunks_total)
*allocation = H5D_SPACE_STATUS_ALLOCATED;
else
*allocation = H5D_SPACE_STATUS_PART_ALLOCATED;
@@ -757,7 +689,7 @@ H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr)
H5T_t * type = NULL;
H5O_fill_t *fill_prop = NULL;
hbool_t use_at_least_v18 = FALSE;
- const char continuation[1] = ""; /* requred for work-around */
+ const char continuation[1] = ""; /* required for work-around */
size_t get_value = 0;
size_t ret_value = 0;
@@ -804,7 +736,7 @@ H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't get size of continuation message")
ret_value += get_value;
- /* Fill Value (backwards compatability) message size */
+ /* Fill Value (backwards compatibility) message size */
if (fill_prop->buf && !use_at_least_v18) {
H5O_fill_t old_fill_prop; /* Copy for writing "old" fill value */
@@ -893,7 +825,7 @@ H5D__prepare_minimized_oh(H5F_t *file, H5D_t *dset, H5O_loc_t *oloc)
if (ohdr_size == 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "computed header size is invalid")
- /* Special allocation of space for compact datsets is handled by the call here. */
+ /* Special allocation of space for compact datasets is handled by the call here. */
if (H5O_apply_ohdr(file, oh, dset->shared->dcpl_id, ohdr_size, (size_t)1, oloc) == FAIL)
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "can't apply object header to file")
@@ -1347,10 +1279,19 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest indexing")
} /* end if */
- /* Check if this dataset is going into a parallel file and set space allocation time */
+ /* Check if the file driver would like to force early space allocation */
if (H5F_HAS_FEATURE(file, H5FD_FEAT_ALLOCATE_EARLY))
new_dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY;
+ /*
+ * Check if this dataset is going into a parallel file and set space allocation time.
+ * If the dataset has filters applied to it, writes to the dataset must be collective,
+ * so we don't need to force early space allocation. Otherwise, we force early space
+ * allocation to facilitate independent raw data operations.
+ */
+ if (H5F_HAS_FEATURE(file, H5FD_FEAT_HAS_MPI) && (new_dset->shared->dcpl_cache.pline.nused == 0))
+ new_dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY;
+
/* Set the dataset's I/O operations */
if (H5D__layout_set_io_ops(new_dset) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize I/O operations")
@@ -3433,7 +3374,7 @@ done:
/* Expunge from cache all v1 B-tree type entries associated with tag */
if (H5AC_expunge_tag_type_metadata(dataset->oloc.file, dataset->oloc.addr, H5AC_BT_ID,
- H5AC__NO_FLAGS_SET, TRUE))
+ H5AC__NO_FLAGS_SET))
HDONE_ERROR(H5E_DATASET, H5E_CANTEXPUNGE, FAIL, "unable to expunge index metadata")
} /* end if */
diff --git a/src/H5Dio.c b/src/H5Dio.c
index d1861c4..e226a0a 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -82,8 +82,7 @@ H5FL_DEFINE(H5D_chunk_map_t);
*-------------------------------------------------------------------------
*/
herr_t
-H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space,
- void *buf /*out*/)
+H5D__read(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space, void *buf /*out*/)
{
H5D_chunk_map_t *fm = NULL; /* Chunk file<->memory mapping */
H5D_io_info_t io_info; /* Dataset I/O info */
@@ -166,7 +165,7 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t
* difficulties with the notion.
*
* To solve this, we check to see if H5S_select_shape_same() returns true,
- * and if the ranks of the mem and file spaces are different. If the are,
+ * and if the ranks of the mem and file spaces are different. If they are,
* construct a new mem space that is equivalent to the old mem space, and
* use that instead.
*
@@ -295,13 +294,13 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space,
- const void *buf)
+H5D__write(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space, const void *buf)
{
H5D_chunk_map_t *fm = NULL; /* Chunk file<->memory mapping */
H5D_io_info_t io_info; /* Dataset I/O info */
H5D_type_info_t type_info; /* Datatype info for operation */
hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */
+ hbool_t should_alloc_space = FALSE; /* Whether or not to initialize dataset's storage */
H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */
/* projection of the supplied mem_space to a new */
/* dataspace with rank equal to that of */
@@ -434,8 +433,20 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up I/O operation")
/* Allocate dataspace and initialize it if it hasn't been. */
- if (nelmts > 0 && dataset->shared->dcpl_cache.efl.nused == 0 &&
- !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)) {
+ should_alloc_space = dataset->shared->dcpl_cache.efl.nused == 0 &&
+ !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage);
+
+ /*
+ * If not using an MPI-based VFD, we only need to allocate
+ * and initialize storage if there's a selection in the
+ * dataset's dataspace. Otherwise, we always need to participate
+ * in the storage allocation since this may use collective
+ * operations and we will hang if we don't participate.
+ */
+ if (!H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_HAS_MPI))
+ should_alloc_space = should_alloc_space && (nelmts > 0);
+
+ if (should_alloc_space) {
hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
hbool_t full_overwrite; /* Whether we are over-writing all the elements */
@@ -810,86 +821,35 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_
io_info->io_ops.single_write = H5D__mpio_select_write;
} /* end if */
else {
- int comm_size = 0;
-
- /* Retrieve size of MPI communicator used for file */
- if ((comm_size = H5F_shared_mpi_get_size(io_info->f_sh)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator size")
-
/* Check if there are any filters in the pipeline. If there are,
* we cannot break to independent I/O if this is a write operation
* with multiple ranks involved; otherwise, there will be metadata
* inconsistencies in the file.
*/
- if (comm_size > 1 && io_info->op_type == H5D_IO_OP_WRITE &&
- io_info->dset->shared->dcpl_cache.pline.nused > 0) {
- H5D_mpio_no_collective_cause_t cause;
- uint32_t local_no_collective_cause;
- uint32_t global_no_collective_cause;
- hbool_t local_error_message_previously_written = FALSE;
- hbool_t global_error_message_previously_written = FALSE;
- size_t idx;
- size_t cause_strings_len;
- char local_no_collective_cause_string[512] = "";
- char global_no_collective_cause_string[512] = "";
- const char * cause_strings[] = {
- "independent I/O was requested",
- "datatype conversions were required",
- "data transforms needed to be applied",
- "optimized MPI types flag wasn't set",
- "one of the dataspaces was neither simple nor scalar",
- "dataset was not contiguous or chunked",
- "parallel writes to filtered datasets are disabled",
- "an error occurred while checking if collective I/O was possible"};
-
- cause_strings_len = sizeof(cause_strings) / sizeof(cause_strings[0]);
-
- if (H5CX_get_mpio_local_no_coll_cause(&local_no_collective_cause) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
- "unable to get local no collective cause value")
- if (H5CX_get_mpio_global_no_coll_cause(&global_no_collective_cause) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
- "unable to get global no collective cause value")
-
- /* Append each of the "reason for breaking collective I/O" error messages to the
- * local and global no collective cause strings */
- for (cause = 1, idx = 0;
- (cause < H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE) && (idx < cause_strings_len);
- cause <<= 1, idx++) {
- size_t cause_strlen = HDstrlen(cause_strings[idx]);
-
- if (cause & local_no_collective_cause) {
- /* Check if there were any previous error messages included. If so, prepend a
- * semicolon to separate the messages.
- */
- if (local_error_message_previously_written)
- HDstrncat(local_no_collective_cause_string, "; ", 2);
-
- HDstrncat(local_no_collective_cause_string, cause_strings[idx], cause_strlen);
-
- local_error_message_previously_written = TRUE;
- } /* end if */
-
- if (cause & global_no_collective_cause) {
- /* Check if there were any previous error messages included. If so, prepend a
- * semicolon to separate the messages.
- */
- if (global_error_message_previously_written)
- HDstrncat(global_no_collective_cause_string, "; ", 2);
-
- HDstrncat(global_no_collective_cause_string, cause_strings[idx], cause_strlen);
-
- global_error_message_previously_written = TRUE;
- } /* end if */
- } /* end for */
-
- HGOTO_ERROR(H5E_IO, H5E_NO_INDEPENDENT, FAIL,
- "Can't perform independent write with filters in pipeline.\n"
- " The following caused a break from collective I/O:\n"
- " Local causes: %s\n"
- " Global causes: %s",
- local_no_collective_cause_string, global_no_collective_cause_string);
- } /* end if */
+ if (io_info->op_type == H5D_IO_OP_WRITE && io_info->dset->shared->dcpl_cache.pline.nused > 0) {
+ int comm_size = 0;
+
+ /* Retrieve size of MPI communicator used for file */
+ if ((comm_size = H5F_shared_mpi_get_size(io_info->f_sh)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator size")
+
+ if (comm_size > 1) {
+ char local_no_coll_cause_string[512];
+ char global_no_coll_cause_string[512];
+
+ if (H5D__mpio_get_no_coll_cause_strings(local_no_coll_cause_string, 512,
+ global_no_coll_cause_string, 512) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "can't get reasons for breaking collective I/O")
+
+ HGOTO_ERROR(H5E_IO, H5E_NO_INDEPENDENT, FAIL,
+ "Can't perform independent write with filters in pipeline.\n"
+ " The following caused a break from collective I/O:\n"
+ " Local causes: %s\n"
+ " Global causes: %s",
+ local_no_coll_cause_string, global_no_coll_cause_string);
+ }
+ }
/* If we won't be doing collective I/O, but the user asked for
* collective I/O, change the request to use independent I/O
diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c
index 6c4fc12..6fdec05 100644
--- a/src/H5Dlayout.c
+++ b/src/H5Dlayout.c
@@ -213,7 +213,7 @@ H5D__layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t includ
ret_value++;
/* Dimension sizes */
- ret_value += layout->u.chunk.ndims * layout->u.chunk.enc_bytes_per_dim;
+ ret_value += layout->u.chunk.ndims * (size_t)layout->u.chunk.enc_bytes_per_dim;
/* Type of chunk index */
ret_value++;
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index 448e92d..8577001 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -36,6 +36,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* File access */
#include "H5FDprivate.h" /* File drivers */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
@@ -43,6 +44,15 @@
#include "H5Sprivate.h" /* Dataspaces */
#include "H5VMprivate.h" /* Vector */
+/* uthash is an external, header-only hash table implementation.
+ *
+ * We include the file directly in src/ and #define a few functions
+ * to use our internal memory calls.
+ */
+#define uthash_malloc(sz) H5MM_malloc(sz)
+#define uthash_free(ptr, sz) H5MM_free(ptr) /* Ignoring sz is intentional */
+#include "uthash.h"
+
#ifdef H5_HAVE_PARALLEL
/****************/
@@ -81,9 +91,54 @@
/* Macros to represent the regularity of the selection for multiple chunk IO case. */
#define H5D_CHUNK_SELECT_REG 1
+/*
+ * Threshold value for redistributing shared filtered chunks
+ * on all MPI ranks, or just MPI rank 0
+ */
+#define H5D_CHUNK_REDISTRIBUTE_THRES ((size_t)((25 * H5_MB) / sizeof(H5D_chunk_redistribute_info_t)))
+
+/*
+ * Initial allocation size for the arrays that hold
+ * buffers for chunk modification data that is sent
+ * to other ranks and the MPI_Request objects for
+ * those send operations
+ */
+#define H5D_CHUNK_NUM_SEND_MSGS_INIT 64
+
+/*
+ * Define a tag value for the MPI messages sent/received for
+ * chunk modification data
+ */
+#define H5D_CHUNK_MOD_DATA_TAG 64
+
+/*
+ * Macro to initialize a H5D_chk_idx_info_t
+ * structure, given a pointer to a H5D_io_info_t
+ * structure
+ */
+#define H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, io_info_ptr) \
+ do { \
+ index_info.f = (io_info_ptr)->dset->oloc.file; \
+ index_info.pline = &((io_info_ptr)->dset->shared->dcpl_cache.pline); \
+ index_info.layout = &((io_info_ptr)->dset->shared->layout.u.chunk); \
+ index_info.storage = &((io_info_ptr)->dset->shared->layout.storage.u.chunk); \
+ } while (0)
+
+/*
+ * Macro to initialize a H5D_chunk_ud_t structure
+ * given a pointer to a H5D_chk_idx_info_t structure
+ */
+#define H5D_MPIO_INIT_CHUNK_UD_INFO(chunk_ud, index_info_ptr) \
+ do { \
+ HDmemset(&chunk_ud, 0, sizeof(H5D_chunk_ud_t)); \
+ chunk_ud.common.layout = (index_info_ptr)->layout; \
+ chunk_ud.common.storage = (index_info_ptr)->storage; \
+ } while (0)
+
/******************/
/* Local Typedefs */
/******************/
+
/* Combine chunk address and chunk info into a struct for better performance. */
typedef struct H5D_chunk_addr_info_t {
haddr_t chunk_addr;
@@ -100,115 +155,137 @@ typedef enum H5D_mpio_no_rank0_bcast_cause_t {
} H5D_mpio_no_rank0_bcast_cause_t;
/*
+ * Information necessary for re-allocating file space for a chunk
+ * during a parallel write of a chunked dataset with filters
+ * applied.
+ */
+typedef struct H5D_chunk_alloc_info_t {
+ H5F_block_t chunk_current;
+ H5F_block_t chunk_new;
+ hsize_t chunk_idx;
+} H5D_chunk_alloc_info_t;
+
+/*
+ * Information for a chunk pertaining to the dataset's chunk
+ * index entry for the chunk
+ */
+typedef struct H5D_chunk_index_info_t {
+ hsize_t chunk_idx;
+ unsigned filter_mask;
+ hbool_t need_insert;
+} H5D_chunk_index_info_t;
+
+/*
* Information about a single chunk when performing collective filtered I/O. All
* of the fields of one of these structs are initialized at the start of collective
- * filtered I/O in the function H5D__construct_filtered_io_info_list().
+ * filtered I/O in the function H5D__mpio_collective_filtered_chunk_io_setup(). This
+ * struct's fields are as follows:
*
- * This struct's fields are as follows:
+ * index_info - A structure containing the information needed when collectively
+ * re-inserting the chunk into the dataset's chunk index. The structure
+ * is distributed to all ranks during the re-insertion operation. Its fields
+ * are as follows:
*
- * index - The "Index" of the chunk in the dataset. The index of a chunk is used during
- * the collective re-insertion of chunks into the chunk index after the collective
- * I/O has been performed.
+ * chunk_idx - The index of the chunk in the dataset's chunk index.
*
- * scaled - The scaled coordinates of the chunk in the dataset's file dataspace. The
- * coordinates are used in both the collective re-allocation of space in the file
- * and the collective re-insertion of chunks into the chunk index after the collective
- * I/O has been performed.
+ * filter_mask - A bit-mask that indicates which filters are to be applied to the
+ * chunk. Each filter in a chunk's filter pipeline has a bit position
+ * that can be masked to disable that particular filter for the chunk.
+ * This filter mask is saved alongside the chunk in the file.
*
- * full_overwrite - A flag which determines whether or not a chunk needs to be read from the
- * file when being updated. If a chunk is being fully overwritten (the entire
- * extent is selected in its file dataspace), then it is not necessary to
- * read the chunk from the file. However, if the chunk is not being fully
- * overwritten, it has to be read from the file in order to update the chunk
- * without trashing the parts of the chunk that are not selected.
+ * need_insert - A flag which determines whether or not a chunk needs to be re-inserted into
+ * the chunk index after the write operation.
*
- * num_writers - The total number of processors writing to this chunk. This field is used
- * when the new owner of a chunk is receiving messages, which contain selections in
- * the chunk and data to update the chunk with, from other processors which have this
- * chunk selected in the I/O operation. The new owner must know how many processors it
- * should expect messages from so that it can post an equal number of receive calls.
+ * chunk_info - A pointer to the chunk's H5D_chunk_info_t structure, which contains useful
+ * information like the dataspaces containing the selection in the chunk.
*
- * io_size - The total size of I/O to this chunk. This field is an accumulation of the size of
- * I/O to the chunk from each processor which has the chunk selected and is used to
- * determine the value for the previous full_overwrite flag.
+ * chunk_current - The address in the file and size of this chunk before the filtering
+ * operation. When reading a chunk from the file, this field is used to
+ * read the correct amount of bytes. It is also used when redistributing
+ * shared chunks among MPI ranks and as a parameter to the chunk file
+ * space reallocation function.
*
- * buf - A pointer which serves the dual purpose of holding either the chunk data which is to be
- * written to the file or the chunk data which has been read from the file.
+ * chunk_new - The address in the file and size of this chunk after the filtering
+ * operation. This field is relevant when collectively re-allocating space
+ * in the file for all of the chunks written to in the I/O operation, as
+ * their sizes may have changed after their data has been filtered.
*
- * chunk_states - In the case of dataset writes only, this struct is used to track a chunk's size and
- * address in the file before and after the filtering operation has occurred.
+ * need_read - A flag which determines whether or not a chunk needs to be read from the
+ * file. During writes, if a chunk is being fully overwritten (the entire extent
+ * is selected in its file dataspace), then it is not necessary to read the chunk
+ * from the file. However, if the chunk is not being fully overwritten, it has to
+ * be read from the file in order to update the chunk without trashing the parts
+ * of the chunk that are not selected. During reads, this field should generally
+ * be true, but may be false if the chunk isn't allocated, for example.
*
- * Its fields are as follows:
+ * skip_filter_pline - A flag which determines whether to skip calls to the filter pipeline
+ * for this chunk. This flag is mostly useful for correct handling of
+ * partial edge chunks when the "don't filter partial edge chunks" flag
+ * is set on the dataset's DCPL.
*
- * chunk_current - The address in the file and size of this chunk before the filtering
- * operation. When reading a chunk from the file, this field is used to
- * read the correct amount of bytes. It is also used when redistributing
- * shared chunks among processors and as a parameter to the chunk file
- * space reallocation function.
+ * io_size - The total size of I/O to this chunk. This field is an accumulation of the size of
+ * I/O to the chunk from each MPI rank which has the chunk selected and is used to
+ * determine the value for the previous `full_overwrite` flag.
*
- * new_chunk - The address in the file and size of this chunk after the filtering
- * operation. This field is relevant when collectively re-allocating space
- * in the file for all of the chunks written to in the I/O operation, as
- * their sizes may have changed after their data has been filtered.
+ * chunk_buf_size - The size in bytes of the data buffer allocated for the chunk
*
- * owners - In the case of dataset writes only, this struct is used to manage which single processor
- * will ultimately write data out to the chunk. It allows the other processors to act according
- * to the decision and send their selection in the chunk, as well as the data they wish
- * to update the chunk with, to the processor which is writing to the chunk.
+ * orig_owner - The MPI rank which originally had this chunk selected at the beginning of
+ * the collective filtered I/O operation. This field is currently used when
+ * redistributing shared chunks among MPI ranks.
*
- * Its fields are as follows:
+ * new_owner - The MPI rank which has been selected to perform the modifications to this chunk.
*
- * original_owner - The processor which originally had this chunk selected at the beginning of
- * the collective filtered I/O operation. This field is currently used when
- * redistributing shared chunks among processors.
+ * num_writers - The total number of MPI ranks writing to this chunk. This field is used when
+ * the new owner of a chunk is receiving messages from other MPI ranks that
+ * contain their selections in the chunk and the data to update the chunk with.
+ * The new owner must know how many MPI ranks it should expect messages from so
+ * that it can post an equal number of receive calls.
*
- * new_owner - The processor which has been selected to perform the write to this chunk.
+ * buf - A pointer which serves the dual purpose of holding either the chunk data which is to be
+ * written to the file or the chunk data which has been read from the file.
*
- * async_info - In the case of dataset writes only, this struct is used by the owning processor of the
- * chunk in order to manage the MPI send and receive calls made between it and all of
- * the other processors which have this chunk selected in the I/O operation.
+ * hh - A handle for hash tables provided by the uthash.h header
*
- * Its fields are as follows:
- *
- * receive_requests_array - An array containing one MPI_Request for each of the
- * asynchronous MPI receive calls the owning processor of this
- * chunk makes to another processor in order to receive that
- * processor's chunk modification data and selection in the chunk.
- *
- * receive_buffer_array - An array of buffers into which the owning processor of this chunk
- * will store chunk modification data and the selection in the chunk
- * received from another processor.
- *
- * num_receive_requests - The number of entries in the receive_request_array and
- * receive_buffer_array fields.
*/
typedef struct H5D_filtered_collective_io_info_t {
- hsize_t index;
- hsize_t scaled[H5O_LAYOUT_NDIMS];
- hbool_t full_overwrite;
- size_t num_writers;
- size_t io_size;
- void * buf;
-
- struct {
- H5F_block_t chunk_current;
- H5F_block_t new_chunk;
- } chunk_states;
-
- struct {
- int original_owner;
- int new_owner;
- } owners;
-
- struct {
- MPI_Request * receive_requests_array;
- unsigned char **receive_buffer_array;
- int num_receive_requests;
- } async_info;
+ H5D_chunk_index_info_t index_info;
+
+ H5D_chunk_info_t *chunk_info;
+ H5F_block_t chunk_current;
+ H5F_block_t chunk_new;
+ hbool_t need_read;
+ hbool_t skip_filter_pline;
+ size_t io_size;
+ size_t chunk_buf_size;
+ int orig_owner;
+ int new_owner;
+ int num_writers;
+ void * buf;
+
+ UT_hash_handle hh;
} H5D_filtered_collective_io_info_t;
-/* Function pointer typedef for sort function */
-typedef int (*H5D_mpio_sort_func_cb_t)(const void *, const void *);
+/*
+ * Information necessary for redistributing shared chunks during
+ * a parallel write of a chunked dataset with filters applied.
+ */
+typedef struct H5D_chunk_redistribute_info_t {
+ H5F_block_t chunk_block;
+ hsize_t chunk_idx;
+ int orig_owner;
+ int new_owner;
+ int num_writers;
+} H5D_chunk_redistribute_info_t;
+
+/*
+ * Information used when re-inserting a chunk into a dataset's
+ * chunk index during a parallel write of a chunked dataset with
+ * filters applied.
+ */
+typedef struct H5D_chunk_insert_info_t {
+ H5F_block_t chunk_block;
+ H5D_chunk_index_info_t index_info;
+} H5D_chunk_insert_info_t;
/********************/
/* Local Prototypes */
@@ -216,53 +293,98 @@ typedef int (*H5D_mpio_sort_func_cb_t)(const void *, const void *);
static herr_t H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_map_t *fm);
static herr_t H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- H5D_chunk_map_t *fm);
+ H5D_chunk_map_t *fm, int mpi_rank, int mpi_size);
static herr_t H5D__multi_chunk_filtered_collective_io(H5D_io_info_t * io_info,
- const H5D_type_info_t *type_info, H5D_chunk_map_t *fm);
+ const H5D_type_info_t *type_info, H5D_chunk_map_t *fm,
+ int mpi_rank, int mpi_size);
static herr_t H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- H5D_chunk_map_t *fm, int sum_chunk);
+ H5D_chunk_map_t *fm, int sum_chunk, int mpi_rank, int mpi_size);
static herr_t H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- H5D_chunk_map_t *fm);
+ H5D_chunk_map_t *fm, int mpi_rank, int mpi_size);
static herr_t H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
const H5S_t *file_space, const H5S_t *mem_space);
static herr_t H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, MPI_Datatype mpi_file_type, MPI_Datatype mpi_buf_type);
static herr_t H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
- H5D_chunk_addr_info_t chunk_addr_info_array[], int many_chunk_opt);
+ H5D_chunk_addr_info_t chunk_addr_info_array[], int many_chunk_opt, int mpi_rank,
+ int mpi_size);
static herr_t H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assign_io_mode[],
- haddr_t chunk_addr[]);
+ haddr_t chunk_addr[], int mpi_rank, int mpi_size);
static herr_t H5D__mpio_get_sum_chunk(const H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
int *sum_chunkf);
-static herr_t H5D__construct_filtered_io_info_list(const H5D_io_info_t * io_info,
- const H5D_type_info_t * type_info,
- const H5D_chunk_map_t * fm,
- H5D_filtered_collective_io_info_t **chunk_list,
- size_t * num_entries);
-#if MPI_VERSION >= 3
-static herr_t H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t * io_info,
- const H5D_type_info_t * type_info,
- const H5D_chunk_map_t * fm,
- H5D_filtered_collective_io_info_t *local_chunk_array,
- size_t *local_chunk_array_num_entries);
-#endif
-static herr_t H5D__mpio_array_gatherv(void *local_array, size_t local_array_num_entries,
- size_t array_entry_size, void **gathered_array,
- size_t *gathered_array_num_entries, hbool_t allgather, int root,
- MPI_Comm comm, int (*sort_func)(const void *, const void *));
-static herr_t H5D__mpio_filtered_collective_write_type(H5D_filtered_collective_io_info_t *chunk_list,
- size_t num_entries, MPI_Datatype *new_mem_type,
- hbool_t *mem_type_derived, MPI_Datatype *new_file_type,
- hbool_t *file_type_derived);
-static herr_t H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk_entry,
- const H5D_io_info_t * io_info,
- const H5D_type_info_t * type_info,
- const H5D_chunk_map_t * fm);
+static herr_t H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t * io_info,
+ const H5D_type_info_t * type_info,
+ const H5D_chunk_map_t * fm,
+ H5D_filtered_collective_io_info_t **chunk_list,
+ size_t *num_entries, int mpi_rank);
+static herr_t H5D__mpio_redistribute_shared_chunks(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries,
+ const H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
+ int mpi_rank, int mpi_size,
+ size_t **rank_chunks_assigned_map);
+static herr_t H5D__mpio_redistribute_shared_chunks_int(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t * num_chunks_assigned_map,
+ hbool_t all_ranks_involved,
+ const H5D_io_info_t * io_info,
+ const H5D_chunk_map_t *fm, int mpi_rank, int mpi_size);
+static herr_t H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t *chunk_list_num_entries, H5D_io_info_t *io_info,
+ const H5D_type_info_t *type_info, int mpi_rank,
+ int mpi_size,
+ H5D_filtered_collective_io_info_t **chunk_hash_table,
+ unsigned char *** chunk_msg_bufs,
+ int * chunk_msg_bufs_len);
+static herr_t H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries,
+ const H5D_io_info_t * io_info,
+ const H5D_type_info_t *type_info, int mpi_size);
+static herr_t H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries,
+ const H5D_io_info_t * io_info,
+ const H5D_type_info_t *type_info, int mpi_rank,
+ int mpi_size);
+static herr_t H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries,
+ H5D_filtered_collective_io_info_t *chunk_hash_table,
+ unsigned char ** chunk_msg_bufs,
+ int chunk_msg_bufs_len, const H5D_io_info_t *io_info,
+ const H5D_type_info_t *type_info, int mpi_rank,
+ int mpi_size);
+static herr_t H5D__mpio_collective_filtered_chunk_reallocate(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries,
+ size_t * num_chunks_assigned_map,
+ H5D_io_info_t * io_info,
+ H5D_chk_idx_info_t *idx_info, int mpi_rank,
+ int mpi_size);
+static herr_t H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries,
+ size_t * num_chunks_assigned_map,
+ H5D_io_info_t * io_info,
+ H5D_chk_idx_info_t *idx_info, int mpi_rank,
+ int mpi_size);
+static herr_t H5D__mpio_get_chunk_redistribute_info_types(MPI_Datatype *contig_type,
+ hbool_t * contig_type_derived,
+ MPI_Datatype *resized_type,
+ hbool_t * resized_type_derived);
+static herr_t H5D__mpio_get_chunk_alloc_info_types(MPI_Datatype *contig_type, hbool_t *contig_type_derived,
+ MPI_Datatype *resized_type, hbool_t *resized_type_derived);
+static herr_t H5D__mpio_get_chunk_insert_info_types(MPI_Datatype *contig_type, hbool_t *contig_type_derived,
+ MPI_Datatype *resized_type,
+ hbool_t * resized_type_derived);
+static herr_t H5D__mpio_collective_filtered_io_type(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t num_entries, H5D_io_op_type_t op_type,
+ MPI_Datatype *new_mem_type, hbool_t *mem_type_derived,
+ MPI_Datatype *new_file_type, hbool_t *file_type_derived);
static int H5D__cmp_chunk_addr(const void *chunk_addr_info1, const void *chunk_addr_info2);
static int H5D__cmp_filtered_collective_io_info_entry(const void *filtered_collective_io_info_entry1,
const void *filtered_collective_io_info_entry2);
-#if MPI_VERSION >= 3
-static int H5D__cmp_filtered_collective_io_info_entry_owner(const void *filtered_collective_io_info_entry1,
- const void *filtered_collective_io_info_entry2);
+static int H5D__cmp_chunk_redistribute_info(const void *entry1, const void *entry2);
+static int H5D__cmp_chunk_redistribute_info_orig_owner(const void *entry1, const void *entry2);
+
+#ifdef H5Dmpio_DEBUG
+static herr_t H5D__mpio_debug_init(void);
+static herr_t H5D__mpio_dump_collective_filtered_chunk_list(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries, int mpi_rank);
#endif
/*********************/
@@ -273,6 +395,188 @@ static int H5D__cmp_filtered_collective_io_info_entry_owner(const void *filtered
/* Local Variables */
/*******************/
+/* Declare extern free list to manage the H5S_sel_iter_t struct */
+H5FL_EXTERN(H5S_sel_iter_t);
+
+#ifdef H5Dmpio_DEBUG
+
+/* Flags to control debug actions in this file.
+ * (Meant to be indexed by characters)
+ *
+ * These flags can be set with either (or both) the environment variable
+ * "H5D_mpio_Debug" set to a string containing one or more characters
+ * (flags) or by setting them as a string value for the
+ * "H5D_mpio_debug_key" MPI Info key.
+ *
+ * Supported characters in 'H5D_mpio_Debug' string:
+ * 't' trace function entry and exit
+ * 'f' log to file rather than debugging stream
+ * 'm' show (rough) memory usage statistics
+ * 'c' show critical timing information
+ *
+ * To only show output from a particular MPI rank, specify its rank
+ * number as a character, e.g.:
+ *
+ * '0' only show output from rank 0
+ *
+ * To only show output from a particular range (up to 8 ranks supported
+ * between 0-9) of MPI ranks, specify the start and end ranks separated
+ * by a hyphen, e.g.:
+ *
+ * '0-7' only show output from ranks 0 through 7
+ *
+ */
+static int H5D_mpio_debug_flags_s[256];
+static int H5D_mpio_debug_rank_s[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static hbool_t H5D_mpio_debug_inited = FALSE;
+static const char *const trace_in_pre = "-> ";
+static const char *const trace_out_pre = "<- ";
+static int debug_indent = 0;
+static FILE * debug_stream = NULL;
+
+/* Determine if this rank should output debugging info */
+#define H5D_MPIO_DEBUG_THIS_RANK(rank) \
+ (H5D_mpio_debug_rank_s[0] < 0 || rank == H5D_mpio_debug_rank_s[0] || rank == H5D_mpio_debug_rank_s[1] || \
+ rank == H5D_mpio_debug_rank_s[2] || rank == H5D_mpio_debug_rank_s[3] || \
+ rank == H5D_mpio_debug_rank_s[4] || rank == H5D_mpio_debug_rank_s[5] || \
+ rank == H5D_mpio_debug_rank_s[6] || rank == H5D_mpio_debug_rank_s[7])
+
+/* Print some debugging string */
+#define H5D_MPIO_DEBUG(rank, string) \
+ do { \
+ if (debug_stream && H5D_MPIO_DEBUG_THIS_RANK(rank)) { \
+ HDfprintf(debug_stream, "%*s(Rank %d) " string "\n", debug_indent, "", rank); \
+ HDfflush(debug_stream); \
+ } \
+ } while (0)
+
+/* Print some debugging string with printf-style arguments */
+#define H5D_MPIO_DEBUG_VA(rank, string, ...) \
+ do { \
+ if (debug_stream && H5D_MPIO_DEBUG_THIS_RANK(rank)) { \
+ HDfprintf(debug_stream, "%*s(Rank %d) " string "\n", debug_indent, "", rank, __VA_ARGS__); \
+ HDfflush(debug_stream); \
+ } \
+ } while (0)
+
+#define H5D_MPIO_TRACE_ENTER(rank) \
+ do { \
+ hbool_t trace_flag = H5D_mpio_debug_flags_s[(int)'t']; \
+ \
+ if (trace_flag) { \
+ H5D_MPIO_DEBUG_VA(rank, "%s%s", trace_in_pre, __func__); \
+ debug_indent += (int)HDstrlen(trace_in_pre); \
+ } \
+ } while (0)
+
+#define H5D_MPIO_TRACE_EXIT(rank) \
+ do { \
+ hbool_t trace_flag = H5D_mpio_debug_flags_s[(int)'t']; \
+ \
+ if (trace_flag) { \
+ debug_indent -= (int)HDstrlen(trace_out_pre); \
+ H5D_MPIO_DEBUG_VA(rank, "%s%s", trace_out_pre, __func__); \
+ } \
+ } while (0)
+
+#define H5D_MPIO_TIME_START(rank, op_name) \
+ { \
+ hbool_t time_flag = H5D_mpio_debug_flags_s[(int)'c']; \
+ double start_time = 0.0, end_time = 0.0; \
+ const char *const op = op_name; \
+ \
+ if (time_flag) { \
+ start_time = MPI_Wtime(); \
+ }
+
+#define H5D_MPIO_TIME_STOP(rank) \
+ if (time_flag) { \
+ end_time = MPI_Wtime(); \
+ H5D_MPIO_DEBUG_VA(rank, "'%s' took %f seconds", op, (end_time - start_time)); \
+ } \
+ }
+
+/*---------------------------------------------------------------------------
+ * Function: H5D__mpio_parse_debug_str
+ *
+ * Purpose: Parse a string for H5Dmpio-related debugging flags
+ *
+ * Returns: N/A
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+H5D__mpio_parse_debug_str(const char *s)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ HDassert(s);
+
+ while (*s) {
+ int c = (int)(*s);
+
+ if (c >= (int)'0' && c <= (int)'9') {
+ hbool_t range = FALSE;
+
+ if (*(s + 1) && *(s + 2))
+ range = (int)*(s + 1) == '-' && (int)*(s + 2) >= (int)'0' && (int)*(s + 2) <= (int)'9';
+
+ if (range) {
+ int start_rank = c - (int)'0';
+ int end_rank = (int)*(s + 2) - '0';
+ int num_ranks = end_rank - start_rank + 1;
+ int i;
+
+ if (num_ranks > 8) {
+ end_rank = start_rank + 7;
+ num_ranks = 8;
+ }
+
+ for (i = 0; i < num_ranks; i++)
+ H5D_mpio_debug_rank_s[i] = start_rank++;
+
+ s += 3;
+ }
+ else
+ H5D_mpio_debug_rank_s[0] = c - (int)'0';
+ }
+ else
+ H5D_mpio_debug_flags_s[c]++;
+
+ s++;
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+}
+
+static herr_t
+H5D__mpio_debug_init(void)
+{
+ const char *debug_str;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ HDassert(!H5D_mpio_debug_inited);
+
+ /* Clear the debug flag buffer */
+ HDmemset(H5D_mpio_debug_flags_s, 0, sizeof(H5D_mpio_debug_flags_s));
+
+ /* Retrieve and parse the H5Dmpio debug string */
+ debug_str = HDgetenv("H5D_mpio_Debug");
+ if (debug_str)
+ H5D__mpio_parse_debug_str(debug_str);
+
+ if (H5DEBUG(D))
+ debug_stream = H5DEBUG(D);
+
+ H5D_mpio_debug_inited = TRUE;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+#endif
+
/*-------------------------------------------------------------------------
* Function: H5D__mpio_opt_possible
*
@@ -347,14 +651,9 @@ H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space, co
* use collective IO will defer until each chunk IO is reached.
*/
-#if MPI_VERSION < 3
- /*
- * Don't allow parallel writes to filtered datasets if the MPI version
- * is less than 3. The functions needed (MPI_Mprobe and MPI_Imrecv) will
- * not be available.
- */
- if (io_info->op_type == H5D_IO_OP_WRITE && io_info->dset->shared->layout.type == H5D_CHUNKED &&
- io_info->dset->shared->dcpl_cache.pline.nused > 0)
+#ifndef H5_HAVE_PARALLEL_FILTERED_WRITES
+ /* Don't allow writes to filtered datasets if the functionality is disabled */
+ if (io_info->op_type == H5D_IO_OP_WRITE && io_info->dset->shared->dcpl_cache.pline.nused > 0)
local_cause[0] |= H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED;
#endif
@@ -365,7 +664,7 @@ H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space, co
/* Check to see if the process is reading the entire dataset */
if (H5S_GET_SELECT_TYPE(file_space) != H5S_SEL_ALL)
local_cause[1] |= H5D_MPIO_RANK0_NOT_H5S_ALL;
- /* Only perform this optimization for contigous datasets, currently */
+ /* Only perform this optimization for contiguous datasets, currently */
else if (H5D_CONTIGUOUS != io_info->dset->shared->layout.type)
/* Flag to do a MPI_Bcast of the data from one proc instead of
* having all the processes involved in the collective I/O.
@@ -437,6 +736,150 @@ done:
} /* H5D__mpio_opt_possible() */
/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_get_no_coll_cause_strings
+ *
+ * Purpose: When collective I/O is broken internally, it can be useful
+ * for users to see a representative string for the reason(s)
+ * why it was broken. This routine inspects the current
+ * "cause" flags from the API context and prints strings into
+ * the caller's buffers for the local and global reasons that
+ * collective I/O was broken.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D__mpio_get_no_coll_cause_strings(char *local_cause, size_t local_cause_len, char *global_cause,
+ size_t global_cause_len)
+{
+ uint32_t local_no_coll_cause;
+ uint32_t global_no_coll_cause;
+ size_t local_cause_bytes_written = 0;
+ size_t global_cause_bytes_written = 0;
+ int nbits;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ HDassert((local_cause && local_cause_len > 0) || (global_cause && global_cause_len > 0));
+
+ /*
+ * Use compile-time assertion so this routine is updated
+ * when any new "no collective cause" values are added
+ */
+ HDcompile_assert(H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE == (H5D_mpio_no_collective_cause_t)256);
+
+ /* Initialize output buffers */
+ if (local_cause)
+ *local_cause = '\0';
+ if (global_cause)
+ *global_cause = '\0';
+
+ /* Retrieve the local and global cause flags from the API context */
+ if (H5CX_get_mpio_local_no_coll_cause(&local_no_coll_cause) < 0)
+ HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "unable to get local no collective cause value")
+ if (H5CX_get_mpio_global_no_coll_cause(&global_no_coll_cause) < 0)
+ HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "unable to get global no collective cause value")
+
+ /*
+ * Append each of the "reason for breaking collective I/O"
+ * error messages to the local and global cause string buffers
+ */
+ nbits = 8 * sizeof(local_no_coll_cause);
+ for (int bit_pos = 0; bit_pos < nbits; bit_pos++) {
+ H5D_mpio_no_collective_cause_t cur_cause;
+ const char * cause_str;
+ size_t buf_space_left;
+
+ cur_cause = (H5D_mpio_no_collective_cause_t)(1 << bit_pos);
+ if (cur_cause == H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE)
+ break;
+
+ switch (cur_cause) {
+ case H5D_MPIO_SET_INDEPENDENT:
+ cause_str = "independent I/O was requested";
+ break;
+ case H5D_MPIO_DATATYPE_CONVERSION:
+ cause_str = "datatype conversions were required";
+ break;
+ case H5D_MPIO_DATA_TRANSFORMS:
+ cause_str = "data transforms needed to be applied";
+ break;
+ case H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED:
+ cause_str = "optimized MPI types flag wasn't set";
+ break;
+ case H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES:
+ cause_str = "one of the dataspaces was neither simple nor scalar";
+ break;
+ case H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET:
+ cause_str = "dataset was not contiguous or chunked";
+ break;
+ case H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED:
+ cause_str = "parallel writes to filtered datasets are disabled";
+ break;
+ case H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE:
+ cause_str = "an error occurred while checking if collective I/O was possible";
+ break;
+ case H5D_MPIO_COLLECTIVE:
+ case H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE:
+ default:
+ HDassert(0 && "invalid no collective cause reason");
+ break;
+ }
+
+ /*
+ * Determine if the local reasons for breaking collective I/O
+ * included the current cause
+ */
+ if (local_cause && (cur_cause & local_no_coll_cause)) {
+ buf_space_left = local_cause_len - local_cause_bytes_written;
+
+ /*
+ * Check if there were any previous error messages included. If
+ * so, prepend a semicolon to separate the messages.
+ */
+ if (buf_space_left && local_cause_bytes_written) {
+ HDstrncat(local_cause, "; ", buf_space_left);
+ local_cause_bytes_written += MIN(buf_space_left, 2);
+ buf_space_left -= MIN(buf_space_left, 2);
+ }
+
+ if (buf_space_left) {
+ HDstrncat(local_cause, cause_str, buf_space_left);
+ local_cause_bytes_written += MIN(buf_space_left, HDstrlen(cause_str));
+ }
+ }
+
+ /*
+ * Determine if the global reasons for breaking collective I/O
+ * included the current cause
+ */
+ if (global_cause && (cur_cause & global_no_coll_cause)) {
+ buf_space_left = global_cause_len - global_cause_bytes_written;
+
+ /*
+ * Check if there were any previous error messages included. If
+ * so, prepend a semicolon to separate the messages.
+ */
+ if (buf_space_left && global_cause_bytes_written) {
+ HDstrncat(global_cause, "; ", buf_space_left);
+ global_cause_bytes_written += MIN(buf_space_left, 2);
+ buf_space_left -= MIN(buf_space_left, 2);
+ }
+
+ if (buf_space_left) {
+ HDstrncat(global_cause, cause_str, buf_space_left);
+ global_cause_bytes_written += MIN(buf_space_left, HDstrlen(cause_str));
+ }
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_get_no_coll_cause_strings() */
+
+/*-------------------------------------------------------------------------
* Function: H5D__mpio_select_read
*
* Purpose: MPI-IO function to read directly from app buffer to file.
@@ -449,8 +892,8 @@ done:
*/
herr_t
H5D__mpio_select_read(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
- hsize_t mpi_buf_count, const H5S_t H5_ATTR_UNUSED *file_space,
- const H5S_t H5_ATTR_UNUSED *mem_space)
+ hsize_t mpi_buf_count, H5S_t H5_ATTR_UNUSED *file_space,
+ H5S_t H5_ATTR_UNUSED *mem_space)
{
const H5D_contig_storage_t *store_contig =
&(io_info->store->contig); /* Contiguous storage info for this I/O operation */
@@ -480,8 +923,8 @@ done:
*/
herr_t
H5D__mpio_select_write(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
- hsize_t mpi_buf_count, const H5S_t H5_ATTR_UNUSED *file_space,
- const H5S_t H5_ATTR_UNUSED *mem_space)
+ hsize_t mpi_buf_count, H5S_t H5_ATTR_UNUSED *file_space,
+ H5S_t H5_ATTR_UNUSED *mem_space)
{
const H5D_contig_storage_t *store_contig =
&(io_info->store->contig); /* Contiguous storage info for this I/O operation */
@@ -500,145 +943,6 @@ done:
} /* end H5D__mpio_select_write() */
/*-------------------------------------------------------------------------
- * Function: H5D__mpio_array_gatherv
- *
- * Purpose: Given an array, specified in local_array, by each processor
- * calling this function, collects each array into a single
- * array which is then either gathered to the processor
- * specified by root, when allgather is false, or is
- * distributed back to all processors when allgather is true.
- *
- * The number of entries in the array contributed by an
- * individual processor and the size of each entry should be
- * specified in local_array_num_entries and array_entry_size,
- * respectively.
- *
- * The MPI communicator to use should be specified for comm.
- *
- * If the sort_func argument is supplied, the array is sorted
- * before the function returns.
- *
- * Note: if allgather is specified as true, root is ignored.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Jordan Henderson
- * Sunday, April 9th, 2017
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D__mpio_array_gatherv(void *local_array, size_t local_array_num_entries, size_t array_entry_size,
- void **_gathered_array, size_t *_gathered_array_num_entries, hbool_t allgather,
- int root, MPI_Comm comm, H5D_mpio_sort_func_cb_t sort_func)
-{
- size_t gathered_array_num_entries = 0; /* The size of the newly-constructed array */
- void * gathered_array = NULL; /* The newly-constructed array returned to the caller */
- int *receive_counts_array = NULL; /* Array containing number of entries each processor is contributing */
- int *displacements_array =
- NULL; /* Array of displacements where each processor places its data in the final array */
- int mpi_code, mpi_rank, mpi_size;
- int sendcount;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- HDassert(_gathered_array);
- HDassert(_gathered_array_num_entries);
-
- MPI_Comm_size(comm, &mpi_size);
- MPI_Comm_rank(comm, &mpi_rank);
-
- /* Determine the size of the end result array by collecting the number
- * of entries contributed by each processor into a single total.
- */
- if (MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_array_num_entries, &gathered_array_num_entries, 1,
- MPI_INT, MPI_SUM, comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code)
-
- /* If 0 entries resulted from the collective operation, no processor is contributing anything and there is
- * nothing to do */
- if (gathered_array_num_entries > 0) {
- /*
- * If gathering to all processors, all processors need to allocate space for the resulting array, as
- * well as the receive counts and displacements arrays for the collective MPI_Allgatherv call.
- * Otherwise, only the root processor needs to allocate the space for an MPI_Gatherv call.
- */
- if (allgather || (mpi_rank == root)) {
- if (NULL == (gathered_array = H5MM_malloc(gathered_array_num_entries * array_entry_size)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate gathered array")
-
- if (NULL == (receive_counts_array = (int *)H5MM_malloc((size_t)mpi_size * sizeof(int))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate receive counts array")
-
- if (NULL == (displacements_array = (int *)H5MM_malloc((size_t)mpi_size * sizeof(int))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate receive displacements array")
- } /* end if */
-
- /*
- * If gathering to all processors, inform each processor of how many entries each other processor is
- * contributing to the resulting array by collecting the counts into each processor's "receive counts"
- * array. Otherwise, inform only the root processor of how many entries each other processor is
- * contributing.
- */
- if (allgather) {
- if (MPI_SUCCESS != (mpi_code = MPI_Allgather(&local_array_num_entries, 1, MPI_INT,
- receive_counts_array, 1, MPI_INT, comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code)
- } /* end if */
- else {
- if (MPI_SUCCESS != (mpi_code = MPI_Gather(&local_array_num_entries, 1, MPI_INT,
- receive_counts_array, 1, MPI_INT, root, comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code)
- } /* end else */
-
- if (allgather || (mpi_rank == root)) {
- size_t i;
-
- /* Multiply each receive count by the size of the array entry, since the data is sent as bytes. */
- for (i = 0; i < (size_t)mpi_size; i++)
- H5_CHECKED_ASSIGN(receive_counts_array[i], int,
- (size_t)receive_counts_array[i] * array_entry_size, size_t);
-
- /* Set receive buffer offsets for the collective MPI_Allgatherv/MPI_Gatherv call. */
- displacements_array[0] = 0;
- for (i = 1; i < (size_t)mpi_size; i++)
- displacements_array[i] = displacements_array[i - 1] + receive_counts_array[i - 1];
- } /* end if */
-
- /* As the data is sent as bytes, calculate the true sendcount for the data. */
- H5_CHECKED_ASSIGN(sendcount, int, local_array_num_entries *array_entry_size, size_t);
-
- if (allgather) {
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Allgatherv(local_array, sendcount, MPI_BYTE, gathered_array,
- receive_counts_array, displacements_array, MPI_BYTE, comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Allgatherv failed", mpi_code)
- } /* end if */
- else {
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Gatherv(local_array, sendcount, MPI_BYTE, gathered_array,
- receive_counts_array, displacements_array, MPI_BYTE, root, comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Gatherv failed", mpi_code)
- } /* end else */
-
- if (sort_func && (allgather || (mpi_rank == root)))
- HDqsort(gathered_array, gathered_array_num_entries, array_entry_size, sort_func);
- } /* end if */
-
- *_gathered_array = gathered_array;
- *_gathered_array_num_entries = gathered_array_num_entries;
-
-done:
- if (receive_counts_array)
- H5MM_free(receive_counts_array);
- if (displacements_array)
- H5MM_free(displacements_array);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__mpio_array_gatherv() */
-
-/*-------------------------------------------------------------------------
* Function: H5D__mpio_get_sum_chunk
*
* Purpose: Routine for obtaining total number of chunks to cover
@@ -690,7 +994,7 @@ done:
*/
herr_t
H5D__contig_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t H5_ATTR_UNUSED nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t H5_ATTR_UNUSED nelmts, H5S_t *file_space, H5S_t *mem_space,
H5D_chunk_map_t H5_ATTR_UNUSED *fm)
{
H5D_mpio_actual_io_mode_t actual_io_mode = H5D_MPIO_CONTIGUOUS_COLLECTIVE;
@@ -729,7 +1033,7 @@ done:
*/
herr_t
H5D__contig_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t H5_ATTR_UNUSED nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t H5_ATTR_UNUSED nelmts, H5S_t *file_space, H5S_t *mem_space,
H5D_chunk_map_t H5_ATTR_UNUSED *fm)
{
H5D_mpio_actual_io_mode_t actual_io_mode = H5D_MPIO_CONTIGUOUS_COLLECTIVE;
@@ -793,11 +1097,17 @@ static herr_t
H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm)
{
H5FD_mpio_chunk_opt_t chunk_opt_mode;
- int io_option = H5D_MULTI_CHUNK_IO_MORE_OPT;
- int sum_chunk = -1;
+#ifdef H5Dmpio_DEBUG
+ hbool_t log_file_flag = FALSE;
+ FILE * debug_log_file = NULL;
+#endif
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
htri_t temp_not_link_io = FALSE;
#endif
+ int io_option = H5D_MULTI_CHUNK_IO_MORE_OPT;
+ int sum_chunk = -1;
+ int mpi_rank;
+ int mpi_size;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
@@ -808,9 +1118,35 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
HDassert(type_info);
HDassert(fm);
- /* Disable collective metadata reads for chunked dataset I/O operations
- * in order to prevent potential hangs */
- H5CX_set_coll_metadata_read(FALSE);
+ /* Obtain the current rank of the process and the number of ranks */
+ if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain MPI rank")
+ if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain MPI size")
+
+#ifdef H5Dmpio_DEBUG
+ /* Initialize file-level debugging if not initialized */
+ if (!H5D_mpio_debug_inited && H5D__mpio_debug_init() < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize H5Dmpio debugging")
+
+ /* Open file for debugging if necessary */
+ log_file_flag = H5D_mpio_debug_flags_s[(int)'f'];
+ if (log_file_flag) {
+ char debug_log_filename[1024];
+ time_t time_now;
+
+ HDsnprintf(debug_log_filename, 1024, "H5Dmpio_debug.rank%d", mpi_rank);
+
+ if (NULL == (debug_log_file = HDfopen(debug_log_filename, "a")))
+ HGOTO_ERROR(H5E_IO, H5E_OPENERROR, FAIL, "couldn't open debugging log file")
+
+ /* Print a short header for this I/O operation */
+ time_now = HDtime(NULL);
+ HDfprintf(debug_log_file, "##### %s", HDasctime(HDlocaltime(&time_now)));
+
+ debug_stream = debug_log_file;
+ }
+#endif
/* Check the optional property list for the collective chunk IO optimization option */
if (H5CX_get_mpio_chunk_opt_mode(&chunk_opt_mode) < 0)
@@ -824,13 +1160,10 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
/* via default path. branch by num threshold */
else {
unsigned one_link_chunk_io_threshold; /* Threshold to use single collective I/O for all chunks */
- int mpi_size; /* Number of processes in MPI job */
if (H5D__mpio_get_sum_chunk(io_info, fm, &sum_chunk) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL,
"unable to obtain the total chunk number of all processes");
- if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
/* Get the chunk optimization option threshold */
if (H5CX_get_mpio_chunk_opt_num(&one_link_chunk_io_threshold) < 0)
@@ -876,22 +1209,12 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
case H5D_ONE_LINK_CHUNK_IO_MORE_OPT:
/* Check if there are any filters in the pipeline */
if (io_info->dset->shared->dcpl_cache.pline.nused > 0) {
- /* For now, Multi-chunk IO must be forced for parallel filtered read,
- * so that data can be unfiltered as it is received. There is significant
- * complexity in unfiltering the data when it is read all at once into a
- * single buffer.
- */
- if (io_info->op_type == H5D_IO_OP_READ) {
- if (H5D__multi_chunk_filtered_collective_io(io_info, type_info, fm) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
- "couldn't finish optimized multiple filtered chunk MPI-IO")
- } /* end if */
- else if (H5D__link_chunk_filtered_collective_io(io_info, type_info, fm) < 0)
+ if (H5D__link_chunk_filtered_collective_io(io_info, type_info, fm, mpi_rank, mpi_size) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish filtered linked chunk MPI-IO")
} /* end if */
else
/* Perform unfiltered link chunk collective IO */
- if (H5D__link_chunk_collective_io(io_info, type_info, fm, sum_chunk) < 0)
+ if (H5D__link_chunk_collective_io(io_info, type_info, fm, sum_chunk, mpi_rank, mpi_size) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish linked chunk MPI-IO")
break;
@@ -899,18 +1222,28 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
default: /* multiple chunk IO via threshold */
/* Check if there are any filters in the pipeline */
if (io_info->dset->shared->dcpl_cache.pline.nused > 0) {
- if (H5D__multi_chunk_filtered_collective_io(io_info, type_info, fm) < 0)
+ if (H5D__multi_chunk_filtered_collective_io(io_info, type_info, fm, mpi_rank, mpi_size) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
"couldn't finish optimized multiple filtered chunk MPI-IO")
} /* end if */
else
/* Perform unfiltered multi chunk collective IO */
- if (H5D__multi_chunk_collective_io(io_info, type_info, fm) < 0)
+ if (H5D__multi_chunk_collective_io(io_info, type_info, fm, mpi_rank, mpi_size) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish optimized multiple chunk MPI-IO")
break;
} /* end switch */
done:
+#ifdef H5Dmpio_DEBUG
+ /* Close debugging log file */
+ if (debug_log_file) {
+ HDfprintf(debug_log_file, "##############\n\n");
+ if (EOF == HDfclose(debug_log_file))
+ HDONE_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "couldn't close debugging log file")
+ debug_stream = H5DEBUG(D);
+ }
+#endif
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__chunk_collective_io */
@@ -929,8 +1262,8 @@ done:
*/
herr_t
H5D__chunk_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t H5_ATTR_UNUSED nelmts, const H5S_t H5_ATTR_UNUSED *file_space,
- const H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
+ hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
+ H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -959,8 +1292,8 @@ done:
*/
herr_t
H5D__chunk_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t H5_ATTR_UNUSED nelmts, const H5S_t H5_ATTR_UNUSED *file_space,
- const H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
+ hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
+ H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -993,12 +1326,12 @@ done:
*/
static herr_t
H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm,
- int sum_chunk)
+ int sum_chunk, int mpi_rank, int mpi_size)
{
H5D_chunk_addr_info_t *chunk_addr_info_array = NULL;
- MPI_Datatype chunk_final_mtype; /* Final memory MPI datatype for all chunks with seletion */
+ MPI_Datatype chunk_final_mtype; /* Final memory MPI datatype for all chunks with selection */
hbool_t chunk_final_mtype_is_derived = FALSE;
- MPI_Datatype chunk_final_ftype; /* Final file MPI datatype for all chunks with seletion */
+ MPI_Datatype chunk_final_ftype; /* Final file MPI datatype for all chunks with selection */
hbool_t chunk_final_ftype_is_derived = FALSE;
H5D_storage_t ctg_store; /* Storage info for "fake" contiguous dataset */
size_t total_chunks;
@@ -1074,9 +1407,8 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
/* Set up the base storage address for this chunk */
io_info->store = &ctg_store;
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "before inter_collective_io for total chunk = 1 \n");
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "before inter_collective_io for total chunk = 1");
#endif
/* Perform I/O */
@@ -1092,9 +1424,8 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
num_chunk = H5SL_count(fm->sel_chunks);
H5_CHECK_OVERFLOW(num_chunk, size_t, int);
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "total_chunks = %zu, num_chunk = %zu\n", total_chunks, num_chunk);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG_VA(mpi_rank, "total_chunks = %zu, num_chunk = %zu", total_chunks, num_chunk);
#endif
/* Set up MPI datatype for chunks selected */
@@ -1125,18 +1456,17 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
"couldn't allocate chunk file is derived datatype flags buffer")
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "before sorting the chunk address \n");
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "before sorting chunk addresses");
#endif
+
/* Sort the chunk address */
- if (H5D__sort_chunk(io_info, fm, chunk_addr_info_array, sum_chunk) < 0)
+ if (H5D__sort_chunk(io_info, fm, chunk_addr_info_array, sum_chunk, mpi_rank, mpi_size) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL, "unable to sort chunk address")
ctg_store.contig.dset_addr = chunk_addr_info_array[0].chunk_addr;
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "after sorting the chunk address \n");
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "after sorting chunk addresses");
#endif
/* Obtain MPI derived datatype from all individual chunks */
@@ -1241,9 +1571,9 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
/* No chunks selected for this process */
mpi_buf_count = (hsize_t)0;
} /* end else */
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "before coming to final collective IO\n");
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "before coming to final collective I/O");
#endif
/* Set up the base storage address for this chunk */
@@ -1256,11 +1586,11 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
} /* end else */
done:
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "before freeing memory inside H5D_link_collective_io ret_value = %d\n",
- ret_value);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG_VA(mpi_rank, "before freeing memory inside H5D_link_collective_io ret_value = %d",
+ ret_value);
#endif
+
/* Release resources */
if (chunk_addr_info_array)
H5MM_xfree(chunk_addr_info_array);
@@ -1293,68 +1623,89 @@ done:
/*-------------------------------------------------------------------------
* Function: H5D__link_chunk_filtered_collective_io
*
- * Purpose: Routine for one collective IO with one MPI derived datatype
- * to link with all filtered chunks
- *
- * 1. Construct a list of selected chunks in the collective IO
- * operation
- * A. If any chunk is being written to by more than 1
- * process, the process writing to the chunk which
- * currently has the least amount of chunks assigned
- * to it becomes the new owner (in the case of ties,
- * the lowest MPI rank becomes the new owner)
- * 2. If the operation is a write operation
- * A. Loop through each chunk in the operation
- * I. If this is not a full overwrite of the chunk
- * a) Read the chunk from file and pass the chunk
- * through the filter pipeline in reverse order
- * (Unfilter the chunk)
+ * Purpose: Performs collective I/O on filtered chunks by creating a
+ * single MPI derived datatype to link with all filtered
+ * chunks. The general algorithm is as follows:
+ *
+ * 1. Construct a list of selected chunks in the collective
+ * I/O operation
+ * 2. If the operation is a read operation
+ * A. Ensure that the list of chunks is sorted in
+ * monotonically non-decreasing order of chunk offset
+ * in the file
+ * B. Participate in a collective read of chunks from
+ * the file
+ * C. Loop through each selected chunk, unfiltering it and
+ * scattering the data to the application's read buffer
+ * 3. If the operation is a write operation
+ * A. Redistribute any chunks being written by more than 1
+ * MPI rank, such that the chunk is only owned by 1 MPI
+ * rank. The rank writing to the chunk which currently
+ * has the least amount of chunks assigned to it becomes
+ * the new owner (in the case of ties, the lowest MPI
+ * rank becomes the new owner)
+ * B. Participate in a collective read of chunks from the
+ * file
+ * C. Loop through each chunk selected in the operation
+ * and for each chunk:
+ * I. If we actually read the chunk from the file (if
+ * a chunk is being fully overwritten, we skip
+ * reading it), pass the chunk through the filter
+ * pipeline in reverse order (unfilter the chunk)
* II. Update the chunk data with the modifications from
- * the owning process
+ * the owning MPI rank
* III. Receive any modification data from other
- * processes and update the chunk data with these
+ * ranks and update the chunk data with those
* modifications
* IV. Filter the chunk
- * B. Contribute the modified chunks to an array gathered
- * by all processes which contains the new sizes of
- * every chunk modified in the collective IO operation
- * C. All processes collectively re-allocate each chunk
- * from the gathered array with their new sizes after
- * the filter operation
- * D. If this process has any chunks selected in the IO
- * operation, create an MPI derived type for memory and
- * file to write out the process' selected chunks to the
- * file
- * E. Perform the collective write
- * F. All processes collectively re-insert each modified
+ * D. Contribute the modified chunks to an array gathered
+ * by all ranks which contains information for
+ * re-allocating space in the file for every chunk
+ * modified. Then, each rank collectively re-allocates
+ * each chunk from the gathered array with their new
+ * sizes after the filter operation
+ * E. Proceed with the collective write operation for all
+ * the modified chunks
+ * F. Contribute the modified chunks to an array gathered
+ * by all ranks which contains information for
+ * re-inserting every chunk modified into the chunk
+ * index. Then, each rank collectively re-inserts each
* chunk from the gathered array into the chunk index
*
+ * TODO: Note that steps D. and F. here are both collective
+ * operations that partially share data from the
+ * H5D_filtered_collective_io_info_t structure. To
+ * try to conserve on memory a bit, the distributed
+ * arrays these operations create are discarded after
+ * each operation is performed. If memory consumption
+ * here proves to not be an issue, the necessary data
+ * for both operations could be combined into a single
+ * structure so that only one collective MPI operation
+ * is needed to carry out both operations, rather than
+ * two.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Jordan Henderson
- * Friday, Nov. 4th, 2016
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- H5D_chunk_map_t *fm)
+ H5D_chunk_map_t *fm, int mpi_rank, int mpi_size)
{
- H5D_filtered_collective_io_info_t *chunk_list = NULL; /* The list of chunks being read/written */
- H5D_filtered_collective_io_info_t *collective_chunk_list =
- NULL; /* The list of chunks used during collective operations */
- H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
- MPI_Datatype mem_type = MPI_BYTE;
- MPI_Datatype file_type = MPI_BYTE;
- hbool_t mem_type_is_derived = FALSE;
- hbool_t file_type_is_derived = FALSE;
- size_t chunk_list_num_entries;
- size_t collective_chunk_list_num_entries;
- size_t * num_chunks_selected_array = NULL; /* Array of number of chunks selected on each process */
- size_t i; /* Local index variable */
- int mpi_rank, mpi_size, mpi_code;
- herr_t ret_value = SUCCEED;
+ H5D_filtered_collective_io_info_t *chunk_list = NULL; /* The list of chunks being read/written */
+ H5D_filtered_collective_io_info_t *chunk_hash_table = NULL;
+ unsigned char ** chunk_msg_bufs = NULL;
+ H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
+ MPI_Datatype mem_type = MPI_BYTE;
+ MPI_Datatype file_type = MPI_BYTE;
+ hbool_t mem_type_is_derived = FALSE;
+ hbool_t file_type_is_derived = FALSE;
+ size_t * rank_chunks_assigned_map = NULL;
+ size_t chunk_list_num_entries;
+ size_t i;
+ int chunk_msg_bufs_len = 0;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
@@ -1362,11 +1713,12 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
HDassert(type_info);
HDassert(fm);
- /* Obtain the current rank of the process and the number of processes */
- if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
- if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_DEBUG_VA(mpi_rank, "Performing Linked-chunk I/O (%s) with MPI Comm size of %d",
+ io_info->op_type == H5D_IO_OP_WRITE ? "write" : "read", mpi_size);
+ H5D_MPIO_TIME_START(mpi_rank, "Linked-chunk I/O");
+#endif
/* Set the actual-chunk-opt-mode property. */
H5CX_set_mpio_actual_chunk_opt(H5D_MPIO_LINK_CHUNK);
@@ -1377,123 +1729,127 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
H5CX_set_mpio_actual_io_mode(H5D_MPIO_CHUNK_COLLECTIVE);
/* Build a list of selected chunks in the collective io operation */
- if (H5D__construct_filtered_io_info_list(io_info, type_info, fm, &chunk_list, &chunk_list_num_entries) <
- 0)
+ if (H5D__mpio_collective_filtered_chunk_io_setup(io_info, type_info, fm, &chunk_list,
+ &chunk_list_num_entries, mpi_rank) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't construct filtered I/O info list")
- if (io_info->op_type == H5D_IO_OP_WRITE) { /* Filtered collective write */
+ if (io_info->op_type == H5D_IO_OP_READ) { /* Filtered collective read */
+ if (H5D__mpio_collective_filtered_chunk_read(chunk_list, chunk_list_num_entries, io_info, type_info,
+ mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't read filtered chunks")
+ }
+ else { /* Filtered collective write */
H5D_chk_idx_info_t index_info;
- H5D_chunk_ud_t udata;
hsize_t mpi_buf_count;
- /* Construct chunked index info */
- index_info.f = io_info->dset->oloc.file;
- index_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
- index_info.layout = &(io_info->dset->shared->layout.u.chunk);
- index_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
-
- /* Set up chunk information for insertion to chunk index */
- udata.common.layout = index_info.layout;
- udata.common.storage = index_info.storage;
- udata.filter_mask = 0;
-
- /* Iterate through all the chunks in the collective write operation,
- * updating each chunk with the data modifications from other processes,
- * then re-filtering the chunk.
+ H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, io_info);
+
+ if (mpi_size > 1) {
+ /* Redistribute shared chunks being written to */
+ if (H5D__mpio_redistribute_shared_chunks(chunk_list, chunk_list_num_entries, io_info, fm,
+ mpi_rank, mpi_size, &rank_chunks_assigned_map) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to redistribute shared chunks")
+
+ /* Send any chunk modification messages for chunks this rank no longer owns */
+ if (H5D__mpio_share_chunk_modification_data(chunk_list, &chunk_list_num_entries, io_info,
+ type_info, mpi_rank, mpi_size, &chunk_hash_table,
+ &chunk_msg_bufs, &chunk_msg_bufs_len) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
+ "unable to send chunk modification data between MPI ranks")
+
+ /* Make sure the local chunk list was updated correctly */
+ HDassert(chunk_list_num_entries == rank_chunks_assigned_map[mpi_rank]);
+ }
+
+ /* Proceed to update all the chunks this rank owns with its own
+ * modification data and data from other ranks, before re-filtering
+ * the chunks. As chunk reads are done collectively here, all ranks
+ * must participate.
*/
- for (i = 0; i < chunk_list_num_entries; i++)
- if (mpi_rank == chunk_list[i].owners.new_owner)
- if (H5D__filtered_collective_chunk_entry_io(&chunk_list[i], io_info, type_info, fm) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't process chunk entry")
-
- /* Gather the new chunk sizes to all processes for a collective reallocation
- * of the chunks in the file.
- */
- if (H5D__mpio_array_gatherv(chunk_list, chunk_list_num_entries,
- sizeof(H5D_filtered_collective_io_info_t),
- (void **)&collective_chunk_list, &collective_chunk_list_num_entries, true,
- 0, io_info->comm, NULL) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL, "couldn't gather new chunk sizes")
-
- /* Collectively re-allocate the modified chunks (from each process) in the file */
- for (i = 0; i < collective_chunk_list_num_entries; i++) {
- hbool_t insert;
-
- if (H5D__chunk_file_alloc(&index_info, &collective_chunk_list[i].chunk_states.chunk_current,
- &collective_chunk_list[i].chunk_states.new_chunk, &insert,
- collective_chunk_list[i].scaled) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk")
- } /* end for */
-
- if (NULL == (num_chunks_selected_array = (size_t *)H5MM_malloc((size_t)mpi_size * sizeof(size_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate num chunks selected array")
-
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Allgather(&chunk_list_num_entries, 1, MPI_UNSIGNED_LONG_LONG,
- num_chunks_selected_array, 1, MPI_UNSIGNED_LONG_LONG, io_info->comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code)
-
- /* If this process has any chunks selected, create a MPI type for collectively
- * writing out the chunks to file. Otherwise, the process contributes to the
+ if (H5D__mpio_collective_filtered_chunk_update(chunk_list, chunk_list_num_entries, chunk_hash_table,
+ chunk_msg_bufs, chunk_msg_bufs_len, io_info, type_info,
+ mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't update modified chunks")
+
+ /* Free up resources used by chunk hash table now that we're done updating chunks */
+ HASH_CLEAR(hh, chunk_hash_table);
+
+ /* All ranks now collectively re-allocate file space for all chunks */
+ if (H5D__mpio_collective_filtered_chunk_reallocate(chunk_list, chunk_list_num_entries,
+ rank_chunks_assigned_map, io_info, &index_info,
+ mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
+ "couldn't collectively re-allocate file space for chunks")
+
+ /* If this rank has any chunks selected, create a MPI type for collectively
+ * writing out the chunks to file. Otherwise, the rank contributes to the
* collective write with a none type.
*/
- if (chunk_list_num_entries) {
- size_t offset;
-
- /* During the collective re-allocation of chunks in the file, the record for each
- * chunk is only updated in the collective array, not in the local copy of chunks on each
- * process. However, each process needs the updated chunk records so that they can create
- * a MPI type for the collective write that will write to the chunk's possible new locations
- * in the file instead of the old ones. This ugly hack seems to be the best solution to
- * copy the information back to the local array and avoid having to modify the collective
- * write type function in an ugly way so that it will accept the collective array instead
- * of the local array. This works correctly because the array gather function guarantees
- * that the chunk data in the collective array is ordered in blocks by rank.
- */
- for (i = 0, offset = 0; i < (size_t)mpi_rank; i++)
- offset += num_chunks_selected_array[i];
-
- H5MM_memcpy(chunk_list, &collective_chunk_list[offset],
- num_chunks_selected_array[mpi_rank] * sizeof(H5D_filtered_collective_io_info_t));
+ if (H5D__mpio_collective_filtered_io_type(chunk_list, chunk_list_num_entries, io_info->op_type,
+ &mem_type, &mem_type_is_derived, &file_type,
+ &file_type_is_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "couldn't create MPI type for writing filtered chunks")
- /* Create single MPI type encompassing each selection in the dataspace */
- if (H5D__mpio_filtered_collective_write_type(chunk_list, chunk_list_num_entries, &mem_type,
- &mem_type_is_derived, &file_type,
- &file_type_is_derived) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "couldn't create MPI link chunk I/O type")
+ mpi_buf_count = (file_type_is_derived || mem_type_is_derived) ? 1 : 0;
- /* Override the write buffer to point to the address of the first
- * chunk data buffer
+ /* Setup contig storage info for I/O operation */
+ if (chunk_list_num_entries) {
+ /*
+ * Override the write buffer to point to the first
+ * chunk's data buffer
*/
io_info->u.wbuf = chunk_list[0].buf;
- } /* end if */
-
- /* We have a single, complicated MPI datatype for both memory & file */
- mpi_buf_count = (mem_type_is_derived && file_type_is_derived) ? (hsize_t)1 : (hsize_t)0;
- /* Set up the base storage address for this operation */
- ctg_store.contig.dset_addr = 0; /* Write address must be set to address 0 */
- io_info->store = &ctg_store;
+ /*
+ * Setup the base storage address for this operation
+ * to be the first chunk's file address
+ */
+ ctg_store.contig.dset_addr = chunk_list[0].chunk_new.offset;
+ }
+ else
+ ctg_store.contig.dset_addr = 0;
/* Perform I/O */
+ io_info->store = &ctg_store;
if (H5D__final_collective_io(io_info, type_info, mpi_buf_count, file_type, mem_type) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish MPI-IO")
+ /* Free up resources in anticipation of following collective operation */
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ if (chunk_list[i].buf) {
+ H5MM_free(chunk_list[i].buf);
+ chunk_list[i].buf = NULL;
+ }
+ }
+
/* Participate in the collective re-insertion of all chunks modified
- * in this iteration into the chunk index
+ * into the chunk index
*/
- for (i = 0; i < collective_chunk_list_num_entries; i++) {
- udata.chunk_block = collective_chunk_list[i].chunk_states.new_chunk;
- udata.common.scaled = collective_chunk_list[i].scaled;
- udata.chunk_idx = collective_chunk_list[i].index;
-
- if ((index_info.storage->ops->insert)(&index_info, &udata, io_info->dset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert chunk address into index")
- } /* end for */
- } /* end if */
+ if (H5D__mpio_collective_filtered_chunk_reinsert(chunk_list, chunk_list_num_entries,
+ rank_chunks_assigned_map, io_info, &index_info,
+ mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
+ "couldn't collectively re-insert modified chunks into chunk index")
+ }
done:
- /* Free resources used by a process which had some selection */
+ /* Free the MPI buf and file types, if they were derived */
+ if (mem_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&mem_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ if (file_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&file_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+
+ if (chunk_msg_bufs) {
+ for (i = 0; i < (size_t)chunk_msg_bufs_len; i++)
+ H5MM_free(chunk_msg_bufs[i]);
+
+ H5MM_free(chunk_msg_bufs);
+ }
+
+ HASH_CLEAR(hh, chunk_hash_table);
+
+ /* Free resources used by a rank which had some selection */
if (chunk_list) {
for (i = 0; i < chunk_list_num_entries; i++)
if (chunk_list[i].buf)
@@ -1502,16 +1858,13 @@ done:
H5MM_free(chunk_list);
} /* end if */
- if (num_chunks_selected_array)
- H5MM_free(num_chunks_selected_array);
- if (collective_chunk_list)
- H5MM_free(collective_chunk_list);
+ if (rank_chunks_assigned_map)
+ H5MM_free(rank_chunks_assigned_map);
- /* Free the MPI buf and file types, if they were derived */
- if (mem_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&mem_type)))
- HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
- if (file_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&file_type)))
- HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__link_chunk_filtered_collective_io() */
@@ -1534,7 +1887,8 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm)
+H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm,
+ int mpi_rank, int mpi_size)
{
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
@@ -1547,11 +1901,8 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
H5FD_mpio_collective_opt_t last_coll_opt_mode =
H5FD_MPIO_COLLECTIVE_IO; /* Last parallel transfer with independent IO or collective IO with this mode
*/
- size_t total_chunk; /* Total # of chunks in dataset */
-#ifdef H5Dmpio_DEBUG
- int mpi_rank;
-#endif
- size_t u; /* Local index variable */
+ size_t total_chunk; /* Total # of chunks in dataset */
+ size_t u; /* Local index variable */
H5D_mpio_actual_io_mode_t actual_io_mode =
H5D_MPIO_NO_COLLECTIVE; /* Local variable for tracking the I/O mode used. */
herr_t ret_value = SUCCEED;
@@ -1561,10 +1912,6 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
/* Set the actual chunk opt mode property */
H5CX_set_mpio_actual_chunk_opt(H5D_MPIO_MULTI_CHUNK);
-#ifdef H5Dmpio_DEBUG
- mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file);
-#endif
-
/* Retrieve total # of chunks in dataset */
H5_CHECKED_ASSIGN(total_chunk, size_t, fm->layout->u.chunk.nchunks, hsize_t);
HDassert(total_chunk != 0);
@@ -1572,13 +1919,13 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
/* Allocate memories */
chunk_io_option = (uint8_t *)H5MM_calloc(total_chunk);
chunk_addr = (haddr_t *)H5MM_calloc(total_chunk * sizeof(haddr_t));
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "total_chunk %zu\n", total_chunk);
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG_VA(mpi_rank, "total_chunk %zu", total_chunk);
#endif
/* Obtain IO option for each chunk */
- if (H5D__obtain_mpio_mode(io_info, fm, chunk_io_option, chunk_addr) < 0)
+ if (H5D__obtain_mpio_mode(io_info, fm, chunk_io_option, chunk_addr, mpi_rank, mpi_size) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTRECV, FAIL, "unable to obtain MPIO mode")
/* Set up contiguous I/O info object */
@@ -1606,9 +1953,8 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
H5S_t * fspace; /* Dataspace describing chunk & selection in it */
H5S_t * mspace; /* Dataspace describing selection in memory corresponding to this chunk */
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "mpi_rank = %d, chunk index = %zu\n", mpi_rank, u);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG_VA(mpi_rank, "mpi_rank = %d, chunk index = %zu", mpi_rank, u);
#endif
/* Get the chunk info for this chunk, if there are elements selected */
chunk_info = fm->select_chunk[u];
@@ -1626,10 +1972,9 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
* needs to contribute MPI NONE TYPE.
*/
if (chunk_io_option[u] == H5D_CHUNK_IO_MODE_COL) {
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "inside collective chunk IO mpi_rank = %d, chunk index = %zu\n",
- mpi_rank, u);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG_VA(mpi_rank, "inside collective chunk IO mpi_rank = %d, chunk index = %zu",
+ mpi_rank, u);
#endif
/* Set the file & memory dataspaces */
@@ -1665,10 +2010,9 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish shared collective MPI-IO")
} /* end if */
else { /* possible independent IO for this chunk */
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "inside independent IO mpi_rank = %d, chunk index = %zu\n", mpi_rank,
- u);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG_VA(mpi_rank, "inside independent IO mpi_rank = %d, chunk index = %zu", mpi_rank,
+ u);
#endif
HDassert(chunk_io_option[u] == 0);
@@ -1698,9 +2042,8 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
/* Perform the I/O */
if (H5D__inter_collective_io(&ctg_io_info, type_info, fspace, mspace) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish shared collective MPI-IO")
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "after inter collective IO\n");
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "after inter collective IO");
#endif
} /* end else */
} /* end for */
@@ -1720,80 +2063,101 @@ done:
/*-------------------------------------------------------------------------
* Function: H5D__multi_chunk_filtered_collective_io
*
- * Purpose: To do filtered collective IO iteratively to save on memory.
- * While link_chunk_filtered_collective_io will construct and
- * work on a list of all of the chunks selected in the IO
- * operation at once, this function works iteratively on a set
- * of chunks at a time; at most one chunk per rank per
- * iteration.
- *
- * 1. Construct a list of selected chunks in the collective IO
- * operation
- * A. If any chunk is being written to by more than 1
- * process, the process writing to the chunk which
- * currently has the least amount of chunks assigned
- * to it becomes the new owner (in the case of ties,
- * the lowest MPI rank becomes the new owner)
- * 2. If the operation is a read operation
- * A. Loop through each chunk in the operation
- * I. Read the chunk from the file
- * II. Unfilter the chunk
- * III. Scatter the read chunk data to the user's buffer
- * 3. If the operation is a write operation
- * A. Loop through each chunk in the operation
- * I. If this is not a full overwrite of the chunk
- * a) Read the chunk from file and pass the chunk
- * through the filter pipeline in reverse order
- * (Unfilter the chunk)
- * II. Update the chunk data with the modifications from
- * the owning process
- * III. Receive any modification data from other
- * processes and update the chunk data with these
- * modifications
- * IV. Filter the chunk
- * V. Contribute the chunk to an array gathered by
- * all processes which contains every chunk
- * modified in this iteration (up to one chunk
- * per process, some processes may not have a
- * selection/may have less chunks to work on than
- * other processes)
- * VI. All processes collectively re-allocate each
- * chunk from the gathered array with their new
- * sizes after the filter operation
- * VII. Proceed with the collective write operation
- * for the chunks modified on this iteration
- * VIII. All processes collectively re-insert each
- * chunk from the gathered array into the chunk
- * index
+ * Purpose: Performs collective I/O on filtered chunks iteratively to
+ * save on memory and potentially get better performance
+ * depending on the average number of chunks per rank. While
+ * linked-chunk I/O will construct and work on a list of all
+ * of the chunks selected in the I/O operation at once, this
+ * function works iteratively on a set of chunks at a time; at
+ * most one chunk per rank per iteration. The general
+ * algorithm is as follows:
+ *
+ * 1. Construct a list of selected chunks in the collective
+ * I/O operation
+ * 2. If the operation is a read operation, loop an amount of
+ * times equal to the maximum number of chunks selected on
+ * any particular rank and on each iteration:
+ * A. Participate in a collective read of chunks from
+ * the file (ranks that run out of chunks still need
+ * to participate)
+ * B. Unfilter the chunk that was read (if any)
+ * C. Scatter the read chunk's data to the application's
+ * read buffer
+ * 3. If the operation is a write operation, redistribute any
+ * chunks being written to by more than 1 MPI rank, such
+ * that the chunk is only owned by 1 MPI rank. The rank
+ * writing to the chunk which currently has the least
+ * amount of chunks assigned to it becomes the new owner
+ * (in the case of ties, the lowest MPI rank becomes the
+ * new owner). Then, loop an amount of times equal to the
+ * maximum number of chunks selected on any particular
+ * rank and on each iteration:
+ * A. Participate in a collective read of chunks from
+ * the file (ranks that run out of chunks still need
+ * to participate)
+ * I. If we actually read a chunk from the file (if
+ * a chunk is being fully overwritten, we skip
+ * reading it), pass the chunk through the filter
+ * pipeline in reverse order (unfilter the chunk)
+ * B. Update the chunk data with the modifications from
+ * the owning rank
+ * C. Receive any modification data from other ranks and
+ * update the chunk data with those modifications
+ * D. Filter the chunk
+ * E. Contribute the chunk to an array gathered by
+ * all ranks which contains information for
+ * re-allocating space in the file for every chunk
+ * modified in this iteration (up to one chunk per
+ * rank; some ranks may not have a selection/may have
+ * less chunks to work on than other ranks). Then,
+ * each rank collectively re-allocates each chunk
+ * from the gathered array with their new sizes
+ * after the filter operation
+ * F. Proceed with the collective write operation
+ * for the chunks modified on this iteration
+ * G. Contribute the chunk to an array gathered by
+ * all ranks which contains information for
+ * re-inserting every chunk modified on this
+ * iteration into the chunk index. Then, each rank
+ * collectively re-inserts each chunk from the
+ * gathered array into the chunk index
+ *
+ * TODO: Note that steps E. and G. here are both collective
+ * operations that partially share data from the
+ * H5D_filtered_collective_io_info_t structure. To
+ * try to conserve on memory a bit, the distributed
+ * arrays these operations create are discarded after
+ * each operation is performed. If memory consumption
+ * here proves to not be an issue, the necessary data
+ * for both operations could be combined into a single
+ * structure so that only one collective MPI operation
+ * is needed to carry out both operations, rather than
+ * two.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Jordan Henderson
- * Friday, Dec. 2nd, 2016
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- H5D_chunk_map_t *fm)
+ H5D_chunk_map_t *fm, int mpi_rank, int mpi_size)
{
- H5D_filtered_collective_io_info_t *chunk_list = NULL; /* The list of chunks being read/written */
- H5D_filtered_collective_io_info_t *collective_chunk_list =
- NULL; /* The list of chunks used during collective operations */
- H5D_storage_t store; /* union of EFL and chunk pointer in file space */
- H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
- H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
- MPI_Datatype *file_type_array = NULL;
- MPI_Datatype *mem_type_array = NULL;
- hbool_t * file_type_is_derived_array = NULL;
- hbool_t * mem_type_is_derived_array = NULL;
- hbool_t * has_chunk_selected_array =
- NULL; /* Array of whether or not each process is contributing a chunk to each iteration */
- size_t chunk_list_num_entries;
- size_t collective_chunk_list_num_entries;
- size_t i, j; /* Local index variable */
- int mpi_rank, mpi_size, mpi_code;
- herr_t ret_value = SUCCEED;
+ H5D_filtered_collective_io_info_t *chunk_list = NULL; /* The list of chunks being read/written */
+ H5D_filtered_collective_io_info_t *chunk_hash_table = NULL;
+ unsigned char ** chunk_msg_bufs = NULL;
+ H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
+ H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
+ MPI_Datatype mem_type = MPI_BYTE;
+ MPI_Datatype file_type = MPI_BYTE;
+ hbool_t mem_type_is_derived = FALSE;
+ hbool_t file_type_is_derived = FALSE;
+ hbool_t have_chunk_to_process;
+ size_t chunk_list_num_entries;
+ size_t i;
+ size_t max_num_chunks;
+ int chunk_msg_bufs_len = 0;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
@@ -1801,11 +2165,12 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
HDassert(type_info);
HDassert(fm);
- /* Obtain the current rank of the process and the number of processes */
- if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
- if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_DEBUG_VA(mpi_rank, "Performing Multi-chunk I/O (%s) with MPI Comm size of %d",
+ io_info->op_type == H5D_IO_OP_WRITE ? "write" : "read", mpi_size);
+ H5D_MPIO_TIME_START(mpi_rank, "Multi-chunk I/O");
+#endif
/* Set the actual chunk opt mode property */
H5CX_set_mpio_actual_chunk_opt(H5D_MPIO_MULTI_CHUNK);
@@ -1816,10 +2181,19 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
H5CX_set_mpio_actual_io_mode(H5D_MPIO_CHUNK_COLLECTIVE);
/* Build a list of selected chunks in the collective IO operation */
- if (H5D__construct_filtered_io_info_list(io_info, type_info, fm, &chunk_list, &chunk_list_num_entries) <
- 0)
+ if (H5D__mpio_collective_filtered_chunk_io_setup(io_info, type_info, fm, &chunk_list,
+ &chunk_list_num_entries, mpi_rank) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't construct filtered I/O info list")
+ /* Retrieve the maximum number of chunks selected for any rank */
+ if (MPI_SUCCESS != (mpi_code = MPI_Allreduce(&chunk_list_num_entries, &max_num_chunks, 1,
+ MPI_UNSIGNED_LONG_LONG, MPI_MAX, io_info->comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code)
+
+ /* If no one has anything selected at all, end the operation */
+ if (0 == max_num_chunks)
+ HGOTO_DONE(SUCCEED);
+
/* Set up contiguous I/O info object */
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
ctg_io_info.store = &ctg_store;
@@ -1827,190 +2201,147 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
/* Initialize temporary contiguous storage info */
ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size;
- ctg_store.contig.dset_addr = 0;
-
- /* Set dataset storage for I/O info */
- io_info->store = &store;
if (io_info->op_type == H5D_IO_OP_READ) { /* Filtered collective read */
- for (i = 0; i < chunk_list_num_entries; i++)
- if (H5D__filtered_collective_chunk_entry_io(&chunk_list[i], io_info, type_info, fm) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't process chunk entry")
- } /* end if */
+ for (i = 0; i < max_num_chunks; i++) {
+ /* Check if this rank has a chunk to work on for this iteration */
+ have_chunk_to_process = (i < chunk_list_num_entries);
+
+ if (H5D__mpio_collective_filtered_chunk_read(have_chunk_to_process ? &chunk_list[i] : NULL,
+ have_chunk_to_process ? 1 : 0, io_info, type_info,
+ mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't read filtered chunks")
+
+ if (have_chunk_to_process && chunk_list[i].buf) {
+ H5MM_free(chunk_list[i].buf);
+ chunk_list[i].buf = NULL;
+ }
+ }
+ }
else { /* Filtered collective write */
H5D_chk_idx_info_t index_info;
- H5D_chunk_ud_t udata;
- size_t max_num_chunks;
hsize_t mpi_buf_count;
/* Construct chunked index info */
- index_info.f = io_info->dset->oloc.file;
- index_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
- index_info.layout = &(io_info->dset->shared->layout.u.chunk);
- index_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
-
- /* Set up chunk information for insertion to chunk index */
- udata.common.layout = index_info.layout;
- udata.common.storage = index_info.storage;
- udata.filter_mask = 0;
-
- /* Retrieve the maximum number of chunks being written among all processes */
- if (MPI_SUCCESS != (mpi_code = MPI_Allreduce(&chunk_list_num_entries, &max_num_chunks, 1,
- MPI_UNSIGNED_LONG_LONG, MPI_MAX, io_info->comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code)
-
- /* If no one is writing anything at all, end the operation */
- if (!(max_num_chunks > 0))
- HGOTO_DONE(SUCCEED);
-
- /* Allocate arrays for storing MPI file and mem types and whether or not the
- * types were derived.
- */
- if (NULL == (file_type_array = (MPI_Datatype *)H5MM_malloc(max_num_chunks * sizeof(MPI_Datatype))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate file type array")
-
- if (NULL == (file_type_is_derived_array = (hbool_t *)H5MM_calloc(max_num_chunks * sizeof(hbool_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate file type is derived array")
-
- if (NULL == (mem_type_array = (MPI_Datatype *)H5MM_malloc(max_num_chunks * sizeof(MPI_Datatype))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate mem type array")
-
- if (NULL == (mem_type_is_derived_array = (hbool_t *)H5MM_calloc(max_num_chunks * sizeof(hbool_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate mem type is derived array")
-
- /* Iterate over the max number of chunks among all processes, as this process could
- * have no chunks left to work on, but it still needs to participate in the collective
- * re-allocation and re-insertion of chunks modified by other processes.
+ H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, io_info);
+
+ if (mpi_size > 1) {
+ /* Redistribute shared chunks being written to */
+ if (H5D__mpio_redistribute_shared_chunks(chunk_list, chunk_list_num_entries, io_info, fm,
+ mpi_rank, mpi_size, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to redistribute shared chunks")
+
+ /* Send any chunk modification messages for chunks this rank no longer owns */
+ if (H5D__mpio_share_chunk_modification_data(chunk_list, &chunk_list_num_entries, io_info,
+ type_info, mpi_rank, mpi_size, &chunk_hash_table,
+ &chunk_msg_bufs, &chunk_msg_bufs_len) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
+ "unable to send chunk modification data between MPI ranks")
+ }
+
+ /* Iterate over the max number of chunks among all ranks, as this rank could
+ * have no chunks left to work on, but it still needs to participate in the
+ * collective re-allocation and re-insertion of chunks modified by other ranks.
*/
for (i = 0; i < max_num_chunks; i++) {
- /* Check if this process has a chunk to work on for this iteration */
- hbool_t have_chunk_to_process =
- (i < chunk_list_num_entries) && (mpi_rank == chunk_list[i].owners.new_owner);
+ /* Check if this rank has a chunk to work on for this iteration */
+ have_chunk_to_process = (i < chunk_list_num_entries) && (mpi_rank == chunk_list[i].new_owner);
- if (have_chunk_to_process)
- if (H5D__filtered_collective_chunk_entry_io(&chunk_list[i], io_info, type_info, fm) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't process chunk entry")
-
- /* Gather the new chunk sizes to all processes for a collective re-allocation
- * of the chunks in the file
+ /* Proceed to update the chunk this rank owns (if any left) with its
+ * own modification data and data from other ranks, before re-filtering
+ * the chunks. As chunk reads are done collectively here, all ranks
+ * must participate.
*/
- if (H5D__mpio_array_gatherv(&chunk_list[i], have_chunk_to_process ? 1 : 0,
- sizeof(H5D_filtered_collective_io_info_t),
- (void **)&collective_chunk_list, &collective_chunk_list_num_entries,
- true, 0, io_info->comm, NULL) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL, "couldn't gather new chunk sizes")
-
- /* Participate in the collective re-allocation of all chunks modified
- * in this iteration.
+ if (H5D__mpio_collective_filtered_chunk_update(have_chunk_to_process ? &chunk_list[i] : NULL,
+ have_chunk_to_process ? 1 : 0, chunk_hash_table,
+ chunk_msg_bufs, chunk_msg_bufs_len, io_info,
+ type_info, mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't update modified chunks")
+
+ /* All ranks now collectively re-allocate file space for all chunks */
+ if (H5D__mpio_collective_filtered_chunk_reallocate(have_chunk_to_process ? &chunk_list[i] : NULL,
+ have_chunk_to_process ? 1 : 0, NULL, io_info,
+ &index_info, mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
+ "couldn't collectively re-allocate file space for chunks")
+
+ /*
+ * If this rank has a chunk to work on, create a MPI type
+ * for writing out the chunk. Otherwise, the rank will
+ * use MPI_BYTE for the file and memory type and specify
+ * a count of 0.
*/
- for (j = 0; j < collective_chunk_list_num_entries; j++) {
- hbool_t insert = FALSE;
-
- if (H5D__chunk_file_alloc(&index_info, &collective_chunk_list[j].chunk_states.chunk_current,
- &collective_chunk_list[j].chunk_states.new_chunk, &insert,
- chunk_list[j].scaled) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk")
- } /* end for */
+ if (H5D__mpio_collective_filtered_io_type(
+ have_chunk_to_process ? &chunk_list[i] : NULL, have_chunk_to_process ? 1 : 0,
+ io_info->op_type, &mem_type, &mem_type_is_derived, &file_type, &file_type_is_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "couldn't create MPI type for writing filtered chunks")
- if (NULL ==
- (has_chunk_selected_array = (hbool_t *)H5MM_malloc((size_t)mpi_size * sizeof(hbool_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate num chunks selected array")
+ mpi_buf_count = (file_type_is_derived || mem_type_is_derived) ? 1 : 0;
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Allgather(&have_chunk_to_process, 1, MPI_C_BOOL, has_chunk_selected_array, 1,
- MPI_C_BOOL, io_info->comm)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code)
-
- /* If this process has a chunk to work on, create a MPI type for the
- * memory and file for writing out the chunk
- */
+ /* Override the write buffer to point to the chunk data buffer */
if (have_chunk_to_process) {
- size_t offset;
- int mpi_type_count;
-
- for (j = 0, offset = 0; j < (size_t)mpi_rank; j++)
- offset += has_chunk_selected_array[j];
-
- /* Collect the new chunk info back to the local copy, since only the record in the
- * collective array gets updated by the chunk re-allocation */
- H5MM_memcpy(&chunk_list[i].chunk_states.new_chunk,
- &collective_chunk_list[offset].chunk_states.new_chunk,
- sizeof(chunk_list[i].chunk_states.new_chunk));
-
- H5_CHECKED_ASSIGN(mpi_type_count, int, chunk_list[i].chunk_states.new_chunk.length, hsize_t);
-
- /* Create MPI memory type for writing to chunk */
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Type_contiguous(mpi_type_count, MPI_BYTE, &mem_type_array[i])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
- if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&mem_type_array[i])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
- mem_type_is_derived_array[i] = TRUE;
-
- /* Create MPI file type for writing to chunk */
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Type_contiguous(mpi_type_count, MPI_BYTE, &file_type_array[i])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
- if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&file_type_array[i])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
- file_type_is_derived_array[i] = TRUE;
-
- mpi_buf_count = 1;
-
- /* Set up the base storage address for this operation */
- ctg_store.contig.dset_addr = chunk_list[i].chunk_states.new_chunk.offset;
-
- /* Override the write buffer to point to the address of the
- * chunk data buffer
+ /*
+ * Override the write buffer to point to the
+ * chunk's data buffer
*/
ctg_io_info.u.wbuf = chunk_list[i].buf;
- } /* end if */
- else {
- mem_type_array[i] = file_type_array[i] = MPI_BYTE;
- mpi_buf_count = 0;
- } /* end else */
+
+ /*
+ * Setup the base storage address for this
+ * operation to be the chunk's file address
+ */
+ ctg_store.contig.dset_addr = chunk_list[i].chunk_new.offset;
+ }
+ else
+ ctg_store.contig.dset_addr = 0;
/* Perform the I/O */
- if (H5D__final_collective_io(&ctg_io_info, type_info, mpi_buf_count, file_type_array[i],
- mem_type_array[i]) < 0)
+ if (H5D__final_collective_io(&ctg_io_info, type_info, mpi_buf_count, file_type, mem_type) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish MPI-IO")
+ /* Free up resources in anticipation of following collective operation */
+ if (have_chunk_to_process && chunk_list[i].buf) {
+ H5MM_free(chunk_list[i].buf);
+ chunk_list[i].buf = NULL;
+ }
+
/* Participate in the collective re-insertion of all chunks modified
* in this iteration into the chunk index
*/
- for (j = 0; j < collective_chunk_list_num_entries; j++) {
- udata.chunk_block = collective_chunk_list[j].chunk_states.new_chunk;
- udata.common.scaled = collective_chunk_list[j].scaled;
- udata.chunk_idx = collective_chunk_list[j].index;
-
- if ((index_info.storage->ops->insert)(&index_info, &udata, io_info->dset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
- "unable to insert chunk address into index")
- } /* end for */
+ if (H5D__mpio_collective_filtered_chunk_reinsert(have_chunk_to_process ? &chunk_list[i] : NULL,
+ have_chunk_to_process ? 1 : 0, NULL, io_info,
+ &index_info, mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
+ "couldn't collectively re-insert modified chunks into chunk index")
+
+ /* Free the MPI types, if they were derived */
+ if (mem_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&mem_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ mem_type_is_derived = FALSE;
+ if (file_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&file_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ file_type_is_derived = FALSE;
+ } /* end for */
+ }
- if (collective_chunk_list) {
- H5MM_free(collective_chunk_list);
- collective_chunk_list = NULL;
- } /* end if */
- if (has_chunk_selected_array) {
- H5MM_free(has_chunk_selected_array);
- has_chunk_selected_array = NULL;
- } /* end if */
- } /* end for */
+done:
+ /* Free the MPI buf and file types, if they were derived */
+ if (mem_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&mem_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ if (file_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&file_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
- /* Free the MPI file and memory types, if they were derived */
- for (i = 0; i < max_num_chunks; i++) {
- if (file_type_is_derived_array[i])
- if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&file_type_array[i])))
- HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ if (chunk_msg_bufs) {
+ for (i = 0; i < (size_t)chunk_msg_bufs_len; i++)
+ H5MM_free(chunk_msg_bufs[i]);
- if (mem_type_is_derived_array[i])
- if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&mem_type_array[i])))
- HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
- } /* end for */
- } /* end else */
+ H5MM_free(chunk_msg_bufs);
+ }
-done:
+ HASH_CLEAR(hh, chunk_hash_table);
+
+ /* Free resources used by a rank which had some selection */
if (chunk_list) {
for (i = 0; i < chunk_list_num_entries; i++)
if (chunk_list[i].buf)
@@ -2019,16 +2350,10 @@ done:
H5MM_free(chunk_list);
} /* end if */
- if (collective_chunk_list)
- H5MM_free(collective_chunk_list);
- if (file_type_array)
- H5MM_free(file_type_array);
- if (mem_type_array)
- H5MM_free(mem_type_array);
- if (file_type_is_derived_array)
- H5MM_free(file_type_is_derived_array);
- if (mem_type_is_derived_array)
- H5MM_free(mem_type_is_derived_array);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__multi_chunk_filtered_collective_io() */
@@ -2054,11 +2379,22 @@ H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
hbool_t mbt_is_derived = FALSE;
hbool_t mft_is_derived = FALSE;
MPI_Datatype mpi_file_type, mpi_buf_type;
- int mpi_code; /* MPI return code */
- herr_t ret_value = SUCCEED; /* return value */
+ int mpi_code; /* MPI return code */
+#ifdef H5Dmpio_DEBUG
+ int mpi_rank;
+#endif
+ herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_STATIC
+#ifdef H5Dmpio_DEBUG
+ mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file);
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Inter collective I/O");
+ if (mpi_rank < 0)
+ HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain MPI rank")
+#endif
+
if ((file_space != NULL) && (mem_space != NULL)) {
int mpi_file_count; /* Number of file "objects" to transfer */
hsize_t *permute_map = NULL; /* array that holds the mapping from the old,
@@ -2117,9 +2453,8 @@ H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
mft_is_derived = FALSE;
} /* end else */
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "before final collective IO \n");
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "before final collective I/O");
#endif
/* Perform final collective I/O operation */
@@ -2133,9 +2468,10 @@ done:
if (mft_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&mpi_file_type)))
HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "before leaving inter_collective_io ret_value = %d\n", ret_value);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_DEBUG_VA(mpi_rank, "before leaving inter_collective_io ret_value = %d", ret_value);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
#endif
FUNC_LEAVE_NOAPI(ret_value)
@@ -2157,10 +2493,21 @@ static herr_t
H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t mpi_buf_count,
MPI_Datatype mpi_file_type, MPI_Datatype mpi_buf_type)
{
+#ifdef H5Dmpio_DEBUG
+ int mpi_rank;
+#endif
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
+#ifdef H5Dmpio_DEBUG
+ mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file);
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Final collective I/O");
+ if (mpi_rank < 0)
+ HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain MPI rank")
+#endif
+
/* Pass buf type, file type to the file driver. */
if (H5CX_set_mpi_coll_datatypes(mpi_buf_type, mpi_file_type) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set MPI-I/O collective I/O datatypes")
@@ -2175,10 +2522,12 @@ H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
} /* end else */
done:
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "ret_value before leaving final_collective_io=%d\n", ret_value);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_DEBUG_VA(mpi_rank, "ret_value before leaving final_collective_io=%d", ret_value);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
#endif
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__final_collective_io */
@@ -2220,62 +2569,149 @@ H5D__cmp_chunk_addr(const void *chunk_addr_info1, const void *chunk_addr_info2)
*
* Return: -1, 0, 1
*
- * Programmer: Jordan Henderson
- * Wednesday, Nov. 30th, 2016
- *
*-------------------------------------------------------------------------
*/
static int
H5D__cmp_filtered_collective_io_info_entry(const void *filtered_collective_io_info_entry1,
const void *filtered_collective_io_info_entry2)
{
- haddr_t addr1 = HADDR_UNDEF, addr2 = HADDR_UNDEF;
+ const H5D_filtered_collective_io_info_t *entry1;
+ const H5D_filtered_collective_io_info_t *entry2;
+ haddr_t addr1 = HADDR_UNDEF;
+ haddr_t addr2 = HADDR_UNDEF;
+ int ret_value;
FUNC_ENTER_STATIC_NOERR
- addr1 = ((const H5D_filtered_collective_io_info_t *)filtered_collective_io_info_entry1)
- ->chunk_states.new_chunk.offset;
- addr2 = ((const H5D_filtered_collective_io_info_t *)filtered_collective_io_info_entry2)
- ->chunk_states.new_chunk.offset;
+ entry1 = (const H5D_filtered_collective_io_info_t *)filtered_collective_io_info_entry1;
+ entry2 = (const H5D_filtered_collective_io_info_t *)filtered_collective_io_info_entry2;
- FUNC_LEAVE_NOAPI(H5F_addr_cmp(addr1, addr2))
-} /* end H5D__cmp_filtered_collective_io_info_entry() */
+ addr1 = entry1->chunk_new.offset;
+ addr2 = entry2->chunk_new.offset;
-#if MPI_VERSION >= 3
+ /*
+ * If both chunk addresses are defined, H5F_addr_cmp is safe to use.
+ * Otherwise, if both addresses aren't defined, compared chunk
+ * entries based on their chunk index. Finally, if only one chunk
+ * address is defined, return the appropriate value based on which
+ * is defined.
+ */
+ if (H5F_addr_defined(addr1) && H5F_addr_defined(addr2)) {
+ ret_value = H5F_addr_cmp(addr1, addr2);
+ }
+ else if (!H5F_addr_defined(addr1) && !H5F_addr_defined(addr2)) {
+ hsize_t chunk_idx1 = entry1->index_info.chunk_idx;
+ hsize_t chunk_idx2 = entry2->index_info.chunk_idx;
+
+ ret_value = (chunk_idx1 > chunk_idx2) - (chunk_idx1 < chunk_idx2);
+ }
+ else
+ ret_value = H5F_addr_defined(addr1) ? 1 : -1;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__cmp_filtered_collective_io_info_entry() */
/*-------------------------------------------------------------------------
- * Function: H5D__cmp_filtered_collective_io_info_entry_owner
+ * Function: H5D__cmp_chunk_redistribute_info
*
- * Purpose: Routine to compare filtered collective chunk io info
- * entries's original owner fields
+ * Purpose: Routine to compare two H5D_chunk_redistribute_info_t
+ * structures
*
- * Description: Callback for qsort() to compare filtered collective chunk
- * io info entries's original owner fields
+ * Description: Callback for qsort() to compare two
+ * H5D_chunk_redistribute_info_t structures
+ *
+ * Return: -1, 0, 1
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5D__cmp_chunk_redistribute_info(const void *_entry1, const void *_entry2)
+{
+ const H5D_chunk_redistribute_info_t *entry1;
+ const H5D_chunk_redistribute_info_t *entry2;
+ hsize_t chunk_index1;
+ hsize_t chunk_index2;
+ int ret_value;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ entry1 = (const H5D_chunk_redistribute_info_t *)_entry1;
+ entry2 = (const H5D_chunk_redistribute_info_t *)_entry2;
+
+ chunk_index1 = entry1->chunk_idx;
+ chunk_index2 = entry2->chunk_idx;
+
+ if (chunk_index1 == chunk_index2) {
+ int orig_owner1 = entry1->orig_owner;
+ int orig_owner2 = entry2->orig_owner;
+
+ ret_value = (orig_owner1 > orig_owner2) - (orig_owner1 < orig_owner2);
+ }
+ else
+ ret_value = (chunk_index1 > chunk_index2) - (chunk_index1 < chunk_index2);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__cmp_chunk_redistribute_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__cmp_chunk_redistribute_info_orig_owner
*
- * Return: The difference between the two
- * H5D_filtered_collective_io_info_t's original owner fields
+ * Purpose: Routine to compare the original owning MPI rank for two
+ * H5D_chunk_redistribute_info_t structures
*
- * Programmer: Jordan Henderson
- * Monday, Apr. 10th, 2017
+ * Description: Callback for qsort() to compare the original owning MPI
+ * rank for two H5D_chunk_redistribute_info_t
+ * structures
+ *
+ * Return: -1, 0, 1
*
*-------------------------------------------------------------------------
*/
static int
-H5D__cmp_filtered_collective_io_info_entry_owner(const void *filtered_collective_io_info_entry1,
- const void *filtered_collective_io_info_entry2)
+H5D__cmp_chunk_redistribute_info_orig_owner(const void *_entry1, const void *_entry2)
{
- int owner1 = -1, owner2 = -1;
+ const H5D_chunk_redistribute_info_t *entry1;
+ const H5D_chunk_redistribute_info_t *entry2;
+ int owner1 = -1;
+ int owner2 = -1;
+ int ret_value;
FUNC_ENTER_STATIC_NOERR
- owner1 = ((const H5D_filtered_collective_io_info_t *)filtered_collective_io_info_entry1)
- ->owners.original_owner;
- owner2 = ((const H5D_filtered_collective_io_info_t *)filtered_collective_io_info_entry2)
- ->owners.original_owner;
+ entry1 = (const H5D_chunk_redistribute_info_t *)_entry1;
+ entry2 = (const H5D_chunk_redistribute_info_t *)_entry2;
- FUNC_LEAVE_NOAPI(owner1 - owner2)
-} /* end H5D__cmp_filtered_collective_io_info_entry_owner() */
-#endif
+ owner1 = entry1->orig_owner;
+ owner2 = entry2->orig_owner;
+
+ if (owner1 == owner2) {
+ haddr_t addr1 = entry1->chunk_block.offset;
+ haddr_t addr2 = entry2->chunk_block.offset;
+
+ /*
+ * If both chunk addresses are defined, H5F_addr_cmp is safe to use.
+ * Otherwise, if both addresses aren't defined, compared chunk
+ * entries based on their chunk index. Finally, if only one chunk
+ * address is defined, return the appropriate value based on which
+ * is defined.
+ */
+ if (H5F_addr_defined(addr1) && H5F_addr_defined(addr2)) {
+ ret_value = H5F_addr_cmp(addr1, addr2);
+ }
+ else if (!H5F_addr_defined(addr1) && !H5F_addr_defined(addr2)) {
+ hsize_t chunk_idx1 = entry1->chunk_idx;
+ hsize_t chunk_idx2 = entry2->chunk_idx;
+
+ ret_value = (chunk_idx1 > chunk_idx2) - (chunk_idx1 < chunk_idx2);
+ }
+ else
+ ret_value = H5F_addr_defined(addr1) ? 1 : -1;
+ }
+ else
+ ret_value = (owner1 > owner2) - (owner1 < owner2);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__cmp_chunk_redistribute_info_orig_owner() */
/*-------------------------------------------------------------------------
* Function: H5D__sort_chunk
@@ -2304,26 +2740,24 @@ H5D__cmp_filtered_collective_io_info_entry_owner(const void *filtered_collective
*/
static herr_t
H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
- H5D_chunk_addr_info_t chunk_addr_info_array[], int sum_chunk)
+ H5D_chunk_addr_info_t chunk_addr_info_array[], int sum_chunk, int mpi_rank, int mpi_size)
{
- H5SL_node_t * chunk_node; /* Current node in chunk skip list */
- H5D_chunk_info_t *chunk_info; /* Current chunking info. of this node. */
- haddr_t chunk_addr; /* Current chunking address of this node */
- haddr_t *total_chunk_addr_array = NULL; /* The array of chunk address for the total number of chunk */
- hbool_t do_sort = FALSE; /* Whether the addresses need to be sorted */
- int bsearch_coll_chunk_threshold;
- int many_chunk_opt = H5D_OBTAIN_ONE_CHUNK_ADDR_IND;
- int mpi_size; /* Number of MPI processes */
- int mpi_code; /* MPI return code */
- int i; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5SL_node_t * chunk_node; /* Current node in chunk skip list */
+ H5D_chunk_info_t *chunk_info; /* Current chunking info. of this node. */
+ haddr_t chunk_addr; /* Current chunking address of this node */
+ haddr_t *total_chunk_addr_array = NULL; /* The array of chunk address for the total number of chunk */
+ H5P_coll_md_read_flag_t md_reads_file_flag;
+ hbool_t md_reads_context_flag;
+ hbool_t restore_md_reads_state = FALSE;
+ hbool_t do_sort = FALSE; /* Whether the addresses need to be sorted */
+ int bsearch_coll_chunk_threshold;
+ int many_chunk_opt = H5D_OBTAIN_ONE_CHUNK_ADDR_IND;
+ int mpi_code; /* MPI return code */
+ int i; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
- /* Retrieve # of MPI processes */
- if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
-
/* Calculate the actual threshold to obtain all chunk addresses collectively
* The bigger this number is, the more possible the use of obtaining chunk
* address collectively.
@@ -2337,31 +2771,56 @@ H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
((sum_chunk / mpi_size) >= H5D_ALL_CHUNK_ADDR_THRES_COL_NUM))
many_chunk_opt = H5D_OBTAIN_ALL_CHUNK_ADDR_COL;
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "many_chunk_opt= %d\n", many_chunk_opt);
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG_VA(mpi_rank, "many_chunk_opt = %d", many_chunk_opt);
#endif
/* If we need to optimize the way to obtain the chunk address */
if (many_chunk_opt != H5D_OBTAIN_ONE_CHUNK_ADDR_IND) {
- int mpi_rank;
-
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "Coming inside H5D_OBTAIN_ALL_CHUNK_ADDR_COL\n");
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "Coming inside H5D_OBTAIN_ALL_CHUNK_ADDR_COL");
#endif
/* Allocate array for chunk addresses */
if (NULL == (total_chunk_addr_array =
(haddr_t *)H5MM_malloc(sizeof(haddr_t) * (size_t)fm->layout->u.chunk.nchunks)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory chunk address array")
- /* Retrieve all the chunk addresses with process 0 */
- if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
-
if (mpi_rank == 0) {
- if (H5D__chunk_addrmap(io_info, total_chunk_addr_array) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
+ herr_t result;
+
+ /*
+ * If enabled, disable collective metadata reads here.
+ * Since the chunk address mapping is done on rank 0
+ * only here, it will cause problems if collective
+ * metadata reads are enabled.
+ */
+ if (H5F_get_coll_metadata_reads(io_info->dset->oloc.file)) {
+ md_reads_file_flag = H5P_FORCE_FALSE;
+ md_reads_context_flag = FALSE;
+ H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag,
+ &md_reads_context_flag);
+ restore_md_reads_state = TRUE;
+ }
+
+ result = H5D__chunk_addrmap(io_info, total_chunk_addr_array);
+
+ /* Ensure that we restore the old collective metadata reads state */
+ if (restore_md_reads_state) {
+ H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag,
+ &md_reads_context_flag);
+ restore_md_reads_state = FALSE;
+ }
+
+ if (result < 0) {
+ size_t u;
+
+ /* Clear total chunk address array */
+ for (u = 0; u < (size_t)fm->layout->u.chunk.nchunks; u++)
+ total_chunk_addr_array[u] = HADDR_UNDEF;
+
+ /* Push error, but still participate in following MPI_Bcast */
+ HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
+ }
} /* end if */
/* Broadcasting the MPI_IO option info. and chunk address info. */
@@ -2405,10 +2864,10 @@ H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
chunk_node = H5SL_next(chunk_node);
} /* end while */
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- HDfprintf(H5DEBUG(D), "before Qsort\n");
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_DEBUG(mpi_rank, "before Qsort");
#endif
+
if (do_sort) {
size_t num_chunks = H5SL_count(fm->sel_chunks);
@@ -2416,6 +2875,10 @@ H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
} /* end if */
done:
+ /* Re-enable collective metadata reads if we disabled them */
+ if (restore_md_reads_state)
+ H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag, &md_reads_context_flag);
+
if (total_chunk_addr_array)
H5MM_xfree(total_chunk_addr_array);
@@ -2432,7 +2895,7 @@ done:
*
* 1) Each process provides two piece of information for all chunks having selection
* a) chunk index
- * b) wheather this chunk is regular(for MPI derived datatype not working case)
+ * b) whether this chunk is regular(for MPI derived datatype not working case)
*
* 2) Gather all the information to the root process
*
@@ -2461,22 +2924,24 @@ done:
*/
static herr_t
H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assign_io_mode[],
- haddr_t chunk_addr[])
+ haddr_t chunk_addr[], int mpi_rank, int mpi_size)
{
- size_t total_chunks;
- unsigned percent_nproc_per_chunk, threshold_nproc_per_chunk;
- uint8_t * io_mode_info = NULL;
- uint8_t * recv_io_mode_info = NULL;
- uint8_t * mergebuf = NULL;
- uint8_t * tempbuf;
- H5SL_node_t * chunk_node;
- H5D_chunk_info_t *chunk_info;
- int mpi_size, mpi_rank;
- MPI_Comm comm;
- int root;
- size_t ic;
- int mpi_code;
- herr_t ret_value = SUCCEED;
+ size_t total_chunks;
+ unsigned percent_nproc_per_chunk, threshold_nproc_per_chunk;
+ uint8_t * io_mode_info = NULL;
+ uint8_t * recv_io_mode_info = NULL;
+ uint8_t * mergebuf = NULL;
+ uint8_t * tempbuf;
+ H5SL_node_t * chunk_node;
+ H5D_chunk_info_t * chunk_info;
+ H5P_coll_md_read_flag_t md_reads_file_flag;
+ hbool_t md_reads_context_flag;
+ hbool_t restore_md_reads_state = FALSE;
+ MPI_Comm comm;
+ int root;
+ size_t ic;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
@@ -2484,12 +2949,6 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
root = 0;
comm = io_info->comm;
- /* Obtain the number of process and the current rank of the process */
- if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
- if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
-
/* Setup parameters */
H5_CHECKED_ASSIGN(total_chunks, size_t, fm->layout->u.chunk.nchunks, hsize_t);
if (H5CX_get_mpio_chunk_opt_ratio(&percent_nproc_per_chunk) < 0)
@@ -2536,6 +2995,20 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
size_t nproc;
unsigned *nproc_per_chunk;
+ /*
+ * If enabled, disable collective metadata reads here.
+ * Since the chunk address mapping is done on rank 0
+ * only here, it will cause problems if collective
+ * metadata reads are enabled.
+ */
+ if (H5F_get_coll_metadata_reads(io_info->dset->oloc.file)) {
+ md_reads_file_flag = H5P_FORCE_FALSE;
+ md_reads_context_flag = FALSE;
+ H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag,
+ &md_reads_context_flag);
+ restore_md_reads_state = TRUE;
+ }
+
/* pre-computing: calculate number of processes and
regularity of the selection occupied in each chunk */
if (NULL == (nproc_per_chunk = (unsigned *)H5MM_calloc(total_chunks * sizeof(unsigned))))
@@ -2602,6 +3075,10 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
#endif
done:
+ /* Re-enable collective metadata reads if we disabled them */
+ if (restore_md_reads_state)
+ H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag, &md_reads_context_flag);
+
if (io_mode_info)
H5MM_free(io_mode_info);
if (mergebuf)
@@ -2615,34 +3092,32 @@ done:
} /* end H5D__obtain_mpio_mode() */
/*-------------------------------------------------------------------------
- * Function: H5D__construct_filtered_io_info_list
+ * Function: H5D__mpio_collective_filtered_chunk_io_setup
*
* Purpose: Constructs a list of entries which contain the necessary
* information for inter-process communication when performing
* collective io on filtered chunks. This list is used by
- * each process when performing I/O on locally selected chunks
- * and also in operations that must be collectively done
- * on every chunk, such as chunk re-allocation, insertion of
- * chunks into the chunk index, etc.
+ * each MPI rank when performing I/O on locally selected
+ * chunks and also in operations that must be collectively
+ * done on every chunk, such as chunk re-allocation, insertion
+ * of chunks into the chunk index, etc.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Jordan Henderson
- * Tuesday, January 10th, 2017
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__construct_filtered_io_info_list(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- const H5D_chunk_map_t * fm,
- H5D_filtered_collective_io_info_t **chunk_list, size_t *num_entries)
+H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
+ const H5D_chunk_map_t * fm,
+ H5D_filtered_collective_io_info_t **chunk_list,
+ size_t *num_entries, int mpi_rank)
{
- H5D_filtered_collective_io_info_t *local_info_array =
- NULL; /* The list of initially selected chunks for this process */
- size_t num_chunks_selected;
- size_t i;
- int mpi_rank;
- herr_t ret_value = SUCCEED;
+ H5D_filtered_collective_io_info_t *local_info_array = NULL;
+ H5D_chunk_ud_t udata;
+ hbool_t filter_partial_edge_chunks;
+ size_t num_chunks_selected;
+ size_t i;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
@@ -2652,19 +3127,23 @@ H5D__construct_filtered_io_info_list(const H5D_io_info_t *io_info, const H5D_typ
HDassert(chunk_list);
HDassert(num_entries);
- if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Filtered Collective I/O Setup");
+#endif
- /* Each process builds a local list of the chunks they have selected */
+ /* Each rank builds a local list of the chunks they have selected */
if ((num_chunks_selected = H5SL_count(fm->sel_chunks))) {
H5D_chunk_info_t *chunk_info;
- H5D_chunk_ud_t udata;
H5SL_node_t * chunk_node;
hsize_t select_npoints;
- hssize_t chunk_npoints;
+ hbool_t need_sort = FALSE;
- if (NULL == (local_info_array = (H5D_filtered_collective_io_info_t *)H5MM_malloc(
- num_chunks_selected * sizeof(H5D_filtered_collective_io_info_t))))
+ /* Determine whether partial edge chunks should be filtered */
+ filter_partial_edge_chunks = !(io_info->dset->shared->layout.u.chunk.flags &
+ H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS);
+
+ if (NULL == (local_info_array = H5MM_malloc(num_chunks_selected * sizeof(*local_info_array))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate local io info array buffer")
chunk_node = H5SL_first(fm->sel_chunks);
@@ -2675,275 +3154,787 @@ H5D__construct_filtered_io_info_list(const H5D_io_info_t *io_info, const H5D_typ
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
- local_info_array[i].index = chunk_info->index;
- local_info_array[i].chunk_states.chunk_current = local_info_array[i].chunk_states.new_chunk =
- udata.chunk_block;
- local_info_array[i].num_writers = 0;
- local_info_array[i].owners.original_owner = local_info_array[i].owners.new_owner = mpi_rank;
- local_info_array[i].buf = NULL;
-
- local_info_array[i].async_info.num_receive_requests = 0;
- local_info_array[i].async_info.receive_buffer_array = NULL;
- local_info_array[i].async_info.receive_requests_array = NULL;
-
- H5MM_memcpy(local_info_array[i].scaled, chunk_info->scaled, sizeof(chunk_info->scaled));
-
- select_npoints = H5S_GET_SELECT_NPOINTS(chunk_info->mspace);
- local_info_array[i].io_size = (size_t)select_npoints * type_info->src_type_size;
-
- /* Currently the full overwrite status of a chunk is only obtained on a per-process
- * basis. This means that if the total selection in the chunk, as determined by the combination
- * of selections of all of the processes interested in the chunk, covers the entire chunk,
- * the performance optimization of not reading the chunk from the file is still valid, but
- * is not applied in the current implementation. Something like an appropriately placed
- * MPI_Allreduce or a running total of the number of chunk points selected during chunk
- * redistribution should suffice for implementing this case - JTH.
+ /* Initialize rank-local chunk info */
+ local_info_array[i].chunk_info = chunk_info;
+ local_info_array[i].chunk_buf_size = 0;
+ local_info_array[i].num_writers = 0;
+ local_info_array[i].orig_owner = mpi_rank;
+ local_info_array[i].new_owner = mpi_rank;
+ local_info_array[i].buf = NULL;
+
+ select_npoints = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
+ local_info_array[i].io_size = (size_t)select_npoints * type_info->dst_type_size;
+
+ /*
+ * Determine whether this chunk will need to be read from the file. If this is
+ * a read operation, the chunk will be read. If this is a write operation, we
+ * generally need to read a filtered chunk from the file before modifying it,
+ * unless the chunk is being fully overwritten.
+ *
+ * TODO: Currently the full overwrite status of a chunk is only obtained on a
+ * per-rank basis. This means that if the total selection in the chunk, as
+ * determined by the combination of selections of all of the ranks interested in
+ * the chunk, covers the entire chunk, the performance optimization of not reading
+ * the chunk from the file is still valid, but is not applied in the current
+ * implementation.
+ *
+ * To implement this case, a few approaches were considered:
+ *
+ * - Keep a running total (distributed to each rank) of the number of chunk
+ * elements selected during chunk redistribution and compare that to the total
+ * number of elements in the chunk once redistribution is finished
+ *
+ * - Process all incoming chunk messages before doing I/O (these are currently
+ * processed AFTER doing I/O), combine the owning rank's selection in a chunk
+ * with the selections received from other ranks and check to see whether that
+ * combined selection covers the entire chunk
+ *
+ * The first approach will be dangerous if the application performs an overlapping
+ * write to a chunk, as the number of selected elements can equal or exceed the
+ * number of elements in the chunk without the whole chunk selection being covered.
+ * While it might be considered erroneous for an application to do an overlapping
+ * write, we don't explicitly disallow it.
+ *
+ * The second approach contains a bit of complexity in that part of the chunk
+ * messages will be needed before doing I/O and part will be needed after doing I/O.
+ * Since modification data from chunk messages can't be applied until after any I/O
+ * is performed (otherwise, we'll overwrite any applied modification data), chunk
+ * messages are currently entirely processed after I/O. However, in order to determine
+ * if a chunk is being fully overwritten, we need the dataspace portion of the chunk
+ * messages before doing I/O. The naive way to do this is to process chunk messages
+ * twice, using just the relevant information from the message before and after I/O.
+ * The better way would be to avoid processing chunk messages twice by extracting (and
+ * keeping around) the dataspace portion of the message before I/O and processing the
+ * rest of the chunk message after I/O. Note that the dataspace portion of each chunk
+ * message is used to correctly apply chunk modification data from the message, so
+ * must be kept around both before and after I/O in this case.
+ */
+ if (io_info->op_type == H5D_IO_OP_READ)
+ local_info_array[i].need_read = TRUE;
+ else {
+ local_info_array[i].need_read =
+ local_info_array[i].io_size < (size_t)io_info->dset->shared->layout.u.chunk.size;
+ }
+
+ local_info_array[i].skip_filter_pline = FALSE;
+ if (!filter_partial_edge_chunks) {
+ /*
+ * If this is a partial edge chunk and the "don't filter partial edge
+ * chunks" flag is set, make sure not to apply filters to the chunk.
+ */
+ if (H5D__chunk_is_partial_edge_chunk(io_info->dset->shared->ndims,
+ io_info->dset->shared->layout.u.chunk.dim,
+ chunk_info->scaled, io_info->dset->shared->curr_dims))
+ local_info_array[i].skip_filter_pline = TRUE;
+ }
+
+ /* Initialize the chunk's shared info */
+ local_info_array[i].chunk_current = udata.chunk_block;
+ local_info_array[i].chunk_new = udata.chunk_block;
+
+ /*
+ * Check if the list is not in ascending order of offset in the file
+ * or has unallocated chunks. In either case, the list should get
+ * sorted.
+ */
+ if (i) {
+ haddr_t curr_chunk_offset = local_info_array[i].chunk_current.offset;
+ haddr_t prev_chunk_offset = local_info_array[i - 1].chunk_current.offset;
+
+ if (!H5F_addr_defined(prev_chunk_offset) || !H5F_addr_defined(curr_chunk_offset) ||
+ (curr_chunk_offset < prev_chunk_offset))
+ need_sort = TRUE;
+ }
+
+ /*
+ * Extensible arrays may calculate a chunk's index a little differently
+ * than normal when the dataset's unlimited dimension is not the
+ * slowest-changing dimension, so set the index here based on what the
+ * extensible array code calculated instead of what was calculated
+ * in the chunk file mapping.
*/
- if ((chunk_npoints = H5S_GET_EXTENT_NPOINTS(chunk_info->fspace)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
- local_info_array[i].full_overwrite =
- (local_info_array[i].io_size >= (hsize_t)chunk_npoints * type_info->dst_type_size) ? TRUE
- : FALSE;
+ if (io_info->dset->shared->layout.u.chunk.idx_type == H5D_CHUNK_IDX_EARRAY)
+ local_info_array[i].index_info.chunk_idx = udata.chunk_idx;
+ else
+ local_info_array[i].index_info.chunk_idx = chunk_info->index;
+
+ local_info_array[i].index_info.filter_mask = udata.filter_mask;
+ local_info_array[i].index_info.need_insert = FALSE;
chunk_node = H5SL_next(chunk_node);
- } /* end for */
- } /* end if */
+ }
- /* Redistribute shared chunks to new owners as necessary */
- if (io_info->op_type == H5D_IO_OP_WRITE)
-#if MPI_VERSION >= 3
- if (H5D__chunk_redistribute_shared_chunks(io_info, type_info, fm, local_info_array,
- &num_chunks_selected) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to redistribute shared chunks")
-#else
- HGOTO_ERROR(
- H5E_DATASET, H5E_WRITEERROR, FAIL,
- "unable to redistribute shared chunks - MPI version < 3 (MPI_Mprobe and MPI_Imrecv missing)")
+ /* Ensure the chunk list is sorted in ascending order of offset in the file */
+ if (need_sort)
+ HDqsort(local_info_array, num_chunks_selected, sizeof(H5D_filtered_collective_io_info_t),
+ H5D__cmp_filtered_collective_io_info_entry);
+
+#ifdef H5Dmpio_DEBUG
+ H5D__mpio_dump_collective_filtered_chunk_list(local_info_array, num_chunks_selected, mpi_rank);
#endif
+ }
+ else if (H5F_get_coll_metadata_reads(io_info->dset->oloc.file)) {
+ hsize_t scaled[H5O_LAYOUT_NDIMS] = {0};
+
+ /*
+ * If this rank has no selection in the dataset and collective
+ * metadata reads are enabled, do a fake lookup of a chunk to
+ * ensure that this rank has the chunk index opened. Otherwise,
+ * only the ranks that had a selection will have opened the
+ * chunk index and they will have done so independently. Therefore,
+ * when ranks with no selection participate in later collective
+ * metadata reads, they will try to open the chunk index collectively
+ * and issues will occur since other ranks won't participate.
+ *
+ * In the future, we should consider having a chunk index "open"
+ * callback that can be used to ensure collectivity between ranks
+ * in a more natural way, but this hack should suffice for now.
+ */
+ if (H5D__chunk_lookup(io_info->dset, scaled, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
+ }
*chunk_list = local_info_array;
*num_entries = num_chunks_selected;
done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__construct_filtered_io_info_list() */
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
-#if MPI_VERSION >= 3
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_collective_filtered_chunk_io_setup() */
/*-------------------------------------------------------------------------
- * Function: H5D__chunk_redistribute_shared_chunks
- *
- * Purpose: When performing a collective write on a Dataset with
- * filters applied, this function is used to redistribute any
- * chunks which are selected by more than one process, so as
- * to preserve file integrity after the write by ensuring
- * that any shared chunks are only modified by one process.
- *
- * The current implementation follows this 3-phase process:
- *
- * - Collect everyone's list of chunks into one large list,
- * sort the list in increasing order of chunk offset in the
- * file and hand the list off to rank 0
- *
- * - Rank 0 scans the list looking for matching runs of chunk
- * offset in the file (corresponding to a shared chunk which
- * has been selected by more than one rank in the I/O
- * operation) and for each shared chunk, it redistributes
- * the chunk to the process writing to the chunk which
- * currently has the least amount of chunks assigned to it
- * by modifying the "new_owner" field in each of the list
- * entries corresponding to that chunk
- *
- * - After the chunks have been redistributed, rank 0 re-sorts
- * the list in order of previous owner so that each rank
- * will get back exactly the array that they contributed to
- * the redistribution operation, with the "new_owner" field
- * of each chunk they are modifying having possibly been
- * modified. Rank 0 then scatters each segment of the list
- * back to its corresponding rank
+ * Function: H5D__mpio_redistribute_shared_chunks
+ *
+ * Purpose: When performing a parallel write on a chunked Dataset with
+ * filters applied, we must ensure that any particular chunk
+ * is only written to by a single MPI rank in order to avoid
+ * potential data races on the chunk. This function is used to
+ * redistribute (by assigning ownership to a single rank) any
+ * chunks which are selected by more than one MPI rank.
+ *
+ * An initial Allgather is performed to determine how many
+ * chunks each rank has selected in the write operation and
+ * then that number is compared against a threshold value to
+ * determine whether chunk redistribution should be done on
+ * MPI rank 0 only, or on all MPI ranks.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Jordan Henderson
- * Monday, May 1, 2017
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_redistribute_shared_chunks(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries, const H5D_io_info_t *io_info,
+ const H5D_chunk_map_t *fm, int mpi_rank, int mpi_size,
+ size_t **rank_chunks_assigned_map)
+{
+ hbool_t redistribute_on_all_ranks;
+ size_t *num_chunks_map = NULL;
+ size_t coll_chunk_list_size = 0;
+ size_t i;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(chunk_list || 0 == chunk_list_num_entries);
+ HDassert(io_info);
+ HDassert(fm);
+ HDassert(mpi_size > 1); /* No chunk sharing is possible for MPI Comm size of 1 */
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Redistribute shared chunks");
+#endif
+
+ /*
+ * Allocate an array for each rank to keep track of the number of
+ * chunks assigned to any other rank in order to cut down on future
+ * MPI communication.
+ */
+ if (NULL == (num_chunks_map = H5MM_malloc((size_t)mpi_size * sizeof(*num_chunks_map))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate assigned chunks array")
+
+ /* Perform initial Allgather to determine the collective chunk list size */
+ if (MPI_SUCCESS != (mpi_code = MPI_Allgather(&chunk_list_num_entries, 1, H5_SIZE_T_AS_MPI_TYPE,
+ num_chunks_map, 1, H5_SIZE_T_AS_MPI_TYPE, io_info->comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code)
+
+ for (i = 0; i < (size_t)mpi_size; i++)
+ coll_chunk_list_size += num_chunks_map[i];
+
+ /*
+ * Determine whether we should perform chunk redistribution on all
+ * ranks or just rank 0. For a relatively small number of chunks,
+ * we redistribute on all ranks to cut down on MPI communication
+ * overhead. For a larger number of chunks, we redistribute on
+ * rank 0 only to cut down on memory usage.
+ */
+ redistribute_on_all_ranks = coll_chunk_list_size < H5D_CHUNK_REDISTRIBUTE_THRES;
+
+ if (H5D__mpio_redistribute_shared_chunks_int(chunk_list, num_chunks_map, redistribute_on_all_ranks,
+ io_info, fm, mpi_rank, mpi_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREDISTRIBUTE, FAIL, "can't redistribute shared chunks")
+
+ /*
+ * If the caller provided a pointer for the mapping from
+ * rank value -> number of chunks assigned, return that
+ * mapping here.
+ */
+ if (rank_chunks_assigned_map) {
+ /*
+ * If we performed chunk redistribution on rank 0 only, distribute
+ * the rank value -> number of chunks assigned mapping back to all
+ * ranks.
+ */
+ if (!redistribute_on_all_ranks) {
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Bcast(num_chunks_map, mpi_size, H5_SIZE_T_AS_MPI_TYPE, 0, io_info->comm)))
+ HMPI_GOTO_ERROR(FAIL, "couldn't broadcast chunk mapping to other ranks", mpi_code)
+ }
+
+ *rank_chunks_assigned_map = num_chunks_map;
+ }
+
+done:
+ if (!rank_chunks_assigned_map || (ret_value < 0)) {
+ num_chunks_map = H5MM_xfree(num_chunks_map);
+ }
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_redistribute_shared_chunks() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_redistribute_shared_chunks_int
+ *
+ * Purpose: Routine to perform redistribution of shared chunks during
+ * parallel writes to datasets with filters applied.
+ *
+ * If `all_ranks_involved` is TRUE, chunk redistribution
+ * occurs on all MPI ranks. This is usually done when there
+ * is a relatively small number of chunks involved in order to
+ * cut down on MPI communication overhead while increasing
+ * total memory usage a bit.
+ *
+ * If `all_ranks_involved` is FALSE, only rank 0 will perform
+ * chunk redistribution. This is usually done when there is
+ * a relatively large number of chunks involved in order to
+ * cut down on total memory usage at the cost of increased
+ * overhead from MPI communication.
+ *
+ * This implementation is as follows:
+ *
+ * - All MPI ranks send their list of selected chunks to the
+ * ranks involved in chunk redistribution. Then, the
+ * involved ranks sort this new list in order of chunk
+ * index.
+ *
+ * - The involved ranks scan the list looking for matching
+ * runs of chunk index values (corresponding to a shared
+ * chunk which has been selected by more than one rank in
+ * the I/O operation) and for each shared chunk,
+ * redistribute the chunk to the MPI rank writing to the
+ * chunk which currently has the least amount of chunks
+ * assigned to it. This is done by modifying the "new_owner"
+ * field in each of the list entries corresponding to that
+ * chunk. The involved ranks then re-sort the list in order
+ * of original chunk owner so that each rank's section of
+ * contributed chunks is contiguous in the collective chunk
+ * list.
+ *
+ * - If chunk redistribution occurred on all ranks, each rank
+ * scans through the collective chunk list to find their
+ * contributed section of chunks and uses that to update
+ * their local chunk list with the newly-updated "new_owner"
+ * and "num_writers" fields. If chunk redistribution
+ * occurred only on rank 0, an MPI_Scatterv operation will
+ * be used to scatter the segments of the collective chunk
+ * list from rank 0 back to the corresponding ranks.
+ *
+ * Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- const H5D_chunk_map_t * fm,
- H5D_filtered_collective_io_info_t *local_chunk_array,
- size_t * local_chunk_array_num_entries)
+H5D__mpio_redistribute_shared_chunks_int(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t *num_chunks_assigned_map, hbool_t all_ranks_involved,
+ const H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
+ int mpi_rank, int mpi_size)
{
- H5D_filtered_collective_io_info_t *shared_chunks_info_array =
- NULL; /* The list of all chunks selected in the operation by all processes */
- H5S_sel_iter_t *mem_iter = NULL; /* Memory iterator for H5D__gather_mem */
- unsigned char **mod_data =
- NULL; /* Array of chunk modification data buffers sent by a process to new chunk owners */
- MPI_Request *send_requests = NULL; /* Array of MPI_Isend chunk modification data send requests */
- MPI_Status * send_statuses = NULL; /* Array of MPI_Isend chunk modification send statuses */
- hbool_t mem_iter_init = FALSE;
- size_t shared_chunks_info_array_num_entries = 0;
- size_t num_send_requests = 0;
- size_t * num_assigned_chunks_array = NULL;
- size_t i, last_assigned_idx;
- int * send_counts = NULL;
- int * send_displacements = NULL;
- int scatter_recvcount_int;
- int mpi_rank, mpi_size, mpi_code;
+ MPI_Datatype struct_type;
+ MPI_Datatype packed_type;
+ hbool_t struct_type_derived = FALSE;
+ hbool_t packed_type_derived = FALSE;
+ size_t i;
+ size_t coll_chunk_list_num_entries = 0;
+ void * coll_chunk_list = NULL;
+ int * counts_disps_array = NULL;
+ int * counts_ptr = NULL;
+ int * displacements_ptr = NULL;
+ int num_chunks_int;
+ int mpi_code;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
+ HDassert(num_chunks_assigned_map);
+ HDassert(chunk_list || 0 == num_chunks_assigned_map[mpi_rank]);
HDassert(io_info);
- HDassert(type_info);
HDassert(fm);
- HDassert(local_chunk_array_num_entries);
+ HDassert(mpi_size > 1);
- if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank")
- if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Redistribute shared chunks (internal)");
+#endif
- /* Set to latest format for encoding dataspace */
- H5CX_set_libver_bounds(NULL);
+ /*
+ * Make sure it's safe to cast this rank's number
+ * of chunks to be sent into an int for MPI
+ */
+ H5_CHECKED_ASSIGN(num_chunks_int, int, num_chunks_assigned_map[mpi_rank], size_t);
- if (*local_chunk_array_num_entries)
- if (NULL == (send_requests =
- (MPI_Request *)H5MM_malloc(*local_chunk_array_num_entries * sizeof(MPI_Request))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate send requests buffer")
+ /*
+ * Phase 1 - Participate in collective gathering of every rank's
+ * list of chunks to the ranks which are performing the redistribution
+ * operation.
+ */
- if (NULL == (mem_iter = (H5S_sel_iter_t *)H5MM_malloc(sizeof(H5S_sel_iter_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate memory iterator")
+ if (all_ranks_involved || (mpi_rank == 0)) {
+ /*
+ * Allocate array to store the receive counts of each rank, as well as
+ * the displacements into the final array where each rank will place
+ * their data. The first half of the array contains the receive counts
+ * (in rank order), while the latter half contains the displacements
+ * (also in rank order).
+ */
+ if (NULL == (counts_disps_array = H5MM_malloc(2 * (size_t)mpi_size * sizeof(*counts_disps_array)))) {
+ /* Push an error, but still participate in collective gather operation */
+ HDONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "couldn't allocate receive counts and displacements array")
+ }
+ else {
+ /* Set the receive counts from the assigned chunks map */
+ counts_ptr = counts_disps_array;
+
+ for (i = 0; i < (size_t)mpi_size; i++)
+ H5_CHECKED_ASSIGN(counts_ptr[i], int, num_chunks_assigned_map[i], size_t);
+
+ /* Set the displacements into the receive buffer for the gather operation */
+ displacements_ptr = &counts_disps_array[mpi_size];
+
+ *displacements_ptr = 0;
+ for (i = 1; i < (size_t)mpi_size; i++)
+ displacements_ptr[i] = displacements_ptr[i - 1] + counts_ptr[i - 1];
+ }
+ }
- /* Gather every rank's list of chunks to rank 0 to allow it to perform the redistribution operation. After
- * this call, the gathered list will initially be sorted in increasing order of chunk offset in the file.
+ /*
+ * Construct MPI derived types for extracting information
+ * necessary for MPI communication
*/
- if (H5D__mpio_array_gatherv(local_chunk_array, *local_chunk_array_num_entries,
- sizeof(H5D_filtered_collective_io_info_t), (void **)&shared_chunks_info_array,
- &shared_chunks_info_array_num_entries, false, 0, io_info->comm,
- H5D__cmp_filtered_collective_io_info_entry) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL, "couldn't gather array")
+ if (H5D__mpio_get_chunk_redistribute_info_types(&packed_type, &packed_type_derived, &struct_type,
+ &struct_type_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "can't create derived datatypes for chunk redistribution info")
+
+ /* Perform gather operation */
+ if (H5_mpio_gatherv_alloc(chunk_list, num_chunks_int, struct_type, counts_ptr, displacements_ptr,
+ packed_type, all_ranks_involved, 0, io_info->comm, mpi_rank, mpi_size,
+ &coll_chunk_list, &coll_chunk_list_num_entries) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL,
+ "can't gather chunk redistribution info to involved ranks")
- /* Rank 0 redistributes any shared chunks to new owners as necessary */
- if (mpi_rank == 0) {
- if (NULL == (send_counts = (int *)H5MM_calloc((size_t)mpi_size * sizeof(int))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate send counts buffer")
+ /*
+ * If all ranks are redistributing shared chunks, we no
+ * longer need the receive counts and displacements array
+ */
+ if (all_ranks_involved) {
+ counts_disps_array = H5MM_xfree(counts_disps_array);
+ }
- if (NULL == (send_displacements = (int *)H5MM_malloc((size_t)mpi_size * sizeof(int))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate send displacements buffer")
+ /*
+ * Phase 2 - Involved ranks now redistribute any shared chunks to new
+ * owners as necessary.
+ */
- if (NULL == (num_assigned_chunks_array = (size_t *)H5MM_calloc((size_t)mpi_size * sizeof(size_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
- "unable to allocate number of assigned chunks array")
+ if (all_ranks_involved || (mpi_rank == 0)) {
+ H5D_chunk_redistribute_info_t *chunk_entry;
+ hsize_t curr_chunk_idx;
+ size_t set_begin_index;
+ int num_writers;
+ int new_chunk_owner;
- for (i = 0; i < shared_chunks_info_array_num_entries;) {
- H5D_filtered_collective_io_info_t *chunk_entry;
- haddr_t last_seen_addr = shared_chunks_info_array[i].chunk_states.chunk_current.offset;
- size_t set_begin_index = i;
- size_t num_writers = 0;
- int new_chunk_owner = shared_chunks_info_array[i].owners.original_owner;
+ /* Clear the mapping from rank value -> number of assigned chunks */
+ HDmemset(num_chunks_assigned_map, 0, (size_t)mpi_size * sizeof(*num_chunks_assigned_map));
- /* Process each set of duplicate entries caused by another process writing to the same chunk */
- do {
- chunk_entry = &shared_chunks_info_array[i];
+ /* Sort collective chunk list according to chunk index */
+ HDqsort(coll_chunk_list, coll_chunk_list_num_entries, sizeof(H5D_chunk_redistribute_info_t),
+ H5D__cmp_chunk_redistribute_info);
- send_counts[chunk_entry->owners.original_owner] += (int)sizeof(*chunk_entry);
+ /*
+ * Process all chunks in the collective chunk list.
+ * Note that the loop counter is incremented by both
+ * the outer loop (while processing each entry in
+ * the collective chunk list) and the inner loop
+ * (while processing duplicate entries for shared
+ * chunks).
+ */
+ chunk_entry = &((H5D_chunk_redistribute_info_t *)coll_chunk_list)[0];
+ for (i = 0; i < coll_chunk_list_num_entries;) {
+ /* Set chunk's initial new owner to its original owner */
+ new_chunk_owner = chunk_entry->orig_owner;
+
+ /*
+ * Set the current chunk index so we know when we've processed
+ * all duplicate entries for a particular shared chunk
+ */
+ curr_chunk_idx = chunk_entry->chunk_idx;
+
+ /* Reset the initial number of writers to this chunk */
+ num_writers = 0;
- /* The new owner of the chunk is determined by the process
+ /* Set index for the beginning of this section of duplicate chunk entries */
+ set_begin_index = i;
+
+ /*
+ * Process each chunk entry in the set for the current
+ * (possibly shared) chunk and increment the loop counter
+ * while doing so.
+ */
+ do {
+ /*
+ * The new owner of the chunk is determined by the rank
* writing to the chunk which currently has the least amount
* of chunks assigned to it
*/
- if (num_assigned_chunks_array[chunk_entry->owners.original_owner] <
- num_assigned_chunks_array[new_chunk_owner])
- new_chunk_owner = chunk_entry->owners.original_owner;
+ if (num_chunks_assigned_map[chunk_entry->orig_owner] <
+ num_chunks_assigned_map[new_chunk_owner])
+ new_chunk_owner = chunk_entry->orig_owner;
+ /* Update the number of writers to this particular chunk */
num_writers++;
- } while (++i < shared_chunks_info_array_num_entries &&
- shared_chunks_info_array[i].chunk_states.chunk_current.offset == last_seen_addr);
- /* Set all of the chunk entries' "new_owner" fields */
+ chunk_entry++;
+ } while (++i < coll_chunk_list_num_entries && chunk_entry->chunk_idx == curr_chunk_idx);
+
+ /* We should never have more writers to a chunk than the number of MPI ranks */
+ HDassert(num_writers <= mpi_size);
+
+ /* Set all processed chunk entries' "new_owner" and "num_writers" fields */
for (; set_begin_index < i; set_begin_index++) {
- shared_chunks_info_array[set_begin_index].owners.new_owner = new_chunk_owner;
- shared_chunks_info_array[set_begin_index].num_writers = num_writers;
- } /* end for */
+ H5D_chunk_redistribute_info_t *entry;
- num_assigned_chunks_array[new_chunk_owner]++;
- } /* end for */
+ entry = &((H5D_chunk_redistribute_info_t *)coll_chunk_list)[set_begin_index];
+
+ entry->new_owner = new_chunk_owner;
+ entry->num_writers = num_writers;
+ }
+
+ /* Update the number of chunks assigned to the MPI rank that now owns this chunk */
+ num_chunks_assigned_map[new_chunk_owner]++;
+ }
- /* Sort the new list in order of previous owner so that each original owner of a chunk
- * entry gets that entry back, with the possibly newly-modified "new_owner" field
+ /*
+ * Re-sort the collective chunk list in order of original chunk owner
+ * so that each rank's section of contributed chunks is contiguous in
+ * the collective chunk list.
+ *
+ * NOTE: this re-sort is frail in that it needs to sort the collective
+ * chunk list so that each rank's section of contributed chunks
+ * is in the exact order it was contributed in, or things will
+ * be scrambled when each rank's local chunk list is updated.
+ * Therefore, the sorting algorithm here is tied to the one
+ * used during the I/O setup operation. Specifically, chunks
+ * are first sorted by ascending order of offset in the file and
+ * then by chunk index. In the future, a better redistribution
+ * algorithm may be devised that doesn't rely on frail sorting,
+ * but the current implementation is a quick and naive approach.
*/
- if (shared_chunks_info_array_num_entries > 1)
- HDqsort(shared_chunks_info_array, shared_chunks_info_array_num_entries,
- sizeof(H5D_filtered_collective_io_info_t),
- H5D__cmp_filtered_collective_io_info_entry_owner);
-
- send_displacements[0] = 0;
- for (i = 1; i < (size_t)mpi_size; i++)
- send_displacements[i] = send_displacements[i - 1] + send_counts[i - 1];
- } /* end if */
+ HDqsort(coll_chunk_list, coll_chunk_list_num_entries, sizeof(H5D_chunk_redistribute_info_t),
+ H5D__cmp_chunk_redistribute_info_orig_owner);
+ }
- /* Scatter the segments of the list back to each process */
- H5_CHECKED_ASSIGN(scatter_recvcount_int, int,
- *local_chunk_array_num_entries * sizeof(H5D_filtered_collective_io_info_t), size_t);
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Scatterv(shared_chunks_info_array, send_counts, send_displacements, MPI_BYTE,
- local_chunk_array, scatter_recvcount_int, MPI_BYTE, 0, io_info->comm)))
- HMPI_GOTO_ERROR(FAIL, "unable to scatter shared chunks info buffer", mpi_code)
+ if (all_ranks_involved) {
+ /*
+ * If redistribution occurred on all ranks, search for the section
+ * in the collective chunk list corresponding to this rank's locally
+ * selected chunks and update the local list after redistribution.
+ */
+ for (i = 0; i < coll_chunk_list_num_entries; i++)
+ if (mpi_rank == ((H5D_chunk_redistribute_info_t *)coll_chunk_list)[i].orig_owner)
+ break;
- if (shared_chunks_info_array) {
- H5MM_free(shared_chunks_info_array);
- shared_chunks_info_array = NULL;
- } /* end if */
+ for (size_t j = 0; j < (size_t)num_chunks_int; j++) {
+ H5D_chunk_redistribute_info_t *coll_entry;
+
+ coll_entry = &((H5D_chunk_redistribute_info_t *)coll_chunk_list)[i++];
+
+ chunk_list[j].new_owner = coll_entry->new_owner;
+ chunk_list[j].num_writers = coll_entry->num_writers;
+ }
+ }
+ else {
+ /*
+ * If redistribution occurred only on rank 0, scatter the segments
+ * of the collective chunk list back to each rank so that their
+ * local chunk lists get updated
+ */
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Scatterv(coll_chunk_list, counts_ptr, displacements_ptr, packed_type, chunk_list,
+ num_chunks_int, struct_type, 0, io_info->comm)))
+ HMPI_GOTO_ERROR(FAIL, "unable to scatter shared chunks info buffer", mpi_code)
+ }
- /* Now that the chunks have been redistributed, each process must send its modification data
- * to the new owners of any of the chunks it previously possessed. Accordingly, each process
- * must also issue asynchronous receives for any messages it may receive for each of the
- * chunks it is assigned, in order to avoid potential deadlocking issues.
+#ifdef H5Dmpio_DEBUG
+ H5D__mpio_dump_collective_filtered_chunk_list(chunk_list, num_chunks_assigned_map[mpi_rank], mpi_rank);
+#endif
+
+done:
+ H5MM_free(coll_chunk_list);
+
+ if (struct_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&struct_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+ if (packed_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&packed_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+
+ H5MM_free(counts_disps_array);
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_redistribute_shared_chunks_int() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_share_chunk_modification_data
+ *
+ * Purpose: When performing a parallel write on a chunked dataset with
+ * filters applied, we must first ensure that any particular
+ * chunk is only written to by a single MPI rank in order to
+ * avoid potential data races on the chunk. Once dataset
+ * chunks have been redistributed in a suitable manner, each
+ * MPI rank must send its chunk data to other ranks for each
+ * chunk it no longer owns.
+ *
+ * The current implementation here follows the Nonblocking
+ * Consensus algorithm described in:
+ * http://unixer.de/publications/img/hoefler-dsde-protocols.pdf
+ *
+ * First, each MPI rank scans through its list of selected
+ * chunks and does the following for each chunk:
+ *
+ * * If a chunk in the MPI rank's chunk list is still owned
+ * by that rank, the rank checks how many messages are
+ * incoming for that chunk and adds that to its running
+ * total. Then, the rank updates its local chunk list so
+ * that any previous chunk entries for chunks that are no
+ * longer owned by the rank get overwritten by chunk
+ * entries for chunks the rank still owns. Since the data
+ * for the chunks no longer owned will have already been
+ * sent, those chunks can effectively be discarded.
+ * * If a chunk in the MPI rank's chunk list is no longer
+ * owned by that rank, the rank sends the data it wishes to
+ * update the chunk with to the MPI rank that now has
+ * ownership of that chunk. To do this, it encodes the
+ * chunk's index, its selection in the chunk and its
+ * modification data into a buffer and then posts a
+ * non-blocking MPI_Issend to the owning rank.
+ *
+ * Once this step is complete, all MPI ranks allocate arrays
+ * to hold chunk message receive buffers and MPI request
+ * objects for each non-blocking receive they will post for
+ * incoming chunk modification messages. Then, all MPI ranks
+ * enter a loop that alternates between non-blocking
+ * MPI_Iprobe calls to probe for incoming messages and
+ * MPI_Testall calls to see if all send requests have
+ * completed. As chunk modification messages arrive,
+ * non-blocking MPI_Irecv calls will be posted for each
+ * message.
+ *
+ * Once all send requests have completed, an MPI_Ibarrier is
+ * posted and the loop then alternates between MPI_Iprobe
+ * calls and MPI_Test calls to check if all ranks have reached
+ * the non-blocking barrier. Once all ranks have reached the
+ * barrier, processing can move on to updating the selected
+ * chunks that are owned in the operation.
+ *
+ * Any chunk messages that were received from other ranks
+ * will be returned through the `chunk_msg_bufs` array and
+ * `chunk_msg_bufs_len` will be set appropriately.
+ *
+ * NOTE: The use of non-blocking sends and receives of chunk
+ * data here may contribute to large amounts of memory
+ * usage/MPI request overhead if the number of shared
+ * chunks is high. If this becomes a problem, it may be
+ * useful to split the message receiving loop away so
+ * that chunk modification messages can be received and
+ * processed immediately (MPI_Recv) using a single chunk
+ * message buffer. However, it's possible this may
+ * degrade performance since the chunk message sends
+ * are synchronous (MPI_Issend) in the Nonblocking
+ * Consensus algorithm.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t *chunk_list_num_entries, H5D_io_info_t *io_info,
+ const H5D_type_info_t *type_info, int mpi_rank, int mpi_size,
+ H5D_filtered_collective_io_info_t **chunk_hash_table,
+ unsigned char ***chunk_msg_bufs, int *chunk_msg_bufs_len)
+{
+#if MPI_VERSION >= 3
+ H5D_filtered_collective_io_info_t *chunk_table = NULL;
+ H5S_sel_iter_t * mem_iter = NULL;
+ unsigned char ** msg_send_bufs = NULL;
+ unsigned char ** msg_recv_bufs = NULL;
+ MPI_Request * send_requests = NULL;
+ MPI_Request * recv_requests = NULL;
+ MPI_Request ibarrier = MPI_REQUEST_NULL;
+ hbool_t mem_iter_init = FALSE;
+ hbool_t ibarrier_posted = FALSE;
+ size_t send_bufs_nalloc = 0;
+ size_t num_send_requests = 0;
+ size_t num_recv_requests = 0;
+ size_t num_msgs_incoming = 0;
+ size_t last_assigned_idx;
+ size_t i;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(chunk_list_num_entries);
+ HDassert(chunk_list || 0 == *chunk_list_num_entries);
+ HDassert(io_info);
+ HDassert(type_info);
+ HDassert(mpi_size > 1);
+ HDassert(chunk_msg_bufs);
+ HDassert(chunk_msg_bufs_len);
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Share chunk modification data");
+#endif
+
+ /* Set to latest format for encoding dataspace */
+ H5CX_set_libver_bounds(NULL);
+
+ if (*chunk_list_num_entries) {
+ /* Allocate a selection iterator for iterating over chunk dataspaces */
+ if (NULL == (mem_iter = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate dataspace selection iterator")
+
+ /*
+ * Allocate send buffer and MPI_Request arrays for non-blocking
+ * sends of outgoing chunk messages
+ */
+ send_bufs_nalloc = H5D_CHUNK_NUM_SEND_MSGS_INIT;
+ if (NULL == (msg_send_bufs = H5MM_malloc(send_bufs_nalloc * sizeof(*msg_send_bufs))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
+ "couldn't allocate chunk modification message buffer array")
+
+ if (NULL == (send_requests = H5MM_malloc(send_bufs_nalloc * sizeof(*send_requests))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate send requests array")
+ }
+
+ /*
+ * For each chunk this rank owns, add to the total number of
+ * incoming MPI messages, then update the local chunk list to
+ * overwrite any previous chunks no longer owned by this rank.
+ * Since the data for those chunks will have already been sent,
+ * this rank should no longer be interested in them and they
+ * can effectively be discarded. This bookkeeping also makes
+ * the code for the collective file space re-allocation and
+ * chunk re-insertion operations a bit simpler.
+ *
+ * For each chunk this rank doesn't own, use non-blocking
+ * synchronous sends to send the data this rank is writing to
+ * the rank that does own the chunk.
*/
- if (*local_chunk_array_num_entries)
- if (NULL == (mod_data = (unsigned char **)H5MM_malloc(*local_chunk_array_num_entries *
- sizeof(unsigned char *))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate modification data buffer array")
-
- /* Perform all the sends on the chunks that this rank doesn't own */
- /* (Sends and recvs must be two separate loops, to avoid deadlock) */
- for (i = 0, last_assigned_idx = 0; i < *local_chunk_array_num_entries; i++) {
- H5D_filtered_collective_io_info_t *chunk_entry = &local_chunk_array[i];
-
- if (mpi_rank != chunk_entry->owners.new_owner) {
- H5D_chunk_info_t *chunk_info = NULL;
+ for (i = 0, last_assigned_idx = 0; i < *chunk_list_num_entries; i++) {
+ H5D_filtered_collective_io_info_t *chunk_entry = &chunk_list[i];
+
+ if (mpi_rank == chunk_entry->new_owner) {
+ num_msgs_incoming += (size_t)(chunk_entry->num_writers - 1);
+
+ /*
+ * Overwrite chunk entries this rank doesn't own with entries that it
+ * does own, since it has sent the necessary data and is no longer
+ * interested in the chunks it doesn't own.
+ */
+ chunk_list[last_assigned_idx] = chunk_list[i];
+
+ /*
+ * Since, at large scale, a chunk's index value may be larger than
+ * the maximum value that can be stored in an int, we cannot rely
+ * on using a chunk's index value as the tag for the MPI messages
+ * sent/received for a chunk. Therefore, add this chunk to a hash
+ * table with the chunk's index as a key so that we can quickly find
+ * the chunk when processing chunk messages that were received. The
+ * message itself will contain the chunk's index so we can update
+ * the correct chunk with the received data.
+ */
+ HASH_ADD(hh, chunk_table, index_info.chunk_idx, sizeof(hsize_t), &chunk_list[last_assigned_idx]);
+
+ last_assigned_idx++;
+ }
+ else {
+ H5D_chunk_info_t *chunk_info = chunk_entry->chunk_info;
unsigned char * mod_data_p = NULL;
hsize_t iter_nelmts;
- size_t mod_data_size;
+ size_t mod_data_size = 0;
+ size_t space_size = 0;
- /* Look up the chunk and get its file and memory dataspaces */
- if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_entry->index)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't locate chunk in skip list")
+ /* Add the size of the chunk index to the encoded size */
+ mod_data_size += sizeof(hsize_t);
- /* Determine size of serialized chunk file dataspace, plus the size of
- * the data being written
- */
- if (H5S_encode(chunk_info->fspace, &mod_data_p, &mod_data_size) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "unable to get encoded dataspace size")
+ /* Determine size of serialized chunk file dataspace */
+ if (H5S_encode(chunk_info->fspace, &mod_data_p, &space_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get encoded dataspace size")
+ mod_data_size += space_size;
+ /* Determine size of data being written */
iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace);
-
H5_CHECK_OVERFLOW(iter_nelmts, hsize_t, size_t);
+
mod_data_size += (size_t)iter_nelmts * type_info->src_type_size;
- if (NULL == (mod_data[num_send_requests] = (unsigned char *)H5MM_malloc(mod_data_size)))
+ if (NULL == (msg_send_bufs[num_send_requests] = H5MM_malloc(mod_data_size)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
- "couldn't allocate chunk modification send buffer")
+ "couldn't allocate chunk modification message buffer")
+
+ mod_data_p = msg_send_bufs[num_send_requests];
+
+ /* Store the chunk's index into the buffer */
+ HDmemcpy(mod_data_p, &chunk_entry->index_info.chunk_idx, sizeof(hsize_t));
+ mod_data_p += sizeof(hsize_t);
/* Serialize the chunk's file dataspace into the buffer */
- mod_data_p = mod_data[num_send_requests];
if (H5S_encode(chunk_info->fspace, &mod_data_p, &mod_data_size) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "unable to encode dataspace")
/* Initialize iterator for memory selection */
- if (H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size, 0) < 0)
+ if (H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size,
+ H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
"unable to initialize memory selection information")
mem_iter_init = TRUE;
@@ -2952,466 +3943,2057 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty
if (0 == H5D__gather_mem(io_info->u.wbuf, mem_iter, (size_t)iter_nelmts, mod_data_p))
HGOTO_ERROR(H5E_IO, H5E_CANTGATHER, FAIL, "couldn't gather from write buffer")
- /* Send modification data to new owner */
+ /*
+ * Ensure that the size of the chunk data being sent can be
+ * safely cast to an int for MPI. Note that this should
+ * generally be OK for now (unless a rank is sending a
+ * whole 32-bit-sized chunk of data + its encoded selection),
+ * but if we allow larger than 32-bit-sized chunks in the
+ * future, this may become a problem and derived datatypes
+ * will need to be used.
+ */
H5_CHECK_OVERFLOW(mod_data_size, size_t, int)
- H5_CHECK_OVERFLOW(chunk_entry->index, hsize_t, int)
+
+ /* Send modification data to new owner */
if (MPI_SUCCESS !=
- (mpi_code = MPI_Isend(mod_data[num_send_requests], (int)mod_data_size, MPI_BYTE,
- chunk_entry->owners.new_owner, (int)chunk_entry->index, io_info->comm,
- &send_requests[num_send_requests])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Isend failed", mpi_code)
+ (mpi_code = MPI_Issend(msg_send_bufs[num_send_requests], (int)mod_data_size, MPI_BYTE,
+ chunk_entry->new_owner, H5D_CHUNK_MOD_DATA_TAG, io_info->comm,
+ &send_requests[num_send_requests])))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Issend failed", mpi_code)
+
+ num_send_requests++;
+
+ /* Resize send buffer and send request arrays if necessary */
+ if (num_send_requests == send_bufs_nalloc) {
+ void *tmp_alloc;
+
+ send_bufs_nalloc = (size_t)((double)send_bufs_nalloc * 1.5);
+
+ if (NULL ==
+ (tmp_alloc = H5MM_realloc(msg_send_bufs, send_bufs_nalloc * sizeof(*msg_send_bufs))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
+ "couldn't resize chunk modification message buffer array")
+ msg_send_bufs = tmp_alloc;
+
+ if (NULL ==
+ (tmp_alloc = H5MM_realloc(send_requests, send_bufs_nalloc * sizeof(*send_requests))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't resize send requests array")
+ send_requests = tmp_alloc;
+ }
- if (mem_iter_init && H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
+ if (H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release memory selection iterator")
mem_iter_init = FALSE;
+ }
+ }
- num_send_requests++;
- } /* end if */
- } /* end for */
+ /* Check if the number of send or receive requests will overflow an int (MPI requirement) */
+ if (num_send_requests > INT_MAX || num_msgs_incoming > INT_MAX)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
+ "too many shared chunks in parallel filtered write operation")
+
+ H5_CHECK_OVERFLOW(num_send_requests, size_t, int)
+ H5_CHECK_OVERFLOW(num_msgs_incoming, size_t, int)
+
+ /*
+ * Allocate receive buffer and MPI_Request arrays for non-blocking
+ * receives of incoming chunk messages
+ */
+ if (num_msgs_incoming) {
+ if (NULL == (msg_recv_bufs = H5MM_malloc(num_msgs_incoming * sizeof(*msg_recv_bufs))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
+ "couldn't allocate chunk modification message buffer array")
- /* Perform all the recvs on the chunks this rank owns */
- for (i = 0, last_assigned_idx = 0; i < *local_chunk_array_num_entries; i++) {
- H5D_filtered_collective_io_info_t *chunk_entry = &local_chunk_array[i];
+ if (NULL == (recv_requests = H5MM_malloc(num_msgs_incoming * sizeof(*recv_requests))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate receive requests array")
+ }
- if (mpi_rank == chunk_entry->owners.new_owner) {
- /* Allocate all necessary buffers for an asynchronous receive operation */
- if (chunk_entry->num_writers > 1) {
- MPI_Message message;
- MPI_Status status;
- size_t j;
+ /* Process any incoming messages until everyone is done */
+ do {
+ MPI_Status status;
+ int msg_flag;
- chunk_entry->async_info.num_receive_requests = (int)chunk_entry->num_writers - 1;
- if (NULL == (chunk_entry->async_info.receive_requests_array = (MPI_Request *)H5MM_malloc(
- (size_t)chunk_entry->async_info.num_receive_requests * sizeof(MPI_Request))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate async requests array")
+ /* Probe for an incoming message from any rank */
+ if (MPI_SUCCESS != (mpi_code = MPI_Iprobe(MPI_ANY_SOURCE, H5D_CHUNK_MOD_DATA_TAG, io_info->comm,
+ &msg_flag, &status)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Iprobe failed", mpi_code)
- if (NULL ==
- (chunk_entry->async_info.receive_buffer_array = (unsigned char **)H5MM_malloc(
- (size_t)chunk_entry->async_info.num_receive_requests * sizeof(unsigned char *))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate async receive buffers")
+ /*
+ * If a message was found, allocate a buffer for the message and
+ * post a non-blocking receive to receive it
+ */
+ if (msg_flag) {
+#if MPI_VERSION >= 3
+ MPI_Count msg_size = 0;
- for (j = 0; j < chunk_entry->num_writers - 1; j++) {
- int count = 0;
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_elements_x(&status, MPI_BYTE, &msg_size)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements_x failed", mpi_code)
- /* Probe for a particular message from any process, removing that message
- * from the receive queue in the process and allocating that much memory
- * for the asynchronous receive
- */
- if (MPI_SUCCESS != (mpi_code = MPI_Mprobe(MPI_ANY_SOURCE, (int)chunk_entry->index,
- io_info->comm, &message, &status)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Mprobe failed", mpi_code)
-
- if (MPI_SUCCESS != (mpi_code = MPI_Get_count(&status, MPI_BYTE, &count)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Get_count failed", mpi_code)
-
- HDassert(count >= 0);
- if (NULL == (chunk_entry->async_info.receive_buffer_array[j] =
- (unsigned char *)H5MM_malloc((size_t)count * sizeof(char *))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
- "unable to allocate modification data receive buffer")
-
- if (MPI_SUCCESS != (mpi_code = MPI_Imrecv(
- chunk_entry->async_info.receive_buffer_array[j], count, MPI_BYTE,
- &message, &chunk_entry->async_info.receive_requests_array[j])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Imrecv failed", mpi_code)
- } /* end for */
- } /* end if */
-
- local_chunk_array[last_assigned_idx++] = local_chunk_array[i];
- } /* end else */
- } /* end for */
+ H5_CHECK_OVERFLOW(msg_size, MPI_Count, int)
+#else
+ int msg_size = 0;
- *local_chunk_array_num_entries = last_assigned_idx;
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_elements(&status, MPI_BYTE, &msg_size)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code)
+#endif
- /* Wait for all async send requests to complete before returning */
- if (num_send_requests) {
- if (NULL == (send_statuses = (MPI_Status *)H5MM_malloc(num_send_requests * sizeof(MPI_Status))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate send statuses buffer")
+ if (msg_size <= 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "invalid chunk modification message size")
- H5_CHECK_OVERFLOW(num_send_requests, size_t, int);
- if (MPI_SUCCESS != (mpi_code = MPI_Waitall((int)num_send_requests, send_requests, send_statuses)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code)
- } /* end if */
+ HDassert((num_recv_requests + 1) <= num_msgs_incoming);
+ if (NULL ==
+ (msg_recv_bufs[num_recv_requests] = H5MM_malloc((size_t)msg_size * sizeof(unsigned char))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
+ "couldn't allocate chunk modification message receive buffer")
-done:
- /* Now that all async send requests have completed, free up the send
- * buffers used in the async operations
+ if (MPI_SUCCESS != (mpi_code = MPI_Irecv(msg_recv_bufs[num_recv_requests], (int)msg_size,
+ MPI_BYTE, status.MPI_SOURCE, H5D_CHUNK_MOD_DATA_TAG,
+ io_info->comm, &recv_requests[num_recv_requests])))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code)
+
+ num_recv_requests++;
+ }
+
+ if (ibarrier_posted) {
+ int ibarrier_completed;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Test(&ibarrier, &ibarrier_completed, MPI_STATUS_IGNORE)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code)
+
+ if (ibarrier_completed)
+ break;
+ }
+ else {
+ int all_sends_completed;
+
+ /* Determine if all send requests have completed */
+ if (MPI_SUCCESS != (mpi_code = MPI_Testall((int)num_send_requests, send_requests,
+ &all_sends_completed, MPI_STATUSES_IGNORE)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Testall failed", mpi_code)
+
+ if (all_sends_completed) {
+ /* Post non-blocking barrier */
+ if (MPI_SUCCESS != (mpi_code = MPI_Ibarrier(io_info->comm, &ibarrier)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code)
+ ibarrier_posted = TRUE;
+
+ /*
+ * Now that all send requests have completed, free up the
+ * send buffers used in the non-blocking operations
+ */
+ if (msg_send_bufs) {
+ for (i = 0; i < num_send_requests; i++) {
+ if (msg_send_bufs[i])
+ H5MM_free(msg_send_bufs[i]);
+ }
+
+ msg_send_bufs = H5MM_xfree(msg_send_bufs);
+ }
+ }
+ }
+ } while (1);
+
+ /*
+ * Ensure all receive requests have completed before moving on.
+ * For linked-chunk I/O, more overlap with computation could
+ * theoretically be achieved by returning the receive requests
+ * array and postponing this wait until during chunk updating
+ * when the data is really needed. However, multi-chunk I/O
+ * only updates a chunk at a time and the messages may not come
+ * in the order that chunks are processed. So, the safest way to
+ * support both I/O modes is to simply make sure all messages
+ * are available.
*/
- for (i = 0; i < num_send_requests; i++) {
- if (mod_data[i])
- H5MM_free(mod_data[i]);
- } /* end for */
+ if (MPI_SUCCESS != (mpi_code = MPI_Waitall((int)num_recv_requests, recv_requests, MPI_STATUSES_IGNORE)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code)
+
+ /* Set the new number of locally-selected chunks */
+ *chunk_list_num_entries = last_assigned_idx;
+ /* Return chunk message buffers if any were received */
+ *chunk_hash_table = chunk_table;
+ *chunk_msg_bufs = msg_recv_bufs;
+ *chunk_msg_bufs_len = (int)num_recv_requests;
+
+done:
+ if (ret_value < 0) {
+ /* If this rank failed, make sure to participate in collective barrier */
+ if (!ibarrier_posted) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Ibarrier(io_info->comm, &ibarrier)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code)
+ }
+
+ if (num_send_requests) {
+ for (i = 0; i < num_send_requests; i++) {
+ MPI_Cancel(&send_requests[i]);
+ }
+ }
+
+ if (recv_requests) {
+ for (i = 0; i < num_recv_requests; i++) {
+ MPI_Cancel(&recv_requests[i]);
+ }
+ }
+
+ if (msg_recv_bufs) {
+ for (i = 0; i < num_recv_requests; i++) {
+ H5MM_free(msg_recv_bufs[i]);
+ }
+
+ H5MM_free(msg_recv_bufs);
+ }
+
+ HASH_CLEAR(hh, chunk_table);
+ }
+
+ if (recv_requests)
+ H5MM_free(recv_requests);
if (send_requests)
H5MM_free(send_requests);
- if (send_statuses)
- H5MM_free(send_statuses);
- if (send_counts)
- H5MM_free(send_counts);
- if (send_displacements)
- H5MM_free(send_displacements);
- if (mod_data)
- H5MM_free(mod_data);
- if (mem_iter_init && H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator")
- if (mem_iter)
- H5MM_free(mem_iter);
- if (num_assigned_chunks_array)
- H5MM_free(num_assigned_chunks_array);
- if (shared_chunks_info_array)
- H5MM_free(shared_chunks_info_array);
+
+ if (msg_send_bufs) {
+ for (i = 0; i < num_send_requests; i++) {
+ if (msg_send_bufs[i])
+ H5MM_free(msg_send_bufs[i]);
+ }
+
+ H5MM_free(msg_send_bufs);
+ }
+
+ if (mem_iter) {
+ if (mem_iter_init && H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release dataspace selection iterator")
+ mem_iter = H5FL_FREE(H5S_sel_iter_t, mem_iter);
+ }
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__chunk_redistribute_shared_chunks() */
+#else
+ FUNC_ENTER_STATIC
+ HERROR(
+ H5E_DATASET, H5E_WRITEERROR,
+ "unable to send chunk modification data between MPI ranks - MPI version < 3 (MPI_Ibarrier missing)")
+ FUNC_LEAVE_NOAPI(FAIL)
#endif
+} /* end H5D__mpio_share_chunk_modification_data() */
/*-------------------------------------------------------------------------
- * Function: H5D__mpio_filtered_collective_write_type
+ * Function: H5D__mpio_collective_filtered_chunk_common_io
*
- * Purpose: Constructs a MPI derived datatype for both the memory and
- * the file for a collective write of filtered chunks. The
- * datatype contains the offsets in the file and the locations
- * of the filtered chunk data buffers.
+ * Purpose: This routine performs the common part of collective I/O
+ * when reading or writing filtered chunks collectively.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Jordan Henderson
- * Tuesday, November 22, 2016
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__mpio_filtered_collective_write_type(H5D_filtered_collective_io_info_t *chunk_list, size_t num_entries,
- MPI_Datatype *new_mem_type, hbool_t *mem_type_derived,
- MPI_Datatype *new_file_type, hbool_t *file_type_derived)
+H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries, const H5D_io_info_t *io_info,
+ const H5D_type_info_t *type_info, int mpi_size)
{
- MPI_Aint *write_buf_array = NULL; /* Relative displacements of filtered chunk data buffers */
- MPI_Aint *file_offset_array = NULL; /* Chunk offsets in the file */
- int * length_array = NULL; /* Filtered Chunk lengths */
- herr_t ret_value = SUCCEED;
+ H5D_io_info_t coll_io_info;
+ H5D_storage_t ctg_store;
+ MPI_Datatype file_type = MPI_DATATYPE_NULL;
+ MPI_Datatype mem_type = MPI_DATATYPE_NULL;
+ hbool_t mem_type_is_derived = FALSE;
+ hbool_t file_type_is_derived = FALSE;
+ hsize_t mpi_buf_count;
+ haddr_t base_read_offset = HADDR_UNDEF;
+ size_t num_chunks;
+ size_t i;
+ char fake_buf; /* Used as a fake buffer for ranks with no chunks, thus a NULL buf pointer */
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
- HDassert(chunk_list);
- HDassert(new_mem_type);
- HDassert(mem_type_derived);
- HDassert(new_file_type);
- HDassert(file_type_derived);
+ HDassert(chunk_list || 0 == chunk_list_num_entries);
+ HDassert(io_info);
+ HDassert(type_info);
- if (num_entries > 0) {
- size_t i;
- int mpi_code;
- void * base_buf;
-
- H5_CHECK_OVERFLOW(num_entries, size_t, int);
-
- /* Allocate arrays */
- if (NULL == (length_array = (int *)H5MM_malloc((size_t)num_entries * sizeof(int))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
- "memory allocation failed for filtered collective write length array")
- if (NULL == (write_buf_array = (MPI_Aint *)H5MM_malloc((size_t)num_entries * sizeof(MPI_Aint))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
- "memory allocation failed for filtered collective write buf length array")
- if (NULL == (file_offset_array = (MPI_Aint *)H5MM_malloc((size_t)num_entries * sizeof(MPI_Aint))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
- "memory allocation failed for collective write offset array")
-
- /* Ensure the list is sorted in ascending order of offset in the file */
- HDqsort(chunk_list, num_entries, sizeof(H5D_filtered_collective_io_info_t),
- H5D__cmp_filtered_collective_io_info_entry);
+ /* Initialize temporary I/O info */
+ coll_io_info = *io_info;
- base_buf = chunk_list[0].buf;
- for (i = 0; i < num_entries; i++) {
- /* Set up the offset in the file, the length of the chunk data, and the relative
- * displacement of the chunk data write buffer
- */
- file_offset_array[i] = (MPI_Aint)chunk_list[i].chunk_states.new_chunk.offset;
- length_array[i] = (int)chunk_list[i].chunk_states.new_chunk.length;
- write_buf_array[i] = (MPI_Aint)chunk_list[i].buf - (MPI_Aint)base_buf;
- } /* end for */
+ /*
+ * Construct MPI derived datatype for collective I/O on chunks
+ */
+ if (H5D__mpio_collective_filtered_io_type(chunk_list, chunk_list_num_entries, io_info->op_type, &mem_type,
+ &mem_type_is_derived, &file_type, &file_type_is_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "couldn't create MPI I/O type for chunk I/O")
- /* Create memory MPI type */
- if (MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)num_entries, length_array,
- write_buf_array, MPI_BYTE, new_mem_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
- *mem_type_derived = TRUE;
- if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_mem_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
-
- /* Create file MPI type */
- if (MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)num_entries, length_array,
- file_offset_array, MPI_BYTE, new_file_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
- *file_type_derived = TRUE;
- if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_file_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
- } /* end if */
+ /*
+ * For reads, determine how many chunks are actually being read.
+ * Note that if this is a read during a write operation
+ * (read chunk -> unfilter -> modify -> write back), some
+ * chunks may not need to be read if they're being fully
+ * overwritten during a write operation.
+ */
+ if (io_info->op_type == H5D_IO_OP_READ) {
+ for (i = 0, num_chunks = 0; i < chunk_list_num_entries; i++) {
+ HDassert(chunk_list[i].buf);
+
+ if (chunk_list[i].need_read) {
+ if (!H5F_addr_defined(base_read_offset))
+ base_read_offset = chunk_list[i].chunk_current.offset;
+
+ num_chunks++;
+ }
+ }
+ }
+ else
+ num_chunks = chunk_list_num_entries;
+
+ /*
+ * If this rank doesn't have a selection, it can
+ * skip I/O if independent I/O was requested at
+ * the low level, or if the MPI communicator size
+ * is 1.
+ *
+ * Otherwise, this rank has to participate in
+ * collective I/O, but probably has a NULL buf
+ * pointer, so override to a fake buffer since our
+ * write/read function expects one.
+ */
+ if (num_chunks == 0) {
+ H5FD_mpio_collective_opt_t coll_opt_mode;
+
+ /* Get the collective_opt property to check whether the application wants to do IO individually. */
+ if (H5CX_get_mpio_coll_opt(&coll_opt_mode) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_opt property")
+
+ if ((mpi_size == 1) || (H5FD_MPIO_INDIVIDUAL_IO == coll_opt_mode)) {
+ HGOTO_DONE(SUCCEED)
+ }
+ else {
+ if (io_info->op_type == H5D_IO_OP_WRITE)
+ coll_io_info.u.wbuf = &fake_buf;
+ else
+ coll_io_info.u.rbuf = &fake_buf;
+ }
+ }
+
+ /*
+ * Setup for I/O operation
+ */
+
+ mpi_buf_count = (num_chunks) ? 1 : 0;
+
+ if (num_chunks) {
+ /*
+ * Setup the base storage address for this operation
+ * to be the first chunk's file address
+ */
+ if (io_info->op_type == H5D_IO_OP_WRITE)
+ ctg_store.contig.dset_addr = chunk_list[0].chunk_new.offset;
+ else
+ ctg_store.contig.dset_addr = base_read_offset;
+ }
+ else
+ ctg_store.contig.dset_addr = 0;
+
+ ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size;
+ coll_io_info.store = &ctg_store;
+
+ /* Perform I/O */
+ if (H5D__final_collective_io(&coll_io_info, type_info, mpi_buf_count, file_type, mem_type) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't finish MPI I/O")
done:
- if (write_buf_array)
- H5MM_free(write_buf_array);
- if (file_offset_array)
- H5MM_free(file_offset_array);
- if (length_array)
- H5MM_free(length_array);
+ /* Free the MPI buf and file types, if they were derived */
+ if (mem_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&mem_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ if (file_type_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&file_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__mpio_filtered_collective_write_type() */
+} /* end H5D__mpio_collective_filtered_chunk_common_io() */
/*-------------------------------------------------------------------------
- * Function: H5D__filtered_collective_chunk_entry_io
+ * Function: H5D__mpio_collective_filtered_chunk_read
*
- * Purpose: Given an entry for a filtered chunk, performs the necessary
- * steps for updating the chunk data during a collective
- * write, or for reading the chunk from file during a
- * collective read.
+ * Purpose: This routine coordinates a collective read across all ranks
+ * of the chunks they have selected. Each rank will then go
+ * and
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Jordan Henderson
- * Wednesday, January 18, 2017
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk_entry,
- const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- const H5D_chunk_map_t *fm)
+H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries, const H5D_io_info_t *io_info,
+ const H5D_type_info_t *type_info, int mpi_rank, int mpi_size)
{
- H5D_chunk_info_t *chunk_info = NULL;
- H5S_sel_iter_t * mem_iter = NULL; /* Memory iterator for H5D__scatter_mem/H5D__gather_mem */
- H5S_sel_iter_t * file_iter = NULL;
- H5Z_EDC_t err_detect; /* Error detection info */
- H5Z_cb_t filter_cb; /* I/O filter callback function */
- unsigned filter_mask = 0;
- hsize_t iter_nelmts; /* Number of points to iterate over for the chunk IO operation */
- hssize_t extent_npoints;
- hsize_t true_chunk_size;
- hbool_t mem_iter_init = FALSE;
- hbool_t file_iter_init = FALSE;
- size_t buf_size;
- size_t i;
- H5S_t * dataspace = NULL; /* Other process' dataspace for the chunk */
- void * tmp_gath_buf = NULL; /* Temporary gather buffer to gather into from application buffer
- before scattering out to the chunk data buffer (when writing data),
- or vice versa (when reading data) */
- int mpi_code;
- herr_t ret_value = SUCCEED;
+ H5D_fill_buf_info_t fb_info;
+ H5D_chunk_info_t * chunk_info = NULL;
+ H5D_io_info_t coll_io_info;
+ H5Z_EDC_t err_detect; /* Error detection info */
+ H5Z_cb_t filter_cb; /* I/O filter callback function */
+ hsize_t file_chunk_size = 0;
+ hsize_t iter_nelmts; /* Number of points to iterate over for the chunk IO operation */
+ hbool_t should_fill = FALSE;
+ hbool_t fb_info_init = FALSE;
+ hbool_t index_empty = FALSE;
+ size_t i;
+ H5S_t * fill_space = NULL;
+ void * base_read_buf = NULL;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
- HDassert(chunk_entry);
+ HDassert(chunk_list || 0 == chunk_list_num_entries);
HDassert(io_info);
HDassert(type_info);
- HDassert(fm);
- /* Retrieve filter settings from API context */
- if (H5CX_get_err_detect(&err_detect) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get error detection info")
- if (H5CX_get_filter_cb(&filter_cb) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get I/O filter callback function")
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Filtered collective chunk read");
+#else
+ (void)mpi_rank;
+#endif
- /* Look up the chunk and get its file and memory dataspaces */
- if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_entry->index)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't locate chunk in skip list")
+ /* Initialize temporary I/O info */
+ coll_io_info = *io_info;
+ coll_io_info.u.rbuf = NULL;
- if ((extent_npoints = H5S_GET_EXTENT_NPOINTS(chunk_info->fspace)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
- true_chunk_size = (hsize_t)extent_npoints * type_info->src_type_size;
+ if (chunk_list_num_entries) {
+ /* Retrieve filter settings from API context */
+ if (H5CX_get_err_detect(&err_detect) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get error detection info")
+ if (H5CX_get_filter_cb(&filter_cb) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get I/O filter callback function")
- /* If the size of the filtered chunk is larger than the number of points in the
- * chunk file space extent times the datatype size, allocate enough space to hold the
- * whole filtered chunk. Otherwise, allocate a buffer equal to the size of the
- * chunk so that the unfiltering operation doesn't have to grow the buffer.
+ /* Set size of full chunks in dataset */
+ file_chunk_size = io_info->dset->shared->layout.u.chunk.size;
+
+ /* Determine if fill values should be "read" for unallocated chunks */
+ should_fill = (io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC) ||
+ ((io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET) &&
+ io_info->dset->shared->dcpl_cache.fill.fill_defined);
+ }
+
+ /*
+ * Allocate memory buffers for all chunks being read. Chunk data buffers are of
+ * the largest size between the chunk's current filtered size and the chunk's true
+ * size, as calculated by the number of elements in the chunk's file space extent
+ * multiplied by the datatype size. This tries to ensure that:
+ *
+ * * If we're reading the chunk and the filter normally reduces the chunk size,
+ * the unfiltering operation won't need to grow the buffer.
+ * * If we're reading the chunk and the filter normally grows the chunk size,
+ * we make sure to read into a buffer of size equal to the filtered chunk's
+ * size; reading into a (smaller) buffer of size equal to the unfiltered
+ * chunk size would of course be bad.
*/
- buf_size = MAX(chunk_entry->chunk_states.chunk_current.length, true_chunk_size);
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ HDassert(chunk_list[i].need_read);
+
+ chunk_list[i].chunk_buf_size = MAX(chunk_list[i].chunk_current.length, file_chunk_size);
+
+ if (NULL == (chunk_list[i].buf = H5MM_malloc(chunk_list[i].chunk_buf_size))) {
+ /* Push an error, but participate in collective read */
+ HDONE_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk data buffer")
+ break;
+ }
+
+ /*
+ * Check if chunk is currently allocated. If not, don't try to
+ * read it from the file. Instead, just fill the chunk buffer
+ * with the fill value if necessary.
+ */
+ if (H5F_addr_defined(chunk_list[i].chunk_current.offset)) {
+ /* Set first read buffer */
+ if (!base_read_buf)
+ base_read_buf = chunk_list[i].buf;
+
+ /* Set chunk's new length for eventual filter pipeline calls */
+ if (chunk_list[i].skip_filter_pline)
+ chunk_list[i].chunk_new.length = file_chunk_size;
+ else
+ chunk_list[i].chunk_new.length = chunk_list[i].chunk_current.length;
+ }
+ else {
+ chunk_list[i].need_read = FALSE;
+
+ /* Set chunk's new length for eventual filter pipeline calls */
+ chunk_list[i].chunk_new.length = file_chunk_size;
+
+ if (should_fill) {
+ /* Initialize fill value buffer if not already initialized */
+ if (!fb_info_init) {
+ hsize_t chunk_dims[H5S_MAX_RANK];
+
+ HDassert(io_info->dset->shared->ndims == io_info->dset->shared->layout.u.chunk.ndims - 1);
+ for (size_t j = 0; j < io_info->dset->shared->layout.u.chunk.ndims - 1; j++)
+ chunk_dims[j] = (hsize_t)io_info->dset->shared->layout.u.chunk.dim[j];
+
+ /* Get a dataspace for filling chunk memory buffers */
+ if (NULL == (fill_space = H5S_create_simple(
+ io_info->dset->shared->layout.u.chunk.ndims - 1, chunk_dims, NULL)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create chunk fill dataspace")
+
+ /* Initialize fill value buffer */
+ if (H5D__fill_init(&fb_info, NULL, (H5MM_allocate_t)H5D__chunk_mem_alloc,
+ (void *)&io_info->dset->shared->dcpl_cache.pline,
+ (H5MM_free_t)H5D__chunk_mem_free,
+ (void *)&io_info->dset->shared->dcpl_cache.pline,
+ &io_info->dset->shared->dcpl_cache.fill, io_info->dset->shared->type,
+ io_info->dset->shared->type_id, 0, file_chunk_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill value buffer")
+
+ fb_info_init = TRUE;
+ }
- if (NULL == (chunk_entry->buf = H5MM_malloc(buf_size)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk data buffer")
+ /* Write fill value to memory buffer */
+ HDassert(fb_info.fill_buf);
+ if (H5D__fill(fb_info.fill_buf, io_info->dset->shared->type, chunk_list[i].buf,
+ type_info->mem_type, fill_space) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't fill chunk buffer with fill value")
+ }
+ }
+ }
- /* If this is not a full chunk overwrite or this is a read operation, the chunk must be
- * read from the file and unfiltered.
+ /*
+ * If dataset is incrementally allocated and hasn't been written to
+ * yet, the chunk index should be empty. In this case, a collective
+ * read of chunks is essentially a no-op, so avoid it here.
*/
- if (!chunk_entry->full_overwrite || io_info->op_type == H5D_IO_OP_READ) {
- H5FD_mpio_xfer_t xfer_mode; /* Parallel transfer for this request */
+ index_empty = FALSE;
+ if (io_info->dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR)
+ if (H5D__chunk_index_empty(io_info->dset, &index_empty) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't determine if chunk index is empty")
- chunk_entry->chunk_states.new_chunk.length = chunk_entry->chunk_states.chunk_current.length;
+ if (!index_empty) {
+ /*
+ * Override the read buffer to point to the address of
+ * the first chunk data buffer being read into
+ */
+ if (base_read_buf)
+ coll_io_info.u.rbuf = base_read_buf;
- /* Currently, these chunk reads are done independently and will likely
- * cause issues with collective metadata reads enabled. In the future,
- * this should be refactored to use collective chunk reads - JTH */
+ /* Perform collective chunk read */
+ if (H5D__mpio_collective_filtered_chunk_common_io(chunk_list, chunk_list_num_entries, &coll_io_info,
+ type_info, mpi_size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't finish collective filtered chunk read")
+ }
- /* Get the original state of parallel I/O transfer mode */
- if (H5CX_get_io_xfer_mode(&xfer_mode) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode")
+ /*
+ * Iterate through all the read chunks, unfiltering them and scattering their
+ * data out to the application's read buffer.
+ */
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ chunk_info = chunk_list[i].chunk_info;
+
+ /* Unfilter the chunk, unless we didn't read it from the file */
+ if (chunk_list[i].need_read && !chunk_list[i].skip_filter_pline) {
+ if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, H5Z_FLAG_REVERSE,
+ &(chunk_list[i].index_info.filter_mask), err_detect, filter_cb,
+ (size_t *)&chunk_list[i].chunk_new.length, &chunk_list[i].chunk_buf_size,
+ &chunk_list[i].buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFILTER, FAIL, "couldn't unfilter chunk for modifying")
+ }
+
+ /* Scatter the chunk data to the read buffer */
+ iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
+
+ if (H5D_select_io_mem(io_info->u.rbuf, chunk_info->mspace, chunk_list[i].buf, chunk_info->fspace,
+ type_info->src_type_size, (size_t)iter_nelmts) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't copy chunk data to read buffer")
+ }
- /* Change the xfer_mode to independent for handling the I/O */
- if (H5CX_set_io_xfer_mode(H5FD_MPIO_INDEPENDENT) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set MPI-I/O transfer mode")
+done:
+ /* Free all resources used by entries in the chunk list */
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ if (chunk_list[i].buf) {
+ H5MM_free(chunk_list[i].buf);
+ chunk_list[i].buf = NULL;
+ }
+ }
- if (H5F_shared_block_read(io_info->f_sh, H5FD_MEM_DRAW,
- chunk_entry->chunk_states.chunk_current.offset,
- chunk_entry->chunk_states.new_chunk.length, chunk_entry->buf) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read raw data chunk")
+ /* Release the fill buffer info, if it's been initialized */
+ if (fb_info_init && H5D__fill_term(&fb_info) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release fill buffer info")
+ if (fill_space && (H5S_close(fill_space) < 0))
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close fill space")
- /* Return to the original I/O transfer mode setting */
- if (H5CX_set_io_xfer_mode(xfer_mode) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set MPI-I/O transfer mode")
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
- if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, H5Z_FLAG_REVERSE, &filter_mask, err_detect,
- filter_cb, (size_t *)&chunk_entry->chunk_states.new_chunk.length, &buf_size,
- &chunk_entry->buf) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFILTER, FAIL, "couldn't unfilter chunk for modifying")
- } /* end if */
- else {
- chunk_entry->chunk_states.new_chunk.length = true_chunk_size;
- } /* end else */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_collective_filtered_chunk_read() */
- /* Initialize iterator for memory selection */
- if (NULL == (mem_iter = (H5S_sel_iter_t *)H5MM_malloc(sizeof(H5S_sel_iter_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate memory iterator")
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_collective_filtered_chunk_update
+ *
+ * Purpose: When performing a parallel write on a chunked dataset with
+ * filters applied, all ranks must update their owned chunks
+ * with their own modification data and data from other ranks.
+ * This routine is responsible for coordinating that process.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries,
+ H5D_filtered_collective_io_info_t *chunk_hash_table,
+ unsigned char **chunk_msg_bufs, int chunk_msg_bufs_len,
+ const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
+ int mpi_rank, int mpi_size)
+{
+ H5D_fill_buf_info_t fb_info;
+ H5D_chunk_info_t * chunk_info = NULL;
+ H5S_sel_iter_t * sel_iter = NULL; /* Dataspace selection iterator for H5D__scatter_mem */
+ H5D_io_info_t coll_io_info;
+ H5Z_EDC_t err_detect; /* Error detection info */
+ H5Z_cb_t filter_cb; /* I/O filter callback function */
+ hsize_t file_chunk_size = 0;
+ hsize_t iter_nelmts; /* Number of points to iterate over for the chunk IO operation */
+ hbool_t should_fill = FALSE;
+ hbool_t fb_info_init = FALSE;
+ hbool_t sel_iter_init = FALSE;
+ hbool_t index_empty = FALSE;
+ size_t i;
+ H5S_t * dataspace = NULL;
+ H5S_t * fill_space = NULL;
+ void * base_read_buf = NULL;
+ herr_t ret_value = SUCCEED;
- if (H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size, 0) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information")
- mem_iter_init = TRUE;
+ FUNC_ENTER_STATIC
- /* If this is a read operation, scatter the read chunk data to the user's buffer.
- *
- * If this is a write operation, update the chunk data buffer with the modifications
- * from the current process, then apply any modifications from other processes. Finally,
- * filter the newly-updated chunk.
- */
- switch (io_info->op_type) {
- case H5D_IO_OP_READ:
- if (NULL == (file_iter = (H5S_sel_iter_t *)H5MM_malloc(sizeof(H5S_sel_iter_t))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate file iterator")
+ HDassert(chunk_list || 0 == chunk_list_num_entries);
+ HDassert((chunk_msg_bufs && chunk_hash_table) || 0 == chunk_msg_bufs_len);
+ HDassert(io_info);
+ HDassert(type_info);
- if (H5S_select_iter_init(file_iter, chunk_info->fspace, type_info->src_type_size, 0) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to initialize memory selection information")
- file_iter_init = TRUE;
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Filtered collective chunk update");
+#endif
- iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
+ if (chunk_list_num_entries) {
+ /* Retrieve filter settings from API context */
+ if (H5CX_get_err_detect(&err_detect) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get error detection info")
+ if (H5CX_get_filter_cb(&filter_cb) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get I/O filter callback function")
- if (NULL == (tmp_gath_buf = H5MM_malloc(iter_nelmts * type_info->src_type_size)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate temporary gather buffer")
+ /* Set size of full chunks in dataset */
+ file_chunk_size = io_info->dset->shared->layout.u.chunk.size;
- if (!H5D__gather_mem(chunk_entry->buf, file_iter, (size_t)iter_nelmts, tmp_gath_buf))
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't gather from chunk buffer")
+ /* Determine if fill values should be written to chunks */
+ should_fill = (io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC) ||
+ ((io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET) &&
+ io_info->dset->shared->dcpl_cache.fill.fill_defined);
+ }
- iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace);
+ /*
+ * Allocate memory buffers for all owned chunks. Chunk data buffers are of the
+ * largest size between the chunk's current filtered size and the chunk's true
+ * size, as calculated by the number of elements in the chunk's file space extent
+ * multiplied by the datatype size. This tries to ensure that:
+ *
+ * * If we're fully overwriting the chunk and the filter normally reduces the
+ * chunk size, we simply have the exact buffer size required to hold the
+ * unfiltered chunk data.
+ * * If we're fully overwriting the chunk and the filter normally grows the
+ * chunk size (e.g., fletcher32 filter), the final filtering operation
+ * (hopefully) won't need to grow the buffer.
+ * * If we're reading the chunk and the filter normally reduces the chunk size,
+ * the unfiltering operation won't need to grow the buffer.
+ * * If we're reading the chunk and the filter normally grows the chunk size,
+ * we make sure to read into a buffer of size equal to the filtered chunk's
+ * size; reading into a (smaller) buffer of size equal to the unfiltered
+ * chunk size would of course be bad.
+ */
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ HDassert(mpi_rank == chunk_list[i].new_owner);
- if (H5D__scatter_mem(tmp_gath_buf, mem_iter, (size_t)iter_nelmts, io_info->u.rbuf) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't scatter to read buffer")
+ chunk_list[i].chunk_buf_size = MAX(chunk_list[i].chunk_current.length, file_chunk_size);
+ /*
+ * If this chunk hasn't been allocated yet and we aren't writing
+ * out fill values to it, make sure to 0-fill its memory buffer
+ * so we don't use uninitialized memory.
+ */
+ if (!H5F_addr_defined(chunk_list[i].chunk_current.offset) && !should_fill)
+ chunk_list[i].buf = H5MM_calloc(chunk_list[i].chunk_buf_size);
+ else
+ chunk_list[i].buf = H5MM_malloc(chunk_list[i].chunk_buf_size);
+
+ if (NULL == chunk_list[i].buf) {
+ /* Push an error, but participate in collective read */
+ HDONE_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk data buffer")
break;
+ }
+
+ /* Set chunk's new length for eventual filter pipeline calls */
+ if (chunk_list[i].need_read) {
+ /*
+ * Check if chunk is currently allocated. If not, don't try to
+ * read it from the file. Instead, just fill the chunk buffer
+ * with the fill value if fill values are to be written.
+ */
+ if (H5F_addr_defined(chunk_list[i].chunk_current.offset)) {
+ /* Set first read buffer */
+ if (!base_read_buf)
+ base_read_buf = chunk_list[i].buf;
+
+ /* Set chunk's new length for eventual filter pipeline calls */
+ if (chunk_list[i].skip_filter_pline)
+ chunk_list[i].chunk_new.length = file_chunk_size;
+ else
+ chunk_list[i].chunk_new.length = chunk_list[i].chunk_current.length;
+ }
+ else {
+ chunk_list[i].need_read = FALSE;
+
+ /* Set chunk's new length for eventual filter pipeline calls */
+ chunk_list[i].chunk_new.length = file_chunk_size;
+
+ if (should_fill) {
+ /* Initialize fill value buffer if not already initialized */
+ if (!fb_info_init) {
+ hsize_t chunk_dims[H5S_MAX_RANK];
+
+ HDassert(io_info->dset->shared->ndims ==
+ io_info->dset->shared->layout.u.chunk.ndims - 1);
+ for (size_t j = 0; j < io_info->dset->shared->layout.u.chunk.ndims - 1; j++)
+ chunk_dims[j] = (hsize_t)io_info->dset->shared->layout.u.chunk.dim[j];
+
+ /* Get a dataspace for filling chunk memory buffers */
+ if (NULL == (fill_space = H5S_create_simple(
+ io_info->dset->shared->layout.u.chunk.ndims - 1, chunk_dims, NULL)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to create chunk fill dataspace")
+
+ /* Initialize fill value buffer */
+ if (H5D__fill_init(&fb_info, NULL, (H5MM_allocate_t)H5D__chunk_mem_alloc,
+ (void *)&io_info->dset->shared->dcpl_cache.pline,
+ (H5MM_free_t)H5D__chunk_mem_free,
+ (void *)&io_info->dset->shared->dcpl_cache.pline,
+ &io_info->dset->shared->dcpl_cache.fill,
+ io_info->dset->shared->type, io_info->dset->shared->type_id, 0,
+ file_chunk_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill value buffer")
+
+ fb_info_init = TRUE;
+ }
+
+ /* Write fill value to memory buffer */
+ HDassert(fb_info.fill_buf);
+ if (H5D__fill(fb_info.fill_buf, io_info->dset->shared->type, chunk_list[i].buf,
+ type_info->mem_type, fill_space) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "couldn't fill chunk buffer with fill value")
+ }
+ }
+ }
+ else
+ chunk_list[i].chunk_new.length = file_chunk_size;
+ }
- case H5D_IO_OP_WRITE:
- iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace);
+ /*
+ * If dataset is incrementally allocated and hasn't been written to
+ * yet, the chunk index should be empty. In this case, a collective
+ * read of chunks is essentially a no-op, so avoid it here.
+ */
+ index_empty = FALSE;
+ if (io_info->dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR)
+ if (H5D__chunk_index_empty(io_info->dset, &index_empty) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't determine if chunk index is empty")
+
+ if (!index_empty) {
+ /*
+ * Setup for I/O operation
+ */
- if (NULL == (tmp_gath_buf = H5MM_malloc(iter_nelmts * type_info->src_type_size)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate temporary gather buffer")
+ /* Initialize temporary I/O info */
+ coll_io_info = *io_info;
+ coll_io_info.op_type = H5D_IO_OP_READ;
- /* Gather modification data from the application write buffer into a temporary buffer */
- if (0 == H5D__gather_mem(io_info->u.wbuf, mem_iter, (size_t)iter_nelmts, tmp_gath_buf))
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't gather from write buffer")
+ /* Override the read buffer to point to the address of the first
+ * chunk data buffer being read into
+ */
+ if (base_read_buf)
+ coll_io_info.u.rbuf = base_read_buf;
- if (H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator")
- mem_iter_init = FALSE;
+ /* Read all chunks that need to be read from the file */
+ if (H5D__mpio_collective_filtered_chunk_common_io(chunk_list, chunk_list_num_entries, &coll_io_info,
+ type_info, mpi_size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't finish collective filtered chunk read")
+ }
- /* Initialize iterator for file selection */
- if (H5S_select_iter_init(mem_iter, chunk_info->fspace, type_info->dst_type_size, 0) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to initialize file selection information")
- mem_iter_init = TRUE;
+ /*
+ * Now that all owned chunks have been read, update the chunks
+ * with modification data from the owning rank and other ranks.
+ */
- iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
+ /* Process all chunks with data from the owning rank first */
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ HDassert(mpi_rank == chunk_list[i].new_owner);
- /* Scatter the owner's modification data into the chunk data buffer according to
- * the file space.
- */
- if (H5D__scatter_mem(tmp_gath_buf, mem_iter, (size_t)iter_nelmts, chunk_entry->buf) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't scatter to chunk data buffer")
+ chunk_info = chunk_list[i].chunk_info;
- if (H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator")
- mem_iter_init = FALSE;
+ /*
+ * If this chunk wasn't being fully overwritten, we read it from
+ * the file, so we need to unfilter it
+ */
+ if (chunk_list[i].need_read && !chunk_list[i].skip_filter_pline) {
+ if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, H5Z_FLAG_REVERSE,
+ &(chunk_list[i].index_info.filter_mask), err_detect, filter_cb,
+ (size_t *)&chunk_list[i].chunk_new.length, &chunk_list[i].chunk_buf_size,
+ &chunk_list[i].buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFILTER, FAIL, "couldn't unfilter chunk for modifying")
+ }
+
+ iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace);
+
+ if (H5D_select_io_mem(chunk_list[i].buf, chunk_info->fspace, io_info->u.wbuf, chunk_info->mspace,
+ type_info->dst_type_size, (size_t)iter_nelmts) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't copy chunk data to write buffer")
+ }
- if (MPI_SUCCESS !=
- (mpi_code = MPI_Waitall(chunk_entry->async_info.num_receive_requests,
- chunk_entry->async_info.receive_requests_array, MPI_STATUSES_IGNORE)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code)
+ /* Allocate iterator for memory selection */
+ if (NULL == (sel_iter = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate memory iterator")
- /* For each asynchronous receive call previously posted, receive the chunk modification
- * buffer from another rank and update the chunk data
+ /* Now process all received chunk message buffers */
+ for (i = 0; i < (size_t)chunk_msg_bufs_len; i++) {
+ H5D_filtered_collective_io_info_t *chunk_entry = NULL;
+ const unsigned char * msg_ptr = chunk_msg_bufs[i];
+ hsize_t chunk_idx;
+
+ if (msg_ptr) {
+ /* Retrieve the chunk's index value */
+ HDmemcpy(&chunk_idx, msg_ptr, sizeof(hsize_t));
+ msg_ptr += sizeof(hsize_t);
+
+ /* Find the chunk entry according to its chunk index */
+ HASH_FIND(hh, chunk_hash_table, &chunk_idx, sizeof(hsize_t), chunk_entry);
+ HDassert(chunk_entry);
+ HDassert(mpi_rank == chunk_entry->new_owner);
+
+ /*
+ * Only process the chunk if its data buffer is allocated.
+ * In the case of multi-chunk I/O, we're only working on
+ * a chunk at a time, so we need to skip over messages
+ * that aren't for the chunk we're currently working on.
*/
- for (i = 0; i < (size_t)chunk_entry->async_info.num_receive_requests; i++) {
- const unsigned char *mod_data_p;
-
- /* Decode the process' chunk file dataspace */
- mod_data_p = chunk_entry->async_info.receive_buffer_array[i];
- if (NULL == (dataspace = H5S_decode(&mod_data_p)))
+ if (!chunk_entry->buf)
+ continue;
+ else {
+ /* Decode the chunk file dataspace from the message */
+ if (NULL == (dataspace = H5S_decode(&msg_ptr)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTDECODE, FAIL, "unable to decode dataspace")
- if (H5S_select_iter_init(mem_iter, dataspace, type_info->dst_type_size, 0) < 0)
+ if (H5S_select_iter_init(sel_iter, dataspace, type_info->dst_type_size,
+ H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
"unable to initialize memory selection information")
- mem_iter_init = TRUE;
+ sel_iter_init = TRUE;
iter_nelmts = H5S_GET_SELECT_NPOINTS(dataspace);
/* Update the chunk data with the received modification data */
- if (H5D__scatter_mem(mod_data_p, mem_iter, (size_t)iter_nelmts, chunk_entry->buf) < 0)
+ if (H5D__scatter_mem(msg_ptr, sel_iter, (size_t)iter_nelmts, chunk_entry->buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't scatter to write buffer")
- if (H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
+ if (H5S_SELECT_ITER_RELEASE(sel_iter) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator")
- mem_iter_init = FALSE;
+ sel_iter_init = FALSE;
+
if (dataspace) {
if (H5S_close(dataspace) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace")
dataspace = NULL;
}
- H5MM_free(chunk_entry->async_info.receive_buffer_array[i]);
- } /* end for */
- /* Filter the chunk */
- if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, 0, &filter_mask, err_detect, filter_cb,
- (size_t *)&chunk_entry->chunk_states.new_chunk.length, &buf_size,
- &chunk_entry->buf) < 0)
+ H5MM_free(chunk_msg_bufs[i]);
+ chunk_msg_bufs[i] = NULL;
+ }
+ }
+ }
+
+ /* Finally, filter all the chunks */
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ if (!chunk_list[i].skip_filter_pline) {
+ if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, 0,
+ &(chunk_list[i].index_info.filter_mask), err_detect, filter_cb,
+ (size_t *)&chunk_list[i].chunk_new.length, &chunk_list[i].chunk_buf_size,
+ &chunk_list[i].buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "output pipeline failed")
+ }
#if H5_SIZEOF_SIZE_T > 4
- /* Check for the chunk expanding too much to encode in a 32-bit value */
- if (chunk_entry->chunk_states.new_chunk.length > ((size_t)0xffffffff))
- HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length")
+ /* Check for the chunk expanding too much to encode in a 32-bit value */
+ if (chunk_list[i].chunk_new.length > ((size_t)0xffffffff))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length")
#endif
- break;
+ }
- default:
- HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "invalid I/O operation")
- } /* end switch */
+done:
+ if (sel_iter) {
+ if (sel_iter_init && H5S_SELECT_ITER_RELEASE(sel_iter) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator")
+ sel_iter = H5FL_FREE(H5S_sel_iter_t, sel_iter);
+ }
+ if (dataspace && (H5S_close(dataspace) < 0))
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace")
+ if (fill_space && (H5S_close(fill_space) < 0))
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close fill space")
+
+ /* Release the fill buffer info, if it's been initialized */
+ if (fb_info_init && H5D__fill_term(&fb_info) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release fill buffer info")
+
+ /* On failure, try to free all resources used by entries in the chunk list */
+ if (ret_value < 0) {
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ if (chunk_list[i].buf) {
+ H5MM_free(chunk_list[i].buf);
+ chunk_list[i].buf = NULL;
+ }
+ }
+ }
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_collective_filtered_chunk_update() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_collective_filtered_chunk_reallocate
+ *
+ * Purpose: When performing a parallel write on a chunked dataset with
+ * filters applied, all ranks must eventually get together and
+ * perform a collective reallocation of space in the file for
+ * all chunks that were modified on all ranks. This routine is
+ * responsible for coordinating that process.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_collective_filtered_chunk_reallocate(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries, size_t *num_chunks_assigned_map,
+ H5D_io_info_t *io_info, H5D_chk_idx_info_t *idx_info,
+ int mpi_rank, int mpi_size)
+{
+ H5D_chunk_alloc_info_t *collective_list = NULL;
+ MPI_Datatype send_type;
+ MPI_Datatype recv_type;
+ hbool_t send_type_derived = FALSE;
+ hbool_t recv_type_derived = FALSE;
+ hbool_t need_sort = FALSE;
+ size_t collective_num_entries = 0;
+ size_t num_local_chunks_processed = 0;
+ size_t i;
+ void * gathered_array = NULL;
+ int * counts_disps_array = NULL;
+ int * counts_ptr = NULL;
+ int * displacements_ptr = NULL;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(chunk_list || 0 == chunk_list_num_entries);
+ HDassert(io_info);
+ HDassert(idx_info);
+ HDassert(idx_info->storage->idx_type != H5D_CHUNK_IDX_NONE);
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Reallocation of chunk file space");
+#endif
+
+ /*
+ * Make sure it's safe to cast this rank's number
+ * of chunks to be sent into an int for MPI
+ */
+ H5_CHECK_OVERFLOW(chunk_list_num_entries, size_t, int);
+
+ /* Create derived datatypes for the chunk file space info needed */
+ if (H5D__mpio_get_chunk_alloc_info_types(&recv_type, &recv_type_derived, &send_type, &send_type_derived) <
+ 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "can't create derived datatypes for chunk file space info")
+
+ /*
+ * Gather the new chunk sizes to all ranks for a collective reallocation
+ * of the chunks in the file.
+ */
+ if (num_chunks_assigned_map) {
+ /*
+ * If a mapping between rank value -> number of assigned chunks has
+ * been provided (usually during linked-chunk I/O), we can use this
+ * to optimize MPI overhead a bit since MPI ranks won't need to
+ * first inform each other about how many chunks they're contributing.
+ */
+ if (NULL == (counts_disps_array = H5MM_malloc(2 * (size_t)mpi_size * sizeof(*counts_disps_array)))) {
+ /* Push an error, but still participate in collective gather operation */
+ HDONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "couldn't allocate receive counts and displacements array")
+ }
+ else {
+ /* Set the receive counts from the assigned chunks map */
+ counts_ptr = counts_disps_array;
+
+ for (i = 0; i < (size_t)mpi_size; i++)
+ H5_CHECKED_ASSIGN(counts_ptr[i], int, num_chunks_assigned_map[i], size_t);
+
+ /* Set the displacements into the receive buffer for the gather operation */
+ displacements_ptr = &counts_disps_array[mpi_size];
+
+ *displacements_ptr = 0;
+ for (i = 1; i < (size_t)mpi_size; i++)
+ displacements_ptr[i] = displacements_ptr[i - 1] + counts_ptr[i - 1];
+ }
+
+ /* Perform gather operation */
+ if (H5_mpio_gatherv_alloc(chunk_list, (int)chunk_list_num_entries, send_type, counts_ptr,
+ displacements_ptr, recv_type, TRUE, 0, io_info->comm, mpi_rank, mpi_size,
+ &gathered_array, &collective_num_entries) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL, "can't gather chunk file space info to/from ranks")
+ }
+ else {
+ /*
+ * If no mapping between rank value -> number of assigned chunks has
+ * been provided (usually during multi-chunk I/O), all MPI ranks will
+ * need to first inform other ranks about how many chunks they're
+ * contributing before performing the actual gather operation. Use
+ * the 'simple' MPI_Allgatherv wrapper for this.
+ */
+ if (H5_mpio_gatherv_alloc_simple(chunk_list, (int)chunk_list_num_entries, send_type, recv_type, TRUE,
+ 0, io_info->comm, mpi_rank, mpi_size, &gathered_array,
+ &collective_num_entries) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL, "can't gather chunk file space info to/from ranks")
+ }
+
+ /* Collectively re-allocate the modified chunks (from each rank) in the file */
+ collective_list = (H5D_chunk_alloc_info_t *)gathered_array;
+ for (i = 0, num_local_chunks_processed = 0; i < collective_num_entries; i++) {
+ H5D_chunk_alloc_info_t *coll_entry = &collective_list[i];
+ hbool_t need_insert;
+ hbool_t update_local_chunk;
+
+ if (H5D__chunk_file_alloc(idx_info, &coll_entry->chunk_current, &coll_entry->chunk_new, &need_insert,
+ NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk")
+
+ /*
+ * If we just re-allocated a chunk that is local to this
+ * rank, make sure to update the chunk entry in the local
+ * chunk list
+ */
+ update_local_chunk =
+ (num_local_chunks_processed < chunk_list_num_entries) &&
+ (coll_entry->chunk_idx == chunk_list[num_local_chunks_processed].index_info.chunk_idx);
+
+ if (update_local_chunk) {
+ H5D_filtered_collective_io_info_t *local_chunk;
+
+ local_chunk = &chunk_list[num_local_chunks_processed];
+
+ /* Sanity check that this chunk is actually local */
+ HDassert(mpi_rank == local_chunk->orig_owner);
+ HDassert(mpi_rank == local_chunk->new_owner);
+
+ local_chunk->chunk_new = coll_entry->chunk_new;
+ local_chunk->index_info.need_insert = need_insert;
+
+ /*
+ * Since chunk reallocation can move chunks around, check if
+ * the local chunk list is still in ascending offset of order
+ * in the file
+ */
+ if (num_local_chunks_processed) {
+ haddr_t curr_chunk_offset = local_chunk->chunk_new.offset;
+ haddr_t prev_chunk_offset = chunk_list[num_local_chunks_processed - 1].chunk_new.offset;
+
+ HDassert(H5F_addr_defined(prev_chunk_offset) && H5F_addr_defined(curr_chunk_offset));
+ if (curr_chunk_offset < prev_chunk_offset)
+ need_sort = TRUE;
+ }
+
+ num_local_chunks_processed++;
+ }
+ }
+
+ HDassert(chunk_list_num_entries == num_local_chunks_processed);
+
+ /*
+ * Ensure this rank's local chunk list is sorted in
+ * ascending order of offset in the file
+ */
+ if (need_sort)
+ HDqsort(chunk_list, chunk_list_num_entries, sizeof(H5D_filtered_collective_io_info_t),
+ H5D__cmp_filtered_collective_io_info_entry);
+
+done:
+ H5MM_free(gathered_array);
+ H5MM_free(counts_disps_array);
+
+ if (send_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&send_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+ if (recv_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&recv_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D__mpio_collective_filtered_chunk_reallocate() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_collective_filtered_chunk_reinsert
+ *
+ * Purpose: When performing a parallel write on a chunked dataset with
+ * filters applied, all ranks must eventually get together and
+ * perform a collective reinsertion into the dataset's chunk
+ * index of chunks that were modified. This routine is
+ * responsible for coordinating that process.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries, size_t *num_chunks_assigned_map,
+ H5D_io_info_t *io_info, H5D_chk_idx_info_t *idx_info,
+ int mpi_rank, int mpi_size)
+{
+ H5D_chunk_ud_t chunk_ud;
+ MPI_Datatype send_type;
+ MPI_Datatype recv_type;
+ hbool_t send_type_derived = FALSE;
+ hbool_t recv_type_derived = FALSE;
+ hsize_t scaled_coords[H5O_LAYOUT_NDIMS];
+ size_t collective_num_entries = 0;
+ size_t i;
+ void * gathered_array = NULL;
+ int * counts_disps_array = NULL;
+ int * counts_ptr = NULL;
+ int * displacements_ptr = NULL;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(chunk_list || 0 == chunk_list_num_entries);
+ HDassert(io_info);
+ HDassert(idx_info);
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TRACE_ENTER(mpi_rank);
+ H5D_MPIO_TIME_START(mpi_rank, "Reinsertion of modified chunks into chunk index");
+#endif
+
+ /* Only re-insert chunks if index has an insert method */
+ if (!idx_info->storage->ops->insert)
+ HGOTO_DONE(SUCCEED);
+
+ /*
+ * Make sure it's safe to cast this rank's number
+ * of chunks to be sent into an int for MPI
+ */
+ H5_CHECK_OVERFLOW(chunk_list_num_entries, size_t, int);
+
+ /* Create derived datatypes for the chunk re-insertion info needed */
+ if (H5D__mpio_get_chunk_insert_info_types(&recv_type, &recv_type_derived, &send_type,
+ &send_type_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "can't create derived datatypes for chunk re-insertion info")
+
+ /*
+ * Gather information to all ranks for a collective re-insertion
+ * of the modified chunks into the chunk index
+ */
+ if (num_chunks_assigned_map) {
+ /*
+ * If a mapping between rank value -> number of assigned chunks has
+ * been provided (usually during linked-chunk I/O), we can use this
+ * to optimize MPI overhead a bit since MPI ranks won't need to
+ * first inform each other about how many chunks they're contributing.
+ */
+ if (NULL == (counts_disps_array = H5MM_malloc(2 * (size_t)mpi_size * sizeof(*counts_disps_array)))) {
+ /* Push an error, but still participate in collective gather operation */
+ HDONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "couldn't allocate receive counts and displacements array")
+ }
+ else {
+ /* Set the receive counts from the assigned chunks map */
+ counts_ptr = counts_disps_array;
+
+ for (i = 0; i < (size_t)mpi_size; i++)
+ H5_CHECKED_ASSIGN(counts_ptr[i], int, num_chunks_assigned_map[i], size_t);
+
+ /* Set the displacements into the receive buffer for the gather operation */
+ displacements_ptr = &counts_disps_array[mpi_size];
+
+ *displacements_ptr = 0;
+ for (i = 1; i < (size_t)mpi_size; i++)
+ displacements_ptr[i] = displacements_ptr[i - 1] + counts_ptr[i - 1];
+ }
+
+ /* Perform gather operation */
+ if (H5_mpio_gatherv_alloc(chunk_list, (int)chunk_list_num_entries, send_type, counts_ptr,
+ displacements_ptr, recv_type, TRUE, 0, io_info->comm, mpi_rank, mpi_size,
+ &gathered_array, &collective_num_entries) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL,
+ "can't gather chunk index re-insertion info to/from ranks")
+ }
+ else {
+ /*
+ * If no mapping between rank value -> number of assigned chunks has
+ * been provided (usually during multi-chunk I/O), all MPI ranks will
+ * need to first inform other ranks about how many chunks they're
+ * contributing before performing the actual gather operation. Use
+ * the 'simple' MPI_Allgatherv wrapper for this.
+ */
+ if (H5_mpio_gatherv_alloc_simple(chunk_list, (int)chunk_list_num_entries, send_type, recv_type, TRUE,
+ 0, io_info->comm, mpi_rank, mpi_size, &gathered_array,
+ &collective_num_entries) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGATHER, FAIL,
+ "can't gather chunk index re-insertion info to/from ranks")
+ }
+
+ /* Initialize static chunk udata fields from chunk index info */
+ H5D_MPIO_INIT_CHUNK_UD_INFO(chunk_ud, idx_info);
+
+ for (i = 0; i < collective_num_entries; i++) {
+ H5D_chunk_insert_info_t *coll_entry = &((H5D_chunk_insert_info_t *)gathered_array)[i];
+
+ /*
+ * We only need to reinsert this chunk if we had to actually
+ * allocate or reallocate space in the file for it
+ */
+ if (!coll_entry->index_info.need_insert)
+ continue;
+
+ chunk_ud.chunk_block = coll_entry->chunk_block;
+ chunk_ud.chunk_idx = coll_entry->index_info.chunk_idx;
+ chunk_ud.filter_mask = coll_entry->index_info.filter_mask;
+ chunk_ud.common.scaled = scaled_coords;
+
+ /* Calculate scaled coordinates for the chunk */
+ if (idx_info->layout->idx_type == H5D_CHUNK_IDX_EARRAY && idx_info->layout->u.earray.unlim_dim > 0) {
+ /*
+ * Extensible arrays where the unlimited dimension is not
+ * the slowest-changing dimension "swizzle" the coordinates
+ * to move the unlimited dimension value to offset 0. Therefore,
+ * we use the "swizzled" down chunks to calculate the "swizzled"
+ * scaled coordinates and then we undo the "swizzle" operation.
+ *
+ * TODO: In the future, this is something that should be handled
+ * by the particular chunk index rather than manually
+ * here. Likely, the chunk index ops should get a new
+ * callback that accepts a chunk index and provides the
+ * caller with the scaled coordinates for that chunk.
+ */
+ H5VM_array_calc_pre(chunk_ud.chunk_idx, io_info->dset->shared->ndims,
+ idx_info->layout->u.earray.swizzled_down_chunks, scaled_coords);
+
+ H5VM_unswizzle_coords(hsize_t, scaled_coords, idx_info->layout->u.earray.unlim_dim);
+ }
+ else {
+ H5VM_array_calc_pre(chunk_ud.chunk_idx, io_info->dset->shared->ndims,
+ io_info->dset->shared->layout.u.chunk.down_chunks, scaled_coords);
+ }
+
+ scaled_coords[io_info->dset->shared->ndims] = 0;
+
+#ifndef NDEBUG
+ /*
+ * If a matching local chunk entry is found, the
+ * `chunk_info` structure (which contains the chunk's
+ * pre-computed scaled coordinates) will be valid
+ * for this rank. Compare those coordinates against
+ * the calculated coordinates above to make sure
+ * they match.
+ */
+ for (size_t dbg_idx = 0; dbg_idx < chunk_list_num_entries; dbg_idx++) {
+ if (coll_entry->index_info.chunk_idx == chunk_list[dbg_idx].index_info.chunk_idx) {
+ hbool_t coords_match = !HDmemcmp(scaled_coords, chunk_list[dbg_idx].chunk_info->scaled,
+ io_info->dset->shared->ndims * sizeof(hsize_t));
+
+ HDassert(coords_match && "Calculated scaled coordinates for chunk didn't match "
+ "chunk's actual scaled coordinates!");
+ break;
+ }
+ }
+#endif
+
+ if ((idx_info->storage->ops->insert)(idx_info, &chunk_ud, io_info->dset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert chunk address into index")
+ }
+
+done:
+ H5MM_free(gathered_array);
+ H5MM_free(counts_disps_array);
+
+ if (send_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&send_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+ if (recv_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&recv_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+
+#ifdef H5Dmpio_DEBUG
+ H5D_MPIO_TIME_STOP(mpi_rank);
+ H5D_MPIO_TRACE_EXIT(mpi_rank);
+#endif
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_collective_filtered_chunk_reinsert() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_get_chunk_redistribute_info_types
+ *
+ * Purpose: Constructs MPI derived datatypes for communicating the
+ * info from a H5D_filtered_collective_io_info_t structure
+ * that is necessary for redistributing shared chunks during a
+ * collective write of filtered chunks.
+ *
+ * The datatype returned through `contig_type` has an extent
+ * equal to the size of an H5D_chunk_redistribute_info_t
+ * structure and is suitable for communicating that structure
+ * type.
+ *
+ * The datatype returned through `resized_type` has an extent
+ * equal to the size of an H5D_filtered_collective_io_info_t
+ * structure. This makes it suitable for sending an array of
+ * those structures, while extracting out just the info
+ * necessary for the chunk redistribution operation during
+ * communication.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_get_chunk_redistribute_info_types(MPI_Datatype *contig_type, hbool_t *contig_type_derived,
+ MPI_Datatype *resized_type, hbool_t *resized_type_derived)
+{
+ MPI_Datatype struct_type = MPI_DATATYPE_NULL;
+ hbool_t struct_type_derived = FALSE;
+ MPI_Datatype chunk_block_type = MPI_DATATYPE_NULL;
+ hbool_t chunk_block_type_derived = FALSE;
+ MPI_Datatype types[5];
+ MPI_Aint displacements[5];
+ int block_lengths[5];
+ int field_count;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(contig_type);
+ HDassert(contig_type_derived);
+ HDassert(resized_type);
+ HDassert(resized_type_derived);
+
+ *contig_type_derived = FALSE;
+ *resized_type_derived = FALSE;
+
+ /* Create struct type for the inner H5F_block_t structure */
+ if (H5F_mpi_get_file_block_type(FALSE, &chunk_block_type, &chunk_block_type_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't create derived type for chunk file description")
+
+ field_count = 5;
+ HDassert(field_count == (sizeof(types) / sizeof(MPI_Datatype)));
+
+ /*
+ * Create structure type to pack chunk H5F_block_t structure
+ * next to chunk_idx, orig_owner, new_owner and num_writers
+ * fields
+ */
+ block_lengths[0] = 1;
+ block_lengths[1] = 1;
+ block_lengths[2] = 1;
+ block_lengths[3] = 1;
+ block_lengths[4] = 1;
+ displacements[0] = offsetof(H5D_chunk_redistribute_info_t, chunk_block);
+ displacements[1] = offsetof(H5D_chunk_redistribute_info_t, chunk_idx);
+ displacements[2] = offsetof(H5D_chunk_redistribute_info_t, orig_owner);
+ displacements[3] = offsetof(H5D_chunk_redistribute_info_t, new_owner);
+ displacements[4] = offsetof(H5D_chunk_redistribute_info_t, num_writers);
+ types[0] = chunk_block_type;
+ types[1] = HSIZE_AS_MPI_TYPE;
+ types[2] = MPI_INT;
+ types[3] = MPI_INT;
+ types[4] = MPI_INT;
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_struct(field_count, block_lengths, displacements, types, contig_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ *contig_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(contig_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+ /* Create struct type to extract the chunk_current, chunk_idx, orig_owner,
+ * new_owner and num_writers fields from a H5D_filtered_collective_io_info_t
+ * structure
+ */
+ block_lengths[0] = 1;
+ block_lengths[1] = 1;
+ block_lengths[2] = 1;
+ block_lengths[3] = 1;
+ block_lengths[4] = 1;
+ displacements[0] = offsetof(H5D_filtered_collective_io_info_t, chunk_current);
+ displacements[1] = offsetof(H5D_filtered_collective_io_info_t, index_info.chunk_idx);
+ displacements[2] = offsetof(H5D_filtered_collective_io_info_t, orig_owner);
+ displacements[3] = offsetof(H5D_filtered_collective_io_info_t, new_owner);
+ displacements[4] = offsetof(H5D_filtered_collective_io_info_t, num_writers);
+ types[0] = chunk_block_type;
+ types[1] = HSIZE_AS_MPI_TYPE;
+ types[2] = MPI_INT;
+ types[3] = MPI_INT;
+ types[4] = MPI_INT;
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_struct(field_count, block_lengths, displacements, types, &struct_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ struct_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_resized(
+ struct_type, 0, sizeof(H5D_filtered_collective_io_info_t), resized_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_resized failed", mpi_code)
+ *resized_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(resized_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+done:
+ if (struct_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&struct_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+ if (chunk_block_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&chunk_block_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+
+ if (ret_value < 0) {
+ if (*resized_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(resized_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *resized_type_derived = FALSE;
+ }
+ if (*contig_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(contig_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *contig_type_derived = FALSE;
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_get_chunk_redistribute_info_types() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_get_chunk_alloc_info_types
+ *
+ * Purpose: Constructs MPI derived datatypes for communicating the info
+ * from a H5D_filtered_collective_io_info_t structure that is
+ * necessary for re-allocating file space during a collective
+ * write of filtered chunks.
+ *
+ * The datatype returned through `contig_type` has an extent
+ * equal to the size of an H5D_chunk_alloc_info_t structure
+ * and is suitable for communicating that structure type.
+ *
+ * The datatype returned through `resized_type` has an extent
+ * equal to the size of an H5D_filtered_collective_io_info_t
+ * structure. This makes it suitable for sending an array of
+ * those structures, while extracting out just the info
+ * necessary for the chunk file space reallocation operation
+ * during communication.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_get_chunk_alloc_info_types(MPI_Datatype *contig_type, hbool_t *contig_type_derived,
+ MPI_Datatype *resized_type, hbool_t *resized_type_derived)
+{
+ MPI_Datatype struct_type = MPI_DATATYPE_NULL;
+ hbool_t struct_type_derived = FALSE;
+ MPI_Datatype chunk_block_type = MPI_DATATYPE_NULL;
+ hbool_t chunk_block_type_derived = FALSE;
+ MPI_Datatype types[3];
+ MPI_Aint displacements[3];
+ int block_lengths[3];
+ int field_count;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(contig_type);
+ HDassert(contig_type_derived);
+ HDassert(resized_type);
+ HDassert(resized_type_derived);
+
+ *contig_type_derived = FALSE;
+ *resized_type_derived = FALSE;
+
+ /* Create struct type for the inner H5F_block_t structure */
+ if (H5F_mpi_get_file_block_type(FALSE, &chunk_block_type, &chunk_block_type_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't create derived type for chunk file description")
+
+ field_count = 3;
+ HDassert(field_count == (sizeof(types) / sizeof(MPI_Datatype)));
+
+ /*
+ * Create structure type to pack both chunk H5F_block_t structures
+ * next to chunk_idx field
+ */
+ block_lengths[0] = 1;
+ block_lengths[1] = 1;
+ block_lengths[2] = 1;
+ displacements[0] = offsetof(H5D_chunk_alloc_info_t, chunk_current);
+ displacements[1] = offsetof(H5D_chunk_alloc_info_t, chunk_new);
+ displacements[2] = offsetof(H5D_chunk_alloc_info_t, chunk_idx);
+ types[0] = chunk_block_type;
+ types[1] = chunk_block_type;
+ types[2] = HSIZE_AS_MPI_TYPE;
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_struct(field_count, block_lengths, displacements, types, contig_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ *contig_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(contig_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+ /*
+ * Create struct type to extract the chunk_current, chunk_new and chunk_idx
+ * fields from a H5D_filtered_collective_io_info_t structure
+ */
+ block_lengths[0] = 1;
+ block_lengths[1] = 1;
+ block_lengths[2] = 1;
+ displacements[0] = offsetof(H5D_filtered_collective_io_info_t, chunk_current);
+ displacements[1] = offsetof(H5D_filtered_collective_io_info_t, chunk_new);
+ displacements[2] = offsetof(H5D_filtered_collective_io_info_t, index_info.chunk_idx);
+ types[0] = chunk_block_type;
+ types[1] = chunk_block_type;
+ types[2] = HSIZE_AS_MPI_TYPE;
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_struct(field_count, block_lengths, displacements, types, &struct_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ struct_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_resized(
+ struct_type, 0, sizeof(H5D_filtered_collective_io_info_t), resized_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_resized failed", mpi_code)
+ *resized_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(resized_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+done:
+ if (struct_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&struct_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+ if (chunk_block_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&chunk_block_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+
+ if (ret_value < 0) {
+ if (*resized_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(resized_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *resized_type_derived = FALSE;
+ }
+ if (*contig_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(contig_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *contig_type_derived = FALSE;
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_get_chunk_alloc_info_types() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_get_chunk_insert_info_types
+ *
+ * Purpose: Constructs MPI derived datatypes for communicating the
+ * information necessary when reinserting chunks into a
+ * dataset's chunk index. This includes the chunk's new offset
+ * and size (H5F_block_t) and the inner `index_info` structure
+ * of a H5D_filtered_collective_io_info_t structure.
+ *
+ * The datatype returned through `contig_type` has an extent
+ * equal to the size of an H5D_chunk_insert_info_t structure
+ * and is suitable for communicating that structure type.
+ *
+ * The datatype returned through `resized_type` has an extent
+ * equal to the size of the encompassing
+ * H5D_filtered_collective_io_info_t structure. This makes it
+ * suitable for sending an array of
+ * H5D_filtered_collective_io_info_t structures, while
+ * extracting out just the information needed during
+ * communication.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_get_chunk_insert_info_types(MPI_Datatype *contig_type, hbool_t *contig_type_derived,
+ MPI_Datatype *resized_type, hbool_t *resized_type_derived)
+{
+ MPI_Datatype struct_type = MPI_DATATYPE_NULL;
+ hbool_t struct_type_derived = FALSE;
+ MPI_Datatype chunk_block_type = MPI_DATATYPE_NULL;
+ hbool_t chunk_block_type_derived = FALSE;
+ MPI_Aint contig_type_extent;
+ MPI_Datatype types[4];
+ MPI_Aint displacements[4];
+ int block_lengths[4];
+ int field_count;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(contig_type);
+ HDassert(contig_type_derived);
+ HDassert(resized_type);
+ HDassert(resized_type_derived);
+
+ *contig_type_derived = FALSE;
+ *resized_type_derived = FALSE;
+
+ /* Create struct type for an H5F_block_t structure */
+ if (H5F_mpi_get_file_block_type(FALSE, &chunk_block_type, &chunk_block_type_derived) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't create derived type for chunk file description")
+
+ field_count = 4;
+ HDassert(field_count == (sizeof(types) / sizeof(MPI_Datatype)));
+
+ /*
+ * Create struct type to pack information into memory as follows:
+ *
+ * Chunk's new Offset/Size (H5F_block_t) ->
+ * Chunk Index Info (H5D_chunk_index_info_t)
+ */
+ block_lengths[0] = 1;
+ block_lengths[1] = 1;
+ block_lengths[2] = 1;
+ block_lengths[3] = 1;
+ displacements[0] = offsetof(H5D_chunk_insert_info_t, chunk_block);
+ displacements[1] = offsetof(H5D_chunk_insert_info_t, index_info.chunk_idx);
+ displacements[2] = offsetof(H5D_chunk_insert_info_t, index_info.filter_mask);
+ displacements[3] = offsetof(H5D_chunk_insert_info_t, index_info.need_insert);
+ types[0] = chunk_block_type;
+ types[1] = HSIZE_AS_MPI_TYPE;
+ types[2] = MPI_UNSIGNED;
+ types[3] = MPI_C_BOOL;
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_struct(field_count, block_lengths, displacements, types, &struct_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ struct_type_derived = TRUE;
+
+ contig_type_extent = (MPI_Aint)(sizeof(H5F_block_t) + sizeof(H5D_chunk_index_info_t));
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_resized(struct_type, 0, contig_type_extent, contig_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_resized failed", mpi_code)
+ *contig_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(contig_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+ struct_type_derived = FALSE;
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&struct_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+
+ /*
+ * Create struct type to correctly extract all needed
+ * information from a H5D_filtered_collective_io_info_t
+ * structure.
+ */
+ displacements[0] = offsetof(H5D_filtered_collective_io_info_t, chunk_new);
+ displacements[1] = offsetof(H5D_filtered_collective_io_info_t, index_info.chunk_idx);
+ displacements[2] = offsetof(H5D_filtered_collective_io_info_t, index_info.filter_mask);
+ displacements[3] = offsetof(H5D_filtered_collective_io_info_t, index_info.need_insert);
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_struct(field_count, block_lengths, displacements, types, &struct_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ struct_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_resized(
+ struct_type, 0, sizeof(H5D_filtered_collective_io_info_t), resized_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_resized failed", mpi_code)
+ *resized_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(resized_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+done:
+ if (struct_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&struct_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+ if (chunk_block_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&chunk_block_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ }
+
+ if (ret_value < 0) {
+ if (*resized_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(resized_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *resized_type_derived = FALSE;
+ }
+ if (*contig_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(contig_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *contig_type_derived = FALSE;
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_get_chunk_insert_info_types() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__mpio_collective_filtered_io_type
+ *
+ * Purpose: Constructs a MPI derived datatype for both the memory and
+ * the file for a collective I/O operation on filtered chunks.
+ * The datatype contains the chunk offsets and lengths in the
+ * file and the locations of the chunk data buffers to read
+ * into/write from.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__mpio_collective_filtered_io_type(H5D_filtered_collective_io_info_t *chunk_list, size_t num_entries,
+ H5D_io_op_type_t op_type, MPI_Datatype *new_mem_type,
+ hbool_t *mem_type_derived, MPI_Datatype *new_file_type,
+ hbool_t *file_type_derived)
+{
+ MPI_Aint *io_buf_array = NULL; /* Relative displacements of filtered chunk data buffers */
+ MPI_Aint *file_offset_array = NULL; /* Chunk offsets in the file */
+ int * length_array = NULL; /* Filtered Chunk lengths */
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(chunk_list || 0 == num_entries);
+ HDassert(new_mem_type);
+ HDassert(mem_type_derived);
+ HDassert(new_file_type);
+ HDassert(file_type_derived);
+
+ *mem_type_derived = FALSE;
+ *file_type_derived = FALSE;
+ *new_mem_type = MPI_BYTE;
+ *new_file_type = MPI_BYTE;
+
+ if (num_entries > 0) {
+ H5F_block_t *chunk_block;
+ size_t last_valid_idx = 0;
+ size_t i;
+ int chunk_count;
+
+ /*
+ * Determine number of chunks for I/O operation and
+ * setup for derived datatype creation if I/O operation
+ * includes multiple chunks
+ */
+ if (num_entries == 1) {
+ /* Set last valid index to 0 for contiguous datatype creation */
+ last_valid_idx = 0;
+
+ if (op_type == H5D_IO_OP_WRITE)
+ chunk_count = 1;
+ else
+ chunk_count = chunk_list[0].need_read ? 1 : 0;
+ }
+ else {
+ MPI_Aint chunk_buf;
+ MPI_Aint base_buf;
+ haddr_t base_offset = HADDR_UNDEF;
+
+ H5_CHECK_OVERFLOW(num_entries, size_t, int);
+
+ /* Allocate arrays */
+ if (NULL == (length_array = H5MM_malloc((size_t)num_entries * sizeof(int))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for filtered collective I/O length array")
+ if (NULL == (io_buf_array = H5MM_malloc((size_t)num_entries * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for filtered collective I/O buf length array")
+ if (NULL == (file_offset_array = H5MM_malloc((size_t)num_entries * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for filtered collective I/O offset array")
+
+ /*
+ * If doing a write, we can set the base chunk offset
+ * and base chunk data buffer right away.
+ *
+ * If doing a read, some chunks may be skipped over
+ * for reading if they aren't yet allocated in the
+ * file. Therefore, we have to find the first chunk
+ * actually being read in order to set the base chunk
+ * offset and base chunk data buffer.
+ */
+ if (op_type == H5D_IO_OP_WRITE) {
+#if MPI_VERSION >= 3
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_address(chunk_list[0].buf, &base_buf)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_address failed", mpi_code)
+#else
+ base_buf = (MPI_Aint)chunk_list[0].buf;
+#endif
+
+ base_offset = chunk_list[0].chunk_new.offset;
+ }
+
+ for (i = 0, chunk_count = 0; i < num_entries; i++) {
+ if (op_type == H5D_IO_OP_READ) {
+ /*
+ * If this chunk isn't being read, don't add it
+ * to the MPI type we're building up for I/O
+ */
+ if (!chunk_list[i].need_read)
+ continue;
+
+ /*
+ * If this chunk is being read, go ahead and
+ * set the base chunk offset and base chunk
+ * data buffer if we haven't already
+ */
+ if (!H5F_addr_defined(base_offset)) {
+#if MPI_VERSION >= 3
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_address(chunk_list[i].buf, &base_buf)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_address failed", mpi_code)
+#else
+ base_buf = (MPI_Aint)chunk_list[i].buf;
+#endif
+
+ base_offset = chunk_list[i].chunk_current.offset;
+ }
+ }
+
+ /* Set convenience pointer for current chunk block */
+ chunk_block =
+ (op_type == H5D_IO_OP_READ) ? &chunk_list[i].chunk_current : &chunk_list[i].chunk_new;
+
+ /*
+ * Set the current chunk entry's offset in the file, relative to
+ * the first chunk entry
+ */
+ HDassert(H5F_addr_defined(chunk_block->offset));
+ file_offset_array[chunk_count] = (MPI_Aint)(chunk_block->offset - base_offset);
+
+ /*
+ * Ensure the chunk list is sorted in ascending ordering of
+ * offset in the file
+ */
+ if (chunk_count)
+ HDassert(file_offset_array[chunk_count] > file_offset_array[chunk_count - 1]);
+
+ /* Set the current chunk entry's size for the I/O operation */
+ H5_CHECK_OVERFLOW(chunk_block->length, hsize_t, int);
+ length_array[chunk_count] = (int)chunk_block->length;
+
+ /*
+ * Set the displacement of the chunk entry's chunk data buffer,
+ * relative to the first entry's data buffer
+ */
+#if MPI_VERSION >= 3 && MPI_SUBVERSION >= 1
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_address(chunk_list[i].buf, &chunk_buf)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_address failed", mpi_code)
+
+ io_buf_array[chunk_count] = MPI_Aint_diff(chunk_buf, base_buf);
+#else
+ chunk_buf = (MPI_Aint)chunk_list[i].buf;
+ io_buf_array[chunk_count] = chunk_buf - base_buf;
+#endif
+
+ /*
+ * Set last valid index in case only a single chunk will
+ * be involved in the I/O operation
+ */
+ last_valid_idx = i;
+
+ chunk_count++;
+ } /* end for */
+ }
+
+ /*
+ * Create derived datatypes for the chunk list if this
+ * rank has any chunks to work on
+ */
+ if (chunk_count > 0) {
+ if (chunk_count == 1) {
+ int chunk_len;
+
+ /* Single chunk - use a contiguous type for both memory and file */
+
+ /* Ensure that we can cast chunk size to an int for MPI */
+ chunk_block = (op_type == H5D_IO_OP_READ) ? &chunk_list[last_valid_idx].chunk_current
+ : &chunk_list[last_valid_idx].chunk_new;
+ H5_CHECKED_ASSIGN(chunk_len, int, chunk_block->length, hsize_t);
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(chunk_len, MPI_BYTE, new_file_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ *new_mem_type = *new_file_type;
+
+ /*
+ * Since we use the same datatype for both memory and file, only
+ * mark the file type as derived so the caller doesn't try to
+ * free the same type twice
+ */
+ *mem_type_derived = FALSE;
+ *file_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_file_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+ }
+ else {
+ HDassert(file_offset_array);
+ HDassert(length_array);
+ HDassert(io_buf_array);
+
+ /* Multiple chunks - use an hindexed type for both memory and file */
+
+ /* Create memory MPI type */
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed(
+ chunk_count, length_array, io_buf_array, MPI_BYTE, new_mem_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
+ *mem_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_mem_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+ /* Create file MPI type */
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_hindexed(chunk_count, length_array, file_offset_array,
+ MPI_BYTE, new_file_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
+ *file_type_derived = TRUE;
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_file_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+ }
+ }
+ } /* end if */
done:
- if (chunk_entry->async_info.receive_buffer_array)
- H5MM_free(chunk_entry->async_info.receive_buffer_array);
- if (chunk_entry->async_info.receive_requests_array)
- H5MM_free(chunk_entry->async_info.receive_requests_array);
- if (tmp_gath_buf)
- H5MM_free(tmp_gath_buf);
- if (file_iter_init && H5S_SELECT_ITER_RELEASE(file_iter) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator")
- if (file_iter)
- H5MM_free(file_iter);
- if (mem_iter_init && H5S_SELECT_ITER_RELEASE(mem_iter) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator")
- if (mem_iter)
- H5MM_free(mem_iter);
- if (dataspace)
- if (H5S_close(dataspace) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace")
+ if (file_offset_array)
+ H5MM_free(file_offset_array);
+ if (io_buf_array)
+ H5MM_free(io_buf_array);
+ if (length_array)
+ H5MM_free(length_array);
+
+ if (ret_value < 0) {
+ if (*file_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(new_file_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *file_type_derived = FALSE;
+ }
+ if (*mem_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(new_mem_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *mem_type_derived = FALSE;
+ }
+ }
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__filtered_collective_chunk_entry_io() */
+} /* end H5D__mpio_collective_filtered_io_type() */
+
+#ifdef H5Dmpio_DEBUG
+
+static herr_t
+H5D__mpio_dump_collective_filtered_chunk_list(H5D_filtered_collective_io_info_t *chunk_list,
+ size_t chunk_list_num_entries, int mpi_rank)
+{
+ H5D_filtered_collective_io_info_t *chunk_entry;
+ size_t i;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ H5D_MPIO_DEBUG(mpi_rank, "CHUNK LIST: [");
+ for (i = 0; i < chunk_list_num_entries; i++) {
+ unsigned chunk_rank;
+
+ chunk_entry = &chunk_list[i];
+
+ HDassert(chunk_entry->chunk_info);
+ chunk_rank = (unsigned)H5S_GET_EXTENT_NDIMS(chunk_entry->chunk_info->fspace);
+
+ H5D_MPIO_DEBUG(mpi_rank, " {");
+ H5D_MPIO_DEBUG_VA(mpi_rank, " - Entry %zu -", i);
+
+ H5D_MPIO_DEBUG(mpi_rank, " - Chunk Fspace Info -");
+ H5D_MPIO_DEBUG_VA(mpi_rank,
+ " Chunk Current Info: { Offset: %" PRIuHADDR ", Length: %" PRIuHADDR " }",
+ chunk_entry->chunk_current.offset, chunk_entry->chunk_current.length);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Chunk New Info: { Offset: %" PRIuHADDR ", Length: %" PRIuHADDR " }",
+ chunk_entry->chunk_new.offset, chunk_entry->chunk_new.length);
+
+ H5D_MPIO_DEBUG(mpi_rank, " - Chunk Insert Info -");
+ H5D_MPIO_DEBUG_VA(mpi_rank,
+ " Chunk Scaled Coords (4-d): { %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE
+ ", %" PRIuHSIZE " }",
+ chunk_rank < 1 ? 0 : chunk_entry->chunk_info->scaled[0],
+ chunk_rank < 2 ? 0 : chunk_entry->chunk_info->scaled[1],
+ chunk_rank < 3 ? 0 : chunk_entry->chunk_info->scaled[2],
+ chunk_rank < 4 ? 0 : chunk_entry->chunk_info->scaled[3]);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Chunk Index: %" PRIuHSIZE, chunk_entry->index_info.chunk_idx);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Filter Mask: %u", chunk_entry->index_info.filter_mask);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Need Insert: %s",
+ chunk_entry->index_info.need_insert ? "YES" : "NO");
+
+ H5D_MPIO_DEBUG(mpi_rank, " - Other Info -");
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Chunk Info Ptr: %p", (void *)chunk_entry->chunk_info);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Need Read: %s", chunk_entry->need_read ? "YES" : "NO");
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Chunk I/O Size: %zu", chunk_entry->io_size);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Chunk Buffer Size: %zu", chunk_entry->chunk_buf_size);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Original Owner: %d", chunk_entry->orig_owner);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " New Owner: %d", chunk_entry->new_owner);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " # of Writers: %d", chunk_entry->num_writers);
+ H5D_MPIO_DEBUG_VA(mpi_rank, " Chunk Data Buffer Ptr: %p", (void *)chunk_entry->buf);
+
+ H5D_MPIO_DEBUG(mpi_rank, " }");
+ }
+ H5D_MPIO_DEBUG(mpi_rank, "]");
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__mpio_dump_collective_filtered_chunk_list() */
+
+#endif
+
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 92ea120..5114d6a 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -123,13 +123,12 @@ typedef hbool_t (*H5D_layout_is_space_alloc_func_t)(const H5O_storage_t *storage
typedef hbool_t (*H5D_layout_is_data_cached_func_t)(const H5D_shared_t *shared_dset);
typedef herr_t (*H5D_layout_io_init_func_t)(const struct H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space,
- struct H5D_chunk_map_t *cm);
+ H5S_t *file_space, H5S_t *mem_space, struct H5D_chunk_map_t *cm);
typedef herr_t (*H5D_layout_read_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
struct H5D_chunk_map_t *fm);
typedef herr_t (*H5D_layout_write_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
struct H5D_chunk_map_t *fm);
typedef ssize_t (*H5D_layout_readvv_func_t)(const struct H5D_io_info_t *io_info, size_t dset_max_nseq,
size_t *dset_curr_seq, size_t dset_len_arr[],
@@ -170,10 +169,10 @@ typedef struct H5D_layout_ops_t {
/* Function pointers for either multiple or single block I/O access */
typedef herr_t (*H5D_io_single_read_func_t)(const struct H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space);
+ H5S_t *file_space, H5S_t *mem_space);
typedef herr_t (*H5D_io_single_write_func_t)(const struct H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space);
+ H5S_t *file_space, H5S_t *mem_space);
/* Typedef for raw data I/O framework info */
typedef struct H5D_io_ops_t {
@@ -347,10 +346,10 @@ typedef struct H5D_chunk_map_t {
H5O_layout_t *layout; /* Dataset layout information*/
hsize_t nelmts; /* Number of elements selected in file & memory dataspaces */
- const H5S_t *file_space; /* Pointer to the file dataspace */
- unsigned f_ndims; /* Number of dimensions for file dataspace */
+ H5S_t * file_space; /* Pointer to the file dataspace */
+ unsigned f_ndims; /* Number of dimensions for file dataspace */
- const H5S_t * mem_space; /* Pointer to the memory dataspace */
+ H5S_t * mem_space; /* Pointer to the memory dataspace */
H5S_t * mchunk_tmpl; /* Dataspace template for new memory chunks */
H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */
unsigned m_ndims; /* Number of dimensions for memory dataspace */
@@ -435,7 +434,7 @@ typedef struct H5D_rdcdc_t {
/*
* A dataset is made of two layers, an H5D_t struct that is unique to
- * each instance of an opened datset, and a shared struct that is only
+ * each instance of an opened dataset, and a shared struct that is only
* created once for a given dataset. Thus, if a dataset is opened twice,
* there will be two IDs and two H5D_t structs, both sharing one H5D_shared_t.
*/
@@ -561,6 +560,7 @@ H5_DLL herr_t H5D__alloc_storage(const H5D_io_info_t *io_info, H5D_time_alloc_t
hbool_t full_overwrite, hsize_t old_dim[]);
H5_DLL herr_t H5D__get_storage_size(const H5D_t *dset, hsize_t *storage_size);
H5_DLL herr_t H5D__get_chunk_storage_size(H5D_t *dset, const hsize_t *offset, hsize_t *storage_size);
+H5_DLL herr_t H5D__chunk_index_empty(const H5D_t *dset, hbool_t *empty);
H5_DLL herr_t H5D__get_num_chunks(const H5D_t *dset, const H5S_t *space, hsize_t *nchunks);
H5_DLL herr_t H5D__get_chunk_info(const H5D_t *dset, const H5S_t *space, hsize_t chk_idx, hsize_t *coord,
unsigned *filter_mask, haddr_t *offset, hsize_t *size);
@@ -582,25 +582,29 @@ H5_DLL herr_t H5D__refresh(H5D_t *dataset, hid_t dset_id);
H5_DLL herr_t H5D__format_convert(H5D_t *dataset);
/* Internal I/O routines */
-H5_DLL herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space,
+H5_DLL herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space,
void *buf /*out*/);
-H5_DLL herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space,
+H5_DLL herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space,
const void *buf);
/* Functions that perform direct serial I/O operations */
H5_DLL herr_t H5D__select_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space);
+ H5S_t *file_space, H5S_t *mem_space);
H5_DLL herr_t H5D__select_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
+
+/* Functions that perform direct copying between memory buffers */
+H5_DLL herr_t H5D_select_io_mem(void *dst_buf, const H5S_t *dst_space, const void *src_buf,
+ const H5S_t *src_space, size_t elmt_size, size_t nelmts);
/* Functions that perform scatter-gather serial I/O operations */
H5_DLL herr_t H5D__scatter_mem(const void *_tscat_buf, H5S_sel_iter_t *iter, size_t nelmts, void *_buf);
H5_DLL size_t H5D__gather_mem(const void *_buf, H5S_sel_iter_t *iter, size_t nelmts,
void *_tgath_buf /*out*/);
H5_DLL herr_t H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
H5_DLL herr_t H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
/* Functions that operate on dataset's layout information */
H5_DLL herr_t H5D__layout_set_io_ops(const H5D_t *dataset);
@@ -618,9 +622,9 @@ H5_DLL hbool_t H5D__contig_is_space_alloc(const H5O_storage_t *storage);
H5_DLL hbool_t H5D__contig_is_data_cached(const H5D_shared_t *shared_dset);
H5_DLL herr_t H5D__contig_fill(const H5D_io_info_t *io_info);
H5_DLL herr_t H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm);
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
H5_DLL herr_t H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm);
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
H5_DLL herr_t H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, H5F_t *f_dst,
H5O_storage_contig_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info);
H5_DLL herr_t H5D__contig_delete(H5F_t *f, const H5O_storage_t *store);
@@ -637,7 +641,13 @@ H5_DLL herr_t H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_ov
const hsize_t old_dim[]);
H5_DLL herr_t H5D__chunk_file_alloc(const H5D_chk_idx_info_t *idx_info, const H5F_block_t *old_chunk,
H5F_block_t *new_chunk, hbool_t *need_insert, const hsize_t *scaled);
+H5_DLL void * H5D__chunk_mem_alloc(size_t size, const H5O_pline_t *pline);
+H5_DLL void H5D__chunk_mem_free(void *chk, const void *_pline);
+H5_DLL void * H5D__chunk_mem_xfree(void *chk, const void *pline);
+H5_DLL void * H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline);
H5_DLL herr_t H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[]);
+H5_DLL hbool_t H5D__chunk_is_partial_edge_chunk(unsigned dset_ndims, const uint32_t *chunk_dims,
+ const hsize_t *chunk_scaled, const hsize_t *dset_dims);
H5_DLL herr_t H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim);
H5_DLL herr_t H5D__chunk_set_sizes(H5D_t *dset);
#ifdef H5_HAVE_PARALLEL
@@ -687,7 +697,7 @@ H5_DLL herr_t H5D__efl_bh_info(H5F_t *f, H5O_efl_t *efl, hsize_t *heap_size);
/* Functions that perform fill value operations on datasets */
H5_DLL herr_t H5D__fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type,
- const H5S_t *space);
+ H5S_t *space);
H5_DLL herr_t H5D__fill_init(H5D_fill_buf_info_t *fb_info, void *caller_fill_buf, H5MM_allocate_t alloc_func,
void *alloc_info, H5MM_free_t free_func, void *free_info, const H5O_fill_t *fill,
const H5T_t *dset_type, hid_t dset_type_id, size_t nelmts, size_t min_buf_size);
@@ -696,39 +706,41 @@ H5_DLL herr_t H5D__fill_term(H5D_fill_buf_info_t *fb_info);
#ifdef H5_HAVE_PARALLEL
-#ifdef H5S_DEBUG
+#ifdef H5D_DEBUG
#ifndef H5Dmpio_DEBUG
#define H5Dmpio_DEBUG
#endif /*H5Dmpio_DEBUG*/
-#endif /*H5S_DEBUG*/
+#endif /*H5D_DEBUG*/
/* MPI-IO function to read, it will select either regular or irregular read */
H5_DLL herr_t H5D__mpio_select_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
/* MPI-IO function to write, it will select either regular or irregular read */
H5_DLL herr_t H5D__mpio_select_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space);
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
/* MPI-IO functions to handle contiguous collective IO */
H5_DLL herr_t H5D__contig_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
H5D_chunk_map_t *fm);
H5_DLL herr_t H5D__contig_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
H5D_chunk_map_t *fm);
/* MPI-IO functions to handle chunked collective IO */
H5_DLL herr_t H5D__chunk_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
H5D_chunk_map_t *fm);
H5_DLL herr_t H5D__chunk_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
+ hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
H5D_chunk_map_t *fm);
/* MPI-IO function to check if a direct I/O transfer is possible between
* memory and the file */
H5_DLL htri_t H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space,
const H5S_t *mem_space, const H5D_type_info_t *type_info);
+H5_DLL herr_t H5D__mpio_get_no_coll_cause_strings(char *local_cause, size_t local_cause_len,
+ char *global_cause, size_t global_cause_len);
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index c496414..02644ed 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -77,7 +77,7 @@ typedef enum H5D_chunk_index_t {
*/
typedef enum H5D_alloc_time_t {
H5D_ALLOC_TIME_ERROR = -1, /**< Error */
- H5D_ALLOC_TIME_DEFAULT = 0, /**< \todo Define this! */
+ H5D_ALLOC_TIME_DEFAULT = 0, /**< Default (layout dependent) */
H5D_ALLOC_TIME_EARLY = 1, /**< Allocate on creation */
H5D_ALLOC_TIME_LATE = 2, /**< Allocate on first write */
H5D_ALLOC_TIME_INCR = 3 /**< Allocate incrementally (by chunk) */
@@ -91,9 +91,9 @@ typedef enum H5D_alloc_time_t {
typedef enum H5D_space_status_t {
H5D_SPACE_STATUS_ERROR = -1, /**< Error */
H5D_SPACE_STATUS_NOT_ALLOCATED = 0, /**< Space has not been allocated for this dataset. */
- H5D_SPACE_STATUS_PART_ALLOCATED = 1, /**< Space has been allocated for this dataset. */
- H5D_SPACE_STATUS_ALLOCATED = 2 /**< Space has been partially allocated for this dataset. (Used only for
- datasets with chunked storage.) */
+ H5D_SPACE_STATUS_PART_ALLOCATED = 1, /**< Space has been partially allocated for this dataset.
+ (Used only for datasets with chunked storage.) */
+ H5D_SPACE_STATUS_ALLOCATED = 2 /**< Space has been allocated for this dataset. */
} H5D_space_status_t;
//! <!-- [H5D_space_status_t_snip] -->
@@ -127,8 +127,8 @@ typedef enum H5D_fill_value_t {
*/
typedef enum H5D_vds_view_t {
H5D_VDS_ERROR = -1, /**< Error */
- H5D_VDS_FIRST_MISSING = 0, /**< \todo Define this! */
- H5D_VDS_LAST_AVAILABLE = 1 /**< \todo Define this! */
+ H5D_VDS_FIRST_MISSING = 0, /**< Include all data before the first missing mapped data */
+ H5D_VDS_LAST_AVAILABLE = 1 /**< Include all available mapped data */
} H5D_vds_view_t;
//! <!-- [H5D_vds_view_t_snip] -->
@@ -300,7 +300,7 @@ extern "C" {
* caller may derive new datatypes, dataspaces, and creation and
* access properties from the old ones and reuse them in calls to
* create additional datasets. Once created, the dataset can be
- * read from or written to. Reading data from a datatset that was
+ * read from or written to. Reading data from a dataset that was
* not previously written, the HDF5 library will return default
* or user-defined fill values.
*
@@ -682,8 +682,7 @@ H5_DLL herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, u
* Iterate over all chunked datasets and chunks in a file.
* \snippet H5D_examples.c H5Ovisit_cb
*
- * \version 1.?.?
- * \todo When was this function introduced?
+ * \since 1.13.0
*
*/
H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, hid_t dxpl_id, H5D_chunk_iter_op_t cb, void *op_data);
diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c
index 971ddfb..500ea9e 100644
--- a/src/H5Dscatgath.c
+++ b/src/H5Dscatgath.c
@@ -437,7 +437,7 @@ done:
*/
herr_t
H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space)
+ H5S_t *file_space, H5S_t *mem_space)
{
void * buf = io_info->u.rbuf; /* Local pointer to application buffer */
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info*/
@@ -577,7 +577,7 @@ done:
*/
herr_t
H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space)
+ H5S_t *file_space, H5S_t *mem_space)
{
const void * buf = io_info->u.wbuf; /* Local pointer to application buffer */
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info*/
diff --git a/src/H5Dselect.c b/src/H5Dselect.c
index 7d2ead1..f464ca5 100644
--- a/src/H5Dselect.c
+++ b/src/H5Dselect.c
@@ -44,8 +44,8 @@
/* Local Prototypes */
/********************/
-static herr_t H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space);
+static herr_t H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5S_t *file_space,
+ H5S_t *mem_space);
/*********************/
/* Package Variables */
@@ -77,8 +77,8 @@ H5FL_EXTERN(H5S_sel_iter_t);
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, const H5S_t *file_space,
- const H5S_t *mem_space)
+H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5S_t *file_space,
+ H5S_t *mem_space)
{
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info */
hbool_t mem_iter_init = FALSE; /* Memory selection iteration info has been initialized */
@@ -105,6 +105,9 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, co
HDassert(io_info->store);
HDassert(io_info->u.rbuf);
+ if (elmt_size == 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid elmt_size of 0")
+
/* Check for only one element in selection */
if (nelmts == 1) {
hsize_t single_mem_off; /* Offset in memory */
@@ -226,8 +229,6 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, co
/* Decrement number of elements left to process */
HDassert(((size_t)tmp_file_len % elmt_size) == 0);
- if (elmt_size == 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "Resulted in division by zero")
nelmts -= ((size_t)tmp_file_len / elmt_size);
} /* end while */
} /* end else */
@@ -257,6 +258,188 @@ done:
} /* end H5D__select_io() */
/*-------------------------------------------------------------------------
+ * Function: H5D_select_io_mem
+ *
+ * Purpose: Perform memory copies directly between two memory buffers
+ * according to the selections in the `dst_space` and
+ * `src_space` dataspaces.
+ *
+ * Note: This routine is [basically] the same as H5D__select_io,
+ * with the only difference being that the readvv/writevv
+ * calls are exchanged for H5VM_memcpyvv calls. Changes should
+ * be made to both routines.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_select_io_mem(void *dst_buf, const H5S_t *dst_space, const void *src_buf, const H5S_t *src_space,
+ size_t elmt_size, size_t nelmts)
+{
+ H5S_sel_iter_t *dst_sel_iter = NULL; /* Destination dataspace iteration info */
+ H5S_sel_iter_t *src_sel_iter = NULL; /* Source dataspace iteration info */
+ hbool_t dst_sel_iter_init = FALSE; /* Destination dataspace selection iterator initialized? */
+ hbool_t src_sel_iter_init = FALSE; /* Source dataspace selection iterator initialized? */
+ hsize_t * dst_off = NULL; /* Pointer to sequence offsets in destination buffer */
+ hsize_t * src_off = NULL; /* Pointer to sequence offsets in source buffer */
+ size_t * dst_len = NULL; /* Pointer to sequence lengths in destination buffer */
+ size_t * src_len = NULL; /* Pointer to sequence lengths in source buffer */
+ size_t curr_dst_seq; /* Current destination buffer sequence to operate on */
+ size_t curr_src_seq; /* Current source buffer sequence to operate on */
+ size_t dst_nseq; /* Number of sequences generated for destination buffer */
+ size_t src_nseq; /* Number of sequences generated for source buffer */
+ size_t dxpl_vec_size; /* Vector length from API context's DXPL */
+ size_t vec_size; /* Vector length */
+ ssize_t bytes_copied;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(dst_buf);
+ HDassert(dst_space);
+ HDassert(src_buf);
+ HDassert(src_space);
+
+ if (elmt_size == 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid elmt_size of 0")
+
+ /* Check for only one element in selection */
+ if (nelmts == 1) {
+ hsize_t single_dst_off; /* Offset in dst_space */
+ hsize_t single_src_off; /* Offset in src_space */
+ size_t single_dst_len; /* Length in dst_space */
+ size_t single_src_len; /* Length in src_space */
+
+ /* Get offset of first element in selections */
+ if (H5S_SELECT_OFFSET(dst_space, &single_dst_off) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve destination selection offset")
+ if (H5S_SELECT_OFFSET(src_space, &single_src_off) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve source selection offset")
+
+ /* Set up necessary information for I/O operation */
+ dst_nseq = src_nseq = 1;
+ curr_dst_seq = curr_src_seq = 0;
+ single_dst_off *= elmt_size;
+ single_src_off *= elmt_size;
+ single_dst_len = single_src_len = elmt_size;
+
+ /* Perform vectorized memcpy from src_buf to dst_buf */
+ if ((bytes_copied =
+ H5VM_memcpyvv(dst_buf, dst_nseq, &curr_dst_seq, &single_dst_len, &single_dst_off, src_buf,
+ src_nseq, &curr_src_seq, &single_src_len, &single_src_off)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+
+ HDassert(((size_t)bytes_copied % elmt_size) == 0);
+ }
+ else {
+ unsigned sel_iter_flags = H5S_SEL_ITER_GET_SEQ_LIST_SORTED | H5S_SEL_ITER_SHARE_WITH_DATASPACE;
+ size_t dst_nelem; /* Number of elements used in destination buffer sequences */
+ size_t src_nelem; /* Number of elements used in source buffer sequences */
+
+ /* Get info from API context */
+ if (H5CX_get_vec_size(&dxpl_vec_size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't retrieve I/O vector size")
+
+ /* Allocate the vector I/O arrays */
+ if (dxpl_vec_size > H5D_IO_VECTOR_SIZE)
+ vec_size = dxpl_vec_size;
+ else
+ vec_size = H5D_IO_VECTOR_SIZE;
+
+ if (NULL == (dst_len = H5FL_SEQ_MALLOC(size_t, vec_size)))
+ HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O length vector array")
+ if (NULL == (dst_off = H5FL_SEQ_MALLOC(hsize_t, vec_size)))
+ HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O offset vector array")
+ if (NULL == (src_len = H5FL_SEQ_MALLOC(size_t, vec_size)))
+ HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O length vector array")
+ if (NULL == (src_off = H5FL_SEQ_MALLOC(hsize_t, vec_size)))
+ HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O offset vector array")
+
+ /* Allocate the dataspace selection iterators */
+ if (NULL == (dst_sel_iter = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate destination selection iterator")
+ if (NULL == (src_sel_iter = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate source selection iterator")
+
+ /* Initialize destination selection iterator */
+ if (H5S_select_iter_init(dst_sel_iter, dst_space, elmt_size, sel_iter_flags) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ dst_sel_iter_init = TRUE; /* Destination selection iteration info has been initialized */
+
+ /* Initialize source selection iterator */
+ if (H5S_select_iter_init(src_sel_iter, src_space, elmt_size, H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ src_sel_iter_init = TRUE; /* Source selection iteration info has been initialized */
+
+ /* Initialize sequence counts */
+ curr_dst_seq = curr_src_seq = 0;
+ dst_nseq = src_nseq = 0;
+
+ /* Loop, until all bytes are processed */
+ while (nelmts > 0) {
+ /* Check if more destination buffer sequences are needed */
+ if (curr_dst_seq >= dst_nseq) {
+ /* Get sequences for destination selection */
+ if (H5S_SELECT_ITER_GET_SEQ_LIST(dst_sel_iter, vec_size, nelmts, &dst_nseq, &dst_nelem,
+ dst_off, dst_len) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "sequence length generation failed")
+
+ /* Start at the beginning of the sequences again */
+ curr_dst_seq = 0;
+ }
+
+ /* Check if more source buffer sequences are needed */
+ if (curr_src_seq >= src_nseq) {
+ /* Get sequences for source selection */
+ if (H5S_SELECT_ITER_GET_SEQ_LIST(src_sel_iter, vec_size, nelmts, &src_nseq, &src_nelem,
+ src_off, src_len) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "sequence length generation failed")
+
+ /* Start at the beginning of the sequences again */
+ curr_src_seq = 0;
+ } /* end if */
+
+ /* Perform vectorized memcpy from src_buf to dst_buf */
+ if ((bytes_copied = H5VM_memcpyvv(dst_buf, dst_nseq, &curr_dst_seq, dst_len, dst_off, src_buf,
+ src_nseq, &curr_src_seq, src_len, src_off)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
+
+ /* Decrement number of elements left to process */
+ HDassert(((size_t)bytes_copied % elmt_size) == 0);
+ nelmts -= ((size_t)bytes_copied / elmt_size);
+ }
+ }
+
+done:
+ /* Release selection iterators */
+ if (src_sel_iter) {
+ if (src_sel_iter_init && H5S_SELECT_ITER_RELEASE(src_sel_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
+
+ src_sel_iter = H5FL_FREE(H5S_sel_iter_t, src_sel_iter);
+ }
+ if (dst_sel_iter) {
+ if (dst_sel_iter_init && H5S_SELECT_ITER_RELEASE(dst_sel_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
+
+ dst_sel_iter = H5FL_FREE(H5S_sel_iter_t, dst_sel_iter);
+ }
+
+ /* Release vector arrays, if allocated */
+ if (src_off)
+ src_off = H5FL_SEQ_FREE(hsize_t, src_off);
+ if (src_len)
+ src_len = H5FL_SEQ_FREE(size_t, src_len);
+ if (dst_off)
+ dst_off = H5FL_SEQ_FREE(hsize_t, dst_off);
+ if (dst_len)
+ dst_len = H5FL_SEQ_FREE(size_t, dst_len);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_select_io_mem() */
+
+/*-------------------------------------------------------------------------
* Function: H5D__select_read
*
* Purpose: Reads directly from file into application memory.
@@ -270,7 +453,7 @@ done:
*/
herr_t
H5D__select_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space)
+ H5S_t *file_space, H5S_t *mem_space)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -299,7 +482,7 @@ done:
*/
herr_t
H5D__select_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space)
+ H5S_t *file_space, H5S_t *mem_space)
{
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5Dsingle.c b/src/H5Dsingle.c
index eba569e..a843d88 100644
--- a/src/H5Dsingle.c
+++ b/src/H5Dsingle.c
@@ -126,8 +126,14 @@ H5D__single_idx_init(const H5D_chk_idx_info_t *idx_info, const H5S_t H5_ATTR_UNU
HDassert(idx_info->layout);
HDassert(idx_info->storage);
- if (idx_info->pline->nused)
+ if (idx_info->pline->nused) {
idx_info->layout->flags |= H5O_LAYOUT_CHUNK_SINGLE_INDEX_WITH_FILTER;
+
+ if (!H5F_addr_defined(idx_info->storage->idx_addr)) {
+ idx_info->storage->u.single.nbytes = 0;
+ idx_info->storage->u.single.filter_mask = 0;
+ }
+ }
else
idx_info->layout->flags = 0;
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c
index d5375c1..7158e05 100644
--- a/src/H5Dvirtual.c
+++ b/src/H5Dvirtual.c
@@ -84,9 +84,9 @@
/* Layout operation callbacks */
static hbool_t H5D__virtual_is_data_cached(const H5D_shared_t *shared_dset);
static herr_t H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm);
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
static herr_t H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm);
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
static herr_t H5D__virtual_flush(H5D_t *dset);
/* Other functions */
@@ -103,26 +103,37 @@ static herr_t H5D__virtual_build_source_name(char *
size_t static_strlen, size_t nsubs, hsize_t blockno,
char **built_name);
static herr_t H5D__virtual_init_all(const H5D_t *dset);
-static herr_t H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage,
- const H5S_t *file_space, const H5S_t *mem_space, hsize_t *tot_nelmts);
+static herr_t H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_t *file_space,
+ H5S_t *mem_space, hsize_t *tot_nelmts);
static herr_t H5D__virtual_post_io(H5O_storage_virtual_t *storage);
static herr_t H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- const H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset);
+ H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset);
static herr_t H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- const H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset);
+ H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset);
/*********************/
/* Package Variables */
/*********************/
/* Contiguous storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1] = {{NULL, H5D__virtual_init, H5D__virtual_is_space_alloc,
- H5D__virtual_is_data_cached, NULL, H5D__virtual_read,
- H5D__virtual_write,
+const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1] = {{
+ NULL, /* construct */
+ H5D__virtual_init, /* init */
+ H5D__virtual_is_space_alloc, /* is_space_alloc */
+ H5D__virtual_is_data_cached, /* is_data_cached */
+ NULL, /* io_init */
+ H5D__virtual_read, /* ser_read */
+ H5D__virtual_write, /* ser_write */
#ifdef H5_HAVE_PARALLEL
- NULL, NULL,
-#endif /* H5_HAVE_PARALLEL */
- NULL, NULL, H5D__virtual_flush, NULL, NULL}};
+ NULL, /* par_read */
+ NULL, /* par_write */
+#endif
+ NULL, /* readvv */
+ NULL, /* writevv */
+ H5D__virtual_flush, /* flush */
+ NULL, /* io_term */
+ NULL /* dest */
+}};
/*******************/
/* Local Variables */
@@ -195,7 +206,7 @@ H5D_virtual_check_mapping_pre(const H5S_t *vspace, const H5S_t *src_space,
"can't get number of elements in non-unlimited dimension")
if (nenu_vs != nenu_ss)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
- "numbers of elemnts in the non-unlimited dimensions is different for source and "
+ "numbers of elements in the non-unlimited dimensions is different for source and "
"virtual spaces")
} /* end if */
/* We will handle the printf case after parsing the source names */
@@ -1310,7 +1321,7 @@ H5D_virtual_free_parsed_name(H5O_storage_virtual_name_seg_t *name_seg)
H5O_storage_virtual_name_seg_t *next_seg;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Walk name segments, freeing them */
while (name_seg) {
@@ -1320,7 +1331,6 @@ H5D_virtual_free_parsed_name(H5O_storage_virtual_name_seg_t *name_seg)
name_seg = next_seg;
} /* end while */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_virtual_free_parsed_name() */
@@ -1488,7 +1498,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset)
storage->list[i].source_dset.dset->shared->space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent")
- /* Get source space dimenstions */
+ /* Get source space dimensions */
if (H5S_get_simple_extent_dims(storage->list[i].source_select, curr_dims, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions")
@@ -1966,7 +1976,7 @@ H5D__virtual_init_all(const H5D_t *dset)
storage->list[i].source_dset.dset->shared->space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent")
- /* Get source space dimenstions */
+ /* Get source space dimensions */
if (H5S_get_simple_extent_dims(storage->list[i].source_select, source_dims, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions")
@@ -2243,10 +2253,38 @@ H5D__virtual_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id)
storage->printf_gap = (hsize_t)0;
/* Retrieve VDS file FAPL to layout */
- if (storage->source_fapl <= 0)
+ if (storage->source_fapl <= 0) {
+ H5P_genplist_t * source_fapl = NULL; /* Source file FAPL */
+ H5F_close_degree_t close_degree = H5F_CLOSE_WEAK; /* Close degree for source files */
+
if ((storage->source_fapl = H5F_get_access_plist(f, FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fapl")
+ /* Get property list pointer */
+ if (NULL == (source_fapl = (H5P_genplist_t *)H5I_object(storage->source_fapl)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, H5I_INVALID_HID, "not a property list")
+
+ /* Source files must always be opened with H5F_CLOSE_WEAK close degree */
+ if (H5P_set(source_fapl, H5F_ACS_CLOSE_DEGREE_NAME, &close_degree) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree")
+ } /* end if */
+#ifndef NDEBUG
+ else {
+ H5P_genplist_t * source_fapl = NULL; /* Source file FAPL */
+ H5F_close_degree_t close_degree; /* Close degree for source files */
+
+ /* Get property list pointer */
+ if (NULL == (source_fapl = (H5P_genplist_t *)H5I_object(storage->source_fapl)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, H5I_INVALID_HID, "not a property list")
+
+ /* Verify H5F_CLOSE_WEAK close degree is set */
+ if (H5P_get(source_fapl, H5F_ACS_CLOSE_DEGREE_NAME, &close_degree) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file close degree")
+
+ HDassert(close_degree == H5F_CLOSE_WEAK);
+ } /* end else */
+#endif /* NDEBUG */
+
/* Copy DAPL to layout */
if (storage->source_dapl <= 0)
if ((storage->source_dapl = H5P_copy_plist(dapl, FALSE)) < 0)
@@ -2322,7 +2360,7 @@ H5D__virtual_is_data_cached(const H5D_shared_t *shared_dset)
if (storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) {
/* Iterate over sub-source dsets */
for (j = storage->list[i].sub_dset_io_start; j < storage->list[i].sub_dset_io_end; j++)
- /* Check for cahced data in source dset */
+ /* Check for cached data in source dset */
if (storage->list[i].sub_dset[j].dset &&
storage->list[i].sub_dset[j].dset->shared->layout.ops->is_data_cached &&
storage->list[i].sub_dset[j].dset->shared->layout.ops->is_data_cached(
@@ -2355,8 +2393,8 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, const H5S_t *file_space,
- const H5S_t *mem_space, hsize_t *tot_nelmts)
+H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_t *file_space,
+ H5S_t *mem_space, hsize_t *tot_nelmts)
{
hssize_t select_nelmts; /* Number of elements in selection */
hsize_t bounds_start[H5S_MAX_RANK]; /* Selection bounds start */
@@ -2656,7 +2694,7 @@ H5D__virtual_post_io(H5O_storage_virtual_t *storage)
/*-------------------------------------------------------------------------
* Function: H5D__virtual_read_one
*
- * Purpose: Read from a singe source dataset in a virtual dataset.
+ * Purpose: Read from a single source dataset in a virtual dataset.
*
* Return: Non-negative on success/Negative on failure
*
@@ -2666,7 +2704,7 @@ H5D__virtual_post_io(H5O_storage_virtual_t *storage)
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, const H5S_t *file_space,
+H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5S_t *file_space,
H5O_storage_virtual_srcdset_t *source_dset)
{
H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */
@@ -2726,8 +2764,8 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
+H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
+ H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
{
H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */
hsize_t tot_nelmts; /* Total number of elements mapped to mem_space */
@@ -2846,7 +2884,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5D__virtual_write_one
*
- * Purpose: Write to a singe source dataset in a virtual dataset.
+ * Purpose: Write to a single source dataset in a virtual dataset.
*
* Return: Non-negative on success/Negative on failure
*
@@ -2856,7 +2894,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, const H5S_t *file_space,
+H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5S_t *file_space,
H5O_storage_virtual_srcdset_t *source_dset)
{
H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */
@@ -2919,7 +2957,7 @@ done:
*/
static herr_t
H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
+ H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
{
H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */
hsize_t tot_nelmts; /* Total number of elements mapped to mem_space */
diff --git a/src/H5E.c b/src/H5E.c
index a5a9a2e..d203248 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -92,9 +92,6 @@ static herr_t H5E__append_stack(H5E_t *dst_estack, const H5E_t *src_stack);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -141,46 +138,19 @@ static const H5I_class_t H5I_ERRSTK_CLS[1] = {{
*
* Purpose: Initialize the interface from some other layer.
*
- * Return: SUCCEED/FAIL
- *
- * Programmer: Quincey Koziol
- * Tuesday, June 29, 2004
- *
+ * Return: Success: non-negative
+ * Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
H5E_init(void)
{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5E_init() */
-
-/*--------------------------------------------------------------------------
- * Function: H5E__init_package
- *
- * Purpose: Initialize interface-specific information
- *
- * Return: SUCCEED/FAIL
- *
- * Programmer: Raymond Lu
- * Friday, July 11, 2003
- *
- *--------------------------------------------------------------------------
- */
-herr_t
-H5E__init_package(void)
-{
H5E_cls_t *cls; /* Pointer to error class */
H5E_msg_t *msg; /* Pointer to new error message */
char lib_vers[128]; /* Buffer to constructu library version within */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI(FAIL)
/* Initialize the ID group for the error class IDs */
if (H5I_register_type(H5I_ERRCLS_CLS) < 0)
@@ -213,7 +183,7 @@ H5E__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5E__init_package() */
+}
/*-------------------------------------------------------------------------
* Function: H5E_term_package
@@ -237,66 +207,61 @@ H5E_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- int64_t ncls, nmsg, nstk;
-
- /* Check if there are any open error stacks, classes or messages */
- ncls = H5I_nmembers(H5I_ERROR_CLASS);
- nmsg = H5I_nmembers(H5I_ERROR_MSG);
- nstk = H5I_nmembers(H5I_ERROR_STACK);
-
- if ((ncls + nmsg + nstk) > 0) {
- /* Clear the default error stack. Note that
- * the following H5I_clear_type calls do not
- * force the clears and will not be able to
- * clear any error message IDs that are still
- * in use by the default error stack unless we
- * clear that stack manually.
- *
- * Error message IDs will typically still be
- * in use by the default error stack when the
- * application does H5E_BEGIN/END_TRY cleanup
- * at the very end.
- */
- H5E_clear_stack(NULL);
-
- /* Clear any outstanding error stacks */
- if (nstk > 0)
- (void)H5I_clear_type(H5I_ERROR_STACK, FALSE, FALSE);
-
- /* Clear all the error classes */
- if (ncls > 0) {
- (void)H5I_clear_type(H5I_ERROR_CLASS, FALSE, FALSE);
-
- /* Reset the HDF5 error class, if its been closed */
- if (H5I_nmembers(H5I_ERROR_CLASS) == 0)
- H5E_ERR_CLS_g = -1;
- } /* end if */
+ int64_t ncls, nmsg, nstk;
+
+ /* Check if there are any open error stacks, classes or messages */
+ ncls = H5I_nmembers(H5I_ERROR_CLASS);
+ nmsg = H5I_nmembers(H5I_ERROR_MSG);
+ nstk = H5I_nmembers(H5I_ERROR_STACK);
+
+ if ((ncls + nmsg + nstk) > 0) {
+ /* Clear the default error stack. Note that
+ * the following H5I_clear_type calls do not
+ * force the clears and will not be able to
+ * clear any error message IDs that are still
+ * in use by the default error stack unless we
+ * clear that stack manually.
+ *
+ * Error message IDs will typically still be
+ * in use by the default error stack when the
+ * application does H5E_BEGIN/END_TRY cleanup
+ * at the very end.
+ */
+ H5E_clear_stack(NULL);
+
+ /* Clear any outstanding error stacks */
+ if (nstk > 0)
+ (void)H5I_clear_type(H5I_ERROR_STACK, FALSE, FALSE);
+
+ /* Clear all the error classes */
+ if (ncls > 0) {
+ (void)H5I_clear_type(H5I_ERROR_CLASS, FALSE, FALSE);
- /* Clear all the error messages */
- if (nmsg > 0) {
- (void)H5I_clear_type(H5I_ERROR_MSG, FALSE, FALSE);
+ /* Reset the HDF5 error class, if its been closed */
+ if (H5I_nmembers(H5I_ERROR_CLASS) == 0)
+ H5E_ERR_CLS_g = -1;
+ } /* end if */
- /* Reset the HDF5 error messages, if they've been closed */
- if (H5I_nmembers(H5I_ERROR_MSG) == 0) {
+ /* Clear all the error messages */
+ if (nmsg > 0) {
+ (void)H5I_clear_type(H5I_ERROR_MSG, FALSE, FALSE);
+
+ /* Reset the HDF5 error messages, if they've been closed */
+ if (H5I_nmembers(H5I_ERROR_MSG) == 0) {
/* Include the automatically generated error code termination */
#include "H5Eterm.h"
- } /* end if */
- } /* end if */
-
- n++; /*H5I*/
- } /* end if */
- else {
- /* Destroy the error class, message, and stack id groups */
- n += (H5I_dec_type_ref(H5I_ERROR_STACK) > 0);
- n += (H5I_dec_type_ref(H5I_ERROR_CLASS) > 0);
- n += (H5I_dec_type_ref(H5I_ERROR_MSG) > 0);
-
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end else */
- } /* end if */
+ } /* end if */
+ } /* end if */
+
+ n++; /*H5I*/
+ } /* end if */
+ else {
+ /* Destroy the error class, message, and stack id groups */
+ n += (H5I_dec_type_ref(H5I_ERROR_STACK) > 0);
+ n += (H5I_dec_type_ref(H5I_ERROR_CLASS) > 0);
+ n += (H5I_dec_type_ref(H5I_ERROR_MSG) > 0);
+
+ } /* end else */
FUNC_LEAVE_NOAPI(n)
} /* end H5E_term_package() */
@@ -721,7 +686,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5E__close_msg
*
- * Purpose: Private function to close an error messge.
+ * Purpose: Private function to close an error message.
*
* Return: SUCCEED/FAIL
*
diff --git a/src/H5EA.c b/src/H5EA.c
index 8f9a4b6..66eb8cc 100644
--- a/src/H5EA.c
+++ b/src/H5EA.c
@@ -75,9 +75,6 @@ static H5EA_t *H5EA__new(H5F_t *f, haddr_t ea_addr, hbool_t from_open, void *ctx
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Extensible array client ID to class mapping */
/* Remember to add client ID to H5EA_cls_id_t in H5EAprivate.h when adding a new
diff --git a/src/H5EAdbg.c b/src/H5EAdbg.c
index b0e564c..b377422 100644
--- a/src/H5EAdbg.c
+++ b/src/H5EAdbg.c
@@ -237,7 +237,7 @@ H5EA__iblock_debug(H5F_t *f, haddr_t H5_ATTR_UNUSED addr, FILE *stream, int inde
HDfprintf(stream, "%*sData Block Addresses in Index Block:\n", indent, "");
for (u = 0; u < iblock->ndblk_addrs; u++) {
/* Print address */
- HDsprintf(temp_str, "Address #%u:", u);
+ HDsnprintf(temp_str, sizeof(temp_str), "Address #%u:", u);
HDfprintf(stream, "%*s%-*s %" PRIuHADDR "\n", (indent + 3), "", MAX(0, (fwidth - 3)), temp_str,
iblock->dblk_addrs[u]);
} /* end for */
@@ -252,7 +252,7 @@ H5EA__iblock_debug(H5F_t *f, haddr_t H5_ATTR_UNUSED addr, FILE *stream, int inde
HDfprintf(stream, "%*sSuper Block Addresses in Index Block:\n", indent, "");
for (u = 0; u < iblock->nsblk_addrs; u++) {
/* Print address */
- HDsprintf(temp_str, "Address #%u:", u);
+ HDsnprintf(temp_str, sizeof(temp_str), "Address #%u:", u);
HDfprintf(stream, "%*s%-*s %" PRIuHADDR "\n", (indent + 3), "", MAX(0, (fwidth - 3)), temp_str,
iblock->sblk_addrs[u]);
} /* end for */
@@ -341,7 +341,7 @@ H5EA__sblock_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth,
HDfprintf(stream, "%*sData Block Addresses in Super Block:\n", indent, "");
for (u = 0; u < sblock->ndblks; u++) {
/* Print address */
- HDsprintf(temp_str, "Address #%u:", u);
+ HDsnprintf(temp_str, sizeof(temp_str), "Address #%u:", u);
HDfprintf(stream, "%*s%-*s %" PRIuHADDR "\n", (indent + 3), "", MAX(0, (fwidth - 3)), temp_str,
sblock->dblk_addrs[u]);
} /* end for */
diff --git a/src/H5EApkg.h b/src/H5EApkg.h
index bfa8588..2212ccb 100644
--- a/src/H5EApkg.h
+++ b/src/H5EApkg.h
@@ -301,7 +301,7 @@ typedef struct H5EA_dblock_t {
/* Computed/cached values (not stored) */
size_t nelmts; /* Number of elements in block */
- size_t npages; /* Nummber of pages in a block (zero if not paged) */
+ size_t npages; /* Number of pages in a block (zero if not paged) */
} H5EA_dblock_t;
/* The extensible array data block page information */
diff --git a/src/H5EAprivate.h b/src/H5EAprivate.h
index 19dabd9..9481559f 100644
--- a/src/H5EAprivate.h
+++ b/src/H5EAprivate.h
@@ -26,11 +26,6 @@
#ifndef H5EAprivate_H
#define H5EAprivate_H
-/* Include package's public header */
-#ifdef NOT_YET
-#include "H5EApublic.h"
-#endif /* NOT_YET */
-
/* Private headers needed by this file */
#include "H5ACprivate.h" /* Metadata cache */
#include "H5Fprivate.h" /* File access */
diff --git a/src/H5EAtest.c b/src/H5EAtest.c
index 7924eaa..24efbc2 100644
--- a/src/H5EAtest.c
+++ b/src/H5EAtest.c
@@ -322,7 +322,7 @@ H5EA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *
HDassert(elmt);
/* Print element */
- HDsprintf(temp_str, "Element #%llu:", (unsigned long long)idx);
+ HDsnprintf(temp_str, sizeof(temp_str), "Element #%llu:", (unsigned long long)idx);
HDfprintf(stream, "%*s%-*s %llu\n", indent, "", fwidth, temp_str,
(unsigned long long)*(const uint64_t *)elmt);
diff --git a/src/H5ES.c b/src/H5ES.c
index ccc0dd8..ad42000 100644
--- a/src/H5ES.c
+++ b/src/H5ES.c
@@ -236,6 +236,61 @@ done:
} /* end H5ESget_op_counter() */
/*-------------------------------------------------------------------------
+ * Function: H5ESget_requests
+ *
+ * Purpose: Retrieve the requests in an event set. Up to *count
+ * requests are stored in the provided requests array, and
+ * the connector ids corresponding to these requests are
+ * stored in the provided connector_ids array. Either or
+ * both of these arrays may be NULL, in which case this
+ * information is not returned. If these arrays are
+ * non-NULL, they must be large enough to contain *count
+ * entries. On exit, *count is set to the total number of
+ * events in the event set.
+ *
+ * Events are returned in the order they were added to the
+ * event set. If order is H5_ITER_INC or H5_ITER_NATIVE,
+ * events will be returned starting from the oldest. If order
+ * is H5_ITER_DEC, events will be returned starting with the
+ * newest/most recent.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, November 23, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESget_requests(hid_t es_id, H5_iter_order_t order, hid_t *connector_ids, void **requests, size_t array_len,
+ size_t *count /*out*/)
+{
+ H5ES_t *es; /* Event set */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "iIo*i**xzx", es_id, order, connector_ids, requests, array_len, count);
+
+ /* Check arguments */
+ if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier")
+ if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+
+ /* Call internal routine */
+ if (array_len > 0 && (requests || connector_ids))
+ if (H5ES__get_requests(es, order, connector_ids, requests, array_len) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't get requests")
+
+ /* Retrieve the count, if non-NULL */
+ if (count)
+ *count = H5ES__list_count(&es->active);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_requests() */
+
+/*-------------------------------------------------------------------------
* Function: H5ESwait
*
* Purpose: Wait (with timeout) for operations in event set to complete
diff --git a/src/H5ESdevelop.h b/src/H5ESdevelop.h
index 5a0f2b4..2fb9aeb 100644
--- a/src/H5ESdevelop.h
+++ b/src/H5ESdevelop.h
@@ -42,6 +42,8 @@ extern "C" {
#endif
H5_DLL herr_t H5ESinsert_request(hid_t es_id, hid_t connector_id, void *request);
+H5_DLL herr_t H5ESget_requests(hid_t es_id, H5_iter_order_t order, hid_t *connector_ids, void **requests,
+ size_t array_len, size_t *count);
#ifdef __cplusplus
}
diff --git a/src/H5ESint.c b/src/H5ESint.c
index 6f9efe9..7eb5909 100644
--- a/src/H5ESint.c
+++ b/src/H5ESint.c
@@ -50,6 +50,14 @@
/* Local Typedefs */
/******************/
+/* Callback context for get events operations */
+typedef struct H5ES_get_requests_ctx_t {
+ hid_t *connector_ids; /* Output buffer for list of connector IDs that match the above requests */
+ void **requests; /* Output buffer for list of requests in event set */
+ size_t array_len; /* Length of the above output buffers */
+ size_t i; /* Number of elements filled in output buffers */
+} H5ES_get_requests_ctx_t;
+
/* Callback context for wait operations */
typedef struct H5ES_wait_ctx_t {
H5ES_t * es; /* Event set being operated on */
@@ -84,6 +92,7 @@ static herr_t H5ES__close(H5ES_t *es);
static herr_t H5ES__close_cb(void *es, void **request_token);
static herr_t H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app_file,
const char *app_func, unsigned app_line, const char *caller, const char *api_args);
+static int H5ES__get_requests_cb(H5ES_event_t *ev, void *_ctx);
static herr_t H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev);
static herr_t H5ES__op_complete(H5ES_t *es, H5ES_event_t *ev, H5VL_request_status_t ev_status);
static int H5ES__wait_cb(H5ES_event_t *ev, void *_ctx);
@@ -95,9 +104,6 @@ static int H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -118,23 +124,20 @@ static const H5I_class_t H5I_EVENTSET_CLS[1] = {{
H5FL_DEFINE_STATIC(H5ES_t);
/*-------------------------------------------------------------------------
- * Function: H5ES__init_package
+ * Function: H5ES_init
*
- * Purpose: Initializes any interface-specific data or routines.
- *
- * Return: Non-negative on success / Negative on failure
- *
- * Programmer: Quincey Koziol
- * Monday, April 6, 2020
+ * Purpose: Initialize the interface from some other layer.
*
+ * Return: Success: non-negative
+ * Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
-H5ES__init_package(void)
+H5ES_init(void)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI(FAIL)
/* Initialize the ID group for the event set IDs */
if (H5I_register_type(H5I_EVENTSET_CLS) < 0)
@@ -142,7 +145,7 @@ H5ES__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5ES__init_package() */
+}
/*-------------------------------------------------------------------------
* Function: H5ES_term_package
@@ -165,14 +168,8 @@ H5ES_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Destroy the event set ID group */
- n += (H5I_dec_type_ref(H5I_EVENTSET) > 0);
-
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Destroy the event set ID group */
+ n += (H5I_dec_type_ref(H5I_EVENTSET) > 0);
FUNC_LEAVE_NOAPI(n)
} /* end H5ES_term_package() */
@@ -294,7 +291,8 @@ H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app
* there's no need to duplicate it.
*/
ev->op_info.api_name = caller;
- if (NULL == (ev->op_info.api_args = H5MM_xstrdup(api_args)))
+ HDassert(ev->op_info.api_args == NULL);
+ if (api_args && NULL == (ev->op_info.api_args = H5MM_xstrdup(api_args)))
HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments")
/* Append fully initialized event onto the event set's 'active' list */
@@ -431,6 +429,86 @@ done:
} /* end H5ES__insert_request() */
/*-------------------------------------------------------------------------
+ * Function: H5ES__get_requests_cb
+ *
+ * Purpose: Iterator callback for H5ES__get_events - adds the event to
+ * the list.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, November 23, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5ES__get_requests_cb(H5ES_event_t *ev, void *_ctx)
+{
+ H5ES_get_requests_ctx_t *ctx = (H5ES_get_requests_ctx_t *)_ctx; /* Callback context */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Sanity check */
+ HDassert(ev);
+ HDassert(ctx);
+ HDassert(ctx->i < ctx->array_len);
+
+ /* Get the connector ID for the event */
+ if (ctx->connector_ids)
+ ctx->connector_ids[ctx->i] = ev->request->connector->id;
+
+ /* Get the request for the event */
+ if (ctx->requests)
+ ctx->requests[ctx->i] = ev->request->data;
+
+ /* Check if we've run out of room in the arrays */
+ if (++ctx->i == ctx->array_len)
+ ret_value = H5_ITER_STOP;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__get_requests_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__get_requests
+ *
+ * Purpose: Get all requests in an event set.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, November 23, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES__get_requests(H5ES_t *es, H5_iter_order_t order, hid_t *connector_ids, void **requests, size_t array_len)
+{
+ H5ES_get_requests_ctx_t ctx; /* Callback context */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(es);
+ HDassert(array_len > 0);
+ HDassert(requests || connector_ids);
+
+ /* Set up context for iterator callbacks */
+ ctx.connector_ids = connector_ids;
+ ctx.requests = requests;
+ ctx.array_len = array_len;
+ ctx.i = 0;
+
+ /* Iterate over the events in the set */
+ if (H5ES__list_iterate(&es->active, order, H5ES__get_requests_cb, &ctx) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__get_requests() */
+
+/*-------------------------------------------------------------------------
* Function: H5ES__handle_fail
*
* Purpose: Handle a failed event
@@ -673,7 +751,7 @@ H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_fa
ctx.op_failed = op_failed;
/* Iterate over the events in the set, waiting for them to complete */
- if (H5ES__list_iterate(&es->active, H5ES__wait_cb, &ctx) < 0)
+ if (H5ES__list_iterate(&es->active, H5_ITER_NATIVE, H5ES__wait_cb, &ctx) < 0)
HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
done:
@@ -781,7 +859,7 @@ H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, hbool_t *op_failed)
ctx.op_failed = op_failed;
/* Iterate over the events in the set, attempting to cancel them */
- if (H5ES__list_iterate(&es->active, H5ES__cancel_cb, &ctx) < 0)
+ if (H5ES__list_iterate(&es->active, H5_ITER_NATIVE, H5ES__cancel_cb, &ctx) < 0)
HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
done:
@@ -818,13 +896,13 @@ H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx)
* so there's no need to duplicate them internally, but they are duplicated
* here, when they are given back to the user.
*/
- if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->op_info.api_name)))
+ if (NULL == (ctx->curr_err_info->api_name = H5MM_xstrdup(ev->op_info.api_name)))
HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine name")
- if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->op_info.api_args)))
+ if (NULL == (ctx->curr_err_info->api_args = H5MM_xstrdup(ev->op_info.api_args)))
HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine arguments")
- if (NULL == (ctx->curr_err_info->app_file_name = H5MM_strdup(ev->op_info.app_file_name)))
+ if (NULL == (ctx->curr_err_info->app_file_name = H5MM_xstrdup(ev->op_info.app_file_name)))
HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application file name")
- if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->op_info.app_func_name)))
+ if (NULL == (ctx->curr_err_info->app_func_name = H5MM_xstrdup(ev->op_info.app_func_name)))
HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application function name")
ctx->curr_err_info->app_line_num = ev->op_info.app_line_num;
ctx->curr_err_info->op_ins_count = ev->op_info.op_ins_count;
@@ -895,7 +973,7 @@ H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[],
ctx.curr_err_info = &err_info[0];
/* Iterate over the failed events in the set, copying their error info */
- if (H5ES__list_iterate(&es->failed, H5ES__get_err_info_cb, &ctx) < 0)
+ if (H5ES__list_iterate(&es->failed, H5_ITER_NATIVE, H5ES__get_err_info_cb, &ctx) < 0)
HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
/* Set # of failed events cleared from event set's failed list */
@@ -969,7 +1047,7 @@ H5ES__close(H5ES_t *es)
"can't close event set while unfinished operations are present (i.e. wait on event set first)")
/* Iterate over the failed events in the set, releasing them */
- if (H5ES__list_iterate(&es->failed, H5ES__close_failed_cb, (void *)es) < 0)
+ if (H5ES__list_iterate(&es->failed, H5_ITER_NATIVE, H5ES__close_failed_cb, (void *)es) < 0)
HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
/* Release the event set */
diff --git a/src/H5ESlist.c b/src/H5ESlist.c
index c0e24cc..61a9dd1 100644
--- a/src/H5ESlist.c
+++ b/src/H5ESlist.c
@@ -88,6 +88,8 @@ H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev)
HDassert(el);
HDassert(ev);
+ ev->next = NULL;
+
/* Append event onto the event list */
if (NULL == el->tail)
el->head = el->tail = ev;
@@ -133,7 +135,10 @@ H5ES__list_count(const H5ES_event_list_t *el)
* each event.
*
* Note: Iteration is safe for deleting the current event. Modifying
- * the list in other ways is likely unsafe.
+ * the list in other ways is likely unsafe. If order is
+ * H5_ITER_INC or H5_ITER_NATIVE events are visited starting
+ * with the oldest, otherwise they are visited starting with
+ * the newest.
*
* Return: SUCCEED / FAIL
*
@@ -143,7 +148,7 @@ H5ES__list_count(const H5ES_event_list_t *el)
*-------------------------------------------------------------------------
*/
int
-H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx)
+H5ES__list_iterate(H5ES_event_list_t *el, H5_iter_order_t order, H5ES_list_iter_func_t cb, void *ctx)
{
H5ES_event_t *ev; /* Event in list */
int ret_value = H5_ITER_CONT; /* Return value */
@@ -155,12 +160,12 @@ H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx)
HDassert(cb);
/* Iterate over events in list */
- ev = el->head;
+ ev = (order == H5_ITER_DEC) ? el->tail : el->head;
while (ev) {
H5ES_event_t *tmp; /* Temporary event */
/* Get pointer to next node, so it's safe if this one is removed */
- tmp = ev->next;
+ tmp = (order == H5_ITER_DEC) ? ev->prev : ev->next;
/* Perform iterator callback */
if ((ret_value = (*cb)(ev, ctx)) != H5_ITER_CONT) {
diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h
index a7a8e20..6ee50fa 100644
--- a/src/H5ESpkg.h
+++ b/src/H5ESpkg.h
@@ -81,6 +81,8 @@ typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx);
H5_DLL H5ES_t *H5ES__create(void);
H5_DLL herr_t H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token);
H5_DLL herr_t H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_failed);
+H5_DLL herr_t H5ES__get_requests(H5ES_t *es, H5_iter_order_t order, hid_t *connector_ids, void **requests,
+ size_t array_len);
H5_DLL herr_t H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, hbool_t *op_failed);
H5_DLL herr_t H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[],
size_t *num_cleared);
@@ -88,7 +90,8 @@ H5_DLL herr_t H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info
/* Event list operations */
H5_DLL void H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev);
H5_DLL size_t H5ES__list_count(const H5ES_event_list_t *el);
-H5_DLL int H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx);
+H5_DLL int H5ES__list_iterate(H5ES_event_list_t *el, H5_iter_order_t order, H5ES_list_iter_func_t cb,
+ void *ctx);
H5_DLL void H5ES__list_remove(H5ES_event_list_t *el, const H5ES_event_t *ev);
/* Event operations */
diff --git a/src/H5ESprivate.h b/src/H5ESprivate.h
index 3d9ce9f..153e3e3 100644
--- a/src/H5ESprivate.h
+++ b/src/H5ESprivate.h
@@ -51,5 +51,6 @@ typedef struct H5ES_t H5ES_t;
/***************************************/
herr_t H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, const char *caller_args,
...);
+H5_DLL herr_t H5ES_init(void);
#endif /* H5ESprivate_H */
diff --git a/src/H5ESpublic.h b/src/H5ESpublic.h
index c8696b3..c8d1c7b 100644
--- a/src/H5ESpublic.h
+++ b/src/H5ESpublic.h
@@ -200,7 +200,18 @@ H5_DLL herr_t H5ESget_count(hid_t es_id, size_t *count);
/**
* \ingroup H5ES
*
- * \todo Fill in the blanks!
+ * \brief Retrieves the next operation counter to be assigned in an event set
+ *
+ * \es_id
+ * \param[out] counter The next counter value to be assigned to an event
+ * \returns \herr_t
+ *
+ * \details H5ESget_op_counter() retrieves the \p counter that will be assigned
+ * to the next operation inserted into the event set \p es_id.
+ *
+ * \note This is designed for wrapper libraries mainly, to use as a mechanism
+ * for matching operations inserted into the event set with possible
+ * errors that occur.
*
* \since 1.13.0
*
diff --git a/src/H5Eint.c b/src/H5Eint.c
index 6438cd9..d744db3 100644
--- a/src/H5Eint.c
+++ b/src/H5Eint.c
@@ -930,7 +930,7 @@ H5E_dump_api_stack(hbool_t is_api)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Only dump the error stack during an API call */
if (is_api) {
@@ -953,6 +953,5 @@ H5E_dump_api_stack(hbool_t is_api)
#endif /* H5_NO_DEPRECATED_SYMBOLS */
} /* end if */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5E_dump_api_stack() */
diff --git a/src/H5Epkg.h b/src/H5Epkg.h
index 30ff084..b11ee9e 100644
--- a/src/H5Epkg.h
+++ b/src/H5Epkg.h
@@ -48,7 +48,7 @@
* each thread individually. The association of stacks to threads will
* be handled by the pthread library.
*
- * In order for this macro to work, H5E__get_my_stack() must be preceeded
+ * In order for this macro to work, H5E__get_my_stack() must be preceded
* by "H5E_t *estack =".
*/
#define H5E__get_my_stack() H5E__get_stack()
diff --git a/src/H5F.c b/src/H5F.c
index 46c8c0e..6a2d247 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1306,7 +1306,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Funmount
*
- * Purpose: Given a mount point, dissassociate the mount point's file
+ * Purpose: Given a mount point, disassociate the mount point's file
* from the file mounted there. Do not close either file.
*
* The mount point can either be the group in the parent or the
@@ -2262,7 +2262,7 @@ done:
* 1) The file being opened has v3 superblock
* 2) The file is opened with H5F_ACC_RDWR
* 3) The file is not already marked for SWMR writing
- * 4) Current implementaion for opened objects:
+ * 4) Current implementation for opened objects:
* --only allow datasets and groups without attributes
* --disallow named datatype with/without attributes
* --disallow opened attributes attached to objects
@@ -2809,7 +2809,7 @@ H5Fvfd_swmr_end_tick(hid_t file_id)
if (NULL == vol_obj)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
- /* Check on this when go parallel for VFD SWMR */
+ /* TODO: Revisit this when VFD SWMR + parallel works */
/* Set up collective metadata if appropriate */
if (H5CX_set_loc(file_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info")
@@ -2848,7 +2848,7 @@ H5Fvfd_swmr_disable_end_of_tick(hid_t file_id)
if (NULL == vol_obj)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
- /* Check on this when go parallel for VFD SWMR */
+ /* TODO: Revisit this when VFD SWMR + parallel works */
/* Set up collective metadata if appropriate */
if (H5CX_set_loc(file_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info")
@@ -2886,7 +2886,7 @@ H5Fvfd_swmr_enable_end_of_tick(hid_t file_id)
if (NULL == vol_obj)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
- /* Check on this when go parallel for VFD SWMR */
+ /* TODO: Revisit this when VFD SWMR + parallel works */
/* Set up collective metadata if appropriate */
if (H5CX_set_loc(file_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info")
diff --git a/src/H5FA.c b/src/H5FA.c
index ad69ee2..3e81080 100644
--- a/src/H5FA.c
+++ b/src/H5FA.c
@@ -64,9 +64,6 @@ static H5FA_t *H5FA__new(H5F_t *f, haddr_t fa_addr, hbool_t from_open, void *ctx
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Fixed array client ID to class mapping */
/* Remember to add client ID to H5FA_cls_id_t in H5FAprivate.h when adding a new
@@ -95,7 +92,7 @@ H5FL_BLK_DEFINE(fa_native_elmt);
/*-------------------------------------------------------------------------
* Function: H5FA__new
*
- * Purpose: Allocate and initialize a new fixe array wrapper in memory
+ * Purpose: Allocate and initialize a new fixed array wrapper in memory
*
* Return: Pointer to farray wrapper success
* NULL on failure
diff --git a/src/H5FAcache.c b/src/H5FAcache.c
index 6975d3d..05a8762 100644
--- a/src/H5FAcache.c
+++ b/src/H5FAcache.c
@@ -946,7 +946,7 @@ done:
* file space block set.
*
* This function is needed when the data block is paged, as
- * the datablock header and all its pages are allocted as a
+ * the datablock header and all its pages are allocated as a
* single contiguous chunk of file space, and must be
* deallocated the same way.
*
diff --git a/src/H5FAdblkpage.c b/src/H5FAdblkpage.c
index 713bd67..f6a5aef 100644
--- a/src/H5FAdblkpage.c
+++ b/src/H5FAdblkpage.c
@@ -147,7 +147,7 @@ H5FA__dblk_page_create(H5FA_hdr_t *hdr, haddr_t addr, size_t nelmts)
FUNC_ENTER_PACKAGE
#ifdef H5FA_DEBUG
- HDfprintf(stderr, "%s: Called, addr = %a\n", __func__, addr);
+ HDfprintf(stderr, "%s: Called, addr = %" PRIuHADDR "\n", __func__, addr);
#endif /* H5FA_DEBUG */
/* Sanity check */
diff --git a/src/H5FApkg.h b/src/H5FApkg.h
index c4bf934..15f6445 100644
--- a/src/H5FApkg.h
+++ b/src/H5FApkg.h
@@ -179,8 +179,8 @@ typedef struct H5FA_dblock_t {
/* Computed/cached values (not stored) */
haddr_t addr; /* Address of this data block on disk */
hsize_t size; /* Size of data block on disk */
- size_t npages; /* Nummber of pages in data block (zero if not paged) */
- size_t last_page_nelmts; /* Nummber of elements in last page, if paged */
+ size_t npages; /* Number of pages in data block (zero if not paged) */
+ size_t last_page_nelmts; /* Number of elements in last page, if paged */
/* Fixed Array data block information (not stored) */
size_t dblk_page_nelmts; /* # of elements per data block page */
diff --git a/src/H5FAprivate.h b/src/H5FAprivate.h
index 26057bf..745c129 100644
--- a/src/H5FAprivate.h
+++ b/src/H5FAprivate.h
@@ -24,11 +24,6 @@
#ifndef H5FAprivate_H
#define H5FAprivate_H
-/* Include package's public header */
-#ifdef NOT_YET
-#include "H5FApublic.h"
-#endif /* NOT_YET */
-
/* Private headers needed by this file */
#include "H5ACprivate.h" /* Metadata cache */
#include "H5Fprivate.h" /* File access */
@@ -134,7 +129,7 @@ H5_DLL herr_t H5FA_patch_file(H5FA_t *fa, H5F_t *f);
H5_DLL herr_t H5FA_get_stats(const H5FA_t *ea, H5FA_stat_t *stats);
/* Debugging routines */
-#ifdef H5FA_DEBUGGING
-#endif /* H5FA_DEBUGGING */
+#ifdef H5FA_DEBUG
+#endif /* H5FA_DEBUG */
#endif /* H5FAprivate_H */
diff --git a/src/H5FAtest.c b/src/H5FAtest.c
index 384a657..b57f562 100644
--- a/src/H5FAtest.c
+++ b/src/H5FAtest.c
@@ -303,7 +303,7 @@ H5FA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *
HDassert(elmt);
/* Print element */
- HDsprintf(temp_str, "Element #%llu:", (unsigned long long)idx);
+ HDsnprintf(temp_str, sizeof(temp_str), "Element #%llu:", (unsigned long long)idx);
HDfprintf(stream, "%*s%-*s %llu\n", indent, "", fwidth, temp_str,
(unsigned long long)*(const uint64_t *)elmt);
diff --git a/src/H5FD.c b/src/H5FD.c
index 2cae1a8..d3a3247 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -67,9 +67,6 @@ static herr_t H5FD__query(const H5FD_t *f, unsigned long *flags /*out*/);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -103,20 +100,20 @@ static const H5I_class_t H5I_VFL_CLS[1] = {{
}};
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initialize the virtual file layer.
+ * Function: H5FD_init
*
- * Return: SUCCEED/FAIL
+ * Purpose: Initialize the interface from some other layer.
*
+ * Return: Success: non-negative
+ * Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
-H5FD__init_package(void)
+H5FD_init(void)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI(FAIL)
if (H5I_register_type(H5I_VFL_CLS) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface")
@@ -126,7 +123,7 @@ H5FD__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD__init_package() */
+}
/*-------------------------------------------------------------------------
* Function: H5FD_term_package
@@ -150,20 +147,14 @@ H5FD_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- if (H5I_nmembers(H5I_VFL) > 0) {
- (void)H5I_clear_type(H5I_VFL, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
- else {
- /* Destroy the VFL driver ID group */
- n += (H5I_dec_type_ref(H5I_VFL) > 0);
-
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end else */
- } /* end if */
+ if (H5I_nmembers(H5I_VFL) > 0) {
+ (void)H5I_clear_type(H5I_VFL, FALSE, FALSE);
+ n++; /*H5I*/
+ } /* end if */
+ else {
+ /* Destroy the VFL driver ID group */
+ n += (H5I_dec_type_ref(H5I_VFL) > 0);
+ } /* end else */
FUNC_LEAVE_NOAPI(n)
} /* end H5FD_term_package() */
@@ -173,7 +164,7 @@ H5FD_term_package(void)
*
* Purpose: Frees a file driver class struct and returns an indication of
* success. This function is used as the free callback for the
- * virtual file layer object identifiers (cf H5FD__init_package).
+ * virtual file layer object identifiers (cf H5FD_init).
*
* Return: SUCCEED/FAIL
*
@@ -309,6 +300,62 @@ done:
} /* end H5FD_register() */
/*-------------------------------------------------------------------------
+ * Function: H5FDis_driver_registered_by_name
+ *
+ * Purpose: Tests whether a VFD class has been registered or not
+ * according to a supplied driver name.
+ *
+ * Return: >0 if a VFD with that name has been registered
+ * 0 if a VFD with that name has NOT been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FDis_driver_registered_by_name(const char *driver_name)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("t", "*s", driver_name);
+
+ /* Check if driver with this name is registered */
+ if ((ret_value = H5FD_is_driver_registered_by_name(driver_name, NULL)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFD is registered")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDis_driver_registered_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FDis_driver_registered_by_value
+ *
+ * Purpose: Tests whether a VFD class has been registered or not
+ * according to a supplied driver value (ID).
+ *
+ * Return: >0 if a VFD with that value has been registered
+ * 0 if a VFD with that value hasn't been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FDis_driver_registered_by_value(H5FD_class_value_t driver_value)
+{
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("t", "DV", driver_value);
+
+ /* Check if driver with this value is registered */
+ if ((ret_value = H5FD_is_driver_registered_by_value(driver_value, NULL)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFD is registered")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDis_driver_registered_by_value() */
+
+/*-------------------------------------------------------------------------
* Function: H5FDunregister
*
* Purpose: Removes a driver ID from the library. This in no way affects
@@ -406,7 +453,7 @@ H5FD_sb_size(H5FD_t *file)
{
hsize_t ret_value = 0;
- FUNC_ENTER_NOAPI(0)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(file);
@@ -416,7 +463,6 @@ H5FD_sb_size(H5FD_t *file)
if (file->cls->sb_size)
ret_value = (file->cls->sb_size)(file);
-done:
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -544,7 +590,7 @@ H5FD_fapl_get(H5FD_t *file)
{
void *ret_value = NULL;
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(file);
@@ -554,7 +600,6 @@ H5FD_fapl_get(H5FD_t *file)
if (file->cls->fapl_get)
ret_value = (file->cls->fapl_get)(file);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_fapl_get() */
@@ -826,9 +871,6 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
/* Dispatch to file driver */
if (HADDR_UNDEF == maxaddr)
maxaddr = driver->maxaddr;
-#if 0 /* JRM */
- HDfprintf(stderr, "H5FD_open(): calling %s.open().\n", driver->name);
-#endif /* JRM */
if (NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed")
@@ -875,7 +917,6 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
ret_value = file;
done:
- /* XXX We leak H5FD_t's on many error conditions. */
/* Can't cleanup 'file' information, since we don't know what type it is */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_open() */
@@ -929,7 +970,7 @@ H5FD_close(H5FD_t *file)
{
const H5FD_class_t *driver;
H5FD_wrap_t * item;
- H5FD_wrap_t * delete_me = NULL;
+ H5FD_wrap_t * temp = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
@@ -948,11 +989,12 @@ H5FD_close(H5FD_t *file)
if (item->file->exc_owner == file)
item->file->exc_owner = NULL;
if (item->file == file)
- delete_me = item;
+ temp = item;
}
- HDassert(delete_me);
- TAILQ_REMOVE(&all_vfds, delete_me, link);
- H5MM_xfree(delete_me);
+
+ HDassert(temp);
+ TAILQ_REMOVE(&all_vfds, temp, link);
+ H5MM_xfree(temp);
/* Dispatch to the driver for actual close. If the driver fails to
* close the file then the file will be in an unusable state.
@@ -1015,7 +1057,7 @@ H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2)
{
int ret_value = -1; /* Return value */
- FUNC_ENTER_NOAPI(-1) /* return value is arbitrary */
+ FUNC_ENTER_NOAPI_NOERR; /* return value is arbitrary */
if ((!f1 || !f1->cls) && (!f2 || !f2->cls))
HGOTO_DONE(0)
@@ -1376,7 +1418,7 @@ H5FD_get_maxaddr(const H5FD_t *file)
{
haddr_t ret_value = HADDR_UNDEF; /* Return value */
- FUNC_ENTER_NOAPI(HADDR_UNDEF)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(file);
@@ -1384,7 +1426,6 @@ H5FD_get_maxaddr(const H5FD_t *file)
/* Set return value */
ret_value = file->maxaddr;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_get_maxaddr() */
@@ -1456,7 +1497,7 @@ H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map)
HDassert(file->cls);
HDassert(type_map);
- /* Check for VFD class providing a type map retrieval rouine */
+ /* Check for VFD class providing a type map retrieval routine */
if (file->cls->get_type_map) {
/* Retrieve type mapping for this file */
if ((file->cls->get_type_map)(file, type_map) < 0)
@@ -1820,6 +1861,111 @@ done:
} /* end H5FD_unlock() */
/*-------------------------------------------------------------------------
+ * Function: H5FDctl
+ *
+ * Purpose: Perform a CTL operation.
+ *
+ * The desired operation is specified by the op_code
+ * parameter.
+ *
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
+ *
+ * The input and output parameters allow op_code specific
+ * input and output
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: JRM -- 8/3/21
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FDctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **output)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*#ULUL*x**x", file, op_code, flags, input, output);
+
+ /* Check arguments */
+ if (!file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
+
+ if (!file->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
+
+ /* Don't attempt to validate the op code. If appropriate, that will
+ * be done by the underlying VFD callback, along with the input and
+ * output parameters.
+ */
+
+ /* Call private function */
+ if (H5FD_ctl(file, op_code, flags, input, output) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "VFD ctl request failed")
+
+done:
+
+ FUNC_LEAVE_API(ret_value)
+
+} /* end H5FDctl() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_ctl
+ *
+ * Purpose: Private version of H5FDctl()
+ *
+ * The desired operation is specified by the op_code
+ * parameter.
+ *
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
+ *
+ * The input and output parameters allow op_code specific
+ * input and output
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: JRM -- 8/3/21
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_ctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **output)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(file);
+ HDassert(file->cls);
+
+ /* Dispatch to driver if the ctl function exists.
+ *
+ * If it doesn't, fail if the H5FD_CTL__FAIL_IF_UNKNOWN_FLAG is set.
+ *
+ * Otherwise, report success.
+ */
+ if (file->cls->ctl) {
+
+ if ((file->cls->ctl)(file, op_code, flags, input, output) < 0)
+
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "VFD ctl request failed")
+ }
+ else if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) {
+
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL,
+ "VFD ctl request failed (no ctl callback and fail if unknown flag is set)")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5FD_ctl() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD_get_fileno
*
* Purpose: Quick and dirty routine to retrieve the file's 'fileno' value
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 50288c4..a1750ee 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -149,8 +149,10 @@ static herr_t H5FD__core_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD__core_lock(H5FD_t *_file, hbool_t rw);
static herr_t H5FD__core_unlock(H5FD_t *_file);
static herr_t H5FD__core_delete(const char *filename, hid_t fapl_id);
+static inline const H5FD_core_fapl_t *H5FD__core_get_default_config(void);
static const H5FD_class_t H5FD_core_g = {
+ H5FD_CORE_VALUE, /* value */
"core", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -183,9 +185,15 @@ static const H5FD_class_t H5FD_core_g = {
H5FD__core_lock, /* lock */
H5FD__core_unlock, /* unlock */
H5FD__core_delete, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
+/* Default configurations, if none provided */
+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);
@@ -390,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 */
@@ -408,37 +416,30 @@ done:
} /* end H5FD__core_write_to_bstore() */
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
+ * Function: H5FD__core_get_default_config
*
- * Purpose: Initializes any interface-specific data or routines.
+ * Purpose: Retrieves a default configuration for this VFD when no
+ * configuration information has been provided.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Valid Core VFD configuration information pointer (can't
+ * fail)
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5FD__init_package(void)
+static inline const H5FD_core_fapl_t *
+H5FD__core_get_default_config(void)
{
- char * lock_env_var = NULL; /* Environment variable pointer */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
+ char *driver = HDgetenv(HDF5_DRIVER);
- /* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
- if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
- ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
- else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
- ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
- else
- ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
-
- if (H5FD_core_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize core VFD")
+ if (driver) {
+ if (!HDstrcmp(driver, "core"))
+ return &H5FD_core_default_config_g;
+ else if (!HDstrcmp(driver, "core_paged"))
+ return &H5FD_core_default_paged_config_g;
+ }
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
+ return &H5FD_core_default_config_g;
+} /* end H5FD__core_get_default_config() */
/*-------------------------------------------------------------------------
* Function: H5FD_core_init
@@ -457,9 +458,19 @@ done:
hid_t
H5FD_core_init(void)
{
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ char *lock_env_var = NULL; /* Environment variable pointer */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+ FUNC_ENTER_NOAPI_NOERR
+
+ /* Check the use disabled file locks environment variable */
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
+ if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
+ ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
+ else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
+ ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
+ else
+ ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
if (H5I_VFL != H5I_get_type(H5FD_CORE_g))
H5FD_CORE_g = H5FD_register(&H5FD_core_g, sizeof(H5FD_class_t), FALSE);
@@ -467,7 +478,6 @@ H5FD_core_init(void)
/* Set return value */
ret_value = H5FD_CORE_g;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_core_init() */
@@ -528,7 +538,7 @@ H5Pset_core_write_tracking(hid_t plist_id, hbool_t is_enabled, size_t page_size)
if (H5FD_CORE != H5P_peek_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
if (NULL == (old_fa = (const H5FD_core_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
+ old_fa = H5FD__core_get_default_config();
/* Set VFD info values */
HDmemset(&fa, 0, sizeof(H5FD_core_fapl_t));
@@ -538,7 +548,7 @@ H5Pset_core_write_tracking(hid_t plist_id, hbool_t is_enabled, size_t page_size)
fa.page_size = page_size;
/* Set the property values & the driver for the FAPL */
- if (H5P_set_driver(plist, H5FD_CORE, &fa) < 0)
+ if (H5P_set_driver(plist, H5FD_CORE, &fa, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set core VFD as driver")
done:
@@ -622,7 +632,7 @@ H5Pset_fapl_core(hid_t fapl_id, size_t increment, hbool_t backing_store)
fa.page_size = H5FD_CORE_WRITE_TRACKING_PAGE_SIZE;
/* Set the property values & the driver for the FAPL */
- if (H5P_set_driver(plist, H5FD_CORE, &fa) < 0)
+ if (H5P_set_driver(plist, H5FD_CORE, &fa, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set core VFD as driver")
done:
@@ -747,7 +757,7 @@ H5FD__core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
if (NULL == (fa = (const H5FD_core_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ fa = H5FD__core_get_default_config();
/* Build the open flags */
o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
@@ -918,8 +928,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 */
@@ -1512,7 +1522,7 @@ done:
* Addendum -- 12/2/11
* For file images opened with the core file driver, it is
* necessary that we avoid reallocating the core file driver's
- * buffer uneccessarily.
+ * buffer unnecessarily.
*
* To this end, I have made the following functional changes
* to this function.
@@ -1734,7 +1744,7 @@ H5FD__core_delete(const char *filename, hid_t fapl_id)
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
if (NULL == (fa = (const H5FD_core_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
+ fa = H5FD__core_get_default_config();
if (fa->backing_store)
if (HDremove(filename) < 0)
diff --git a/src/H5FDcore.h b/src/H5FDcore.h
index d456c3e..4067980 100644
--- a/src/H5FDcore.h
+++ b/src/H5FDcore.h
@@ -20,7 +20,8 @@
#ifndef H5FDcore_H
#define H5FDcore_H
-#define H5FD_CORE (H5FD_core_init())
+#define H5FD_CORE (H5FDperform_init(H5FD_core_init))
+#define H5FD_CORE_VALUE H5_VFD_CORE
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h
index a723a1d..32cd36f 100644
--- a/src/H5FDdevelop.h
+++ b/src/H5FDdevelop.h
@@ -160,6 +160,7 @@ typedef struct H5FD_t H5FD_t;
/* Class information for each file driver */
typedef struct H5FD_class_t {
+ H5FD_class_value_t value;
const char * name;
haddr_t maxaddr;
H5F_close_degree_t fc_degree;
@@ -192,6 +193,7 @@ typedef struct H5FD_class_t {
herr_t (*lock)(H5FD_t *file, hbool_t rw);
herr_t (*unlock)(H5FD_t *file);
herr_t (*del)(const char *name, hid_t fapl);
+ herr_t (*ctl)(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **output);
H5FD_mem_t fl_map[H5FD_MEM_NTYPES];
} H5FD_class_t;
@@ -225,6 +227,9 @@ struct H5FD_t {
hbool_t paged_aggr; /* Paged aggregation for file space is enabled or not */
};
+/* VFD initialization function */
+typedef hid_t (*H5FD_init_t)(void);
+
/********************/
/* Public Variables */
/********************/
@@ -237,7 +242,10 @@ struct H5FD_t {
extern "C" {
#endif
+H5_DLL hid_t H5FDperform_init(H5FD_init_t op);
H5_DLL hid_t H5FDregister(const H5FD_class_t *cls);
+H5_DLL htri_t H5FDis_driver_registered_by_name(const char *driver_name);
+H5_DLL htri_t H5FDis_driver_registered_by_value(H5FD_class_value_t driver_value);
H5_DLL herr_t H5FDunregister(hid_t driver_id);
H5_DLL H5FD_t *H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr);
H5_DLL herr_t H5FDclose(H5FD_t *file);
@@ -258,6 +266,7 @@ H5_DLL herr_t H5FDtruncate(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
H5_DLL herr_t H5FDlock(H5FD_t *file, hbool_t rw);
H5_DLL herr_t H5FDunlock(H5FD_t *file);
H5_DLL herr_t H5FDdelete(const char *name, hid_t fapl_id);
+H5_DLL herr_t H5FDctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **output);
#ifdef __cplusplus
}
diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c
index a1b7b7e..7a43117 100644
--- a/src/H5FDdirect.c
+++ b/src/H5FDdirect.c
@@ -120,6 +120,8 @@ typedef struct H5FD_direct_t {
/* Prototypes */
static herr_t H5FD__direct_term(void);
+static herr_t H5FD__direct_populate_config(size_t boundary, size_t block_size, size_t cbuf_size,
+ H5FD_direct_fapl_t *fa_out);
static void * H5FD__direct_fapl_get(H5FD_t *file);
static void * H5FD__direct_fapl_copy(const void *_old_fa);
static H5FD_t *H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr);
@@ -140,6 +142,7 @@ static herr_t H5FD__direct_unlock(H5FD_t *_file);
static herr_t H5FD__direct_delete(const char *filename, hid_t fapl_id);
static const H5FD_class_t H5FD_direct_g = {
+ H5FD_DIRECT_VALUE, /* value */
"direct", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -172,48 +175,13 @@ static const H5FD_class_t H5FD_direct_g = {
H5FD__direct_lock, /* lock */
H5FD__direct_unlock, /* unlock */
H5FD__direct_delete, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
/* Declare a free list to manage the H5FD_direct_t struct */
H5FL_DEFINE_STATIC(H5FD_direct_t);
-/*--------------------------------------------------------------------------
-NAME
- H5FD__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5FD__init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines. (Just calls
- H5FD_direct_init currently).
-
---------------------------------------------------------------------------*/
-static herr_t
-H5FD__init_package(void)
-{
- char * lock_env_var = NULL; /* Environment variable pointer */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- /* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
- if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
- ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
- else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
- ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
- else
- ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
-
- if (H5FD_direct_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize direct VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
/*-------------------------------------------------------------------------
* Function: H5FD_direct_init
*
@@ -231,12 +199,25 @@ done:
hid_t
H5FD_direct_init(void)
{
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ char *lock_env_var = NULL; /* Environment variable pointer */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_NOAPI(H5I_INVALID_HID)
- if (H5I_VFL != H5I_get_type(H5FD_DIRECT_g))
+ /* Check the use disabled file locks environment variable */
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
+ if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
+ ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
+ else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
+ ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
+ else
+ ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
+
+ if (H5I_VFL != H5I_get_type(H5FD_DIRECT_g)) {
H5FD_DIRECT_g = H5FD_register(&H5FD_direct_g, sizeof(H5FD_class_t), FALSE);
+ if (H5I_INVALID_HID == H5FD_DIRECT_g)
+ HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register direct");
+ }
/* Set return value */
ret_value = H5FD_DIRECT_g;
@@ -295,28 +276,10 @@ H5Pset_fapl_direct(hid_t fapl_id, size_t boundary, size_t block_size, size_t cbu
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- HDmemset(&fa, 0, sizeof(H5FD_direct_fapl_t));
- if (boundary != 0)
- fa.mboundary = boundary;
- else
- fa.mboundary = MBOUNDARY_DEF;
- if (block_size != 0)
- fa.fbsize = block_size;
- else
- fa.fbsize = FBSIZE_DEF;
- if (cbuf_size != 0)
- fa.cbsize = cbuf_size;
- else
- fa.cbsize = CBSIZE_DEF;
-
- /* Set the default to be true for data alignment */
- fa.must_align = TRUE;
-
- /* Copy buffer size must be a multiple of file block size */
- if (fa.cbsize % fa.fbsize != 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "copy buffer size must be a multiple of block size")
+ if (H5FD__direct_populate_config(boundary, block_size, cbuf_size, &fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
- ret_value = H5P_set_driver(plist, H5FD_DIRECT, &fa);
+ ret_value = H5P_set_driver(plist, H5FD_DIRECT, &fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -366,6 +329,53 @@ done:
} /* end H5Pget_fapl_direct() */
/*-------------------------------------------------------------------------
+ * Function: H5FD__direct_populate_config
+ *
+ * Purpose: Populates a H5FD_direct_fapl_t structure with the provided
+ * values, supplying defaults where values are not provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__direct_populate_config(size_t boundary, size_t block_size, size_t cbuf_size, H5FD_direct_fapl_t *fa_out)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(fa_out);
+
+ HDmemset(fa_out, 0, sizeof(H5FD_direct_fapl_t));
+
+ if (boundary != 0)
+ fa_out->mboundary = boundary;
+ else
+ fa_out->mboundary = MBOUNDARY_DEF;
+
+ if (block_size != 0)
+ fa_out->fbsize = block_size;
+ else
+ fa_out->fbsize = FBSIZE_DEF;
+
+ if (cbuf_size != 0)
+ fa_out->cbsize = cbuf_size;
+ else
+ fa_out->cbsize = CBSIZE_DEF;
+
+ /* Set the default to be true for data alignment */
+ fa_out->must_align = TRUE;
+
+ /* Copy buffer size must be a multiple of file block size */
+ if (fa_out->cbsize % fa_out->fbsize != 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "copy buffer size must be a multiple of block size")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__direct_populate_config() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD__direct_fapl_get
*
* Purpose: Returns a file access property list which indicates how the
@@ -449,6 +459,7 @@ H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
int fd = (-1);
H5FD_direct_t * file = NULL;
const H5FD_direct_fapl_t *fa;
+ H5FD_direct_fapl_t default_fa;
#ifdef H5_HAVE_WIN32_API
HFILE filehandle;
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
@@ -497,8 +508,11 @@ H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
/* Get the driver specific information */
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- if (NULL == (fa = (const H5FD_direct_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ if (NULL == (fa = (const H5FD_direct_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (H5FD__direct_populate_config(0, 0, 0, &default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't initialize driver configuration info")
+ fa = &default_fa;
+ }
file->fd = fd;
H5_CHECKED_ASSIGN(file->eof, haddr_t, sb.st_size, h5_stat_size_t);
diff --git a/src/H5FDdirect.h b/src/H5FDdirect.h
index f06de7f..bfad16a 100644
--- a/src/H5FDdirect.h
+++ b/src/H5FDdirect.h
@@ -21,9 +21,11 @@
#define H5FDdirect_H
#ifdef H5_HAVE_DIRECT
-#define H5FD_DIRECT (H5FD_direct_init())
+#define H5FD_DIRECT (H5FDperform_init(H5FD_direct_init))
+#define H5FD_DIRECT_VALUE H5_VFD_DIRECT
#else
-#define H5FD_DIRECT (H5I_INVALID_HID)
+#define H5FD_DIRECT (H5I_INVALID_HID)
+#define H5FD_DIRECT_VALUE H5_VFD_INVALID
#endif /* H5_HAVE_DIRECT */
#ifdef H5_HAVE_DIRECT
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index 8cf9f9e..3f0080e 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -47,6 +47,9 @@
/* The size of the member name buffers */
#define H5FD_FAM_MEMB_NAME_BUF_SIZE 4096
+/* Default member size - 100 MiB */
+#define H5FD_FAM_DEF_MEM_SIZE ((hsize_t)(100 * H5_MB))
+
/* The driver identification number, initialized at runtime */
static hid_t H5FD_FAMILY_g = 0;
@@ -77,6 +80,10 @@ typedef struct H5FD_family_fapl_t {
hid_t memb_fapl_id; /*file access property list of each memb*/
} H5FD_family_fapl_t;
+/* Private routines */
+static herr_t H5FD__family_get_default_config(H5FD_family_fapl_t *fa_out);
+static char * H5FD__family_get_default_printf_filename(const char *old_filename);
+
/* Callback prototypes */
static herr_t H5FD__family_term(void);
static void * H5FD__family_fapl_get(H5FD_t *_file);
@@ -105,6 +112,7 @@ static herr_t H5FD__family_delete(const char *filename, hid_t fapl_id);
/* The class struct */
static const H5FD_class_t H5FD_family_g = {
+ H5FD_FAMILY_VALUE, /* value */
"family", /* name */
HADDR_MAX, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -137,34 +145,125 @@ static const H5FD_class_t H5FD_family_g = {
H5FD__family_lock, /* lock */
H5FD__family_unlock, /* unlock */
H5FD__family_delete, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
-/*--------------------------------------------------------------------------
-NAME
- H5FD__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5FD__init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines. (Just calls
- H5FD_family_init currently).
-
---------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------
+ * Function: H5FD__family_get_default_config
+ *
+ * Purpose: Populates a H5FD_family_fapl_t structure with default
+ * values.
+ *
+ * Return: Non-negative on Success/Negative on Failure
+ *
+ *-------------------------------------------------------------------------
+ */
static herr_t
-H5FD__init_package(void)
+H5FD__family_get_default_config(H5FD_family_fapl_t *fa_out)
+{
+ H5P_genplist_t *def_plist;
+ H5P_genplist_t *plist;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(fa_out);
+
+ fa_out->memb_size = H5FD_FAM_DEF_MEM_SIZE;
+
+ /* Use copy of default file access property list for member FAPL ID.
+ * The Sec2 driver is explicitly set on the member FAPL ID, as the
+ * default driver might have been replaced with the Family VFD, which
+ * would cause recursion badness in the child members.
+ */
+ if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if ((fa_out->memb_fapl_id = H5P_copy_plist(def_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't copy property list")
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fa_out->memb_fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_set_driver_by_value(plist, H5_VFD_SEC2, NULL, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default driver on member FAPL")
+
+done:
+ if (ret_value < 0 && fa_out->memb_fapl_id >= 0) {
+ if (H5I_dec_ref(fa_out->memb_fapl_id) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement ref. count on member FAPL ID")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__family_get_default_config() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD__family_get_default_printf_filename
+ *
+ * Purpose: Given a filename, allocates and returns a new filename
+ * buffer that contains the given filename modified into this
+ * VFD's printf-style format. For example, the filename
+ * "file1.h5" would be modified to "file1-%06d.h5". This would
+ * allow for member filenames such as "file1-000000.h5",
+ * "file1-000001.h5", etc. The caller is responsible for
+ * freeing the returned buffer.
+ *
+ * Return: Non-negative on Success/Negative on Failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *
+H5FD__family_get_default_printf_filename(const char *old_filename)
{
- herr_t ret_value = SUCCEED;
+ const char *suffix = "-%06d";
+ size_t old_filename_len = 0;
+ size_t new_filename_len = 0;
+ char * file_extension = NULL;
+ char * tmp_buffer = NULL;
+ char * ret_value = NULL;
FUNC_ENTER_STATIC
- if (H5FD_family_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize family VFD")
+ HDassert(old_filename);
+
+ old_filename_len = HDstrlen(old_filename);
+ if (0 == old_filename_len)
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid filename")
+
+ new_filename_len = old_filename_len + HDstrlen(suffix) + 1;
+ if (NULL == (tmp_buffer = H5MM_malloc(new_filename_len)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "can't allocate new filename buffer")
+
+ /* Determine if filename contains a ".h5" extension. */
+ if ((file_extension = HDstrstr(old_filename, ".h5"))) {
+ /* Insert the printf format between the filename and ".h5" extension. */
+ HDstrcpy(tmp_buffer, old_filename);
+ file_extension = HDstrstr(tmp_buffer, ".h5");
+ HDsprintf(file_extension, "%s%s", suffix, ".h5");
+ }
+ else if ((file_extension = HDstrrchr(old_filename, '.'))) {
+ char *new_extension_loc = NULL;
+
+ /* If the filename doesn't contain a ".h5" extension, but contains
+ * AN extension, just insert the printf format before that extension.
+ */
+ HDstrcpy(tmp_buffer, old_filename);
+ new_extension_loc = HDstrrchr(tmp_buffer, '.');
+ HDsprintf(new_extension_loc, "%s%s", suffix, file_extension);
+ }
+ else {
+ /* If the filename doesn't contain an extension at all, just insert
+ * the printf format at the end of the filename.
+ */
+ HDsnprintf(tmp_buffer, new_filename_len, "%s%s", old_filename, suffix);
+ }
+
+ ret_value = tmp_buffer;
done:
+ if (!ret_value)
+ H5MM_xfree(tmp_buffer);
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
+} /* end H5FD__family_get_default_printf_filename() */
/*-------------------------------------------------------------------------
* Function: H5FD_family_init
@@ -183,9 +282,9 @@ done:
hid_t
H5FD_family_init(void)
{
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ hid_t ret_value = H5I_INVALID_HID;
- FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+ FUNC_ENTER_NOAPI_NOERR
if (H5I_VFL != H5I_get_type(H5FD_FAMILY_g))
H5FD_FAMILY_g = H5FD_register(&H5FD_family_g, sizeof(H5FD_class_t), FALSE);
@@ -193,7 +292,6 @@ H5FD_family_init(void)
/* Set return value */
ret_value = H5FD_FAMILY_g;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FD_family_init() */
@@ -242,7 +340,7 @@ herr_t
H5Pset_fapl_family(hid_t fapl_id, hsize_t msize, hid_t memb_fapl_id)
{
herr_t ret_value;
- H5FD_family_fapl_t fa = {0, -1};
+ H5FD_family_fapl_t fa = {0, H5I_INVALID_HID};
H5P_genplist_t * plist; /* Property list pointer */
FUNC_ENTER_API(FAIL)
@@ -251,18 +349,22 @@ H5Pset_fapl_family(hid_t fapl_id, hsize_t msize, hid_t memb_fapl_id)
/* Check arguments */
if (TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (H5P_DEFAULT == memb_fapl_id)
- memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ if (H5P_DEFAULT == memb_fapl_id) {
+ /* Get default configuration for member FAPL */
+ if (H5FD__family_get_default_config(&fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default driver configuration info")
+ }
else if (TRUE != H5P_isa_class(memb_fapl_id, H5P_FILE_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
/* Initialize driver specific information. */
- fa.memb_size = msize;
- fa.memb_fapl_id = memb_fapl_id;
+ fa.memb_size = msize;
+ if (H5P_DEFAULT != memb_fapl_id)
+ fa.memb_fapl_id = memb_fapl_id;
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value = H5P_set_driver(plist, H5FD_FAMILY, &fa);
+ ret_value = H5P_set_driver(plist, H5FD_FAMILY, &fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -588,9 +690,10 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
{
H5FD_family_t *file = NULL;
char * memb_name = NULL, *temp = NULL;
- hsize_t eof = HADDR_UNDEF;
- unsigned t_flags = flags & ~H5F_ACC_CREAT;
- H5FD_t * ret_value = NULL;
+ hsize_t eof = HADDR_UNDEF;
+ hbool_t default_config = FALSE;
+ unsigned t_flags = flags & ~H5F_ACC_CREAT;
+ H5FD_t * ret_value = NULL;
FUNC_ENTER_STATIC
@@ -604,21 +707,32 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
if (NULL == (file = (H5FD_family_t *)H5MM_calloc(sizeof(H5FD_family_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
if (H5P_FILE_ACCESS_DEFAULT == fapl_id) {
- file->memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
- if (H5I_inc_ref(file->memb_fapl_id, FALSE) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
- file->memb_size = 1024 * 1024 * 1024; /*1GB. Actual member size to be updated later */
- file->pmem_size = 1024 * 1024 * 1024; /*1GB. Member size passed in through property */
- file->mem_newsize = 0; /*New member size used by h5repart only */
- } /* end if */
+ H5FD_family_fapl_t default_fa;
+
+ /* Get default configuration */
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default driver configuration info")
+
+ file->memb_fapl_id = default_fa.memb_fapl_id;
+ file->memb_size = H5FD_FAM_DEF_MEM_SIZE; /* Actual member size to be updated later */
+ file->pmem_size = H5FD_FAM_DEF_MEM_SIZE; /* Member size passed in through property */
+ file->mem_newsize = 0; /*New member size used by h5repart only */
+
+ default_config = TRUE;
+ } /* end if */
else {
H5P_genplist_t * plist; /* Property list pointer */
const H5FD_family_fapl_t *fa;
+ H5FD_family_fapl_t default_fa;
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default family VFD configuration")
+ fa = &default_fa;
+ default_config = TRUE;
+ }
/* Check for new family file size. It's used by h5repart only. */
if (H5P_exist_plist(plist, H5F_ACS_FAMILY_NEWSIZE_NAME) > 0) {
@@ -642,7 +756,10 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
} /* end else */
file->memb_size = fa->memb_size; /* Actual member size to be updated later */
file->pmem_size = fa->memb_size; /* Member size passed in through property */
- } /* end else */
+
+ if (default_config && H5I_dec_ref(fa->memb_fapl_id) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_CANTDEC, NULL, "can't decrement ref. count on member FAPL")
+ } /* end else */
file->name = H5MM_strdup(name);
file->flags = flags;
@@ -655,8 +772,16 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad
/* Check that names are unique */
HDsnprintf(memb_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, name, 0);
HDsnprintf(temp, H5FD_FAM_MEMB_NAME_BUF_SIZE, name, 1);
- if (!HDstrcmp(memb_name, temp))
- HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique")
+ if (!HDstrcmp(memb_name, temp)) {
+ if (default_config) {
+ temp = H5MM_xfree(temp);
+ if (NULL == (temp = H5FD__family_get_default_printf_filename(name)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default printf-style filename")
+ name = temp;
+ }
+ else
+ HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique")
+ }
/* Open all the family members */
while (1) {
@@ -1360,7 +1485,9 @@ H5FD__family_delete(const char *filename, hid_t fapl_id)
{
H5P_genplist_t * plist;
const H5FD_family_fapl_t *fa;
- hid_t memb_fapl_id = H5I_INVALID_HID;
+ H5FD_family_fapl_t default_fa = {0, H5I_INVALID_HID};
+ hbool_t default_config = FALSE;
+ hid_t memb_fapl_id = H5I_INVALID_HID;
unsigned current_member;
char * member_name = NULL;
char * temp = NULL;
@@ -1374,13 +1501,21 @@ H5FD__family_delete(const char *filename, hid_t fapl_id)
/* Get the driver info (for the member fapl)
* The family_open call accepts H5P_DEFAULT, so we'll accept that here, too.
*/
- if (H5P_FILE_ACCESS_DEFAULT == fapl_id)
- memb_fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ if (H5P_FILE_ACCESS_DEFAULT == fapl_id) {
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default family VFD configuration")
+ memb_fapl_id = default_fa.memb_fapl_id;
+ default_config = TRUE;
+ }
else {
if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad family VFD driver info")
+ if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (H5FD__family_get_default_config(&default_fa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default family VFD configuration")
+ fa = &default_fa;
+ default_config = TRUE;
+ }
memb_fapl_id = fa->memb_fapl_id;
}
@@ -1393,8 +1528,17 @@ H5FD__family_delete(const char *filename, hid_t fapl_id)
/* Sanity check to make sure that generated names are unique */
HDsnprintf(member_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 0);
HDsnprintf(temp, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 1);
- if (!HDstrcmp(member_name, temp))
- HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "provided file name cannot generate unique sub-files")
+ if (!HDstrcmp(member_name, temp)) {
+ if (default_config) {
+ temp = H5MM_xfree(temp);
+ if (NULL == (temp = H5FD__family_get_default_printf_filename(filename)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default printf-style filename")
+ filename = temp;
+ }
+ else
+ HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL,
+ "provided file name cannot generate unique sub-files")
+ }
/* Delete all the family members */
current_member = 0;
@@ -1430,9 +1574,9 @@ done:
if (temp)
H5MM_xfree(temp);
- /* Don't close memb_fapl_id - We didn't bump its reference count since we're
- * only using it in this call.
- */
+ /* Only close memb_fapl_id if we created one from the default configuration */
+ if (default_fa.memb_fapl_id >= 0 && H5I_dec_ref(default_fa.memb_fapl_id) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement ref. count on member FAPL ID")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD__family_delete() */
diff --git a/src/H5FDfamily.h b/src/H5FDfamily.h
index 20ef532..bd51f36 100644
--- a/src/H5FDfamily.h
+++ b/src/H5FDfamily.h
@@ -20,7 +20,8 @@
#ifndef H5FDfamily_H
#define H5FDfamily_H
-#define H5FD_FAMILY (H5FD_family_init())
+#define H5FD_FAMILY (H5FDperform_init(H5FD_family_init))
+#define H5FD_FAMILY_VALUE H5_VFD_FAMILY
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDhdfs.c b/src/H5FDhdfs.c
index 2c4bff6..4927a40 100644
--- a/src/H5FDhdfs.c
+++ b/src/H5FDhdfs.c
@@ -278,6 +278,7 @@ static herr_t H5FD__hdfs_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD__hdfs_validate_config(const H5FD_hdfs_fapl_t *fa);
static const H5FD_class_t H5FD_hdfs_g = {
+ H5FD_HDFS_VALUE, /* value */
"hdfs", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -310,6 +311,7 @@ static const H5FD_class_t H5FD_hdfs_g = {
NULL, /* lock */
NULL, /* unlock */
NULL, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -317,29 +319,6 @@ static const H5FD_class_t H5FD_hdfs_g = {
H5FL_DEFINE_STATIC(H5FD_hdfs_t);
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initializes any interface-specific data or routines.
- *
- * Return: Non-negative on success/Negative on failure
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__init_package(void)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- if (H5FD_hdfs_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize hdfs VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
-/*-------------------------------------------------------------------------
* Function: H5FD_hdfs_init
*
* Purpose: Initialize this driver by registering the driver with the
@@ -551,16 +530,16 @@ done:
* Function: H5FD__hdfs_validate_config()
*
* Purpose: Test to see if the supplied instance of H5FD_hdfs_fapl_t
- * contains internally consistant data. Return SUCCEED if so,
+ * contains internally consistent data. Return SUCCEED if so,
* and FAIL otherwise.
*
- * Note the difference between internally consistant and
+ * Note the difference between internally consistent and
* correct. As we will have to try to access the target
* object to determine whether the supplied data is correct,
- * we will settle for internal consistancy at this point
+ * we will settle for internal consistency at this point
*
* Return: SUCCEED if instance of H5FD_hdfs_fapl_t contains internally
- * consistant data, FAIL otherwise.
+ * consistent data, FAIL otherwise.
*
* Programmer: Jacob Smith
* 9/10/17
@@ -623,7 +602,7 @@ H5Pset_fapl_hdfs(hid_t fapl_id, H5FD_hdfs_fapl_t *fa)
if (FAIL == H5FD__hdfs_validate_config(fa))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid hdfs config")
- ret_value = H5P_set_driver(plist, H5FD_HDFS, (void *)fa);
+ ret_value = H5P_set_driver(plist, H5FD_HDFS, (void *)fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5FDhdfs.h b/src/H5FDhdfs.h
index 7c871a4..e401e81 100644
--- a/src/H5FDhdfs.h
+++ b/src/H5FDhdfs.h
@@ -22,9 +22,11 @@
#define H5FDhdfs_H
#ifdef H5_HAVE_LIBHDFS
-#define H5FD_HDFS (H5FD_hdfs_init())
+#define H5FD_HDFS (H5FDperform_init(H5FD_hdfs_init))
+#define H5FD_HDFS_VALUE H5_VFD_HDFS
#else /* H5_HAVE_LIBHDFS */
-#define H5FD_HDFS (H5I_INVALID_HID)
+#define H5FD_HDFS (H5I_INVALID_HID)
+#define H5FD_HDFS_VALUE H5_VFD_INVALID
#endif /* H5_HAVE_LIBHDFS */
#ifdef H5_HAVE_LIBHDFS
diff --git a/src/H5FDint.c b/src/H5FDint.c
index 23dfa4d..b1b48c9 100644
--- a/src/H5FDint.c
+++ b/src/H5FDint.c
@@ -35,6 +35,7 @@
#include "H5Fprivate.h" /* File access */
#include "H5FDpkg.h" /* File Drivers */
#include "H5Iprivate.h" /* IDs */
+#include "H5PLprivate.h" /* Plugins */
/****************/
/* Local Macros */
@@ -44,6 +45,20 @@
/* Local Typedefs */
/******************/
+/* Information needed for iterating over the registered VFD hid_t IDs.
+ * The name or value of the new VFD that is being registered is stored
+ * in the name (or value) field and the found_id field is initialized to
+ * H5I_INVALID_HID (-1). If we find a VFD with the same name / value,
+ * we set the found_id field to the existing ID for return to the function.
+ */
+typedef struct H5FD_get_driver_ud_t {
+ /* IN */
+ H5PL_vfd_key_t key;
+
+ /* OUT */
+ hid_t found_id; /* The driver ID, if we found a match */
+} H5FD_get_driver_ud_t;
+
/********************/
/* Package Typedefs */
/********************/
@@ -51,6 +66,7 @@
/********************/
/* Local Prototypes */
/********************/
+static int H5FD__get_driver_cb(void *obj, hid_t id, void *_op_data);
/*********************/
/* Package Variables */
@@ -166,24 +182,6 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, haddr_t addr, size_t size, void *buf /*
HGOTO_DONE(SUCCEED)
#endif /* H5_HAVE_PARALLEL */
- /* If the file is open for SWMR read access, allow access to data past
- * the end of the allocated space (the 'eoa'). This is done because the
- * eoa stored in the file's superblock might be out of sync with the
- * objects being written within the file by the application performing
- * SWMR write operations.
- */
-#if 0 /* JRM */
- if(!(file->access_flags & H5F_ACC_SWMR_READ)) {
- haddr_t eoa;
-
- if(HADDR_UNDEF == (eoa = (file->cls->get_eoa)(file, type)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
-
- if((addr + file->base_addr + size) > eoa)
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu, eoa = %llu", (unsigned long long)(addr + file->base_addr), (unsigned long long)size, (unsigned long long)eoa)
- }
-#endif /* JRM */
-
/* Dispatch to driver */
if ((file->cls->read)(file, type, dxpl_id, addr + file->base_addr, size, buf) < 0)
HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed")
@@ -425,3 +423,357 @@ H5FD_delete(const char *filename, hid_t fapl_id)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_delete() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_check_plugin_load
+ *
+ * Purpose: Check if a VFD plugin matches the search criteria, and can
+ * be loaded.
+ *
+ * Note: Matching the driver's name / value, but the driver having
+ * an incompatible version is not an error, but means that the
+ * driver isn't a "match". Setting the SUCCEED value to FALSE
+ * and not failing for that case allows the plugin framework
+ * to keep looking for other DLLs that match and have a
+ * compatible version.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_check_plugin_load(const H5FD_class_t *cls, const H5PL_key_t *key, hbool_t *success)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOERR
+
+ /* Sanity checks */
+ HDassert(cls);
+ HDassert(key);
+ HDassert(success);
+
+ /* Which kind of key are we looking for? */
+ if (key->vfd.kind == H5FD_GET_DRIVER_BY_NAME) {
+ /* Check if plugin name matches VFD class name */
+ if (cls->name && !HDstrcmp(cls->name, key->vfd.u.name))
+ *success = TRUE;
+ }
+ else {
+ /* Sanity check */
+ HDassert(key->vfd.kind == H5FD_GET_DRIVER_BY_VALUE);
+
+ /* Check if plugin value matches VFD class value */
+ if (cls->value == key->vfd.u.value)
+ *success = TRUE;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_check_plugin_load() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD__get_driver_cb
+ *
+ * Purpose: Callback routine to search through registered VFDs
+ *
+ * Return: Success: H5_ITER_STOP if the class and op_data name
+ * members match. H5_ITER_CONT otherwise.
+ * Failure: Can't fail
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5FD__get_driver_cb(void *obj, hid_t id, void *_op_data)
+{
+ H5FD_get_driver_ud_t *op_data = (H5FD_get_driver_ud_t *)_op_data; /* User data for callback */
+ H5FD_class_t * cls = (H5FD_class_t *)obj;
+ int ret_value = H5_ITER_CONT; /* Callback return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ if (H5FD_GET_DRIVER_BY_NAME == op_data->key.kind) {
+ if (0 == HDstrcmp(cls->name, op_data->key.u.name)) {
+ op_data->found_id = id;
+ ret_value = H5_ITER_STOP;
+ } /* end if */
+ } /* end if */
+ else {
+ HDassert(H5FD_GET_DRIVER_BY_VALUE == op_data->key.kind);
+ if (cls->value == op_data->key.u.value) {
+ op_data->found_id = id;
+ ret_value = H5_ITER_STOP;
+ } /* end if */
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__get_driver_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_register_driver_by_name
+ *
+ * Purpose: Registers a new VFD as a member of the virtual file driver
+ * class.
+ *
+ * Return: Success: A VFD ID which is good until the library is
+ * closed.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_register_driver_by_name(const char *name, hbool_t app_ref)
+{
+ htri_t driver_is_registered = FALSE;
+ hid_t driver_id = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Check if driver is already registered */
+ if ((driver_is_registered = H5FD_is_driver_registered_by_name(name, &driver_id)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't check if driver is already registered")
+
+ /* If driver is already registered, increment ref count on ID and return ID */
+ if (driver_is_registered) {
+ HDassert(driver_id >= 0);
+
+ if (H5I_inc_ref(driver_id, app_ref) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFD")
+ } /* end if */
+ else {
+ H5PL_key_t key;
+ const H5FD_class_t *cls;
+
+ /* Try loading the driver */
+ key.vfd.kind = H5FD_GET_DRIVER_BY_NAME;
+ key.vfd.u.name = name;
+ if (NULL == (cls = (const H5FD_class_t *)H5PL_load(H5PL_TYPE_VFD, &key)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VFD")
+
+ /* Register the driver we loaded */
+ if ((driver_id = H5FD_register(cls, sizeof(*cls), app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VFD ID")
+ } /* end else */
+
+ ret_value = driver_id;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_register_driver_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_register_driver_by_value
+ *
+ * Purpose: Registers a new VFD as a member of the virtual file driver
+ * class.
+ *
+ * Return: Success: A VFD ID which is good until the library is
+ * closed.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_register_driver_by_value(H5FD_class_value_t value, hbool_t app_ref)
+{
+ htri_t driver_is_registered = FALSE;
+ hid_t driver_id = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Check if driver is already registered */
+ if ((driver_is_registered = H5FD_is_driver_registered_by_value(value, &driver_id)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't check if driver is already registered")
+
+ /* If driver is already registered, increment ref count on ID and return ID */
+ if (driver_is_registered) {
+ HDassert(driver_id >= 0);
+
+ if (H5I_inc_ref(driver_id, app_ref) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFD")
+ } /* end if */
+ else {
+ H5PL_key_t key;
+ const H5FD_class_t *cls;
+
+ /* Try loading the driver */
+ key.vfd.kind = H5FD_GET_DRIVER_BY_VALUE;
+ key.vfd.u.value = value;
+ if (NULL == (cls = (const H5FD_class_t *)H5PL_load(H5PL_TYPE_VFD, &key)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VFD")
+
+ /* Register the driver we loaded */
+ if ((driver_id = H5FD_register(cls, sizeof(*cls), app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VFD ID")
+ } /* end else */
+
+ ret_value = driver_id;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_register_driver_by_value() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_is_driver_registered_by_name
+ *
+ * Purpose: Checks if a driver with a particular name is registered.
+ * If `registered_id` is non-NULL and a driver with the
+ * specified name has been registered, the driver's ID will be
+ * returned in `registered_id`.
+ *
+ * Return: >0 if a VFD with that name has been registered
+ * 0 if a VFD with that name has NOT been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FD_is_driver_registered_by_name(const char *driver_name, hid_t *registered_id)
+{
+ H5FD_get_driver_ud_t op_data; /* Callback info for driver search */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_NAME;
+ op_data.key.u.name = driver_name;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with name */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, FAIL, "can't iterate over VFDs")
+
+ /* Found a driver with that name */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ if (registered_id)
+ *registered_id = op_data.found_id;
+ ret_value = TRUE;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_is_driver_registered_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_is_driver_registered_by_value
+ *
+ * Purpose: Checks if a driver with a particular value (ID) is
+ * registered. If `registered_id` is non-NULL and a driver
+ * with the specified value has been registered, the driver's
+ * ID will be returned in `registered_id`.
+ *
+ * Return: >0 if a VFD with that value has been registered
+ * 0 if a VFD with that value has NOT been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FD_is_driver_registered_by_value(H5FD_class_value_t driver_value, hid_t *registered_id)
+{
+ H5FD_get_driver_ud_t op_data; /* Callback info for driver search */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_VALUE;
+ op_data.key.u.value = driver_value;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with value */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, FAIL, "can't iterate over VFDs")
+
+ /* Found a driver with that value */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ if (registered_id)
+ *registered_id = op_data.found_id;
+ ret_value = TRUE;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_is_driver_registered_by_value() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_driver_id_by_name
+ *
+ * Purpose: Retrieves the ID for a registered VFL driver.
+ *
+ * Return: Positive if the VFL driver has been registered
+ * Negative on error (if the driver is not a valid driver or
+ * is not registered)
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_get_driver_id_by_name(const char *name, hbool_t is_api)
+{
+ H5FD_get_driver_ud_t op_data;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with specified name */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VFL drivers")
+
+ /* Found a driver with that name */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ ret_value = op_data.found_id;
+ if (H5I_inc_ref(ret_value, is_api) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFL driver")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_driver_id_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_driver_id_by_value
+ *
+ * Purpose: Retrieves the ID for a registered VFL driver.
+ *
+ * Return: Positive if the VFL driver has been registered
+ * Negative on error (if the driver is not a valid driver or
+ * is not registered)
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_get_driver_id_by_value(H5FD_class_value_t value, hbool_t is_api)
+{
+ H5FD_get_driver_ud_t op_data;
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Set up op data for iteration */
+ op_data.key.kind = H5FD_GET_DRIVER_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
+
+ /* Find driver with specified value */
+ if (H5I_iterate(H5I_VFL, H5FD__get_driver_cb, &op_data, FALSE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VFL drivers")
+
+ /* Found a driver with that value */
+ if (op_data.found_id != H5I_INVALID_HID) {
+ ret_value = op_data.found_id;
+ if (H5I_inc_ref(ret_value, is_api) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VFL driver")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_driver_id_by_value() */
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index f996b9e..af34682 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -180,78 +180,50 @@ static herr_t H5FD__log_unlock(H5FD_t *_file);
static herr_t H5FD__log_delete(const char *filename, hid_t fapl_id);
static const H5FD_class_t H5FD_log_g = {
- "log", /* name */
- MAXADDR, /* maxaddr */
- H5F_CLOSE_WEAK, /* fc_degree */
- H5FD__log_term, /* terminate */
- NULL, /* sb_size */
- NULL, /* sb_encode */
- NULL, /* sb_decode */
- sizeof(H5FD_log_fapl_t), /* fapl_size */
- H5FD__log_fapl_get, /* fapl_get */
- H5FD__log_fapl_copy, /* fapl_copy */
- H5FD__log_fapl_free, /* fapl_free */
- 0, /* dxpl_size */
- NULL, /* dxpl_copy */
- NULL, /* dxpl_free */
- H5FD__log_open, /* open */
- H5FD__log_close, /* close */
- H5FD__log_cmp, /* cmp */
- H5FD__log_query, /* query */
- NULL, /* get_type_map */
- H5FD__log_alloc, /* alloc */
- H5FD__log_free, /* free */
- H5FD__log_get_eoa, /* get_eoa */
- H5FD__log_set_eoa, /* set_eoa */
- H5FD__log_get_eof, /* get_eof */
- H5FD__log_get_handle, /* get_handle */
- H5FD__log_read, /* read */
- H5FD__log_write, /* write */
- NULL, /* flush */
- H5FD__log_truncate, /* truncate */
- H5FD__log_lock, /* lock */
- H5FD__log_unlock, /* unlock */
- H5FD__log_delete, /* del */
- H5FD_FLMAP_DICHOTOMY /* fl_map */
+ H5FD_LOG_VALUE, /* value */
+ "log", /* name */
+ MAXADDR, /* maxaddr */
+ H5F_CLOSE_WEAK, /* fc_degree */
+ H5FD__log_term, /* terminate */
+ NULL, /* sb_size */
+ NULL, /* sb_encode */
+ NULL, /* sb_decode */
+ sizeof(H5FD_log_fapl_t), /* fapl_size */
+ H5FD__log_fapl_get, /* fapl_get */
+ H5FD__log_fapl_copy, /* fapl_copy */
+ H5FD__log_fapl_free, /* fapl_free */
+ 0, /* dxpl_size */
+ NULL, /* dxpl_copy */
+ NULL, /* dxpl_free */
+ H5FD__log_open, /* open */
+ H5FD__log_close, /* close */
+ H5FD__log_cmp, /* cmp */
+ H5FD__log_query, /* query */
+ NULL, /* get_type_map */
+ H5FD__log_alloc, /* alloc */
+ H5FD__log_free, /* free */
+ H5FD__log_get_eoa, /* get_eoa */
+ H5FD__log_set_eoa, /* set_eoa */
+ H5FD__log_get_eof, /* get_eof */
+ H5FD__log_get_handle, /* get_handle */
+ H5FD__log_read, /* read */
+ H5FD__log_write, /* write */
+ NULL, /* flush */
+ H5FD__log_truncate, /* truncate */
+ H5FD__log_lock, /* lock */
+ H5FD__log_unlock, /* unlock */
+ H5FD__log_delete, /* del */
+ NULL, /* ctl */
+ H5FD_FLMAP_DICHOTOMY /* fl_map */
};
+/* Default configuration, if none provided */
+static const H5FD_log_fapl_t H5FD_log_default_config_g = {NULL, H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC, 4096};
+
/* Declare a free list to manage the H5FD_log_t struct */
H5FL_DEFINE_STATIC(H5FD_log_t);
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initializes any interface-specific data or routines.
- *
- * Return: Non-negative on success/Negative on failure
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__init_package(void)
-{
- char * lock_env_var = NULL; /* Environment variable pointer */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- /* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
- if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
- ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
- else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
- ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
- else
- ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
-
- if (H5FD_log_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize log VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
-/*-------------------------------------------------------------------------
* Function: H5FD_log_init
*
* Purpose: Initialize this driver by registering the driver with the
@@ -268,9 +240,19 @@ done:
hid_t
H5FD_log_init(void)
{
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ char *lock_env_var = NULL; /* Environment variable pointer */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+ FUNC_ENTER_NOAPI_NOERR
+
+ /* Check the use disabled file locks environment variable */
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
+ if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
+ ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
+ else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
+ ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
+ else
+ ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
if (H5I_VFL != H5I_get_type(H5FD_LOG_g))
H5FD_LOG_g = H5FD_register(&H5FD_log_g, sizeof(H5FD_class_t), FALSE);
@@ -278,7 +260,6 @@ H5FD_log_init(void)
/* Set return value */
ret_value = H5FD_LOG_g;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_log_init() */
@@ -347,7 +328,7 @@ H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, si
fa.flags = flags;
fa.buf_size = buf_size;
- ret_value = H5P_set_driver(plist, H5FD_LOG, &fa);
+ ret_value = H5P_set_driver(plist, H5FD_LOG, &fa, NULL);
done:
if (fa.logfile)
@@ -482,10 +463,11 @@ static H5FD_t *
H5FD__log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
{
H5FD_log_t * file = NULL;
- H5P_genplist_t * plist; /* Property list */
- const H5FD_log_fapl_t *fa; /* File access property list information */
- int fd = -1; /* File descriptor */
- int o_flags; /* Flags for open() call */
+ H5P_genplist_t * plist; /* Property list */
+ const H5FD_log_fapl_t *fa; /* File access property list information */
+ H5FD_log_fapl_t default_fa = H5FD_log_default_config_g;
+ int fd = -1; /* File descriptor */
+ int o_flags; /* Flags for open() call */
#ifdef H5_HAVE_WIN32_API
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
#endif
@@ -523,8 +505,10 @@ H5FD__log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
/* Get the driver specific information */
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- if (NULL == (fa = (const H5FD_log_fapl_t *)H5P_peek_driver_info(plist)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info")
+ if (NULL == (fa = (const H5FD_log_fapl_t *)H5P_peek_driver_info(plist))) {
+ /* Use default driver configuration*/
+ fa = &default_fa;
+ }
/* Start timer for open() call */
if (fa->flags & H5FD_LOG_TIME_OPEN)
@@ -1559,7 +1543,7 @@ H5FD__log_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, ha
HDfprintf(file->logfp, "%10" PRIuHADDR "-%10" PRIuHADDR " (%10zu bytes) (%s) Written", orig_addr,
(orig_addr + orig_size) - 1, orig_size, flavors[type]);
- /* Check if this is the first write into a "default" section, grabbed by the metadata agregation
+ /* Check if this is the first write into a "default" section, grabbed by the metadata aggregation
* algorithm */
if (file->fa.flags & H5FD_LOG_FLAVOR) {
if ((H5FD_mem_t)file->flavor[orig_addr] == H5FD_MEM_DEFAULT) {
diff --git a/src/H5FDlog.h b/src/H5FDlog.h
index 969c091..a916fec 100644
--- a/src/H5FDlog.h
+++ b/src/H5FDlog.h
@@ -20,7 +20,8 @@
#ifndef H5FDlog_H
#define H5FDlog_H
-#define H5FD_LOG (H5FD_log_init())
+#define H5FD_LOG (H5FDperform_init(H5FD_log_init))
+#define H5FD_LOG_VALUE H5_VFD_LOG
/* Flags for H5Pset_fapl_log() */
/* Flags for tracking 'meta' operations (truncate) */
diff --git a/src/H5FDmirror.c b/src/H5FDmirror.c
index 8cbeff6..e74901a 100644
--- a/src/H5FDmirror.c
+++ b/src/H5FDmirror.c
@@ -160,6 +160,7 @@ static herr_t H5FD__mirror_unlock(H5FD_t *_file);
static herr_t H5FD__mirror_verify_reply(H5FD_mirror_t *file);
static const H5FD_class_t H5FD_mirror_g = {
+ H5FD_MIRROR_VALUE, /* value */
"mirror", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -192,6 +193,7 @@ static const H5FD_class_t H5FD_mirror_g = {
H5FD__mirror_lock, /* lock */
H5FD__mirror_unlock, /* unlock */
NULL, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -204,30 +206,6 @@ H5FL_DEFINE_STATIC(H5FD_mirror_t);
/* Declare a free list to manage the H5FD_mirror_xmit_open_t struct */
H5FL_DEFINE_STATIC(H5FD_mirror_xmit_open_t);
-/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initializes any interface-specific data or routines.
- *
- * Return: Non-negative on success/Negative on failure
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__init_package(void)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- LOG_OP_CALL(__func__);
-
- if (H5FD_mirror_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize mirror VFD");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
/* -------------------------------------------------------------------------
* Function: H5FD_mirror_init
*
@@ -247,9 +225,11 @@ H5FD_mirror_init(void)
LOG_OP_CALL(__func__);
- if (H5I_VFL != H5I_get_type(H5FD_MIRROR_g))
+ if (H5I_VFL != H5I_get_type(H5FD_MIRROR_g)) {
H5FD_MIRROR_g = H5FD_register(&H5FD_mirror_g, sizeof(H5FD_class_t), FALSE);
-
+ if (H5I_INVALID_HID == H5FD_MIRROR_g)
+ HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register mirror");
+ }
ret_value = H5FD_MIRROR_g;
done:
@@ -1167,7 +1147,7 @@ done:
/* -------------------------------------------------------------------------
* Function: H5FD__mirror_fapl_get
*
- * Purpose: Get the file access propety list which could be used to create
+ * Purpose: Get the file access property list which could be used to create
* an identical file.
*
* Return: Success: pointer to the new file access property list value.
@@ -1335,7 +1315,7 @@ H5Pset_fapl_mirror(hid_t fapl_id, H5FD_mirror_fapl_t *fa)
if (H5FD_MIRROR_CURR_FAPL_T_VERSION != fa->version)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown fapl_t version");
- ret_value = H5P_set_driver(plist, H5FD_MIRROR, (const void *)fa);
+ ret_value = H5P_set_driver(plist, H5FD_MIRROR, (const void *)fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5FDmirror.h b/src/H5FDmirror.h
index 49e24c1..b196b2b 100644
--- a/src/H5FDmirror.h
+++ b/src/H5FDmirror.h
@@ -19,7 +19,8 @@
#ifdef H5_HAVE_MIRROR_VFD
-#define H5FD_MIRROR (H5FD_mirror_init())
+#define H5FD_MIRROR (H5FDperform_init(H5FD_mirror_init))
+#define H5FD_MIRROR_VALUE H5_VFD_MIRROR
#ifdef __cplusplus
extern "C" {
@@ -33,7 +34,7 @@ extern "C" {
/* ---------------------------------------------------------------------------
* Structure: H5FD_mirror_fapl_t
*
- * Used to pass configuraiton information to the Mirror VFD.
+ * Used to pass configuration information to the Mirror VFD.
* Populate components as appropriate and pass structure pointer to
* `H5Pset_fapl_mirror()`.
*
diff --git a/src/H5FDmirror_priv.h b/src/H5FDmirror_priv.h
index 21de97b..f647c21 100644
--- a/src/H5FDmirror_priv.h
+++ b/src/H5FDmirror_priv.h
@@ -28,10 +28,10 @@ extern "C" {
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
-/* The maximum allowed size for a receiving buffer when accepting bytes to
+/* Define the maximum allowed size for a receiving buffer when accepting bytes to
* write. Writes larger than this size are performed by multiple accept-write
* steps by the Writer. */
-#define H5FD_MIRROR_DATA_BUFFER_MAX H5_GB /* 1 Gigabyte */
+#define H5FD_MIRROR_DATA_BUFFER_MAX (1024 * 1024 * 1024) /* 1 Gigabyte */
#define H5FD_MIRROR_XMIT_CURR_VERSION 1
#define H5FD_MIRROR_XMIT_MAGIC 0x87F8005B
@@ -80,7 +80,7 @@ extern "C" {
*
* `magic` (uint32_t)
* A "unique" number identifying the structure and endianness of
- * transmitting maching.
+ * transmitting machine.
* Must be set to H5FD_MIRROR_XMIT_MAGIC native to the VFD "sender".
*
* `version` (uint8_t)
@@ -214,13 +214,13 @@ typedef struct H5FD_mirror_xmit_open_t {
*
* `status` (uint32_t)
* Number indicating whether the command was successful or if an
- * occured.
+ * occurred.
* Allowed values are H5FD_MIRROR_STATUS_OK and
* H5FD_MIRROR_STATUS_ERROR.
*
* `message` (char[])
* Error message. Populated if and only if there was a problem.
- * It is possible that a message may reach the end of the alloted
+ * It is possible that a message may reach the end of the allotted
* space without a NULL terminator -- the onus is on the programmer to
* handle this situation.
*
diff --git a/src/H5FDmpi.c b/src/H5FDmpi.c
index 048b8f3..7eb1463 100644
--- a/src/H5FDmpi.c
+++ b/src/H5FDmpi.c
@@ -41,26 +41,42 @@
* Programmer: Quincey Koziol
* Friday, January 30, 2004
*
+ * Changes: Reworked function to use the ctl callback so we can get
+ * rid of H5FD_class_mpi_t. Since there are no real limits
+ * on what the ctl callback can do, its file parameter can't
+ * be constant. Thus, I had to remove the const qualifier
+ * on this functions file parameter as well. Note also the
+ * circumlocution required to use the ctl callbacks output
+ * parameter to pass back the rank without introducing
+ * compiler warnings.
+ * JRM -- 8/13/21
+ *
*-------------------------------------------------------------------------
*/
int
-H5FD_mpi_get_rank(const H5FD_t *file)
+H5FD_mpi_get_rank(H5FD_t *file)
{
- const H5FD_class_mpi_t *cls;
-
- int ret_value;
+ const H5FD_class_t *cls;
+ uint64_t flags = H5FD_CTL__FAIL_IF_UNKNOWN_FLAG | H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG;
+ int rank = -1;
+ void * rank_ptr = (void *)(&rank);
+ int ret_value;
FUNC_ENTER_NOAPI(FAIL)
HDassert(file);
- cls = (const H5FD_class_mpi_t *)(file->cls);
+ cls = (const H5FD_class_t *)(file->cls);
HDassert(cls);
- HDassert(cls->get_rank); /* All MPI drivers must implement this */
+ HDassert(cls->ctl); /* All MPI drivers must implement this */
/* Dispatch to driver */
- if ((ret_value = (cls->get_rank)(file)) < 0)
+ if ((cls->ctl)(file, H5FD_CTL__GET_MPI_RANK_OPCODE, flags, NULL, &rank_ptr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_rank request failed")
+ HDassert(rank >= 0);
+
+ ret_value = rank;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_mpi_get_rank() */
@@ -77,25 +93,43 @@ done:
* Programmer: Quincey Koziol
* Friday, January 30, 2004
*
+ * Changes: Reworked function to use the ctl callback so we can get
+ * rid of H5FD_class_mpi_t. Since there are no real limits
+ * on what the ctl callback can do, its file parameter can't
+ * be constant. Thus, I had to remove the const qualifier
+ * on this functions file parameter as well. Note also the
+ * circumlocution required to use the ctl callbacks output
+ * parameter to pass back the rank without introducing
+ * compiler warnings.
+ * JRM -- 8/13/21
+ *
*-------------------------------------------------------------------------
*/
int
-H5FD_mpi_get_size(const H5FD_t *file)
+H5FD_mpi_get_size(H5FD_t *file)
{
- const H5FD_class_mpi_t *cls;
- int ret_value;
+ const H5FD_class_t *cls;
+ uint64_t flags = H5FD_CTL__FAIL_IF_UNKNOWN_FLAG | H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG;
+ int size = 0;
+ void * size_ptr = (void *)(&size);
+ int ret_value;
FUNC_ENTER_NOAPI(FAIL)
HDassert(file);
- cls = (const H5FD_class_mpi_t *)(file->cls);
+ cls = (const H5FD_class_t *)(file->cls);
HDassert(cls);
- HDassert(cls->get_size); /* All MPI drivers must implement this */
+ HDassert(cls->ctl); /* All MPI drivers must implement this */
/* Dispatch to driver */
- if ((ret_value = (cls->get_size)(file)) < 0)
+ if ((cls->ctl)(file, H5FD_CTL__GET_MPI_SIZE_OPCODE, flags, NULL, &size_ptr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_size request failed")
+ if (0 >= size)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_size request returned bad value")
+
+ ret_value = size;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_mpi_get_size() */
@@ -112,25 +146,43 @@ done:
* Programmer: Quincey Koziol
* Friday, January 30, 2004
*
+ * Changes: Reworked function to use the ctl callback so we can get
+ * rid of H5FD_class_mpi_t. Since there are no real limits
+ * on what the ctl callback can do, its file parameter can't
+ * be constant. Thus, I had to remove the const qualifier
+ * on this functions file parameter as well. Note also the
+ * circumlocution required to use the ctl callbacks output
+ * parameter to pass back the rank without introducing
+ * compiler warnings.
+ * JRM -- 8/13/21
+ *
*-------------------------------------------------------------------------
*/
MPI_Comm
-H5FD_mpi_get_comm(const H5FD_t *file)
+H5FD_mpi_get_comm(H5FD_t *file)
{
- const H5FD_class_mpi_t *cls;
- MPI_Comm ret_value;
+ const H5FD_class_t *cls;
+ uint64_t flags = H5FD_CTL__FAIL_IF_UNKNOWN_FLAG | H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG;
+ MPI_Comm comm = MPI_COMM_NULL;
+ void * comm_ptr = (void *)(&comm);
+ MPI_Comm ret_value;
FUNC_ENTER_NOAPI(MPI_COMM_NULL)
HDassert(file);
- cls = (const H5FD_class_mpi_t *)(file->cls);
+ cls = (const H5FD_class_t *)(file->cls);
HDassert(cls);
- HDassert(cls->get_comm); /* All MPI drivers must implement this */
+ HDassert(cls->ctl); /* All MPI drivers must implement this */
/* Dispatch to driver */
- if ((ret_value = (cls->get_comm)(file)) == MPI_COMM_NULL)
+ if ((cls->ctl)(file, H5FD_CTL__GET_MPI_COMMUNICATOR_OPCODE, flags, NULL, &comm_ptr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed")
+ if (comm == MPI_COMM_NULL)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed -- bad comm")
+
+ ret_value = comm;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_mpi_get_comm() */
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index dd40399..4aa8a96 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -45,6 +45,9 @@ static hid_t H5FD_MPIO_g = 0;
/* (Can be changed by setting "HDF5_MPI_OPT_TYPES" environment variable to '0' or '1') */
hbool_t H5FD_mpi_opt_types_g = TRUE;
+/* Whether the driver initialized MPI on its own */
+hbool_t H5FD_mpi_self_initialized = FALSE;
+
/*
* The view is set to this value
*/
@@ -72,66 +75,61 @@ typedef struct H5FD_mpio_t {
/* Private Prototypes */
/* Callbacks */
-static herr_t H5FD__mpio_term(void);
-static H5FD_t * H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr);
-static herr_t H5FD__mpio_close(H5FD_t *_file);
-static herr_t H5FD__mpio_query(const H5FD_t *_f1, unsigned long *flags);
-static haddr_t H5FD__mpio_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
-static herr_t H5FD__mpio_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
-static haddr_t H5FD__mpio_get_eof(const H5FD_t *_file, H5FD_mem_t type);
-static herr_t H5FD__mpio_get_handle(H5FD_t *_file, hid_t fapl, void **file_handle);
-static herr_t H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
- void *buf);
-static herr_t H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
- const void *buf);
-static herr_t H5FD__mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
-static herr_t H5FD__mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
-static herr_t H5FD__mpio_delete(const char *filename, hid_t fapl_id);
-static int H5FD__mpio_mpi_rank(const H5FD_t *_file);
-static int H5FD__mpio_mpi_size(const H5FD_t *_file);
-static MPI_Comm H5FD__mpio_communicator(const H5FD_t *_file);
+static herr_t H5FD__mpio_term(void);
+static H5FD_t *H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr);
+static herr_t H5FD__mpio_close(H5FD_t *_file);
+static herr_t H5FD__mpio_query(const H5FD_t *_f1, unsigned long *flags);
+static haddr_t H5FD__mpio_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
+static herr_t H5FD__mpio_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
+static haddr_t H5FD__mpio_get_eof(const H5FD_t *_file, H5FD_mem_t type);
+static herr_t H5FD__mpio_get_handle(H5FD_t *_file, hid_t fapl, void **file_handle);
+static herr_t H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
+ void *buf);
+static herr_t H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
+ const void *buf);
+static herr_t H5FD__mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
+static herr_t H5FD__mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
+static herr_t H5FD__mpio_delete(const char *filename, hid_t fapl_id);
+static herr_t H5FD__mpio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input,
+ void **output);
/* The MPIO file driver information */
-static const H5FD_class_mpi_t H5FD_mpio_g = {
- {
- /* Start of superclass information */
- "mpio", /* name */
- HADDR_MAX, /* maxaddr */
- H5F_CLOSE_SEMI, /* fc_degree */
- H5FD__mpio_term, /* terminate */
- NULL, /* sb_size */
- NULL, /* sb_encode */
- NULL, /* sb_decode */
- 0, /* fapl_size */
- NULL, /* fapl_get */
- NULL, /* fapl_copy */
- NULL, /* fapl_free */
- 0, /* dxpl_size */
- NULL, /* dxpl_copy */
- NULL, /* dxpl_free */
- H5FD__mpio_open, /* open */
- H5FD__mpio_close, /* close */
- NULL, /* cmp */
- H5FD__mpio_query, /* query */
- NULL, /* get_type_map */
- NULL, /* alloc */
- NULL, /* free */
- H5FD__mpio_get_eoa, /* get_eoa */
- H5FD__mpio_set_eoa, /* set_eoa */
- H5FD__mpio_get_eof, /* get_eof */
- H5FD__mpio_get_handle, /* get_handle */
- H5FD__mpio_read, /* read */
- H5FD__mpio_write, /* write */
- H5FD__mpio_flush, /* flush */
- H5FD__mpio_truncate, /* truncate */
- NULL, /* lock */
- NULL, /* unlock */
- H5FD__mpio_delete, /* del */
- H5FD_FLMAP_DICHOTOMY /* fl_map */
- }, /* End of superclass information */
- H5FD__mpio_mpi_rank, /* get_rank */
- H5FD__mpio_mpi_size, /* get_size */
- H5FD__mpio_communicator /* get_comm */
+static const H5FD_class_t H5FD_mpio_g = {
+ H5_VFD_MPIO, /* value */
+ "mpio", /* name */
+ HADDR_MAX, /* maxaddr */
+ H5F_CLOSE_SEMI, /* fc_degree */
+ H5FD__mpio_term, /* terminate */
+ NULL, /* sb_size */
+ NULL, /* sb_encode */
+ NULL, /* sb_decode */
+ 0, /* fapl_size */
+ NULL, /* fapl_get */
+ NULL, /* fapl_copy */
+ NULL, /* fapl_free */
+ 0, /* dxpl_size */
+ NULL, /* dxpl_copy */
+ NULL, /* dxpl_free */
+ H5FD__mpio_open, /* open */
+ H5FD__mpio_close, /* close */
+ NULL, /* cmp */
+ H5FD__mpio_query, /* query */
+ NULL, /* get_type_map */
+ NULL, /* alloc */
+ NULL, /* free */
+ H5FD__mpio_get_eoa, /* get_eoa */
+ H5FD__mpio_set_eoa, /* set_eoa */
+ H5FD__mpio_get_eof, /* get_eof */
+ H5FD__mpio_get_handle, /* get_handle */
+ H5FD__mpio_read, /* read */
+ H5FD__mpio_write, /* write */
+ H5FD__mpio_flush, /* flush */
+ H5FD__mpio_truncate, /* truncate */
+ NULL, /* lock */
+ NULL, /* unlock */
+ H5FD__mpio_delete, /* del */
+ H5FD__mpio_ctl, /* ctl */
+ H5FD_FLMAP_DICHOTOMY /* fl_map */
};
#ifdef H5FDmpio_DEBUG
@@ -157,35 +155,6 @@ static int H5FD_mpio_debug_rank_s = -1;
(H5FD_mpio_debug_rank_s < 0 || H5FD_mpio_debug_rank_s == (file)->mpi_rank)
#endif
-/*--------------------------------------------------------------------------
-NAME
- H5FD__init_package -- Initialize interface-specific information
-
-USAGE
- herr_t H5FD__init_package()
-
-RETURNS
- SUCCEED/FAIL
-
-DESCRIPTION
- Initializes any interface-specific data or routines. (Just calls
- H5FD_mpio_init currently).
-
---------------------------------------------------------------------------*/
-static herr_t
-H5FD__init_package(void)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- if (H5FD_mpio_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize mpio VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
#ifdef H5FDmpio_DEBUG
/*---------------------------------------------------------------------------
@@ -219,6 +188,41 @@ H5FD__mpio_parse_debug_str(const char *s)
FUNC_LEAVE_NOAPI_VOID
} /* end H5FD__mpio_parse_debug_str() */
+
+/*---------------------------------------------------------------------------
+ * Function: H5FD__mem_t_to_str
+ *
+ * Purpose: Returns a string representing the enum value in an H5FD_mem_t
+ * enum
+ *
+ * Returns: H5FD_mem_t enum value string
+ *
+ *---------------------------------------------------------------------------
+ */
+static const char *
+H5FD__mem_t_to_str(H5FD_mem_t mem_type)
+{
+ switch (mem_type) {
+ case H5FD_MEM_NOLIST:
+ return "H5FD_MEM_NOLIST";
+ case H5FD_MEM_DEFAULT:
+ return "H5FD_MEM_DEFAULT";
+ case H5FD_MEM_SUPER:
+ return "H5FD_MEM_SUPER";
+ case H5FD_MEM_BTREE:
+ return "H5FD_MEM_BTREE";
+ case H5FD_MEM_DRAW:
+ return "H5FD_MEM_DRAW";
+ case H5FD_MEM_GHEAP:
+ return "H5FD_MEM_GHEAP";
+ case H5FD_MEM_LHEAP:
+ return "H5FD_MEM_LHEAP";
+ case H5FD_MEM_OHDR:
+ return "H5FD_MEM_OHDR";
+ default:
+ return "(Unknown)";
+ }
+}
#endif /* H5FDmpio_DEBUG */
/*-------------------------------------------------------------------------
@@ -239,13 +243,30 @@ hid_t
H5FD_mpio_init(void)
{
static int H5FD_mpio_Debug_inited = 0;
+ char * env = NULL;
hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_NOAPI(H5I_INVALID_HID)
/* Register the MPI-IO VFD, if it isn't already */
- if (H5I_VFL != H5I_get_type(H5FD_MPIO_g))
- H5FD_MPIO_g = H5FD_register((const H5FD_class_t *)&H5FD_mpio_g, sizeof(H5FD_class_mpi_t), FALSE);
+ if (H5I_VFL != H5I_get_type(H5FD_MPIO_g)) {
+ H5FD_MPIO_g = H5FD_register((const H5FD_class_t *)&H5FD_mpio_g, sizeof(H5FD_class_t), FALSE);
+
+ /* Check if MPI driver has been loaded dynamically */
+ env = HDgetenv(HDF5_DRIVER);
+ if (env && !HDstrcmp(env, "mpio")) {
+ int mpi_initialized = 0;
+
+ /* Initialize MPI if not already initialized */
+ if (MPI_SUCCESS != MPI_Initialized(&mpi_initialized))
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, H5I_INVALID_HID, "can't check if MPI is initialized")
+ if (!mpi_initialized) {
+ if (MPI_SUCCESS != MPI_Init(NULL, NULL))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "can't initialize MPI")
+ H5FD_mpi_self_initialized = TRUE;
+ }
+ }
+ }
if (!H5FD_mpio_Debug_inited) {
const char *s; /* String for environment variables */
@@ -292,6 +313,17 @@ H5FD__mpio_term(void)
{
FUNC_ENTER_STATIC_NOERR
+ /* Terminate MPI if the driver initialized it */
+ if (H5FD_mpi_self_initialized) {
+ int mpi_finalized = 0;
+
+ MPI_Finalized(&mpi_finalized);
+ if (!mpi_finalized)
+ MPI_Finalize();
+
+ H5FD_mpi_self_initialized = FALSE;
+ }
+
/* Reset VFL ID */
H5FD_MPIO_g = 0;
@@ -353,7 +385,7 @@ H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info object")
/* duplication is done during driver setting. */
- ret_value = H5P_set_driver(plist, H5FD_MPIO, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_MPIO, NULL, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -808,11 +840,16 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t H5_ATTR
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- /* Get the MPI communicator and info object from the property list */
- if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator")
- if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object")
+ if (H5FD_mpi_self_initialized) {
+ comm = MPI_COMM_WORLD;
+ }
+ else {
+ /* Get the MPI communicator and info object from the property list */
+ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator")
+ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object")
+ }
/* Get the MPI rank of this process and the total number of processes */
if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank)))
@@ -862,14 +899,19 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t H5_ATTR
file->mpi_size = mpi_size;
/* Only processor p0 will get the filesize and broadcast it. */
- if (mpi_rank == 0)
+ if (mpi_rank == 0) {
+ /* If MPI_File_get_size fails, broadcast file size as -1 to signal error */
if (MPI_SUCCESS != (mpi_code = MPI_File_get_size(fh, &file_size)))
- HMPI_GOTO_ERROR(NULL, "MPI_File_get_size failed", mpi_code)
+ file_size = (MPI_Offset)-1;
+ }
/* Broadcast file size */
if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&file_size, (int)sizeof(MPI_Offset), MPI_BYTE, 0, comm)))
HMPI_GOTO_ERROR(NULL, "MPI_Bcast failed", mpi_code)
+ if (file_size < 0)
+ HMPI_GOTO_ERROR(NULL, "MPI_File_get_size failed", mpi_code)
+
/* Determine if the file should be truncated */
if (file_size && (flags & H5F_ACC_TRUNC)) {
/* Truncate the file */
@@ -987,7 +1029,6 @@ H5FD__mpio_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out
*flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
*flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
*flags |= H5FD_FEAT_HAS_MPI; /* This driver uses MPI */
- *flags |= H5FD_FEAT_ALLOCATE_EARLY; /* Allocate space early instead of late */
*flags |= H5FD_FEAT_DEFAULT_VFD_COMPATIBLE; /* VFD creates a file which can be opened with the default
VFD */
} /* end if */
@@ -1165,6 +1206,7 @@ H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU
int n;
#endif
hbool_t use_view_this_time = FALSE;
+ hbool_t derived_type = FALSE;
hbool_t rank0_bcast = FALSE; /* If read-with-rank0-and-bcast flag was used */
#ifdef H5FDmpio_DEBUG
hbool_t H5FD_mpio_debug_t_flag = (H5FD_mpio_debug_flags_s[(int)'t'] && H5FD_MPIO_TRACE_THIS_RANK(file));
@@ -1192,8 +1234,6 @@ H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU
if (H5FD_mpi_haddr_to_MPIOff(addr, &mpi_off /*out*/) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off")
size_i = (int)size;
- if ((hsize_t)size_i != size)
- HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from size to size_i")
/* Only look for MPI views for raw data transfers */
if (type == H5FD_MEM_DRAW) {
@@ -1260,10 +1300,14 @@ H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU
rank0_bcast = TRUE;
/* Read on rank 0 Bcast to other ranks */
- if (file->mpi_rank == 0)
+ if (file->mpi_rank == 0) {
+ /* If MPI_File_read_at fails, push an error, but continue
+ * to participate in following MPI_Bcast */
if (MPI_SUCCESS !=
(mpi_code = MPI_File_read_at(file->f, mpi_off, buf, size_i, buf_type, &mpi_stat)))
- HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at failed", mpi_code)
+ HMPI_DONE_ERROR(FAIL, "MPI_File_read_at failed", mpi_code)
+ }
+
if (MPI_SUCCESS != (mpi_code = MPI_Bcast(buf, size_i, buf_type, 0, file->comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code)
} /* end if */
@@ -1293,6 +1337,21 @@ H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU
HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code)
} /* end if */
else {
+ if (size != (hsize_t)size_i) {
+ /* If HERE, then we need to work around the integer size limit
+ * of 2GB. The input size_t size variable cannot fit into an integer,
+ * but we can get around that limitation by creating a different datatype
+ * and then setting the integer size (or element count) to 1 when using
+ * the derived_type.
+ */
+
+ if (H5_mpio_create_large_type(size, 0, MPI_BYTE, &buf_type) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "can't create MPI-I/O datatype")
+
+ derived_type = TRUE;
+ size_i = 1;
+ }
+
#ifdef H5FDmpio_DEBUG
if (H5FD_mpio_debug_r_flag)
HDfprintf(stderr, "%s: (%d) doing MPI independent IO\n", __func__, file->mpi_rank);
@@ -1307,11 +1366,21 @@ H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU
if (!rank0_bcast || (rank0_bcast && file->mpi_rank == 0)) {
/* How many bytes were actually read? */
#if MPI_VERSION >= 3
- if (MPI_SUCCESS != (mpi_code = MPI_Get_elements_x(&mpi_stat, buf_type, &bytes_read)))
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_elements_x(&mpi_stat, buf_type, &bytes_read))) {
#else
- if (MPI_SUCCESS != (mpi_code = MPI_Get_elements(&mpi_stat, MPI_BYTE, &bytes_read)))
+ if (MPI_SUCCESS != (mpi_code = MPI_Get_elements(&mpi_stat, MPI_BYTE, &bytes_read))) {
#endif
- HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code)
+ if (rank0_bcast && file->mpi_rank == 0) {
+ /* If MPI_Get_elements(_x) fails for a rank 0 bcast strategy,
+ * push an error, but continue to participate in the following
+ * MPI_Bcast.
+ */
+ bytes_read = -1;
+ HMPI_DONE_ERROR(FAIL, "MPI_Get_elements failed", mpi_code)
+ }
+ else
+ HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code)
+ }
} /* end if */
/* If the rank0-bcast feature was used, broadcast the # of bytes read to
@@ -1345,8 +1414,8 @@ H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU
#ifdef H5FDmpio_DEBUG
if (H5FD_mpio_debug_r_flag)
- HDfprintf(stderr, "%s: (%d) mpi_off = %ld bytes_read = %lld\n", __func__, file->mpi_rank,
- (long)mpi_off, bytes_read);
+ HDfprintf(stderr, "%s: (%d) mpi_off = %ld bytes_read = %lld type = %s\n", __func__, file->mpi_rank,
+ (long)mpi_off, bytes_read, H5FD__mem_t_to_str(type));
#endif
/*
@@ -1356,6 +1425,9 @@ H5FD__mpio_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU
HDmemset((char *)buf + bytes_read, 0, (size_t)n);
done:
+ if (derived_type)
+ MPI_Type_free(&buf_type);
+
#ifdef H5FDmpio_DEBUG
if (H5FD_mpio_debug_t_flag)
HDfprintf(stderr, "%s: (%d) Leaving\n", __func__, file->mpi_rank);
@@ -1468,20 +1540,6 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, h
*/
mpi_off = 0;
} /* end if */
- else if (size != (hsize_t)size_i) {
- /* If HERE, then we need to work around the integer size limit
- * of 2GB. The input size_t size variable cannot fit into an integer,
- * but we can get around that limitation by creating a different datatype
- * and then setting the integer size (or element count) to 1 when using
- * the derived_type.
- */
-
- if (H5_mpio_create_large_type(size, 0, MPI_BYTE, &buf_type) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "can't create MPI-I/O datatype")
-
- derived_type = TRUE;
- size_i = 1;
- }
/* Write the data. */
if (use_view_this_time) {
@@ -1527,6 +1585,21 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, h
HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code)
} /* end if */
else {
+ if (size != (hsize_t)size_i) {
+ /* If HERE, then we need to work around the integer size limit
+ * of 2GB. The input size_t size variable cannot fit into an integer,
+ * but we can get around that limitation by creating a different datatype
+ * and then setting the integer size (or element count) to 1 when using
+ * the derived_type.
+ */
+
+ if (H5_mpio_create_large_type(size, 0, MPI_BYTE, &buf_type) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "can't create MPI-I/O datatype")
+
+ derived_type = TRUE;
+ size_i = 1;
+ }
+
#ifdef H5FDmpio_DEBUG
if (H5FD_mpio_debug_w_flag)
HDfprintf(stderr, "%s: (%d) doing MPI independent IO\n", __func__, file->mpi_rank);
@@ -1562,8 +1635,8 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, h
#ifdef H5FDmpio_DEBUG
if (H5FD_mpio_debug_w_flag)
- HDfprintf(stderr, "%s: (%d) mpi_off = %ld bytes_written = %lld\n", __func__, file->mpi_rank,
- (long)mpi_off, bytes_written);
+ HDfprintf(stderr, "%s: (%d) mpi_off = %ld bytes_written = %lld type = %s\n", __func__,
+ file->mpi_rank, (long)mpi_off, bytes_written, H5FD__mem_t_to_str(type));
#endif
/* Each process will keep track of its perceived EOF value locally, and
@@ -1701,17 +1774,19 @@ H5FD__mpio_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t H5_ATTR
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
/* Only processor p0 will get the filesize and broadcast it. */
- /* (Note that throwing an error here will cause non-rank 0 processes
- * to hang in following Bcast. -QAK, 3/17/2018)
- */
- if (0 == file->mpi_rank)
+ if (0 == file->mpi_rank) {
+ /* If MPI_File_get_size fails, broadcast file size as -1 to signal error */
if (MPI_SUCCESS != (mpi_code = MPI_File_get_size(file->f, &size)))
- HMPI_GOTO_ERROR(FAIL, "MPI_File_get_size failed", mpi_code)
+ size = (MPI_Offset)-1;
+ }
/* Broadcast file size */
if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&size, (int)sizeof(MPI_Offset), MPI_BYTE, 0, file->comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code)
+ if (size < 0)
+ HMPI_GOTO_ERROR(FAIL, "MPI_File_get_size failed", mpi_code)
+
if (H5FD_mpi_haddr_to_MPIOff(file->eoa, &needed_eof) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "cannot convert from haddr_t to MPI_Offset")
@@ -1774,11 +1849,16 @@ H5FD__mpio_delete(const char *filename, hid_t fapl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
HDassert(H5FD_MPIO == H5P_peek_driver(plist));
- /* Get the MPI communicator and info from the fapl */
- if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI info object")
- if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator")
+ if (H5FD_mpi_self_initialized) {
+ comm = MPI_COMM_WORLD;
+ }
+ else {
+ /* Get the MPI communicator and info from the fapl */
+ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI info object")
+ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator")
+ }
/* Get the MPI rank of this process */
if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank)))
@@ -1789,96 +1869,101 @@ H5FD__mpio_delete(const char *filename, hid_t fapl_id)
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
/* Delete the file */
- if (mpi_rank == 0)
+ if (mpi_rank == 0) {
+ /* If MPI_File_delete fails, push an error but
+ * still participate in the following MPI_Barrier
+ */
if (MPI_SUCCESS != (mpi_code = MPI_File_delete(filename, info)))
- HMPI_GOTO_ERROR(FAIL, "MPI_File_delete failed", mpi_code)
+ HMPI_DONE_ERROR(FAIL, "MPI_File_delete failed", mpi_code)
+ }
/* Set up a barrier (don't want processes to run ahead of the delete) */
if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code)
done:
+ /* Free duplicated MPI Communicator and Info objects */
+ if (H5_mpi_comm_free(&comm) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI communicator")
+ if (H5_mpi_info_free(&info) < 0)
+ HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI info object")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD__mpio_delete() */
/*-------------------------------------------------------------------------
- * Function: H5FD__mpio_mpi_rank
+ * Function: H5FD__mpio_ctl
*
- * Purpose: Returns the MPI rank for a process
+ * Purpose: MPIO version of the ctl callback.
*
- * Return: Success: non-negative
- * Failure: negative
+ * The desired operation is specified by the op_code
+ * parameter.
*
- * Programmer: Quincey Koziol
- * Thursday, May 16, 2002
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
*
- *-------------------------------------------------------------------------
- */
-static int
-H5FD__mpio_mpi_rank(const H5FD_t *_file)
-{
- const H5FD_mpio_t *file = (const H5FD_mpio_t *)_file;
-
- FUNC_ENTER_STATIC_NOERR
-
- /* Sanity checks */
- HDassert(file);
- HDassert(H5FD_MPIO == file->pub.driver_id);
-
- FUNC_LEAVE_NOAPI(file->mpi_rank)
-} /* end H5FD__mpio_mpi_rank() */
-
-/*-------------------------------------------------------------------------
- * Function: H5FD__mpio_mpi_size
+ * The input and output parameters allow op_code specific
+ * input and output
*
- * Purpose: Returns the number of MPI processes
+ * At present, the supported op codes are:
*
- * Return: Success: non-negative
- * Failure: negative
+ * H5FD_CTL__GET_MPI_COMMUNICATOR_OPCODE
+ * H5FD_CTL__GET_MPI_RANK_OPCODE
+ * H5FD_CTL__GET_MPI_SIZE_OPCODE
*
- * Programmer: Quincey Koziol
- * Thursday, May 16, 2002
+ * Note that these opcodes must be supported by all VFDs that
+ * support MPI.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: JRM -- 8/3/21
*
*-------------------------------------------------------------------------
*/
-static int
-H5FD__mpio_mpi_size(const H5FD_t *_file)
+static herr_t
+H5FD__mpio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input,
+ void **output)
{
- const H5FD_mpio_t *file = (const H5FD_mpio_t *)_file;
+ H5FD_mpio_t *file = (H5FD_mpio_t *)_file;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_NOERR
+ FUNC_ENTER_NOAPI(FAIL)
/* Sanity checks */
HDassert(file);
HDassert(H5FD_MPIO == file->pub.driver_id);
- FUNC_LEAVE_NOAPI(file->mpi_size)
-} /* end H5FD__mpio_mpi_size() */
+ switch (op_code) {
-/*-------------------------------------------------------------------------
- * Function: H5FD__mpio_communicator
- *
- * Purpose: Returns the MPI communicator for the file.
- *
- * Return: Success: The communicator
- * Failure: Can't fail
- *
- * Programmer: Robb Matzke
- * Monday, August 9, 1999
- *
- *-------------------------------------------------------------------------
- */
-static MPI_Comm
-H5FD__mpio_communicator(const H5FD_t *_file)
-{
- const H5FD_mpio_t *file = (const H5FD_mpio_t *)_file;
+ case H5FD_CTL__GET_MPI_COMMUNICATOR_OPCODE:
+ HDassert(output);
+ HDassert(*output);
+ **((MPI_Comm **)output) = file->comm;
+ break;
- FUNC_ENTER_STATIC_NOERR
+ case H5FD_CTL__GET_MPI_RANK_OPCODE:
+ HDassert(output);
+ HDassert(*output);
+ **((int **)output) = file->mpi_rank;
+ break;
- /* Sanity checks */
- HDassert(file);
- HDassert(H5FD_MPIO == file->pub.driver_id);
+ case H5FD_CTL__GET_MPI_SIZE_OPCODE:
+ HDassert(output);
+ HDassert(*output);
+ **((int **)output) = file->mpi_size;
+ break;
+
+ default: /* unknown op code */
+ if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) {
+
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown")
+ }
+ break;
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
- FUNC_LEAVE_NOAPI(file->comm)
-} /* end H5FD__mpio_communicator() */
+} /* end H5FD__mpio_ctl() */
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5FDmpio.h b/src/H5FDmpio.h
index 8caf11c..5ce98ca 100644
--- a/src/H5FDmpio.h
+++ b/src/H5FDmpio.h
@@ -23,7 +23,7 @@
/* Macros */
#ifdef H5_HAVE_PARALLEL
-#define H5FD_MPIO (H5FD_mpio_init())
+#define H5FD_MPIO (H5FDperform_init(H5FD_mpio_init))
#else
#define H5FD_MPIO (H5I_INVALID_HID)
#endif /* H5_HAVE_PARALLEL */
@@ -223,7 +223,7 @@ H5_DLL herr_t H5Pset_dxpl_mpio_collective_opt(hid_t dxpl_id, H5FD_mpio_collectiv
*
* Use of this function is optional.
*
- * \todo Add missing version information
+ * \since 1.8.0
*
*/
H5_DLL herr_t H5Pset_dxpl_mpio_chunk_opt(hid_t dxpl_id, H5FD_mpio_chunk_opt_t opt_mode);
@@ -247,7 +247,7 @@ H5_DLL herr_t H5Pset_dxpl_mpio_chunk_opt(hid_t dxpl_id, H5FD_mpio_chunk_opt_t op
* otherwise, a separate I/O process will be invoked for each chunk
* (multi-chunk I/O).
*
- * \todo Add missing version information
+ * \since 1.8.0
*
*/
H5_DLL herr_t H5Pset_dxpl_mpio_chunk_opt_num(hid_t dxpl_id, unsigned num_chunk_per_proc);
@@ -272,7 +272,7 @@ H5_DLL herr_t H5Pset_dxpl_mpio_chunk_opt_num(hid_t dxpl_id, unsigned num_chunk_p
* percent_proc_per_chunk, the library will do collective I/O for this
* chunk; otherwise, independent I/O will be done for the chunk.
*
- * \todo Add missing version information
+ * \since 1.8.0
*
*/
H5_DLL herr_t H5Pset_dxpl_mpio_chunk_opt_ratio(hid_t dxpl_id, unsigned percent_num_proc_per_chunk);
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index cae4174..d9a6ce9 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -135,8 +135,13 @@ typedef struct H5FD_multi_dxpl_t {
} H5FD_multi_dxpl_t;
/* Private functions */
-static int compute_next(H5FD_multi_t *file);
-static int open_members(H5FD_multi_t *file);
+static herr_t H5FD_split_populate_config(const char *meta_ext, hid_t meta_plist_id, const char *raw_ext,
+ hid_t raw_plist_id, hbool_t relax, H5FD_multi_fapl_t *fa_out);
+static herr_t H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl,
+ const char *const *memb_name, const haddr_t *memb_addr,
+ hbool_t relax, H5FD_multi_fapl_t *fa_out);
+static int compute_next(H5FD_multi_t *file);
+static int open_members(H5FD_multi_t *file);
/* Callback prototypes */
static herr_t H5FD_multi_term(void);
@@ -166,9 +171,12 @@ static herr_t H5FD_multi_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD_multi_lock(H5FD_t *_file, hbool_t rw);
static herr_t H5FD_multi_unlock(H5FD_t *_file);
static herr_t H5FD_multi_delete(const char *filename, hid_t fapl_id);
+static herr_t H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input,
+ void **output);
/* The class struct */
static const H5FD_class_t H5FD_multi_g = {
+ H5_VFD_MULTI, /* value */
"multi", /* name */
HADDR_MAX, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -201,6 +209,7 @@ static const H5FD_class_t H5FD_multi_g = {
H5FD_multi_lock, /* lock */
H5FD_multi_unlock, /* unlock */
H5FD_multi_delete, /* del */
+ H5FD_multi_ctl, /* ctl */
H5FD_FLMAP_DEFAULT /* fl_map */
};
@@ -271,74 +280,19 @@ herr_t
H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id, const char *raw_ext,
hid_t raw_plist_id)
{
- H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
- hid_t memb_fapl[H5FD_MEM_NTYPES];
- const char *memb_name[H5FD_MEM_NTYPES];
- char meta_name[H5FD_MULT_MAX_FILE_NAME_LEN];
- char raw_name[H5FD_MULT_MAX_FILE_NAME_LEN];
- haddr_t memb_addr[H5FD_MEM_NTYPES];
+ H5FD_multi_fapl_t fa;
+ static const char *func = "H5Pset_fapl_split"; /* Function Name for error reporting */
/*NO TRACE*/
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
- /* Initialize */
- ALL_MEMBERS (mt) {
- /* Treat global heap as raw data, not metadata */
- memb_map[mt] = ((mt == H5FD_MEM_DRAW || mt == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : H5FD_MEM_SUPER);
- memb_fapl[mt] = -1;
- memb_name[mt] = NULL;
- memb_addr[mt] = HADDR_UNDEF;
- }
- END_MEMBERS;
-
- /* The file access properties */
- memb_fapl[H5FD_MEM_SUPER] = meta_plist_id;
- memb_fapl[H5FD_MEM_DRAW] = raw_plist_id;
-
- /* The names */
- /* process meta filename */
- if (meta_ext) {
- if (strstr(meta_ext, "%s")) {
- /* Note: this doesn't accommodate for when the '%s' in the user's
- * string is at a position >sizeof(meta_name) - QK & JK - 2013/01/17
- */
- strncpy(meta_name, meta_ext, sizeof(meta_name));
- meta_name[sizeof(meta_name) - 1] = '\0';
- }
- else
- sprintf(meta_name, "%%s%s", meta_ext);
- }
- else {
- strncpy(meta_name, "%s.meta", sizeof(meta_name));
- meta_name[sizeof(meta_name) - 1] = '\0';
- }
- memb_name[H5FD_MEM_SUPER] = meta_name;
-
- /* process raw filename */
- if (raw_ext) {
- if (strstr(raw_ext, "%s")) {
- /* Note: this doesn't accommodate for when the '%s' in the user's
- * string is at a position >sizeof(raw_name) - QK & JK - 2013/01/17
- */
- strncpy(raw_name, raw_ext, sizeof(raw_name));
- raw_name[sizeof(raw_name) - 1] = '\0';
- }
- else
- sprintf(raw_name, "%%s%s", raw_ext);
- }
- else {
- strncpy(raw_name, "%s.raw", sizeof(raw_name));
- raw_name[sizeof(raw_name) - 1] = '\0';
- }
- memb_name[H5FD_MEM_DRAW] = raw_name;
-
- /* The sizes */
- memb_addr[H5FD_MEM_SUPER] = 0;
- memb_addr[H5FD_MEM_DRAW] = HADDR_MAX / 2;
+ if (H5FD_split_populate_config(meta_ext, meta_plist_id, raw_ext, raw_plist_id, TRUE, &fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't setup split driver configuration",
+ -1);
- return H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, TRUE);
+ return H5Pset_driver(fapl, H5FD_MULTI, &fa);
}
/*-------------------------------------------------------------------------
@@ -422,14 +376,7 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, const hid_t *memb_f
const char *const *memb_name, const haddr_t *memb_addr, hbool_t relax)
{
H5FD_multi_fapl_t fa;
- H5FD_mem_t mt, mmt;
- H5FD_mem_t _memb_map[H5FD_MEM_NTYPES];
- hid_t _memb_fapl[H5FD_MEM_NTYPES];
- char _memb_name[H5FD_MEM_NTYPES][16];
- const char * _memb_name_ptrs[H5FD_MEM_NTYPES];
- haddr_t _memb_addr[H5FD_MEM_NTYPES];
- static const char *letters = "Xsbrglo";
- static const char *func = "H5FDset_fapl_multi"; /* Function Name for error reporting */
+ static const char *func = "H5FDset_fapl_multi"; /* Function Name for error reporting */
/*NO TRACE*/
@@ -439,66 +386,9 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, const hid_t *memb_f
/* Check arguments and supply default values */
if (H5I_GENPROP_LST != H5Iget_type(fapl_id) || TRUE != H5Pisa_class(fapl_id, H5P_FILE_ACCESS))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "not an access list", -1);
- if (!memb_map) {
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
- _memb_map[mt] = H5FD_MEM_DEFAULT;
- memb_map = _memb_map;
- }
- if (!memb_fapl) {
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
- _memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
- memb_fapl = _memb_fapl;
- }
- if (!memb_name) {
- assert(strlen(letters) == H5FD_MEM_NTYPES);
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
- sprintf(_memb_name[mt], "%%s-%c.h5", letters[mt]);
- _memb_name_ptrs[mt] = _memb_name[mt];
- }
- memb_name = _memb_name_ptrs;
- }
- if (!memb_addr) {
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
- _memb_addr[mt] = (hsize_t)(mt ? (mt - 1) : 0) * (HADDR_MAX / (H5FD_MEM_NTYPES - 1));
- memb_addr = _memb_addr;
- }
-
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
- /* Map usage type */
- mmt = memb_map[mt];
- if (mmt < 0 || mmt >= H5FD_MEM_NTYPES)
- H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1);
- if (H5FD_MEM_DEFAULT == mmt)
- mmt = mt;
-
- /*
- * All members of MEMB_FAPL must be either defaults or actual file
- * access property lists.
- */
- if (H5P_DEFAULT != memb_fapl[mmt] && TRUE != H5Pisa_class(memb_fapl[mmt], H5P_FILE_ACCESS))
- H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1);
-
- /* All names must be defined */
- if (!memb_name[mmt] || !memb_name[mmt][0])
- H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1);
- }
-
- /*
- * Initialize driver specific information. No need to copy it into the FA
- * struct since all members will be copied by H5Pset_driver().
- */
- memset(&fa, 0, sizeof(H5FD_multi_fapl_t));
- memcpy(fa.memb_map, memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
- memcpy(fa.memb_fapl, memb_fapl, H5FD_MEM_NTYPES * sizeof(hid_t));
- memcpy(fa.memb_name, memb_name, H5FD_MEM_NTYPES * sizeof(char *));
- memcpy(fa.memb_addr, memb_addr, H5FD_MEM_NTYPES * sizeof(haddr_t));
- fa.relax = relax;
+ if (H5FD_multi_populate_config(memb_map, memb_fapl, memb_name, memb_addr, relax, &fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't setup driver configuration", -1);
- /* Patch up H5P_DEFAULT property lists for members */
- for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
- if (fa.memb_fapl[mt] == H5P_DEFAULT)
- fa.memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
- }
return H5Pset_driver(fapl_id, H5FD_MULTI, &fa);
}
@@ -523,6 +413,7 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl
char **memb_name /*out*/, haddr_t *memb_addr /*out*/, hbool_t *relax)
{
const H5FD_multi_fapl_t *fa;
+ H5FD_multi_fapl_t default_fa;
H5FD_mem_t mt;
static const char * func = "H5FDget_fapl_multi"; /* Function Name for error reporting */
@@ -535,8 +426,17 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not an access list", -1);
if (H5FD_MULTI != H5Pget_driver(fapl_id))
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "incorrect VFL driver", -1);
- if (NULL == (fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id)))
- H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "bad VFL driver info", -1);
+ H5E_BEGIN_TRY
+ {
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ }
+ H5E_END_TRY;
+ if (!fa || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) {
+ if (H5FD_multi_populate_config(NULL, NULL, NULL, NULL, TRUE, &default_fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup default driver configuration",
+ -1);
+ fa = &default_fa;
+ }
if (memb_map)
memcpy(memb_map, fa->memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
@@ -565,6 +465,231 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl
}
/*-------------------------------------------------------------------------
+ * Function: H5FD_split_populate_config
+ *
+ * Purpose: Populates a H5FD_multi_fapl_t structure with the provided
+ * split driver values, supplying defaults where values are not
+ * provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_split_populate_config(const char *meta_ext, hid_t meta_plist_id, const char *raw_ext, hid_t raw_plist_id,
+ hbool_t relax, H5FD_multi_fapl_t *fa_out)
+{
+ static const char *func = "H5FD_split_populate_config"; /* Function Name for error reporting */
+ static char
+ meta_name_g[H5FD_MULT_MAX_FILE_NAME_LEN]; /* Static scratch buffer to store metadata member name */
+ static char
+ raw_name_g[H5FD_MULT_MAX_FILE_NAME_LEN]; /* Static scratch buffer to store raw data member name */
+ const char *_memb_name[H5FD_MEM_NTYPES];
+ H5FD_mem_t _memb_map[H5FD_MEM_NTYPES];
+ hid_t _memb_fapl[H5FD_MEM_NTYPES];
+ haddr_t _memb_addr[H5FD_MEM_NTYPES];
+ herr_t ret_value = 0;
+
+ assert(fa_out);
+
+ /* Initialize */
+ ALL_MEMBERS (mt) {
+ /* Treat global heap as raw data, not metadata */
+ _memb_map[mt] = ((mt == H5FD_MEM_DRAW || mt == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : H5FD_MEM_SUPER);
+ _memb_fapl[mt] = H5P_DEFAULT;
+ _memb_name[mt] = NULL;
+ _memb_addr[mt] = HADDR_UNDEF;
+ }
+ END_MEMBERS;
+
+ /* The file access properties */
+ _memb_fapl[H5FD_MEM_SUPER] = meta_plist_id;
+ _memb_fapl[H5FD_MEM_DRAW] = raw_plist_id;
+
+ /* The names */
+ /* process meta filename */
+ if (meta_ext) {
+ if (strstr(meta_ext, "%s")) {
+ /* Note: this doesn't accommodate for when the '%s' in the user's
+ * string is at a position >sizeof(meta_name) - QK & JK - 2013/01/17
+ */
+ strncpy(meta_name_g, meta_ext, sizeof(meta_name_g));
+ meta_name_g[sizeof(meta_name_g) - 1] = '\0';
+ }
+ else
+ snprintf(meta_name_g, sizeof(meta_name_g), "%%s%s", meta_ext);
+ }
+ else {
+ strncpy(meta_name_g, "%s.meta", sizeof(meta_name_g));
+ meta_name_g[sizeof(meta_name_g) - 1] = '\0';
+ }
+ _memb_name[H5FD_MEM_SUPER] = meta_name_g;
+
+ /* process raw filename */
+ if (raw_ext) {
+ if (strstr(raw_ext, "%s")) {
+ /* Note: this doesn't accommodate for when the '%s' in the user's
+ * string is at a position >sizeof(raw_name) - QK & JK - 2013/01/17
+ */
+ strncpy(raw_name_g, raw_ext, sizeof(raw_name_g));
+ raw_name_g[sizeof(raw_name_g) - 1] = '\0';
+ }
+ else
+ snprintf(raw_name_g, sizeof(raw_name_g), "%%s%s", raw_ext);
+ }
+ else {
+ strncpy(raw_name_g, "%s.raw", sizeof(raw_name_g));
+ raw_name_g[sizeof(raw_name_g) - 1] = '\0';
+ }
+ _memb_name[H5FD_MEM_DRAW] = raw_name_g;
+
+ /* The sizes */
+ _memb_addr[H5FD_MEM_SUPER] = 0;
+ _memb_addr[H5FD_MEM_DRAW] = HADDR_MAX / 2;
+
+ ALL_MEMBERS (mt) {
+ /* Map usage type */
+ H5FD_mem_t mmt = _memb_map[mt];
+ if (mmt < 0 || mmt >= H5FD_MEM_NTYPES)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1);
+
+ /*
+ * All members of MEMB_FAPL must be either defaults or actual file
+ * access property lists.
+ */
+ if (H5P_DEFAULT != _memb_fapl[mmt] && TRUE != H5Pisa_class(_memb_fapl[mmt], H5P_FILE_ACCESS))
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1);
+
+ /* All names must be defined */
+ if (!_memb_name[mmt] || !_memb_name[mmt][0])
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1);
+ }
+ END_MEMBERS;
+
+ /*
+ * Initialize driver specific information. No need to copy it into the FA
+ * struct since all members will be copied by H5Pset_driver().
+ */
+ memset(fa_out, 0, sizeof(H5FD_multi_fapl_t));
+ memcpy(fa_out->memb_map, _memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
+ memcpy(fa_out->memb_fapl, _memb_fapl, H5FD_MEM_NTYPES * sizeof(hid_t));
+ memcpy(fa_out->memb_name, _memb_name, H5FD_MEM_NTYPES * sizeof(char *));
+ memcpy(fa_out->memb_addr, _memb_addr, H5FD_MEM_NTYPES * sizeof(haddr_t));
+ fa_out->relax = relax;
+
+ /* Patch up H5P_DEFAULT property lists for members */
+ ALL_MEMBERS (mt) {
+ if (fa_out->memb_fapl[mt] == H5P_DEFAULT) {
+ fa_out->memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
+ if (H5Pset_fapl_sec2(fa_out->memb_fapl[mt]) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET,
+ "can't set sec2 driver on member FAPL", -1);
+ }
+ }
+ END_MEMBERS;
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_populate_config
+ *
+ * Purpose: Populates a H5FD_multi_fapl_t structure with the provided
+ * values, supplying defaults where values are not provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl, const char *const *memb_name,
+ const haddr_t *memb_addr, hbool_t relax, H5FD_multi_fapl_t *fa_out)
+{
+ static const char *func = "H5FD_multi_populate_config"; /* Function Name for error reporting */
+ static const char *letters = "Xsbrglo";
+ static char _memb_name_g[H5FD_MEM_NTYPES][16]; /* Static scratch buffer to store member names */
+ H5FD_mem_t mt, mmt;
+ H5FD_mem_t _memb_map[H5FD_MEM_NTYPES];
+ hid_t _memb_fapl[H5FD_MEM_NTYPES];
+ const char * _memb_name_ptrs[H5FD_MEM_NTYPES];
+ haddr_t _memb_addr[H5FD_MEM_NTYPES];
+ herr_t ret_value = 0;
+
+ assert(fa_out);
+
+ if (!memb_map) {
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
+ _memb_map[mt] = H5FD_MEM_DEFAULT;
+ memb_map = _memb_map;
+ }
+ if (!memb_fapl) {
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ _memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
+ if (H5Pset_fapl_sec2(_memb_fapl[mt]) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET,
+ "can't set sec2 driver on member FAPL", -1);
+ }
+ memb_fapl = _memb_fapl;
+ }
+ if (!memb_name) {
+ assert(strlen(letters) == H5FD_MEM_NTYPES);
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ snprintf(_memb_name_g[mt], 16, "%%s-%c.h5", letters[mt]);
+ _memb_name_ptrs[mt] = _memb_name_g[mt];
+ }
+ memb_name = _memb_name_ptrs;
+ }
+ if (!memb_addr) {
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1))
+ _memb_addr[mt] = (hsize_t)(mt ? (mt - 1) : 0) * (HADDR_MAX / (H5FD_MEM_NTYPES - 1));
+ memb_addr = _memb_addr;
+ }
+
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ /* Map usage type */
+ mmt = memb_map[mt];
+ if (mmt < 0 || mmt >= H5FD_MEM_NTYPES)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1);
+ if (H5FD_MEM_DEFAULT == mmt)
+ mmt = mt;
+
+ /*
+ * All members of MEMB_FAPL must be either defaults or actual file
+ * access property lists.
+ */
+ if (H5P_DEFAULT != memb_fapl[mmt] && TRUE != H5Pisa_class(memb_fapl[mmt], H5P_FILE_ACCESS))
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1);
+
+ /* All names must be defined */
+ if (!memb_name[mmt] || !memb_name[mmt][0])
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1);
+ }
+
+ /*
+ * Initialize driver specific information. No need to copy it into the FA
+ * struct since all members will be copied by H5Pset_driver().
+ */
+ memset(fa_out, 0, sizeof(H5FD_multi_fapl_t));
+ memcpy(fa_out->memb_map, memb_map, H5FD_MEM_NTYPES * sizeof(H5FD_mem_t));
+ memcpy(fa_out->memb_fapl, memb_fapl, H5FD_MEM_NTYPES * sizeof(hid_t));
+ memcpy(fa_out->memb_name, memb_name, H5FD_MEM_NTYPES * sizeof(char *));
+ memcpy(fa_out->memb_addr, memb_addr, H5FD_MEM_NTYPES * sizeof(haddr_t));
+ fa_out->relax = relax;
+
+ /* Patch up H5P_DEFAULT property lists for members */
+ for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ if (fa_out->memb_fapl[mt] == H5P_DEFAULT) {
+ fa_out->memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS);
+ if (H5Pset_fapl_sec2(fa_out->memb_fapl[mt]) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET,
+ "can't set sec2 driver on member FAPL", -1);
+ }
+ }
+
+ return ret_value;
+} /* end H5FD_multi_populate_config() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD_multi_sb_size
*
* Purpose: Returns the size of the private information to be stored in
@@ -1009,12 +1134,26 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr
*/
if (NULL == (file = (H5FD_multi_t *)calloc((size_t)1, sizeof(H5FD_multi_t))))
H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL);
- if (H5P_FILE_ACCESS_DEFAULT == fapl_id || H5FD_MULTI != H5Pget_driver(fapl_id)) {
+ H5E_BEGIN_TRY
+ {
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ }
+ H5E_END_TRY;
+ if (!fa || (H5P_FILE_ACCESS_DEFAULT == fapl_id) || (H5FD_MULTI != H5Pget_driver(fapl_id))) {
+ char *env = getenv(HDF5_DRIVER);
+
close_fapl = fapl_id = H5Pcreate(H5P_FILE_ACCESS);
- if (H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, TRUE) < 0)
- H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error)
+ if (env && !strcmp(env, "split")) {
+ if (H5Pset_fapl_split(fapl_id, NULL, H5P_DEFAULT, NULL, H5P_DEFAULT) < 0)
+ H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error)
+ }
+ else {
+ if (H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, TRUE) < 0)
+ H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error)
+ }
+
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
}
- fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
assert(fa);
ALL_MEMBERS (mt) {
file->fa.memb_map[mt] = fa->memb_map[mt];
@@ -2037,6 +2176,7 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id)
char full_filename[H5FD_MULT_MAX_FILE_NAME_LEN];
int nchars;
const H5FD_multi_fapl_t *fa;
+ H5FD_multi_fapl_t default_fa;
static const char * func = "H5FD_multi_delete"; /* Function Name for error reporting */
/* Clear the error stack */
@@ -2044,11 +2184,26 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id)
assert(filename);
- /* Quiet compiler */
- (void)fapl_id;
-
/* Get the driver info */
- fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ H5E_BEGIN_TRY
+ {
+ fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id);
+ }
+ H5E_END_TRY;
+ if (!fa) {
+ char *env = getenv(HDF5_DRIVER);
+
+ if (env && !strcmp(env, "split")) {
+ if (H5FD_split_populate_config(NULL, H5P_DEFAULT, NULL, H5P_DEFAULT, TRUE, &default_fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", -1);
+ }
+ else {
+ if (H5FD_multi_populate_config(NULL, NULL, NULL, NULL, TRUE, &default_fa) < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", -1);
+ }
+
+ fa = &default_fa;
+ }
assert(fa);
/* Delete each member file using the underlying fapl */
@@ -2070,6 +2225,54 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id)
} /* end H5FD_multi_delete() */
H5_MULTI_GCC_DIAG_ON("format-nonliteral")
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_ctl
+ *
+ * Purpose: Multi VFD version of the ctl callback.
+ *
+ * The desired operation is specified by the op_code
+ * parameter.
+ *
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
+ *
+ * The input and output parameters allow op_code specific
+ * input and output
+ *
+ * At present, this VFD supports no op codes of its own.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, void **output)
+{
+ H5FD_multi_t * file = (H5FD_multi_t *)_file;
+ static const char *func = "H5FD_multi_ctl"; /* Function Name for error reporting */
+ herr_t ret_value = 0;
+
+ /* Silence compiler */
+ (void)file;
+ (void)input;
+ (void)output;
+
+ /* Clear the error stack */
+ H5Eclear2(H5E_DEFAULT);
+
+ switch (op_code) {
+ /* Unknown op code */
+ default:
+ if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_FCNTL,
+ "VFD ctl request failed (unknown op code and fail if unknown flag is set)", -1);
+
+ break;
+ }
+
+ return ret_value;
+} /* end H5FD_multi_ctl() */
+
#ifdef H5private_H
/*
* This is not related to the functionality of the driver code.
diff --git a/src/H5FDmulti.h b/src/H5FDmulti.h
index 62cc9c8..7a01f4c 100644
--- a/src/H5FDmulti.h
+++ b/src/H5FDmulti.h
@@ -20,7 +20,7 @@
#ifndef H5FDmulti_H
#define H5FDmulti_H
-#define H5FD_MULTI (H5FD_multi_init())
+#define H5FD_MULTI (H5FDperform_init(H5FD_multi_init))
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDperform.c b/src/H5FDperform.c
new file mode 100644
index 0000000..4a68c6e
--- /dev/null
+++ b/src/H5FDperform.c
@@ -0,0 +1,59 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5FDmodule.h" /* This source code file is part of the H5FD module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5CXprivate.h" /* API Contexts */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FDpkg.h" /* File Drivers */
+#include "H5Iprivate.h" /* IDs */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FDperform_init
+ *
+ * Purpose: Ensure that the library is initialized and then call
+ * the provided VFD initializer
+ *
+ * Return: Success: Identifier for the VFD just initialized
+ * Failure: H5I_INVALID_HID
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FDperform_init(H5FD_init_t op)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API_NOINIT
+ /*NO TRACE*/
+
+ /* It is possible that an application will evaluate an
+ * `H5FD_*` symbol (`H5FD_FAMILY`, `H5FD_MULTI`, `H5FD_SEC2`, etc.
+ * before the library has had an opportunity to initialize. Call
+ * H5_init_library() to make sure that the library has been initialized
+ * before `init` is run.
+ */
+ if (H5_init_library() < 0)
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, H5I_INVALID_HID, "library initialization failed")
+
+ ret_value = op();
+
+done:
+ FUNC_LEAVE_API_NOINIT(ret_value)
+}
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 7c0dd77..fa51574 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -88,7 +88,7 @@
*
* struct H5FD_vfd_swmr_idx_entry_t
*
- * Indicies into the VFD SWMR metadata file are maintained in arrays of
+ * Indices into the VFD SWMR metadata file are maintained in arrays of
* instances of H5FD_vfd_swmr_index_t.
*
* The fields of H5FD_vfd_swmr_idx_entry_t are discussed below.
@@ -182,7 +182,7 @@ typedef struct H5FD_vfd_swmr_idx_entry_t {
* tick_num: Sequence number of the current tick.
* Initialized to zero on file creation/open, and incremented
* by the VFD SWMR writer at the end of each tick.
- * num_entries: The number of entires in the index.
+ * num_entries: The number of entries in the index.
* entries: The array of index entries
*/
typedef struct H5FD_vfd_swmr_md_index {
@@ -220,8 +220,8 @@ typedef struct H5FD_vfd_swmr_md_header {
* is false.
*/
static inline H5FD_vfd_swmr_idx_entry_t *
-vfd_swmr_pageno_to_mdf_idx_entry(H5FD_vfd_swmr_idx_entry_t *idx, uint32_t nentries, uint64_t target_page,
- bool reuse_garbage)
+H5FD_vfd_swmr_pageno_to_mdf_idx_entry(H5FD_vfd_swmr_idx_entry_t *idx, uint32_t nentries, uint64_t target_page,
+ bool reuse_garbage)
{
uint32_t top;
uint32_t bottom;
@@ -259,13 +259,6 @@ vfd_swmr_pageno_to_mdf_idx_entry(H5FD_vfd_swmr_idx_entry_t *idx, uint32_t nentri
/* Definitions for file MPI type property */
#define H5FD_MPI_XFER_FILE_MPI_TYPE_NAME "H5FD_mpi_file_mpi_type"
-/* Sub-class the H5FD_class_t to add more specific functions for MPI-based VFDs */
-typedef struct H5FD_class_mpi_t {
- H5FD_class_t super; /* Superclass information & methods */
- int (*get_rank)(const H5FD_t *file); /* Get the MPI rank of a process */
- int (*get_size)(const H5FD_t *file); /* Get the MPI size of a communicator */
- MPI_Comm (*get_comm)(const H5FD_t *file); /* Get the communicator for a file */
-} H5FD_class_mpi_t;
#endif
/****************************/
@@ -302,12 +295,19 @@ typedef struct {
} \
}
-/* Define structure to hold driver ID & info for FAPLs */
+/* Define structure to hold driver ID, info & configuration string for FAPLs */
typedef struct {
- hid_t driver_id; /* Driver's ID */
- const void *driver_info; /* Driver info, for open callbacks */
+ hid_t driver_id; /* Driver's ID */
+ const void *driver_info; /* Driver info, for open callbacks */
+ const char *driver_config_str; /* Driver configuration string */
} H5FD_driver_prop_t;
+/* Which kind of VFD field to use for searching */
+typedef enum H5FD_get_driver_kind_t {
+ H5FD_GET_DRIVER_BY_NAME, /* Name field is set */
+ H5FD_GET_DRIVER_BY_VALUE /* Value field is set */
+} H5FD_get_driver_kind_t;
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -318,6 +318,7 @@ typedef struct {
/* Forward declarations for prototype arguments */
struct H5F_t;
+union H5PL_key_t;
H5_DLL int H5FD_term_interface(void);
H5_DLL herr_t H5FD_locate_signature(H5FD_t *file, haddr_t *sig_addr);
@@ -328,11 +329,18 @@ H5_DLL herr_t H5FD_sb_load(H5FD_t *file, const char *name, const uint8_t
H5_DLL void * H5FD_fapl_get(H5FD_t *file);
H5_DLL herr_t H5FD_free_driver_info(hid_t driver_id, const void *driver_info);
H5_DLL hid_t H5FD_register(const void *cls, size_t size, hbool_t app_ref);
+H5_DLL hid_t H5FD_register_driver_by_name(const char *name, hbool_t app_ref);
+H5_DLL hid_t H5FD_register_driver_by_value(H5FD_class_value_t value, hbool_t app_ref);
+H5_DLL htri_t H5FD_is_driver_registered_by_name(const char *driver_name, hid_t *registered_id);
+H5_DLL htri_t H5FD_is_driver_registered_by_value(H5FD_class_value_t driver_value, hid_t *registered_id);
+H5_DLL hid_t H5FD_get_driver_id_by_name(const char *name, hbool_t is_api);
+H5_DLL hid_t H5FD_get_driver_id_by_value(H5FD_class_value_t value, hbool_t is_api);
H5_DLL H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr);
-H5FD_t * H5FD_deduplicate(H5FD_t *, hid_t);
+H5FD_t * H5FD_deduplicate(H5FD_t *file, hid_t fapl_id);
H5_DLL herr_t H5FD_close(H5FD_t *file);
H5_DLL int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2);
H5_DLL herr_t H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags /*out*/);
+H5_DLL herr_t H5FD_check_plugin_load(const H5FD_class_t *cls, const union H5PL_key_t *key, hbool_t *success);
H5_DLL haddr_t H5FD_alloc(H5FD_t *file, H5FD_mem_t type, struct H5F_t *f, hsize_t size, haddr_t *frag_addr,
hsize_t *frag_size);
H5_DLL herr_t H5FD_free(H5FD_t *file, H5FD_mem_t type, struct H5F_t *f, haddr_t addr, hsize_t size);
@@ -352,21 +360,21 @@ H5_DLL herr_t H5FD_truncate(H5FD_t *file, hbool_t closing);
H5_DLL herr_t H5FD_lock(H5FD_t *file, hbool_t rw);
H5_DLL herr_t H5FD_unlock(H5FD_t *file);
H5_DLL herr_t H5FD_delete(const char *name, hid_t fapl_id);
+H5_DLL herr_t H5FD_ctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **output);
H5_DLL herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum);
H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void **file_handle);
H5_DLL herr_t H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr);
H5_DLL haddr_t H5FD_get_base_addr(const H5FD_t *file);
H5_DLL herr_t H5FD_set_paged_aggr(H5FD_t *file, hbool_t paged);
-H5_DLL herr_t H5FD_get_driver_name(const H5FD_t *file, char **driver_name);
+
+H5_DLL herr_t H5FD_init(void);
/* Function prototypes for VFD SWMR */
-H5_DLL int shadow_image_defer_free(struct H5F_shared_t *, const H5FD_vfd_swmr_idx_entry_t *);
H5_DLL herr_t H5FD_vfd_swmr_get_tick_and_idx(H5FD_t *_file, hbool_t read_index, uint64_t *tick_ptr,
uint32_t *num_entries_ptr, H5FD_vfd_swmr_idx_entry_t index[]);
-H5_DLL H5FD_vfd_swmr_idx_entry_t *vfd_swmr_enlarge_shadow_index(struct H5F_t *);
-H5_DLL void H5FD_vfd_swmr_dump_status(H5FD_t *, uint64_t);
-H5_DLL void H5FD_vfd_swmr_set_pb_configured(H5FD_t *_file);
-H5_DLL void H5FD_vfd_swmr_record_elapsed_ticks(H5FD_t *, uint64_t);
+H5_DLL void H5FD_vfd_swmr_dump_status(H5FD_t *file, uint64_t page);
+H5_DLL void H5FD_vfd_swmr_set_pb_configured(H5FD_t *_file);
+H5_DLL void H5FD_vfd_swmr_record_elapsed_ticks(H5FD_t *_file, uint64_t elapsed);
H5_DLL H5FD_t *H5FD_vfd_swmr_dedup(H5FD_t *_self, H5FD_t *_other, hid_t fapl_id);
/* Function prototypes for MPI based VFDs*/
@@ -382,9 +390,9 @@ H5_DLL herr_t H5FD_set_mpio_atomicity(H5FD_t *file, hbool_t flag);
H5_DLL herr_t H5FD_get_mpio_atomicity(H5FD_t *file, hbool_t *flag);
/* Driver specific methods */
-H5_DLL int H5FD_mpi_get_rank(const H5FD_t *file);
-H5_DLL int H5FD_mpi_get_size(const H5FD_t *file);
-H5_DLL MPI_Comm H5FD_mpi_get_comm(const H5FD_t *_file);
+H5_DLL int H5FD_mpi_get_rank(H5FD_t *file);
+H5_DLL int H5FD_mpi_get_size(H5FD_t *file);
+H5_DLL MPI_Comm H5FD_mpi_get_comm(H5FD_t *file);
#endif /* H5_HAVE_PARALLEL */
#endif /* H5FDprivate_H */
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index 0cfb072..a8d85c6 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -28,6 +28,40 @@
#define H5FD_VFD_DEFAULT 0 /* Default VFL driver value */
+/* VFD identifier values
+ * These are H5FD_class_value_t values, NOT hid_t values!
+ */
+#define H5_VFD_INVALID ((H5FD_class_value_t)(-1))
+#define H5_VFD_SEC2 ((H5FD_class_value_t)(0))
+#define H5_VFD_CORE ((H5FD_class_value_t)(1))
+#define H5_VFD_LOG ((H5FD_class_value_t)(2))
+#define H5_VFD_FAMILY ((H5FD_class_value_t)(3))
+#define H5_VFD_MULTI ((H5FD_class_value_t)(4))
+#define H5_VFD_STDIO ((H5FD_class_value_t)(5))
+#define H5_VFD_SPLITTER ((H5FD_class_value_t)(6))
+#ifdef H5_HAVE_PARALLEL
+#define H5_VFD_MPIO ((H5FD_class_value_t)(7))
+#endif
+#ifdef H5_HAVE_DIRECT
+#define H5_VFD_DIRECT ((H5FD_class_value_t)(8))
+#endif
+#ifdef H5_HAVE_MIRROR_VFD
+#define H5_VFD_MIRROR ((H5FD_class_value_t)(9))
+#endif
+#ifdef H5_HAVE_LIBHDFS
+#define H5_VFD_HDFS ((H5FD_class_value_t)(10))
+#endif
+#ifdef H5_HAVE_ROS3_VFD
+#define H5_VFD_ROS3 ((H5FD_class_value_t)(11))
+#endif
+#define H5_VFD_SWMR ((H5FD_class_value_t)(12))
+
+/* VFD IDs below this value are reserved for library use. */
+#define H5_VFD_RESERVED 256
+
+/* Maximum VFD ID */
+#define H5_VFD_MAX 65535
+
/* Define VFL driver features that can be enabled on a per-driver basis */
/* These are returned with the 'query' function pointer in H5FD_class_t */
/*
@@ -137,11 +171,103 @@
* enabled may be used as the Write-Only (W/O) channel driver.
*/
#define H5FD_FEAT_DEFAULT_VFD_COMPATIBLE 0x00008000
+/*
+ * Defining H5FD_FEAT_MEMMANAGE for a VFL driver means that
+ * the driver uses special memory management routines or wishes
+ * to do memory management in a specific manner. Therefore, HDF5
+ * should request that the driver handle any memory management
+ * operations when appropriate.
+ */
+#define H5FD_FEAT_MEMMANAGE 0x00010000
+
+/* ctl function definitions: */
+#define H5FD_CTL_OPC_RESERVED 512 /* Opcodes below this value are reserved for library use */
+#define H5FD_CTL_OPC_EXPER_MIN \
+ H5FD_CTL_OPC_RESERVED /* Minimum opcode value available for experimental use \
+ */
+#define H5FD_CTL_OPC_EXPER_MAX \
+ (H5FD_CTL_OPC_RESERVED + 511) /* Maximum opcode value available for experimental use */
+
+/* ctl function op codes: */
+#define H5FD_CTL__INVALID_OPCODE 0
+#define H5FD_CTL__TEST_OPCODE 1
+#define H5FD_CTL__GET_MPI_COMMUNICATOR_OPCODE 2
+#define H5FD_CTL__GET_MPI_RANK_OPCODE 3
+#define H5FD_CTL__GET_MPI_SIZE_OPCODE 4
+#define H5FD_CTL__MEM_ALLOC 5
+#define H5FD_CTL__MEM_FREE 6
+#define H5FD_CTL__MEM_COPY 7
+
+/* ctl function flags: */
+
+/* Definitions:
+ *
+ * WARNING: While the following definitions of Terminal
+ * and Passthrough VFDs should be workable for now, they
+ * have to be adjusted as our use cases for VFDs expand.
+ *
+ * JRM -- 8/4/21
+ *
+ *
+ * Terminal VFD: Lowest VFD in the VFD stack through
+ * which all VFD calls pass. Note that this definition
+ * is situational. For example, the sec2 VFD is typically
+ * terminal. However, in the context of the family file
+ * driver, it is not -- the family file driver is the
+ * bottom VFD through which all VFD calls pass, and thus
+ * it is terminal.
+ *
+ * Similarly, on the splitter VFD, a sec2 VFD on the
+ * R/W channel is terminal, but a sec2 VFD on the W/O
+ * channel is not.
+ *
+ *
+ * Pass through VFD: Any VFD that relays all VFD calls
+ * (with the possible exception of some non-I/O related
+ * calls) to underlying VFD(s).
+ */
+
+/* Unknown op codes should be ignored silently unless the
+ * H5FD_CTL__FAIL_IF_UNKNOWN_FLAG is set.
+ *
+ * On terminal VFDs, unknown op codes should generate an
+ * error unconditionally if this flag is set.
+ *
+ * On pass through VFDs, unknown op codes should be routed
+ * to the underlying VFD(s) as indicated by any routing
+ * flags. In the absence of such flags, the VFD should
+ * generate an error.
+ */
+#define H5FD_CTL__FAIL_IF_UNKNOWN_FLAG 0x0001
+
+/* The H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG is used only
+ * by non-ternminal VFDs, and only applies to unknown
+ * opcodes. (known op codes should be handled as
+ * appropriate.)
+ *
+ * If this flag is set for an unknown op code, that
+ * op code should be passed to the next VFD down
+ * the VFD stack en-route to the terminal VFD.
+ * If that VFD does not support the ctl call, the
+ * pass through VFD should fail or succeed as directed
+ * by the H5FD_CTL__FAIL_IF_UNKNOWN_FLAG.
+ */
+#define H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG 0x0002
/*******************/
/* Public Typedefs */
/*******************/
+/*
+ * File driver identifiers.
+ *
+ * Values 0 through 255 are for drivers defined by the HDF5 library.
+ * Values 256 through 511 are available for testing new drivers.
+ * Subsequent values should be obtained from the HDF5 development
+ * team at mailto:help@hdfgroup.org.
+ */
+typedef int H5FD_class_value_t;
+
/* Types of allocation requests: see H5Fpublic.h */
typedef enum H5F_mem_t H5FD_mem_t;
@@ -253,6 +379,19 @@ typedef struct {
} H5FD_file_image_callbacks_t;
//! <!-- [H5FD_file_image_callbacks_t_snip] -->
+/**
+ * Define structure to hold "ctl memory copy" parameters
+ */
+//! <!-- [H5FD_ctl_memcpy_args_t_snip] -->
+typedef struct H5FD_ctl_memcpy_args_t {
+ void * dstbuf; /**< Destination buffer */
+ hsize_t dst_off; /**< Offset within destination buffer */
+ const void *srcbuf; /**< Source buffer */
+ hsize_t src_off; /**< Offset within source buffer */
+ size_t len; /**< Length of data to copy from source buffer */
+} H5FD_ctl_memcpy_args_t;
+//! <!-- [H5FD_ctl_memcpy_args_t_snip] -->
+
/********************/
/* Public Variables */
/********************/
diff --git a/src/H5FDros3.c b/src/H5FDros3.c
index c0361f9..922dac5 100644
--- a/src/H5FDros3.c
+++ b/src/H5FDros3.c
@@ -237,6 +237,7 @@ static herr_t H5FD__ros3_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD__ros3_validate_config(const H5FD_ros3_fapl_t *fa);
static const H5FD_class_t H5FD_ros3_g = {
+ H5FD_ROS3_VALUE, /* value */
"ros3", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -269,6 +270,7 @@ static const H5FD_class_t H5FD_ros3_g = {
NULL, /* lock */
NULL, /* unlock */
NULL, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -276,31 +278,6 @@ static const H5FD_class_t H5FD_ros3_g = {
H5FL_DEFINE_STATIC(H5FD_ros3_t);
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initializes any interface-specific data or routines.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Jacob Smith 2017
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__init_package(void)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- if (H5FD_ros3_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize ros3 VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD__init_package() */
-
-/*-------------------------------------------------------------------------
* Function: H5FD_ros3_init
*
* Purpose: Initialize this driver by registering the driver with the
@@ -327,8 +304,12 @@ H5FD_ros3_init(void)
HDfprintf(stdout, "H5FD_ros3_init() called.\n");
#endif
- if (H5I_VFL != H5I_get_type(H5FD_ROS3_g))
+ if (H5I_VFL != H5I_get_type(H5FD_ROS3_g)) {
H5FD_ROS3_g = H5FD_register(&H5FD_ros3_g, sizeof(H5FD_class_t), FALSE);
+ if (H5I_INVALID_HID == H5FD_ROS3_g) {
+ HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register ros3");
+ }
+ }
#if ROS3_STATS
/* pre-compute statsbin boundaries
@@ -377,7 +358,7 @@ H5FD__ros3_term(void)
* Function: H5Pset_fapl_ros3
*
* Purpose: Modify the file access property list to use the H5FD_ROS3
- * driver defined in this source file. All driver specfic
+ * driver defined in this source file. All driver specific
* properties are passed in as a pointer to a suitably
* initialized instance of H5FD_ros3_fapl_t
*
@@ -410,7 +391,7 @@ H5Pset_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa)
if (FAIL == H5FD__ros3_validate_config(fa))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid ros3 config")
- ret_value = H5P_set_driver(plist, H5FD_ROS3, (void *)fa);
+ ret_value = H5P_set_driver(plist, H5FD_ROS3, (void *)fa, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -420,16 +401,16 @@ done:
* Function: H5FD__ros3_validate_config()
*
* Purpose: Test to see if the supplied instance of H5FD_ros3_fapl_t
- * contains internally consistant data. Return SUCCEED if so,
+ * contains internally consistent data. Return SUCCEED if so,
* and FAIL otherwise.
*
- * Note the difference between internally consistant and
+ * Note the difference between internally consistent and
* correct. As we will have to try to access the target
* object to determine whether the supplied data is correct,
- * we will settle for internal consistancy at this point
+ * we will settle for internal consistency at this point
*
* Return: SUCCEED if instance of H5FD_ros3_fapl_t contains internally
- * consistant data, FAIL otherwise.
+ * consistent data, FAIL otherwise.
*
* Programmer: Jacob Smith
* 9/10/17
diff --git a/src/H5FDros3.h b/src/H5FDros3.h
index 8e42ca2..4a623c4 100644
--- a/src/H5FDros3.h
+++ b/src/H5FDros3.h
@@ -22,9 +22,11 @@
#define H5FDros3_H
#ifdef H5_HAVE_ROS3_VFD
-#define H5FD_ROS3 (H5FD_ros3_init())
+#define H5FD_ROS3 (H5FDperform_init(H5FD_ros3_init))
+#define H5FD_ROS3_VALUE H5_VFD_ROS3
#else
-#define H5FD_ROS3 (H5I_INVALID_HID)
+#define H5FD_ROS3 (H5I_INVALID_HID)
+#define H5FD_ROS3_VALUE H5_VFD_INVALID
#endif /* H5_HAVE_ROS3_VFD */
#ifdef H5_HAVE_ROS3_VFD
diff --git a/src/H5FDs3comms.h b/src/H5FDs3comms.h
index da6a62d..b81bfae 100644
--- a/src/H5FDs3comms.h
+++ b/src/H5FDs3comms.h
@@ -179,7 +179,7 @@
* HTTP header fields, of particular use when composing an
* "S3 Canonical Request" for authentication.
*
- * - The creation of a Canoncial Request involves:
+ * - The creation of a Canonical Request involves:
* - convert field names to lower case
* - sort by this lower-case name
* - convert ": " name-value separator in HTTP string to ":"
@@ -459,7 +459,7 @@ typedef struct {
*
* Pointer to NULL-terminated string for "secret" access id to S3 resource.
*
- * Requred to authenticate.
+ * Required to authenticate.
*
* `signing_key` (unsigned char *)
*
@@ -470,7 +470,7 @@ typedef struct {
* which may be re-used for several (up to seven (7)) days from creation?
* Computed once upon file open.
*
- * Requred to authenticate.
+ * Required to authenticate.
*
*----------------------------------------------------------------------------
*/
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index d823e3c..46f5fd4 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -139,8 +139,11 @@ static herr_t H5FD__sec2_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
static herr_t H5FD__sec2_lock(H5FD_t *_file, hbool_t rw);
static herr_t H5FD__sec2_unlock(H5FD_t *_file);
static herr_t H5FD__sec2_delete(const char *filename, hid_t fapl_id);
+static herr_t H5FD__sec2_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input,
+ void **output);
static const H5FD_class_t H5FD_sec2_g = {
+ H5FD_SEC2_VALUE, /* value */
"sec2", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -173,6 +176,7 @@ static const H5FD_class_t H5FD_sec2_g = {
H5FD__sec2_lock, /* lock */
H5FD__sec2_unlock, /* unlock */
H5FD__sec2_delete, /* del */
+ H5FD__sec2_ctl, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -180,39 +184,6 @@ static const H5FD_class_t H5FD_sec2_g = {
H5FL_DEFINE_STATIC(H5FD_sec2_t);
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initializes any interface-specific data or routines.
- *
- * Return: Non-negative on success/Negative on failure
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__init_package(void)
-{
- char * lock_env_var = NULL; /* Environment variable pointer */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- /* Check the use disabled file locks environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
- if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
- ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
- else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
- ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
- else
- ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
-
- if (H5FD_sec2_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize sec2 VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
-/*-------------------------------------------------------------------------
* Function: H5FD_sec2_init
*
* Purpose: Initialize this driver by registering the driver with the
@@ -229,9 +200,19 @@ done:
hid_t
H5FD_sec2_init(void)
{
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ char *lock_env_var = NULL; /* Environment variable pointer */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+ FUNC_ENTER_NOAPI_NOERR
+
+ /* Check the use disabled file locks environment variable */
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
+ if (lock_env_var && !HDstrcmp(lock_env_var, "BEST_EFFORT"))
+ ignore_disabled_file_locks_s = TRUE; /* Override: Ignore disabled locks */
+ else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "1")))
+ ignore_disabled_file_locks_s = FALSE; /* Override: Don't ignore disabled locks */
+ else
+ ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */
if (H5I_VFL != H5I_get_type(H5FD_SEC2_g))
H5FD_SEC2_g = H5FD_register(&H5FD_sec2_g, sizeof(H5FD_class_t), FALSE);
@@ -239,7 +220,6 @@ H5FD_sec2_init(void)
/* Set return value */
ret_value = H5FD_SEC2_g;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_sec2_init() */
@@ -292,7 +272,7 @@ H5Pset_fapl_sec2(hid_t fapl_id)
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value = H5P_set_driver(plist, H5FD_SEC2, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_SEC2, NULL, NULL);
done:
FUNC_LEAVE_API(ret_value)
@@ -1068,3 +1048,47 @@ H5FD__sec2_delete(const char *filename, hid_t H5_ATTR_UNUSED fapl_id)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD__sec2_delete() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD__sec2_ctl
+ *
+ * Purpose: Sec2 VFD version of the ctl callback.
+ *
+ * The desired operation is specified by the op_code
+ * parameter.
+ *
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
+ *
+ * The input and output parameters allow op_code specific
+ * input and output
+ *
+ * At present, no op codes are supported by this VFD.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__sec2_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input,
+ void H5_ATTR_UNUSED **output)
+{
+ H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(file);
+
+ switch (op_code) {
+ /* Unknown op code */
+ default:
+ if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG)
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown flag is set")
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__sec2_ctl() */
diff --git a/src/H5FDsec2.h b/src/H5FDsec2.h
index 541ac71..df4d4d4 100644
--- a/src/H5FDsec2.h
+++ b/src/H5FDsec2.h
@@ -20,7 +20,8 @@
#ifndef H5FDsec2_H
#define H5FDsec2_H
-#define H5FD_SEC2 (H5FD_sec2_init())
+#define H5FD_SEC2 (H5FDperform_init(H5FD_sec2_init))
+#define H5FD_SEC2_VALUE H5_VFD_SEC2
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDspace.c b/src/H5FDspace.c
index de52dc3..48b06ba 100644
--- a/src/H5FDspace.c
+++ b/src/H5FDspace.c
@@ -148,7 +148,7 @@ H5FD__alloc_real(H5FD_t *file, H5FD_mem_t type, hsize_t size, haddr_t *frag_addr
FUNC_ENTER_PACKAGE
#ifdef H5FD_ALLOC_DEBUG
- HDfprintf(stderr, "%s: type = %u, size = %Hu\n", __func__, (unsigned)type, size);
+ HDfprintf(stderr, "%s: type = %u, size = %" PRIuHSIZE "\n", __func__, (unsigned)type, size);
#endif /* H5FD_ALLOC_DEBUG */
/* check args */
@@ -211,7 +211,7 @@ H5FD__alloc_real(H5FD_t *file, H5FD_mem_t type, hsize_t size, haddr_t *frag_addr
done:
#ifdef H5FD_ALLOC_DEBUG
- HDfprintf(stderr, "%s: ret_value = %a\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: ret_value = %" PRIuHADDR "\n", __func__, ret_value);
#endif /* H5FD_ALLOC_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD__alloc_real() */
@@ -287,7 +287,8 @@ H5FD__free_real(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
HDassert(size > 0);
#ifdef H5FD_ALLOC_DEBUG
- HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", __func__, (unsigned)type, addr, size);
+ HDfprintf(stderr, "%s: type = %u, addr = %" PRIuHADDR ", size = %" PRIuHSIZE "\n", __func__,
+ (unsigned)type, addr, size);
#endif /* H5FD_ALLOC_DEBUG */
/* Sanity checking */
@@ -317,11 +318,11 @@ H5FD__free_real(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
eoa = file->cls->get_eoa(file, type);
#ifdef H5FD_ALLOC_DEBUG
- HDfprintf(stderr, "%s: eoa = %a\n", __func__, eoa);
+ HDfprintf(stderr, "%s: eoa = %" PRIuHADDR "\n", __func__, eoa);
#endif /* H5FD_ALLOC_DEBUG */
if (eoa == (addr + size)) {
#ifdef H5FD_ALLOC_DEBUG
- HDfprintf(stderr, "%s: Reducing file size to = %a\n", __func__, addr);
+ HDfprintf(stderr, "%s: Reducing file size to = %" PRIuHADDR "\n", __func__, addr);
#endif /* H5FD_ALLOC_DEBUG */
if (file->cls->set_eoa(file, type, addr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "set end of space allocation request failed")
@@ -330,8 +331,8 @@ H5FD__free_real(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size)
else {
/* leak memory */
#ifdef H5FD_ALLOC_DEBUG
- HDfprintf(stderr, "%s: LEAKED MEMORY!!! type = %u, addr = %a, size = %Hu\n", __func__, (unsigned)type,
- addr, size);
+ HDfprintf(stderr, "%s: LEAKED MEMORY!!! type = %u, addr = %" PRIuHADDR ", size = %" PRIuHSIZE "\n",
+ __func__, (unsigned)type, addr, size);
#endif /* H5FD_ALLOC_DEBUG */
} /* end else */
diff --git a/src/H5FDsplitter.c b/src/H5FDsplitter.c
index 73c898a..509c18e 100644
--- a/src/H5FDsplitter.c
+++ b/src/H5FDsplitter.c
@@ -104,6 +104,10 @@ static int H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr);
/* Prototypes */
static herr_t H5FD__splitter_term(void);
+static herr_t H5FD__splitter_populate_config(H5FD_splitter_vfd_config_t *vfd_config,
+ H5FD_splitter_fapl_t * fapl_out);
+static herr_t H5FD__splitter_get_default_wo_path(char *new_path, size_t new_path_len,
+ const char *base_filename);
static hsize_t H5FD__splitter_sb_size(H5FD_t *_file);
static herr_t H5FD__splitter_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out*/);
static herr_t H5FD__splitter_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf);
@@ -129,8 +133,12 @@ static herr_t H5FD__splitter_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closin
static herr_t H5FD__splitter_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static herr_t H5FD__splitter_lock(H5FD_t *_file, hbool_t rw);
static herr_t H5FD__splitter_unlock(H5FD_t *_file);
+static herr_t H5FD__splitter_delete(const char *filename, hid_t fapl_id);
+static herr_t H5FD__splitter_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input,
+ void **output);
static const H5FD_class_t H5FD_splitter_g = {
+ H5FD_SPLITTER_VALUE, /* value */
"splitter", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -138,7 +146,7 @@ static const H5FD_class_t H5FD_splitter_g = {
H5FD__splitter_sb_size, /* sb_size */
H5FD__splitter_sb_encode, /* sb_encode */
H5FD__splitter_sb_decode, /* sb_decode */
- sizeof(H5FD_splitter_fapl_t), /* fapl_size */
+ sizeof(H5FD_splitter_fapl_t), /* fapl_size */
H5FD__splitter_fapl_get, /* fapl_get */
H5FD__splitter_fapl_copy, /* fapl_copy */
H5FD__splitter_fapl_free, /* fapl_free */
@@ -149,7 +157,7 @@ static const H5FD_class_t H5FD_splitter_g = {
H5FD__splitter_close, /* close */
H5FD__splitter_cmp, /* cmp */
H5FD__splitter_query, /* query */
- H5FD__splitter_get_type_map, /* get_type_map */
+ H5FD__splitter_get_type_map, /* get_type_map */
H5FD__splitter_alloc, /* alloc */
H5FD__splitter_free, /* free */
H5FD__splitter_get_eoa, /* get_eoa */
@@ -162,7 +170,8 @@ static const H5FD_class_t H5FD_splitter_g = {
H5FD__splitter_truncate, /* truncate */
H5FD__splitter_lock, /* lock */
H5FD__splitter_unlock, /* unlock */
- NULL, /* del */
+ H5FD__splitter_delete, /* del */
+ H5FD__splitter_ctl, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -173,30 +182,6 @@ H5FL_DEFINE_STATIC(H5FD_splitter_t);
H5FL_DEFINE_STATIC(H5FD_splitter_fapl_t);
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initializes any interface-specific data or routines.
- *
- * Return: SUCCEED/FAIL
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__init_package(void)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- H5FD_SPLITTER_LOG_CALL(__func__);
-
- if (H5FD_splitter_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize splitter VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
-/*-------------------------------------------------------------------------
* Function: H5FD_splitter_init
*
* Purpose: Initialize the splitter driver by registering it with the
@@ -211,7 +196,7 @@ H5FD_splitter_init(void)
{
hid_t ret_value = H5I_INVALID_HID;
- FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+ FUNC_ENTER_NOAPI_NOERR
H5FD_SPLITTER_LOG_CALL(__func__);
@@ -220,7 +205,6 @@ H5FD_splitter_init(void)
ret_value = H5FD_SPLITTER_g;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_splitter_init() */
@@ -309,57 +293,14 @@ H5Pset_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *vfd_config)
if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid property list")
- /* Make sure that the W/O channel supports write-only capability.
- * Some drivers (e.g. family or multi) do revision of the superblock
- * in-memory, causing problems in that channel.
- * Uses the feature flag H5FD_FEAT_DEFAULT_VFD_COMPATIBLE as the
- * determining attribute.
- */
- if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
- H5FD_class_t * wo_driver = NULL;
- H5FD_driver_prop_t wo_driver_prop;
- H5P_genplist_t * wo_plist_ptr = NULL;
- unsigned long wo_driver_flags = 0;
-
- wo_plist_ptr = (H5P_genplist_t *)H5I_object(vfd_config->wo_fapl_id);
- if (NULL == wo_plist_ptr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- if (H5P_peek(wo_plist_ptr, H5F_ACS_FILE_DRV_NAME, &wo_driver_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID & info")
- wo_driver = (H5FD_class_t *)H5I_object(wo_driver_prop.driver_id);
- if (NULL == wo_driver)
- HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver ID in file access property list")
- if (H5FD_driver_query(wo_driver, &wo_driver_flags) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't query VFD flags")
- if (0 == (H5FD_FEAT_DEFAULT_VFD_COMPATIBLE & wo_driver_flags))
- HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "unsuitable W/O driver")
- } /* end if W/O VFD is non-default */
-
info = H5FL_CALLOC(H5FD_splitter_fapl_t);
if (NULL == info)
HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
- info->ignore_wo_errs = vfd_config->ignore_wo_errs;
- HDstrncpy(info->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
- info->wo_path[H5FD_SPLITTER_PATH_MAX] = '\0';
- HDstrncpy(info->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX + 1);
- info->log_file_path[H5FD_SPLITTER_PATH_MAX] = '\0';
- info->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
- info->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
-
- /* Set non-default channel FAPL IDs in splitter configuration info */
- if (H5P_DEFAULT != vfd_config->rw_fapl_id) {
- if (FALSE == H5P_isa_class(vfd_config->rw_fapl_id, H5P_FILE_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
- info->rw_fapl_id = vfd_config->rw_fapl_id;
- }
- if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
- if (FALSE == H5P_isa_class(vfd_config->wo_fapl_id, H5P_FILE_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
- info->wo_fapl_id = vfd_config->wo_fapl_id;
- }
+ if (H5FD__splitter_populate_config(vfd_config, info) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't setup driver configuration")
- ret_value = H5P_set_driver(plist_ptr, H5FD_SPLITTER, info);
+ ret_value = H5P_set_driver(plist_ptr, H5FD_SPLITTER, info, NULL);
done:
if (info)
@@ -383,9 +324,10 @@ done:
herr_t
H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/)
{
- const H5FD_splitter_fapl_t *fapl_ptr = NULL;
- H5P_genplist_t * plist_ptr = NULL;
- herr_t ret_value = SUCCEED;
+ const H5FD_splitter_fapl_t *fapl_ptr = NULL;
+ H5FD_splitter_fapl_t * default_fapl = NULL;
+ H5P_genplist_t * plist_ptr = NULL;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "ix", fapl_id, config);
@@ -411,8 +353,14 @@ H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
if (H5FD_SPLITTER != H5P_peek_driver(plist_ptr))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
- if (NULL == (fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to get specific-driver info")
+ fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr);
+ if (NULL == fapl_ptr) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
+ fapl_ptr = default_fapl;
+ }
HDstrncpy(config->wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
HDstrncpy(config->log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1);
@@ -425,10 +373,188 @@ H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/)
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't copy W/O FAPL");
done:
+ if (default_fapl)
+ H5FL_FREE(H5FD_splitter_fapl_t, default_fapl);
+
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_fapl_splitter() */
/*-------------------------------------------------------------------------
+ * Function: H5FD__splitter_populate_config
+ *
+ * Purpose: Populates a H5FD_splitter_fapl_t structure with the provided
+ * values, supplying defaults where values are not provided.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__splitter_populate_config(H5FD_splitter_vfd_config_t *vfd_config, H5FD_splitter_fapl_t *fapl_out)
+{
+ H5P_genplist_t *def_plist;
+ H5P_genplist_t *plist;
+ hbool_t free_config = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(fapl_out);
+
+ HDmemset(fapl_out, 0, sizeof(H5FD_splitter_fapl_t));
+
+ if (!vfd_config) {
+ vfd_config = H5MM_calloc(sizeof(H5FD_splitter_vfd_config_t));
+ if (NULL == vfd_config)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
+
+ vfd_config->magic = H5FD_SPLITTER_MAGIC;
+ vfd_config->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION;
+ vfd_config->rw_fapl_id = H5P_DEFAULT;
+ vfd_config->wo_fapl_id = H5P_DEFAULT;
+
+ free_config = TRUE;
+ }
+
+ /* Make sure that the W/O channel supports write-only capability.
+ * Some drivers (e.g. family or multi) do revision of the superblock
+ * in-memory, causing problems in that channel.
+ * Uses the feature flag H5FD_FEAT_DEFAULT_VFD_COMPATIBLE as the
+ * determining attribute.
+ */
+ if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
+ H5FD_class_t * wo_driver = NULL;
+ H5FD_driver_prop_t wo_driver_prop;
+ H5P_genplist_t * wo_plist_ptr = NULL;
+ unsigned long wo_driver_flags = 0;
+
+ wo_plist_ptr = (H5P_genplist_t *)H5I_object(vfd_config->wo_fapl_id);
+ if (NULL == wo_plist_ptr)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_peek(wo_plist_ptr, H5F_ACS_FILE_DRV_NAME, &wo_driver_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID & info")
+ wo_driver = (H5FD_class_t *)H5I_object(wo_driver_prop.driver_id);
+ if (NULL == wo_driver)
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver ID in file access property list")
+ if (H5FD_driver_query(wo_driver, &wo_driver_flags) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't query VFD flags")
+ if (0 == (H5FD_FEAT_DEFAULT_VFD_COMPATIBLE & wo_driver_flags))
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "unsuitable W/O driver")
+ } /* end if W/O VFD is non-default */
+
+ fapl_out->ignore_wo_errs = vfd_config->ignore_wo_errs;
+ HDstrncpy(fapl_out->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
+ fapl_out->wo_path[H5FD_SPLITTER_PATH_MAX] = '\0';
+ HDstrncpy(fapl_out->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX + 1);
+ fapl_out->log_file_path[H5FD_SPLITTER_PATH_MAX] = '\0';
+ fapl_out->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
+ fapl_out->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */
+
+ if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+
+ /* Set non-default channel FAPL IDs in splitter configuration info */
+ if (H5P_DEFAULT != vfd_config->rw_fapl_id) {
+ if (FALSE == H5P_isa_class(vfd_config->rw_fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
+ fapl_out->rw_fapl_id = vfd_config->rw_fapl_id;
+ }
+ else {
+ /* Use copy of default file access property list for R/W channel FAPL ID.
+ * The Sec2 driver is explicitly set on the FAPL ID, as the default
+ * driver might have been replaced with the Splitter VFD, which
+ * would cause recursion badness.
+ */
+ if ((fapl_out->rw_fapl_id = H5P_copy_plist(def_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't copy property list")
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_out->rw_fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_set_driver_by_value(plist, H5_VFD_SEC2, NULL, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default driver on R/W channel FAPL")
+ }
+ if (H5P_DEFAULT != vfd_config->wo_fapl_id) {
+ if (FALSE == H5P_isa_class(vfd_config->wo_fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list")
+ fapl_out->wo_fapl_id = vfd_config->wo_fapl_id;
+ }
+ else {
+ /* Use copy of default file access property list for W/O channel FAPL ID.
+ * The Sec2 driver is explicitly set on the FAPL ID, as the default
+ * driver might have been replaced with the Splitter VFD, which
+ * would cause recursion badness.
+ */
+ if ((fapl_out->wo_fapl_id = H5P_copy_plist(def_plist, FALSE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't copy property list")
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_out->wo_fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (H5P_set_driver_by_value(plist, H5_VFD_SEC2, NULL, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default driver on R/W channel FAPL")
+ }
+
+done:
+ if (free_config && vfd_config)
+ H5MM_free(vfd_config);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__splitter_populate_config() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD__splitter_get_default_wo_path
+ *
+ * Purpose: Given a base filename, returns a default filename for the
+ * W/O channel file by appending '_wo' to the base file name.
+ *
+ * Return: Non-negative on Success/Negative on Failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__splitter_get_default_wo_path(char *new_path, size_t new_path_len, const char *base_filename)
+{
+ const char *suffix = "_wo";
+ size_t old_filename_len = 0;
+ char * file_extension = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(new_path);
+ HDassert(base_filename);
+
+ /* Check that output buffer can hold base filename + `_wo` suffix */
+ old_filename_len = HDstrlen(base_filename);
+ if (old_filename_len > H5FD_SPLITTER_PATH_MAX - HDstrlen(suffix) - 1)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "filename exceeds max length")
+
+ /* Determine if filename contains a ".h5" extension. */
+ if ((file_extension = HDstrstr(base_filename, ".h5"))) {
+ /* Insert the suffix between the filename and ".h5" extension. */
+ HDstrcpy(new_path, base_filename);
+ file_extension = HDstrstr(new_path, ".h5");
+ HDsprintf(file_extension, "%s%s", suffix, ".h5");
+ }
+ else if ((file_extension = HDstrrchr(base_filename, '.'))) {
+ char *new_extension_loc = NULL;
+
+ /* If the filename doesn't contain a ".h5" extension, but contains
+ * AN extension, just insert the suffix before that extension.
+ */
+ HDstrcpy(new_path, base_filename);
+ new_extension_loc = HDstrrchr(new_path, '.');
+ HDsprintf(new_extension_loc, "%s%s", suffix, file_extension);
+ }
+ else {
+ /* If the filename doesn't contain an extension at all, just insert
+ * the suffix at the end of the filename.
+ */
+ HDsnprintf(new_path, new_path_len, "%s%s", base_filename, suffix);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__splitter_get_default_wo_path() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD__splitter_flush
*
* Purpose: Flushes all data to disk for both channels.
@@ -655,10 +781,11 @@ done:
static H5FD_t *
H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, haddr_t maxaddr)
{
- H5FD_splitter_t * file_ptr = NULL; /* Splitter VFD info */
- const H5FD_splitter_fapl_t *fapl_ptr = NULL; /* Driver-specific property list */
- H5P_genplist_t * plist_ptr = NULL;
- H5FD_t * ret_value = NULL;
+ H5FD_splitter_t * file_ptr = NULL; /* Splitter VFD info */
+ const H5FD_splitter_fapl_t *fapl_ptr = NULL; /* Driver-specific property list */
+ H5FD_splitter_fapl_t * default_fapl = NULL;
+ H5P_genplist_t * plist_ptr = NULL;
+ H5FD_t * ret_value = NULL;
FUNC_ENTER_STATIC
@@ -671,8 +798,7 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
if (ADDR_OVERFLOW(maxaddr))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr")
- if ((H5P_FILE_ACCESS_DEFAULT == splitter_fapl_id) || (H5FD_SPLITTER != H5Pget_driver(splitter_fapl_id)))
- /* presupposes that H5P_FILE_ACCESS_DEFAULT is not a splitter */
+ if (H5FD_SPLITTER != H5Pget_driver(splitter_fapl_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "driver is not splitter")
file_ptr = (H5FD_splitter_t *)H5FL_CALLOC(H5FD_splitter_t);
@@ -686,8 +812,20 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha
if (NULL == plist_ptr)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr);
- if (NULL == fapl_ptr)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get VFL driver info")
+ if (NULL == fapl_ptr) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't initialize driver configuration info")
+
+ /* If W/O path is not set, use base filename with '_wo' suffix */
+ if (*default_fapl->wo_path == '\0')
+ if (H5FD__splitter_get_default_wo_path(default_fapl->wo_path, H5FD_SPLITTER_PATH_MAX + 1, name) <
+ 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't generate default filename for W/O channel")
+
+ fapl_ptr = default_fapl;
+ }
/* Copy simpler info */
HDstrncpy(file_ptr->fa.wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1);
@@ -723,6 +861,9 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha
ret_value = (H5FD_t *)file_ptr;
done:
+ if (default_fapl)
+ H5FL_FREE(H5FD_splitter_fapl_t, default_fapl);
+
if (NULL == ret_value) {
if (file_ptr) {
if (H5I_INVALID_HID != file_ptr->fa.rw_fapl_id)
@@ -1145,6 +1286,62 @@ done:
} /* end H5FD__splitter_unlock */
/*-------------------------------------------------------------------------
+ * Function: H5FD__splitter_ctl
+ *
+ * Purpose: Splitter VFD version of the ctl callback.
+ *
+ * The desired operation is specified by the op_code
+ * parameter.
+ *
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
+ *
+ * The input and output parameters allow op_code specific
+ * input and output
+ *
+ * At present, this VFD supports no op codes of its own and
+ * simply passes ctl calls on to the R/W channel VFD.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__splitter_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, void **output)
+{
+ H5FD_splitter_t *file = (H5FD_splitter_t *)_file;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(file);
+
+ switch (op_code) {
+ /* Unknown op code */
+ default:
+ if (flags & H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG) {
+ /* Pass ctl call down to R/W channel VFD */
+ if (H5FDctl(file->rw_file, op_code, flags, input, output) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "VFD ctl request failed")
+ }
+ else {
+ /* If no valid VFD routing flag is specified, fail for unknown op code
+ * if H5FD_CTL__FAIL_IF_UNKNOWN_FLAG flag is set.
+ */
+ if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG)
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL,
+ "VFD ctl request failed (unknown op code and fail if unknown flag is set)")
+ }
+
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD__splitter_ctl() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD__splitter_query
*
* Purpose: Set the flags that this VFL driver is capable of supporting.
@@ -1279,6 +1476,74 @@ done:
} /* end H5FD__splitter_free() */
/*-------------------------------------------------------------------------
+ * Function: H5FD__splitter_delete
+ *
+ * Purpose: Delete a file
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD__splitter_delete(const char *filename, hid_t fapl_id)
+{
+ const H5FD_splitter_fapl_t *fapl_ptr = NULL;
+ H5FD_splitter_fapl_t * default_fapl = NULL;
+ H5P_genplist_t * plist;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(filename);
+
+ /* Get the driver info */
+ if (H5P_FILE_ACCESS_DEFAULT == fapl_id) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
+
+ /* If W/O path is not set, use base filename with '_wo' suffix */
+ if (*default_fapl->wo_path == '\0')
+ if (H5FD__splitter_get_default_wo_path(default_fapl->wo_path, H5FD_SPLITTER_PATH_MAX + 1,
+ filename) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't generate default filename for W/O channel")
+
+ fapl_ptr = default_fapl;
+ }
+ else {
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+ if (NULL == (fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist))) {
+ if (NULL == (default_fapl = H5FL_CALLOC(H5FD_splitter_fapl_t)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL,
+ "unable to allocate file access property list struct")
+ if (H5FD__splitter_populate_config(NULL, default_fapl) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't initialize driver configuration info")
+
+ /* If W/O path is not set, use base filename with '_wo' suffix */
+ if (*default_fapl->wo_path == '\0')
+ if (H5FD__splitter_get_default_wo_path(default_fapl->wo_path, H5FD_SPLITTER_PATH_MAX + 1,
+ filename) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't generate default filename for W/O channel")
+
+ fapl_ptr = default_fapl;
+ }
+ }
+
+ if (H5FDdelete(filename, fapl_ptr->rw_fapl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete file")
+ if (H5FDdelete(fapl_ptr->wo_path, fapl_ptr->wo_fapl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "unable to delete W/O channel file")
+
+done:
+ if (default_fapl)
+ H5FL_FREE(H5FD_splitter_fapl_t, default_fapl);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+/*-------------------------------------------------------------------------
* Function: H5FD__splitter_log_error
*
* Purpose: Log an error from the W/O channel appropriately.
diff --git a/src/H5FDsplitter.h b/src/H5FDsplitter.h
index ee6e7c5..c8751c8 100644
--- a/src/H5FDsplitter.h
+++ b/src/H5FDsplitter.h
@@ -17,7 +17,8 @@
#ifndef H5FDsplitter_H
#define H5FDsplitter_H
-#define H5FD_SPLITTER (H5FD_splitter_init())
+#define H5FD_SPLITTER (H5FDperform_init(H5FD_splitter_init))
+#define H5FD_SPLITTER_VALUE H5_VFD_SPLITTER
/* The version of the H5FD_splitter_vfd_config_t structure used */
#define H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION 1
@@ -34,7 +35,7 @@
* Structure: H5FD_spliiter_vfd_config_t
*
* One-stop shopping for configuring a Splitter VFD (rather than many
- * paramaters passed into H5Pset/get functions).
+ * parameters passed into H5Pset/get functions).
*
* magic (int32_t)
* Semi-unique number, used to sanity-check that a given pointer is
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index 6631325..122379a 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -183,6 +183,7 @@ static herr_t H5FD_stdio_unlock(H5FD_t *_file);
static herr_t H5FD_stdio_delete(const char *filename, hid_t fapl_id);
static const H5FD_class_t H5FD_stdio_g = {
+ H5_VFD_STDIO, /* value */
"stdio", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -215,6 +216,7 @@ static const H5FD_class_t H5FD_stdio_g = {
H5FD_stdio_lock, /* lock */
H5FD_stdio_unlock, /* unlock */
H5FD_stdio_delete, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -242,7 +244,7 @@ H5FD_stdio_init(void)
H5Eclear2(H5E_DEFAULT);
/* Check the use disabled file locks environment variable */
- lock_env_var = getenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = getenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT"))
ignore_disabled_file_locks_s = 1; /* Override: Ignore disabled locks */
else if (lock_env_var && (!strcmp(lock_env_var, "TRUE") || !strcmp(lock_env_var, "1")))
diff --git a/src/H5FDstdio.h b/src/H5FDstdio.h
index 9db92ed..484c6ea 100644
--- a/src/H5FDstdio.h
+++ b/src/H5FDstdio.h
@@ -22,7 +22,7 @@
#include "H5Ipublic.h"
-#define H5FD_STDIO (H5FD_stdio_init())
+#define H5FD_STDIO (H5FDperform_init(H5FD_stdio_init))
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c
index 60812bd..c79a357 100644
--- a/src/H5FDvfd_swmr.c
+++ b/src/H5FDvfd_swmr.c
@@ -90,6 +90,7 @@ static htri_t H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, H5FD
static herr_t H5FD__vfd_swmr_load_hdr_and_idx(H5FD_vfd_swmr_t *, hbool_t);
static const H5FD_class_t H5FD_vfd_swmr_g = {
+ H5FD_VFD_SWMR_VALUE, /* value */
"vfd_swmr", /* name */
MAXADDR, /* maxaddr */
H5F_CLOSE_WEAK, /* fc_degree */
@@ -122,6 +123,7 @@ static const H5FD_class_t H5FD_vfd_swmr_g = {
H5FD__vfd_swmr_lock, /* lock */
H5FD__vfd_swmr_unlock, /* unlock */
NULL, /* del */
+ NULL, /* ctl */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
@@ -132,30 +134,6 @@ H5FL_DEFINE_STATIC(H5FD_vfd_swmr_t);
H5FL_SEQ_DEFINE(H5FD_vfd_swmr_idx_entry_t);
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initializes any interface-specific data or routines.
- *
-b
- * Return: Non-negative on success/Negative on failure
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD__init_package(void)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- if (H5FD_vfd_swmr_init() < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize swmr VFD")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FD__init_package() */
-
-/*-------------------------------------------------------------------------
* Function: H5FD_vfd_swmr_init
*
* Purpose: Initialize this driver by registering the driver with the
@@ -164,9 +142,6 @@ done:
* Return: Success: The driver ID for the VFD SWMR driver.
* Failure: Negative
*
- * Programmer: Robb Matzke
- * Thursday, July 29, 1999
- *
*-------------------------------------------------------------------------
*/
hid_t
@@ -174,7 +149,7 @@ H5FD_vfd_swmr_init(void)
{
hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
if (H5I_VFL != H5I_get_type(H5FD_VFD_SWMR_g))
H5FD_VFD_SWMR_g = H5FD_register(&H5FD_vfd_swmr_g, sizeof(H5FD_class_t), FALSE);
@@ -182,7 +157,6 @@ H5FD_vfd_swmr_init(void)
/* Set return value */
ret_value = H5FD_VFD_SWMR_g;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_vfd_swmr_init() */
@@ -193,9 +167,6 @@ done:
*
* Returns: SUCCEED (Can't fail)
*
- * Programmer: Quincey Koziol
- * Friday, Jan 30, 2004
- *
*---------------------------------------------------------------------------
*/
static herr_t
@@ -231,15 +202,22 @@ H5Pset_fapl_vfd_swmr(hid_t fapl_id)
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value = H5P_set_driver(plist, H5FD_VFD_SWMR, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_VFD_SWMR, NULL, NULL);
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pset_fapl_vfd_swmr() */
-/* Perform the reader-only aspects of opening in VFD SWMR mode:
- * initialize histogram of ticks spent in API calls, wait for the
- * shadow file to appear, load the header and index.
+/*-------------------------------------------------------------------------
+ * Function: H5FD__swmr_reader_open
+ *
+ * Purpose: Perform the reader-only aspects of opening in VFD SWMR mode:
+ * initialize histogram of ticks spent in API calls, wait for
+ * the shadow file to appear, load the header and index.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
*/
static herr_t
H5FD__swmr_reader_open(H5FD_vfd_swmr_t *file)
@@ -258,9 +236,9 @@ H5FD__swmr_reader_open(H5FD_vfd_swmr_t *file)
HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "could not allocate API elapsed ticks")
/* Retry on opening the metadata file */
- for (do_try = h5_retry_init(&retry, H5FD_VFD_SWMR_MD_FILE_RETRY_MAX, H5_RETRY_DEFAULT_MINIVAL,
+ for (do_try = H5_retry_init(&retry, H5FD_VFD_SWMR_MD_FILE_RETRY_MAX, H5_RETRY_DEFAULT_MINIVAL,
H5_RETRY_DEFAULT_MAXIVAL);
- do_try; do_try = h5_retry_next(&retry)) {
+ do_try; do_try = H5_retry_next(&retry)) {
if ((file->md_fd = HDopen(file->md_file_path, O_RDONLY)) >= 0)
break;
}
@@ -374,14 +352,23 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD__vfd_swmr_open() */
-/* Perform the reader-only aspects of closing in VFD SWMR mode: optionally
- * log and always release the histogram of ticks spent in API calls,
- * close the shadow file, release the shadow index.
+/*-------------------------------------------------------------------------
+ * Function: H5FD__swmr_reader_close
+ *
+ * Purpose: Perform the reader-only aspects of closing in VFD SWMR mode:
+ * optionally log and always release the histogram of ticks spent
+ * in API calls, close the shadow file, release the shadow index.
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
*/
-static void
+static herr_t
H5FD__swmr_reader_close(H5FD_vfd_swmr_t *file)
{
- vfd_swmr_reader_did_increase_tick_to(0);
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
if (file->api_elapsed_ticks != NULL)
H5MM_xfree(file->api_elapsed_ticks);
@@ -389,11 +376,14 @@ H5FD__swmr_reader_close(H5FD_vfd_swmr_t *file)
/* Close the metadata file */
if (file->md_fd >= 0 && HDclose(file->md_fd) < 0)
/* Push error, but keep going */
- HERROR(H5E_VFL, H5E_CANTCLOSEFILE, "unable to close the metadata file");
+ HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close the metadata file");
/* Free the index entries */
if (file->md_index.num_entries && file->md_index.entries)
file->md_index.entries = H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, file->md_index.entries);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
} /* end H5FD__swmr_reader_close() */
/*-------------------------------------------------------------------------
@@ -793,7 +783,7 @@ H5FD__vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id
/* Try finding the addr from the index */
target_page = addr / fs_page_size;
- entry = vfd_swmr_pageno_to_mdf_idx_entry(index, num_entries, target_page, FALSE);
+ entry = H5FD_vfd_swmr_pageno_to_mdf_idx_entry(index, num_entries, target_page, FALSE);
if (entry == NULL) {
/* Cannot find addr in index, read from the underlying hdf5 file */
@@ -1034,9 +1024,9 @@ H5FD__vfd_swmr_load_hdr_and_idx(H5FD_vfd_swmr_t *file, hbool_t open)
FUNC_ENTER_STATIC
- for (do_try = h5_retry_init(&retry, H5FD_VFD_SWMR_MD_LOAD_RETRY_MAX, H5_RETRY_ONE_SECOND / 10,
+ for (do_try = H5_retry_init(&retry, H5FD_VFD_SWMR_MD_LOAD_RETRY_MAX, H5_RETRY_ONE_SECOND / 10,
H5_RETRY_ONE_SECOND);
- do_try; do_try = h5_retry_next(&retry)) {
+ do_try; do_try = H5_retry_next(&retry)) {
/* Load and decode the header. Go around again on a temporary
* failure (FALSE). Bail on an irrecoverable failure (FAIL).
@@ -1193,7 +1183,8 @@ H5FD__vfd_swmr_header_deserialize(H5FD_vfd_swmr_t *file, H5FD_vfd_swmr_md_header
UINT32DECODE(p, md_header->fs_page_size);
UINT64DECODE(p, md_header->tick_num);
UINT64DECODE(p, md_header->index_offset);
- if ((index_length = uint64_decode(&p)) > SIZE_MAX)
+ UINT64DECODE(p, index_length);
+ if (index_length > SIZE_MAX)
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "index is too large to hold in core")
md_header->index_length = (size_t)index_length;
@@ -1204,13 +1195,6 @@ H5FD__vfd_swmr_header_deserialize(H5FD_vfd_swmr_t *file, H5FD_vfd_swmr_md_header
/* Sanity check */
HDassert((size_t)(p - image) <= H5FD_MD_HEADER_SIZE);
-#if 0 /* JRM */
- HDfprintf(stderr,
- "---read header ps/tick/idx_off/idx_len = %d / %lld / %lld / %lld\n",
- md_header->fs_page_size, md_header->tick_num,
- md_header->index_offset, md_header->index_length);
-#endif /* JRM */
-
ret_value = TRUE;
done:
@@ -1219,7 +1203,7 @@ done:
} /* H5FD__vfd_swmr_header_deserialize() */
-/*
+/*-------------------------------------------------------------------------
* Function: H5FD__vfd_swmr_index_deserialize()
*
* Purpose: Load and decode the index in the metadata file
@@ -1230,10 +1214,8 @@ done:
* --Decode the index entries if the tick number in the header and
* the index match
*
- * Return: Success: TRUE
- * Failure: FAIL
- * Retry: FALSE
- *
+ * Return: TRUE/FALSE/FAIL
+ *-------------------------------------------------------------------------
*/
static htri_t
H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, H5FD_vfd_swmr_md_index *md_index,
@@ -1343,12 +1325,6 @@ H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, H5FD_vfd_swmr_md_i
/* Sanity check */
HDassert((size_t)(p - image) <= md_header->index_length);
-#if 0 /* JRM */
- HDfprintf(stderr,
- " ---- read index tick/num_entries = %lld / %d \n",
- md_index->tick_num, md_index->num_entries);
-#endif /* JRM */
-
done:
if (image != NULL)
image = H5MM_xfree(image);
@@ -1379,8 +1355,7 @@ done:
* --Return tick_num, num_entries and index from the VFD's
* local copies.
*
- * Return: Success: SUCCEED
- * Failure: FAIL
+ * Return: SUCCEED/FAIL
*
* Programmer: Vailin Choi
*
@@ -1429,8 +1404,7 @@ done:
* Purpose: Dump a variety of information about the vfd swmr reader
* vfd to stderr for debugging purposes.
*
- * Return: Success: SUCCEED
- * Failure: FAIL
+ * Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
@@ -1513,7 +1487,6 @@ H5FD_vfd_swmr_set_pb_configured(H5FD_t *_file)
* Programmer: JRM -- 1/29/19
*
*-------------------------------------------------------------------------
- *
*/
void
H5FD_vfd_swmr_record_elapsed_ticks(H5FD_t *_file, uint64_t elapsed)
diff --git a/src/H5FDvfd_swmr.h b/src/H5FDvfd_swmr.h
index 20a6b96..dfd8d19 100644
--- a/src/H5FDvfd_swmr.h
+++ b/src/H5FDvfd_swmr.h
@@ -16,7 +16,8 @@
#ifndef H5FDvfd_swmr_H
#define H5FDvfd_swmr_H
-#define H5FD_VFD_SWMR (H5FD_vfd_swmr_init())
+#define H5FD_VFD_SWMR (H5FDperform_init(H5FD_vfd_swmr_init))
+#define H5FD_VFD_SWMR_VALUE H5_VFD_SWMR
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5FDvfd_swmr_instr.c b/src/H5FDvfd_swmr_instr.c
deleted file mode 100644
index ad4885a..0000000
--- a/src/H5FDvfd_swmr_instr.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by Akadio, Inc. *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-#include "H5private.h" /* H5_ATTR_UNUSED */
-#include "H5Fpublic.h"
-#include "H5FDvfd_swmr.h"
-
-/* vfd_swmr_writer_may_increase_tick_to() and
- * vfd_swmr_reader_did_increase_tick_to() are instrumentation points for
- * VFD SWMR tests to use to coordinate the tick-number increases
- * on a single writer with the progress of a single reader.
- *
- * This file provides the default, do-nothing implementations for both
- * instrumentation routines.
- *
- * A VFD SWMR writer calls vfd_swmr_writer_may_increase_tick_to() with the
- * increased tick number that it proposes, `tick_num`. The argument
- * `wait_for_reader` tells whether or not the writer can wait for the reader
- * before increasing its tick number. If `true`, then
- * vfd_swmr_writer_may_increase_tick_to() should
- * block until the reader is finished using the shadow-file content
- * from ticks `tick_num - max_lag` and before, returning `true`.
- * If `false`, then
- * vfd_swmr_writer_may_increase_tick_to() immediately return `true` if
- * the new tick number does permissible, otherwise `false`.
- *
- * After a VFD SWMR reader increases its tick number, it calls
- * vfd_swmr_reader_did_increase_tick_to() with the new tick number.
- *
- * The test programs test/vfd_swmr_zoo_{reader,writer} provide
- * their own vfd_swmr_writer_may_increase_tick_to() and
- * vfd_swmr_reader_did_increase_tick_to() implementations that override the
- * ones in the library. In the "zoo"
- * test (test/vfd_swmr_zoo_{reader,writer}), the reader and the writer
- * use a shared file to coordinate tick-number increases so that the writer
- * can call H5Fvfd_swmr_end_tick() to increase its tick number at an arbitrary
- * rate without outrunning the reader.
- */
-bool
-vfd_swmr_writer_may_increase_tick_to(uint64_t H5_ATTR_UNUSED tick_num, bool H5_ATTR_UNUSED wait_for_reader)
-{
- return true;
-}
-
-void
-vfd_swmr_reader_did_increase_tick_to(uint64_t H5_ATTR_UNUSED tick_num)
-{
- return;
-}
diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h
deleted file mode 100644
index f5cf484..0000000
--- a/src/H5FDvfd_swmr_private.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by Akadio, Inc. *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-#ifndef H5FDvfd_swmr_private_H
-#define H5FDvfd_swmr_private_H
-
-#include "H5queue.h" /* for TAILQ_* */
-
-/* Forward declaration */
-struct H5F_t;
-struct H5F_shared_t;
-struct H5FD_vfd_swmr_idx_entry_t;
-
-/*
- * struct eot_queue_entry_t
- *
- * This is the structure for an entry on the end-of-tick queue (EOT queue) of files
- * opened in either VFD SWMR write or VFD SWMR read mode. This queue is maintained
- * in increasing end of tick time order.
- * The structure contains all information required to determine whether the end
- * of tick has arrived for the specified file, and to initiate end of tick processing
- * if it has.
- *
- * The fields of eot_queue_entry_t are discussed below:
- *
- * vfd_swmr_file: Pointer to the instance of H5F_file_t containing the shared
- * fields of the associated file that has been opened in VFD SWMR mode
- * NOTE: for the time being use H5F_t instead of H5F_file_t
- *
- * vfd_swmr_writer: Boolean flag that is set to TRUE if the associated file
- * has been opened in VFD SWMR writer mode, and FALSE if it has been
- * opened in VFD SWMR reader mode.
- *
- * tick_num: Number of the current tick of the target file.
- *
- * end_of_tick: Expiration time of the current tick of the target file.
- *
- * link: Forward and backward linkage between the next element and the previous
- * element (or the queue head). Note that if there is a following entry,
- * `next`, then `next->end_of_tick` must be greater than or equal to
- * `end_of_tick`.
- */
-typedef struct eot_queue_entry {
- hbool_t vfd_swmr_writer;
- uint64_t tick_num;
- struct timespec end_of_tick;
- struct H5F_t * vfd_swmr_file; /* NOTE: for the time being use H5F_t instead H5F_shared_t */
- TAILQ_ENTRY(eot_queue_entry) link;
-} eot_queue_entry_t;
-
-H5_DLLVAR unsigned int vfd_swmr_api_entries_g;
-
-/* The head of the EOT queue */
-typedef TAILQ_HEAD(eot_queue, eot_queue_entry) eot_queue_t;
-
-H5_DLLVAR eot_queue_t eot_queue_g;
-
-/***************************************/
-/* Library-private Function Prototypes */
-/***************************************/
-
-H5_DLL herr_t H5F_vfd_swmr_init(struct H5F_t *f, hbool_t file_create);
-H5_DLL herr_t H5F_vfd_swmr_close_or_flush(struct H5F_t *f, hbool_t closing);
-H5_DLL herr_t H5F_update_vfd_swmr_metadata_file(struct H5F_t *f, uint32_t index_len,
- struct H5FD_vfd_swmr_idx_entry_t *index);
-H5_DLL herr_t H5F_vfd_swmr_writer__delay_write(struct H5F_shared_t *, uint64_t, uint64_t *);
-H5_DLL herr_t H5F_vfd_swmr_writer__prep_for_flush_or_close(struct H5F_t *f);
-herr_t H5F_vfd_swmr_process_eot_queue(hbool_t);
-H5_DLL herr_t H5F_vfd_swmr_writer_end_of_tick(struct H5F_t *f, hbool_t);
-H5_DLL herr_t H5F_vfd_swmr_writer__dump_index(struct H5F_shared_t *);
-H5_DLL herr_t H5F_vfd_swmr_reader_end_of_tick(struct H5F_t *f, hbool_t);
-
-H5_DLL herr_t H5F_vfd_swmr_remove_entry_eot(struct H5F_t *f);
-H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(struct H5F_t *f);
-H5_DLL void H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *);
-H5_DLL herr_t H5F_dump_eot_queue(void);
-
-#endif /* H5FDvfd_swmr_private_H */
diff --git a/src/H5FDwindows.c b/src/H5FDwindows.c
index 6ce33a7..fa3c05f 100644
--- a/src/H5FDwindows.c
+++ b/src/H5FDwindows.c
@@ -56,7 +56,7 @@ H5Pset_fapl_windows(hid_t fapl_id)
if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value = H5P_set_driver(plist, H5FD_WINDOWS, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_WINDOWS, NULL, NULL);
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5FL.c b/src/H5FL.c
index cb58868..a897a24 100644
--- a/src/H5FL.c
+++ b/src/H5FL.c
@@ -114,9 +114,6 @@ struct H5FL_fac_node_t {
struct H5FL_fac_node_t *next; /* Pointer to next block in free list */
};
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* The head of the list of factory things to garbage collect */
static H5FL_fac_gc_list_t H5FL_fac_gc_head = {0, NULL};
@@ -184,20 +181,15 @@ H5FL_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
/* Garbage collect any nodes on the free lists */
- (void)H5FL_garbage_coll();
-
- /* Shut down the various kinds of free lists */
- n += H5FL__reg_term();
- n += H5FL__fac_term_all();
- n += H5FL__arr_term();
- n += H5FL__blk_term();
+ (void)
+ H5FL_garbage_coll();
- /* Mark interface closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Shut down the various kinds of free lists */
+ n += H5FL__reg_term();
+ n += H5FL__fac_term_all();
+ n += H5FL__arr_term();
+ n += H5FL__blk_term();
#ifdef H5FL_TRACK
/* If we haven't freed all the allocated memory, dump out the list now */
@@ -1009,27 +1001,32 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block)
#ifdef H5FL_TRACK
{
- H5FL_track_t *trk = block = ((unsigned char *)block) - sizeof(H5FL_track_t);
+ unsigned char *block_ptr = ((unsigned char *)block) - sizeof(H5FL_track_t);
+ H5FL_track_t trk;
+
+ HDmemcpy(&trk, block_ptr, sizeof(H5FL_track_t));
/* Free tracking information about the allocation location */
- H5CS_close_stack(trk->stack);
+ H5CS_close_stack(trk.stack);
/* The 'func' & 'file' strings are statically allocated (by the compiler)
* and are not allocated, so there's no need to free them.
*/
- trk->file = NULL;
- trk->func = NULL;
+ trk.file = NULL;
+ trk.func = NULL;
/* Remove from "outstanding allocations" list */
- if (trk == H5FL_out_head_g) {
+ if ((void *)block_ptr == (void *)H5FL_out_head_g) {
H5FL_out_head_g = H5FL_out_head_g->next;
if (H5FL_out_head_g)
H5FL_out_head_g->prev = NULL;
} /* end if */
else {
- trk->prev->next = trk->next;
- if (trk->next)
- trk->next->prev = trk->prev;
+ trk.prev->next = trk.next;
+ if (trk.next)
+ trk.next->prev = trk.prev;
} /* end else */
+
+ HDmemcpy(block_ptr, &trk, sizeof(H5FL_track_t));
}
#endif /* H5FL_TRACK */
@@ -1128,25 +1125,30 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_
else {
#ifdef H5FL_TRACK
{
- H5FL_track_t *trk = (H5FL_track_t *)(((unsigned char *)block) - sizeof(H5FL_track_t));
+ unsigned char *block_ptr = ((unsigned char *)block) - sizeof(H5FL_track_t);
+ H5FL_track_t trk;
+
+ HDmemcpy(&trk, block_ptr, sizeof(H5FL_track_t));
/* Release previous tracking information */
- H5CS_close_stack(trk->stack);
+ H5CS_close_stack(trk.stack);
/* The 'func' & 'file' strings are statically allocated (by the compiler)
* and are not allocated, so there's no need to free them.
*/
- trk->file = NULL;
- trk->func = NULL;
+ trk.file = NULL;
+ trk.func = NULL;
/* Store new tracking information */
- trk->stack = H5CS_copy_stack();
- HDassert(trk->stack);
+ trk.stack = H5CS_copy_stack();
+ HDassert(trk.stack);
/* The 'call_func' & 'call_file' strings are statically allocated (by the compiler)
* there's no need to duplicate them.
*/
- trk->file = call_file;
- trk->func = call_func;
- trk->line = call_line;
+ trk.file = call_file;
+ trk.func = call_func;
+ trk.line = call_line;
+
+ HDmemcpy(block_ptr, &trk, sizeof(H5FL_track_t));
}
#endif /* H5FL_TRACK */
ret_value = block;
@@ -1434,10 +1436,42 @@ H5FL_arr_free(H5FL_arr_head_t *head, void *obj)
/* Make certain that the free list is initialized */
HDassert(head->init);
+#ifdef H5FL_TRACK
+ {
+ unsigned char *block_ptr = ((unsigned char *)obj) - sizeof(H5FL_track_t);
+ H5FL_track_t trk;
+
+ HDmemcpy(&trk, block_ptr, sizeof(H5FL_track_t));
+
+ /* Free tracking information about the allocation location */
+ H5CS_close_stack(trk.stack);
+ /* The 'func' & 'file' strings are statically allocated (by the compiler)
+ * and are not allocated, so there's no need to free them.
+ */
+ trk.file = NULL;
+ trk.func = NULL;
+
+ /* Remove from "outstanding allocations" list */
+ if ((void *)block_ptr == H5FL_out_head_g) {
+ H5FL_out_head_g = H5FL_out_head_g->next;
+ if (H5FL_out_head_g)
+ H5FL_out_head_g->prev = NULL;
+ } /* end if */
+ else {
+ trk.prev->next = trk.next;
+ if (trk.next)
+ trk.next->prev = trk.prev;
+ } /* end else */
+
+ HDmemcpy(block_ptr, &trk, sizeof(H5FL_track_t));
+ }
+#endif
+
/* Get the pointer to the info header in front of the block to free */
temp = (H5FL_arr_list_t *)((
void *)((unsigned char *)obj -
- sizeof(H5FL_arr_list_t))); /*lint !e826 Pointer-to-pointer cast is appropriate here */
+ (sizeof(H5FL_arr_list_t) +
+ H5FL_TRACK_SIZE))); /*lint !e826 Pointer-to-pointer cast is appropriate here */
/* Get the number of elements */
free_nelem = temp->nelem;
@@ -1490,7 +1524,7 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem)
+H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS)
{
H5FL_arr_list_t *new_obj; /* Pointer to the new free list node allocated */
size_t mem_size; /* Size of memory block being recycled */
@@ -1531,7 +1565,8 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem)
} /* end if */
/* Otherwise allocate a node */
else {
- if (NULL == (new_obj = (H5FL_arr_list_t *)H5FL__malloc(sizeof(H5FL_arr_list_t) + mem_size)))
+ if (NULL ==
+ (new_obj = (H5FL_arr_list_t *)H5FL__malloc(sizeof(H5FL_arr_list_t) + H5FL_TRACK_SIZE + mem_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Increment the number of blocks of this size */
@@ -1547,6 +1582,28 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem)
/* Get a pointer to the new block */
ret_value = ((char *)new_obj) + sizeof(H5FL_arr_list_t);
+#ifdef H5FL_TRACK
+ /* Copy allocation location information */
+ ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack();
+ HDassert(((H5FL_track_t *)ret_value)->stack);
+ /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler)
+ * there's no need to duplicate them.
+ */
+ ((H5FL_track_t *)ret_value)->file = call_file;
+ ((H5FL_track_t *)ret_value)->func = call_func;
+ ((H5FL_track_t *)ret_value)->line = call_line;
+
+ /* Add to "outstanding allocations" list */
+ ((H5FL_track_t *)ret_value)->prev = NULL;
+ ((H5FL_track_t *)ret_value)->next = H5FL_out_head_g;
+ if (H5FL_out_head_g)
+ H5FL_out_head_g->prev = (H5FL_track_t *)ret_value;
+ H5FL_out_head_g = (H5FL_track_t *)ret_value;
+
+ /* Adjust for allocation tracking information */
+ ret_value = ((unsigned char *)ret_value) + sizeof(H5FL_track_t);
+#endif
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FL_arr_malloc() */
@@ -1565,7 +1622,7 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem)
+H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS)
{
void *ret_value = NULL; /* Pointer to the block to return */
@@ -1576,7 +1633,7 @@ H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem)
HDassert(elem);
/* Allocate the array */
- if (NULL == (ret_value = H5FL_arr_malloc(head, elem)))
+ if (NULL == (ret_value = H5FL_arr_malloc(head, elem H5FL_TRACK_INFO_INT)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Clear to zeros */
@@ -1600,7 +1657,7 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem)
+H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PARAMS)
{
void *ret_value = NULL; /* Pointer to the block to return */
@@ -1612,7 +1669,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem)
/* Check if we are really allocating the object */
if (obj == NULL)
- ret_value = H5FL_arr_malloc(head, new_elem);
+ ret_value = H5FL_arr_malloc(head, new_elem H5FL_TRACK_INFO_INT);
else {
H5FL_arr_list_t *temp; /* Temp. ptr to the new free list node allocated */
@@ -1622,14 +1679,15 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem)
/* Get the pointer to the info header in front of the block to free */
temp = (H5FL_arr_list_t *)((
void *)((unsigned char *)obj -
- sizeof(H5FL_arr_list_t))); /*lint !e826 Pointer-to-pointer cast is appropriate here */
+ (sizeof(H5FL_arr_list_t) +
+ H5FL_TRACK_SIZE))); /*lint !e826 Pointer-to-pointer cast is appropriate here */
/* Check if the size is really changing */
if (temp->nelem != new_elem) {
size_t blk_size; /* Size of block */
/* Get the new array of objects */
- ret_value = H5FL_arr_malloc(head, new_elem);
+ ret_value = H5FL_arr_malloc(head, new_elem H5FL_TRACK_INFO_INT);
/* Copy the appropriate amount of elements */
blk_size = head->list_arr[MIN(temp->nelem, new_elem)].size;
@@ -1638,8 +1696,35 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem)
/* Free the old block */
H5FL_arr_free(head, obj);
} /* end if */
- else
+ else {
+#ifdef H5FL_TRACK
+ unsigned char *block_ptr = ((unsigned char *)obj) - sizeof(H5FL_track_t);
+ H5FL_track_t trk;
+
+ HDmemcpy(&trk, block_ptr, sizeof(H5FL_track_t));
+
+ /* Release previous tracking information */
+ H5CS_close_stack(trk.stack);
+ /* The 'func' & 'file' strings are statically allocated (by the compiler)
+ * and are not allocated, so there's no need to free them.
+ */
+ trk.file = NULL;
+ trk.func = NULL;
+
+ /* Store new tracking information */
+ trk.stack = H5CS_copy_stack();
+ HDassert(trk.stack);
+ /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler)
+ * there's no need to duplicate them.
+ */
+ trk.file = call_file;
+ trk.func = call_func;
+ trk.line = call_line;
+
+ HDmemcpy(block_ptr, &trk, sizeof(H5FL_track_t));
+#endif
ret_value = obj;
+ }
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h
index 381f977..8e9d0d4 100644
--- a/src/H5FLprivate.h
+++ b/src/H5FLprivate.h
@@ -50,6 +50,11 @@
*/
/* #define H5FL_TRACK */
#ifdef H5FL_TRACK
+
+#ifndef H5_HAVE_CODESTACK
+#error "Free list tracking requires code stack to be enabled"
+#endif
+
/* Macro for inclusion in the free list allocation calls */
#define H5FL_TRACK_INFO , __FILE__, __func__, __LINE__
@@ -148,8 +153,8 @@ typedef struct H5FL_reg_head_t {
typedef union H5FL_blk_list_t {
size_t size; /* Size of the page */
union H5FL_blk_list_t *next; /* Pointer to next block in free list */
- double unused1; /* Unused normally, just here for aligment */
- haddr_t unused2; /* Unused normally, just here for aligment */
+ double unused1; /* Unused normally, just here for alignment */
+ haddr_t unused2; /* Unused normally, just here for alignment */
} H5FL_blk_list_t;
/* Data structure for priority queue node of block free lists */
@@ -223,8 +228,8 @@ typedef struct H5FL_blk_head_t {
typedef union H5FL_arr_list_t {
union H5FL_arr_list_t *next; /* Pointer to next block in free list */
size_t nelem; /* Number of elements in this array */
- double unused1; /* Unused normally, just here for aligment */
- haddr_t unused2; /* Unused normally, just here for aligment */
+ double unused1; /* Unused normally, just here for alignment */
+ haddr_t unused2; /* Unused normally, just here for alignment */
} H5FL_arr_list_t;
/* Data structure for each size of array element */
@@ -273,16 +278,17 @@ typedef struct H5FL_arr_head_t {
#define H5FL_BARR_DEFINE_STATIC(b, t, m) static H5FL_ARR_DEFINE_COMMON(sizeof(b), t, m)
/* Allocate an array of type 't' */
-#define H5FL_ARR_MALLOC(t, elem) H5FL_arr_malloc(&(H5FL_ARR_NAME(t)), elem)
+#define H5FL_ARR_MALLOC(t, elem) H5FL_arr_malloc(&(H5FL_ARR_NAME(t)), elem H5FL_TRACK_INFO)
/* Allocate an array of type 't' and clear it to all zeros */
-#define H5FL_ARR_CALLOC(t, elem) H5FL_arr_calloc(&(H5FL_ARR_NAME(t)), elem)
+#define H5FL_ARR_CALLOC(t, elem) H5FL_arr_calloc(&(H5FL_ARR_NAME(t)), elem H5FL_TRACK_INFO)
/* Free an array of type 't' */
#define H5FL_ARR_FREE(t, obj) (t *)H5FL_arr_free(&(H5FL_ARR_NAME(t)), obj)
/* Re-allocate an array of type 't' */
-#define H5FL_ARR_REALLOC(t, obj, new_elem) H5FL_arr_realloc(&(H5FL_ARR_NAME(t)), obj, new_elem)
+#define H5FL_ARR_REALLOC(t, obj, new_elem) \
+ H5FL_arr_realloc(&(H5FL_ARR_NAME(t)), obj, new_elem H5FL_TRACK_INFO)
#else /* H5_NO_ARR_FREE_LISTS */
/* Common macro for H5FL_ARR_DEFINE & H5FL_ARR_DEFINE_STATIC (and H5FL_BARR variants) */
@@ -405,10 +411,10 @@ H5_DLL void *H5FL_reg_calloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS);
H5_DLL void *H5FL_reg_free(H5FL_reg_head_t *head, void *obj);
/* Array free lists */
-H5_DLL void *H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem);
-H5_DLL void *H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem);
+H5_DLL void *H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS);
+H5_DLL void *H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem H5FL_TRACK_PARAMS);
H5_DLL void *H5FL_arr_free(H5FL_arr_head_t *head, void *obj);
-H5_DLL void *H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem);
+H5_DLL void *H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, size_t new_elem H5FL_TRACK_PARAMS);
/* Sequence free lists */
H5_DLL void *H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS);
diff --git a/src/H5FS.c b/src/H5FS.c
index cb18ab3..3c259f4 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -61,9 +61,6 @@ static herr_t H5FS__sinfo_free_node_cb(void *item, void *key, void *op_data);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declare a free list to manage the H5FS_section_class_t sequence information */
H5FL_SEQ_DEFINE(H5FS_section_class_t);
@@ -146,7 +143,8 @@ H5FS_create(H5F_t *f, haddr_t *fs_addr, const H5FS_create_t *fs_create, uint16_t
/* Set the return value */
ret_value = fspace;
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: fspace = %p, fspace->addr = %a\n", __func__, fspace, fspace->addr);
+ HDfprintf(stderr, "%s: fspace = %p, fspace->addr = %" PRIuHADDR "\n", __func__, (void *)fspace,
+ fspace->addr);
#endif /* H5FS_DEBUG */
done:
@@ -155,7 +153,7 @@ done:
HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, NULL, "unable to destroy free space header")
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: Leaving, ret_value = %p\n", __func__, (void *)ret_value);
#endif /* H5FS_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_create() */
@@ -183,8 +181,8 @@ H5FS_open(H5F_t *f, haddr_t fs_addr, uint16_t nclasses, const H5FS_section_class
FUNC_ENTER_NOAPI(NULL)
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: Opening free space manager, fs_addr = %a, nclasses = %Zu\n", __func__, fs_addr,
- nclasses);
+ HDfprintf(stderr, "%s: Opening free space manager, fs_addr = %" PRIuHADDR ", nclasses = %Zu\n", __func__,
+ fs_addr, nclasses);
#endif /* H5FS_DEBUG */
/* Check arguments. */
@@ -204,10 +202,10 @@ H5FS_open(H5F_t *f, haddr_t fs_addr, uint16_t nclasses, const H5FS_section_class
(fspace = (H5FS_t *)H5AC_protect(f, H5AC_FSPACE_HDR, fs_addr, &cache_udata, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, NULL, "unable to load free space header")
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", __func__, fspace->sect_addr);
- HDfprintf(stderr, "%s: fspace->sect_size = %Hu\n", __func__, fspace->sect_size);
- HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu\n", __func__, fspace->alloc_sect_size);
- HDfprintf(stderr, "%s: fspace->sinfo = %p\n", __func__, fspace->sinfo);
+ HDfprintf(stderr, "%s: fspace->sect_addr = %" PRIuHADDR "\n", __func__, fspace->sect_addr);
+ HDfprintf(stderr, "%s: fspace->sect_size = %" PRIuHSIZE "\n", __func__, fspace->sect_size);
+ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %" PRIuHSIZE "\n", __func__, fspace->alloc_sect_size);
+ HDfprintf(stderr, "%s: fspace->sinfo = %p\n", __func__, (void *)fspace->sinfo);
HDfprintf(stderr, "%s: fspace->rc = %u\n", __func__, fspace->rc);
#endif /* H5FS_DEBUG */
@@ -251,7 +249,7 @@ H5FS_delete(H5F_t *f, haddr_t fs_addr)
FUNC_ENTER_NOAPI(FAIL)
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: Deleting free space manager, fs_addr = %a\n", __func__, fs_addr);
+ HDfprintf(stderr, "%s: Deleting free space manager, fs_addr = %" PRIuHADDR "\n", __func__, fs_addr);
#endif /* H5FS_DEBUG */
/* Check arguments. */
@@ -321,7 +319,7 @@ H5FS_delete(H5F_t *f, haddr_t fs_addr)
/* Delete serialized section storage, if there are any */
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", __func__, fspace->sect_addr);
+ HDfprintf(stderr, "%s: fspace->sect_addr = %" PRIuHADDR "\n", __func__, fspace->sect_addr);
#endif /* H5FS_DEBUG */
if (fspace->serial_sect_count > 0) {
unsigned sinfo_status = 0; /* Free space section info's status in the metadata cache */
@@ -407,8 +405,8 @@ H5FS_close(H5F_t *f, H5FS_t *fspace)
HDassert(f);
HDassert(fspace);
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->addr = %a, fspace->sinfo = %p\n", __func__, fspace,
- fspace->addr, fspace->sinfo);
+ HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->addr = %" PRIuHADDR ", fspace->sinfo = %p\n",
+ __func__, (void *)fspace, fspace->addr, (void *)fspace->sinfo);
#endif /* H5FS_DEBUG */
/* Check if section info is valid */
@@ -416,11 +414,12 @@ H5FS_close(H5F_t *f, H5FS_t *fspace)
if (fspace->sinfo) {
#ifdef H5FS_DEBUG
HDfprintf(stderr,
- "%s: fspace->tot_sect_count = %Hu, fspace->serial_sect_count = %Hu, fspace->sect_addr = "
- "%a, fspace->rc = %u\n",
+ "%s: fspace->tot_sect_count = %" PRIuHSIZE ", fspace->serial_sect_count = %" PRIuHSIZE
+ ", fspace->sect_addr = %" PRIuHADDR ", fspace->rc = %u\n",
__func__, fspace->tot_sect_count, fspace->serial_sect_count, fspace->sect_addr, fspace->rc);
- HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", __func__,
- fspace->alloc_sect_size, fspace->sect_size);
+ HDfprintf(stderr,
+ "%s: fspace->alloc_sect_size = %" PRIuHSIZE ", fspace->sect_size = %" PRIuHSIZE "\n",
+ __func__, fspace->alloc_sect_size, fspace->sect_size);
#endif /* H5FS_DEBUG */
/* If there are sections to serialize, update them */
/* (if the free space manager is persistent) */
@@ -711,7 +710,7 @@ H5FS__incr(H5FS_t *fspace)
FUNC_ENTER_PACKAGE
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", __func__, fspace->addr,
+ HDfprintf(stderr, "%s: Entering, fpace->addr = %" PRIuHADDR ", fspace->rc = %u\n", __func__, fspace->addr,
fspace->rc);
#endif /* H5FS_DEBUG */
@@ -751,7 +750,7 @@ H5FS__decr(H5FS_t *fspace)
FUNC_ENTER_PACKAGE
#ifdef H5FS_DEBUG
- HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", __func__, fspace->addr,
+ HDfprintf(stderr, "%s: Entering, fpace->addr = %" PRIuHADDR ", fspace->rc = %u\n", __func__, fspace->addr,
fspace->rc);
#endif /* H5FS_DEBUG */
diff --git a/src/H5FSint.c b/src/H5FSint.c
index 0ab975b..d7950ab 100644
--- a/src/H5FSint.c
+++ b/src/H5FSint.c
@@ -68,31 +68,6 @@
/*******************/
/*-------------------------------------------------------------------------
- * Function: H5FS_init
- *
- * Purpose: Initialize the interface in case it is unable to initialize
- * itself soon enough.
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Saturday, March 4, 2000
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5FS_init(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOERR
- /* FUNC_ENTER() does all the work */
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FS_init() */
-
-/*-------------------------------------------------------------------------
* Function: H5FS__create_flush_depend
*
* Purpose: Create a flush dependency between two data structure components
diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h
index 67983d3..679cb26 100644
--- a/src/H5FSprivate.h
+++ b/src/H5FSprivate.h
@@ -116,7 +116,7 @@ typedef struct H5FS_section_class_t {
const struct H5FS_section_class_t *, const uint8_t *, haddr_t, hsize_t,
unsigned *); /* Routine to deserialize a buffer into a "live" section */
htri_t (*can_merge)(const H5FS_section_info_t *, const H5FS_section_info_t *,
- void *); /* Routine to determine if two nodes are mergable */
+ void *); /* Routine to determine if two nodes are mergeable */
herr_t (*merge)(H5FS_section_info_t **, H5FS_section_info_t *, void *); /* Routine to merge two nodes */
htri_t (*can_shrink)(const H5FS_section_info_t *,
void *); /* Routine to determine if node can shrink container */
@@ -187,9 +187,6 @@ H5FL_SEQ_EXTERN(H5FS_section_class_t);
/* Library-private Function Prototypes */
/***************************************/
-/* Package initialization routine */
-H5_DLL herr_t H5FS_init(void);
-
/* Free space manager routines */
H5_DLL H5FS_t *H5FS_create(H5F_t *f, haddr_t *fs_addr, const H5FS_create_t *fs_create, uint16_t nclasses,
const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment,
diff --git a/src/H5FSsection.c b/src/H5FSsection.c
index d28358c..55f8a94 100644
--- a/src/H5FSsection.c
+++ b/src/H5FSsection.c
@@ -123,7 +123,7 @@ H5FS__sinfo_new(H5F_t *f, H5FS_t *fspace)
HDassert(f);
HDassert(fspace);
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: fspace->addr = %a\n", __func__, fspace->addr);
+ HDfprintf(stderr, "%s: fspace->addr = %" PRIuHADDR "\n", __func__, fspace->addr);
#endif /* H5FS_SINFO_DEBUG */
/* Allocate the free space header */
@@ -136,7 +136,7 @@ H5FS__sinfo_new(H5F_t *f, H5FS_t *fspace)
sinfo->sect_off_size = (fspace->max_sect_addr + 7) / 8;
sinfo->sect_len_size = H5VM_limit_enc_size((uint64_t)fspace->max_sect_size);
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: fspace->max_sect_size = %Hu\n", __func__, fspace->max_sect_size);
+ HDfprintf(stderr, "%s: fspace->max_sect_size = %" PRIuHSIZE "\n", __func__, fspace->max_sect_size);
HDfprintf(stderr, "%s: fspace->max_sect_addr = %u\n", __func__, fspace->max_sect_addr);
HDfprintf(stderr, "%s: sinfo->nbins = %u\n", __func__, sinfo->nbins);
HDfprintf(stderr, "%s: sinfo->sect_off_size = %u, sinfo->sect_len_size = %u\n", __func__,
@@ -200,10 +200,12 @@ H5FS__sinfo_lock(H5F_t *f, H5FS_t *fspace, unsigned accmode)
FUNC_ENTER_STATIC
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: Called, fspace->addr = %a, fspace->sinfo = %p, fspace->sect_addr = %a\n", __func__,
- fspace->addr, fspace->sinfo, fspace->sect_addr);
- HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", __func__,
- fspace->alloc_sect_size, fspace->sect_size);
+ HDfprintf(stderr,
+ "%s: Called, fspace->addr = %" PRIuHADDR ", fspace->sinfo = %p, fspace->sect_addr = %" PRIuHADDR
+ "\n",
+ __func__, fspace->addr, (void *)fspace->sinfo, fspace->sect_addr);
+ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %" PRIuHSIZE ", fspace->sect_size = %" PRIuHSIZE "\n",
+ __func__, fspace->alloc_sect_size, fspace->sect_size);
#endif /* H5FS_SINFO_DEBUG */
/* Check arguments. */
@@ -251,8 +253,8 @@ H5FS__sinfo_lock(H5F_t *f, H5FS_t *fspace, unsigned accmode)
HDassert(H5F_addr_defined(fspace->addr));
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: Reading in existing sections, fspace->sect_addr = %a\n", __func__,
- fspace->sect_addr);
+ HDfprintf(stderr, "%s: Reading in existing sections, fspace->sect_addr = %" PRIuHADDR "\n",
+ __func__, fspace->sect_addr);
#endif /* H5FS_SINFO_DEBUG */
/* Protect the free space sections */
cache_udata.f = f;
@@ -289,10 +291,12 @@ H5FS__sinfo_lock(H5F_t *f, H5FS_t *fspace, unsigned accmode)
done:
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: Leaving, fspace->addr = %a, fspace->sinfo = %p, fspace->sect_addr = %a\n",
- __func__, fspace->addr, fspace->sinfo, fspace->sect_addr);
- HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", __func__,
- fspace->alloc_sect_size, fspace->sect_size);
+ HDfprintf(stderr,
+ "%s: Leaving, fspace->addr = %" PRIuHADDR
+ ", fspace->sinfo = %p, fspace->sect_addr = %" PRIuHADDR "\n",
+ __func__, fspace->addr, (void *)fspace->sinfo, fspace->sect_addr);
+ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %" PRIuHSIZE ", fspace->sect_size = %" PRIuHSIZE "\n",
+ __func__, fspace->alloc_sect_size, fspace->sect_size);
#endif /* H5FS_SINFO_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS__sinfo_lock() */
@@ -331,14 +335,16 @@ H5FS__sinfo_unlock(H5F_t *f, H5FS_t *fspace, hbool_t modified)
FUNC_ENTER_STATIC
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: Called, modified = %t, fspace->addr = %a, fspace->sect_addr = %a\n", __func__,
- modified, fspace->addr, fspace->sect_addr);
+ HDfprintf(stderr,
+ "%s: Called, modified = %d, fspace->addr = %" PRIuHADDR ", fspace->sect_addr = %" PRIuHADDR
+ "\n",
+ __func__, modified, fspace->addr, fspace->sect_addr);
HDfprintf(
stderr,
- "%s: fspace->sinfo_lock_count = %u, fspace->sinfo_modified = %t, fspace->sinfo_protected = %t\n",
+ "%s: fspace->sinfo_lock_count = %u, fspace->sinfo_modified = %d, fspace->sinfo_protected = %d\n",
__func__, fspace->sinfo_lock_count, fspace->sinfo_modified, fspace->sinfo_protected);
- HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", __func__,
- fspace->alloc_sect_size, fspace->sect_size);
+ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %" PRIuHSIZE ", fspace->sect_size = %" PRIuHSIZE "\n",
+ __func__, fspace->alloc_sect_size, fspace->sect_size);
#endif /* H5FS_SINFO_DEBUG */
/* Check arguments. */
@@ -490,7 +496,8 @@ H5FS__sinfo_unlock(H5F_t *f, H5FS_t *fspace, hbool_t modified)
#ifdef H5FS_SINFO_DEBUG
HDfprintf(stderr,
- "%s: Freeing section info on disk, old_sect_addr = %a, old_alloc_sect_size = %Hu\n",
+ "%s: Freeing section info on disk, old_sect_addr = %" PRIuHADDR
+ ", old_alloc_sect_size = %" PRIuHSIZE "\n",
__func__, old_sect_addr, old_alloc_sect_size);
#endif /* H5FS_SINFO_DEBUG */
/* Release space for section info in file */
@@ -1343,7 +1350,8 @@ H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flag
FUNC_ENTER_NOAPI(FAIL)
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: *sect = {%a, %Hu, %u, %s}\n", __func__, sect->addr, sect->size, sect->type,
+ HDfprintf(stderr, "%s: *sect = {%" PRIuHADDR ", %" PRIuHSIZE ", %u, %s}\n", __func__, sect->addr,
+ sect->size, sect->type,
(sect->state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
#endif /* H5FS_SINFO_DEBUG */
@@ -1384,7 +1392,7 @@ H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flag
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list")
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: fspace->tot_space = %Hu\n", __func__, fspace->tot_space);
+ HDfprintf(stderr, "%s: fspace->tot_space = %" PRIuHSIZE "\n", __func__, fspace->tot_space);
#endif /* H5FS_SINFO_DEBUG */
/* Mark free space sections as changed */
/* (if adding sections while deserializing sections, don't set the flag) */
@@ -1429,8 +1437,8 @@ H5FS_sect_try_extend(H5F_t *f, H5FS_t *fspace, haddr_t addr, hsize_t size, hsize
FUNC_ENTER_NOAPI(FAIL)
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: addr = %a, size = %Hu, extra_requested = %hu\n", __func__, addr, size,
- extra_requested);
+ HDfprintf(stderr, "%s: addr = %" PRIuHADDR ", size = %" PRIuHSIZE ", extra_requested = %" PRIuHSIZE "\n",
+ __func__, addr, size, extra_requested);
#endif /* H5FS_SINFO_DEBUG */
/* Check arguments. */
@@ -1442,9 +1450,10 @@ H5FS_sect_try_extend(H5F_t *f, H5FS_t *fspace, haddr_t addr, hsize_t size, hsize
/* Check for any sections on free space list */
#ifdef H5FS_SINFO_DEBUG
- HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", __func__, fspace->tot_sect_count);
- HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", __func__, fspace->serial_sect_count);
- HDfprintf(stderr, "%s: fspace->ghost_sect_count = %Hu\n", __func__, fspace->ghost_sect_count);
+ HDfprintf(stderr, "%s: fspace->tot_sect_count = %" PRIuHSIZE "\n", __func__, fspace->tot_sect_count);
+ HDfprintf(stderr, "%s: fspace->serial_sect_count = %" PRIuHSIZE "\n", __func__,
+ fspace->serial_sect_count);
+ HDfprintf(stderr, "%s: fspace->ghost_sect_count = %" PRIuHSIZE "\n", __func__, fspace->ghost_sect_count);
#endif /* H5FS_SINFO_DEBUG */
if (fspace->tot_sect_count > 0) {
H5FS_section_info_t *sect; /* Temporary free space section */
@@ -2082,11 +2091,11 @@ H5FS_sect_change_class(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, uint
} /* end else */
} /* end if */
- /* Check if the section's class change will affect the mergable list */
+ /* Check if the section's class change will affect the mergeable list */
if ((old_cls->flags & H5FS_CLS_SEPAR_OBJ) != (new_cls->flags & H5FS_CLS_SEPAR_OBJ)) {
- hbool_t to_mergable; /* Flag if the section is changing to a mergable section */
+ hbool_t to_mergable; /* Flag if the section is changing to a mergeable section */
- /* Determine if this section is becoming mergable or is becoming separate */
+ /* Determine if this section is becoming mergeable or is becoming separate */
if (old_cls->flags & H5FS_CLS_SEPAR_OBJ)
to_mergable = TRUE;
else
diff --git a/src/H5Fcwfs.c b/src/H5Fcwfs.c
index d689737..43c8cf7 100644
--- a/src/H5Fcwfs.c
+++ b/src/H5Fcwfs.c
@@ -252,7 +252,7 @@ H5F_cwfs_advance_heap(H5F_t *f, H5HG_heap_t *heap, hbool_t add_heap)
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Check args */
HDassert(f);
@@ -272,7 +272,6 @@ H5F_cwfs_advance_heap(H5F_t *f, H5HG_heap_t *heap, hbool_t add_heap)
f->shared->cwfs[f->shared->ncwfs - 1] = heap;
} /* end if */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_cwfs_advance_heap() */
@@ -295,7 +294,7 @@ H5F_cwfs_remove_heap(H5F_shared_t *shared, H5HG_heap_t *heap)
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Check args */
HDassert(shared);
@@ -310,6 +309,5 @@ H5F_cwfs_remove_heap(H5F_shared_t *shared, H5HG_heap_t *heap)
} /* end if */
} /* end for */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_cwfs_remove_heap() */
diff --git a/src/H5Fefc.c b/src/H5Fefc.c
index 2d4eff2..2c7dd92 100644
--- a/src/H5Fefc.c
+++ b/src/H5Fefc.c
@@ -450,7 +450,7 @@ H5F__efc_release_real(H5F_efc_t *efc)
/* Sanity checks */
HDassert(efc);
- /* Lock the EFC to prevent manipulation of the EFC wile we are releasing it.
+ /* Lock the EFC to prevent manipulation of the EFC while we are releasing it.
* The EFC should never be locked when we enter this function because that
* would require a cycle, a cycle would necessarily invoke
* H5F__efc_try_close(), and that function checks the status of the lock
diff --git a/src/H5Fint.c b/src/H5Fint.c
index b80fd15..9909256 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -32,7 +32,6 @@
#include "H5Iprivate.h" /* IDs */
#include "H5Lprivate.h" /* Links */
#include "H5MFprivate.h" /* File memory management */
-#include "H5MVprivate.h" /* File memory management for VFD SWMR */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5SMprivate.h" /* Shared Object Header Messages */
@@ -92,9 +91,6 @@ static herr_t H5F__flush_phase2(H5F_t *f, hbool_t closing);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Based on the value of the HDF5_USE_FILE_LOCKING environment variable.
* TRUE/FALSE have obvious meanings. FAIL means the environment variable was
* not set, so the code should ignore it and use the fapl value instead.
@@ -139,29 +135,6 @@ H5F_init(void)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_init() */
-
-/*--------------------------------------------------------------------------
-NAME
- H5F__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5F__init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
-
---------------------------------------------------------------------------*/
-herr_t
-H5F__init_package(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
/* Initialize the ID group for the file IDs */
if (H5I_register_type(H5I_FILE_CLS) < 0)
@@ -173,7 +146,7 @@ H5F__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__init_package() */
+} /* end H5F_init() */
/*-------------------------------------------------------------------------
* Function: H5F_term_package
@@ -197,23 +170,17 @@ H5F_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- if (H5I_nmembers(H5I_FILE) > 0) {
- (void)H5I_clear_type(H5I_FILE, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
- else {
- /* Make certain we've cleaned up all the shared file objects */
- H5F_sfile_assert_num(0);
-
- /* Destroy the file object id group */
- n += (H5I_dec_type_ref(H5I_FILE) > 0);
+ if (H5I_nmembers(H5I_FILE) > 0) {
+ (void)H5I_clear_type(H5I_FILE, FALSE, FALSE);
+ n++; /*H5I*/
+ } /* end if */
+ else {
+ /* Make certain we've cleaned up all the shared file objects */
+ H5F_sfile_assert_num(0);
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end else */
- } /* end if */
+ /* Destroy the file object id group */
+ n += (H5I_dec_type_ref(H5I_FILE) > 0);
+ } /* end else */
FUNC_LEAVE_NOAPI(n)
} /* end H5F_term_package() */
@@ -278,7 +245,7 @@ H5F__parse_file_lock_env_var(htri_t *use_locks)
FUNC_ENTER_PACKAGE_NOERR
/* Check the file locking environment variable */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
+ lock_env_var = HDgetenv(HDF5_USE_FILE_LOCKING);
if (lock_env_var && (!HDstrcmp(lock_env_var, "FALSE") || !HDstrcmp(lock_env_var, "0")))
*use_locks = FALSE; /* Override: Never use locks */
else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "BEST_EFFORT") ||
@@ -430,7 +397,7 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
} /* end if */
if (H5P_set(new_plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, &(f->shared->vfd_swmr_config)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set VFD SWMR config")
#ifdef H5_HAVE_PARALLEL
if (H5P_set(new_plist, H5_COLL_MD_READ_FLAG_NAME, &(f->shared->coll_md_read)) < 0)
@@ -459,9 +426,10 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set initial metadata cache resize config.")
/* Prepare the driver property */
- driver_prop.driver_id = f->shared->lf->driver_id;
- driver_prop.driver_info = H5FD_fapl_get(f->shared->lf);
- driver_prop_copied = TRUE;
+ driver_prop.driver_id = f->shared->lf->driver_id;
+ driver_prop.driver_info = H5FD_fapl_get(f->shared->lf);
+ driver_prop.driver_config_str = H5P_peek_driver_config_str(old_plist);
+ driver_prop_copied = TRUE;
/* Set the driver property */
if (H5P_set(new_plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
@@ -1064,7 +1032,7 @@ H5F__is_hdf5(const char *name, hid_t fapl_id)
{
H5FD_t * file = NULL; /* Low-level file struct */
H5F_shared_t *shared = NULL; /* Shared part of file */
- haddr_t sig_addr = HADDR_UNDEF; /* Addess of hdf5 file signature */
+ haddr_t sig_addr = HADDR_UNDEF; /* Address of hdf5 file signature */
htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_PACKAGE
@@ -1161,7 +1129,7 @@ H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5F
/* Initialization for handling file space (for paged aggregation) */
f->shared->pgend_meta_thres = H5F_FILE_SPACE_PGEND_META_THRES;
- /* intialize point of no return */
+ /* initialize point of no return */
f->shared->point_of_no_return = FALSE;
/* Copy the file creation and file access property lists into the
@@ -1298,7 +1266,7 @@ H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5F
f->shared->read_attempts = H5F_METADATA_READ_ATTEMPTS;
}
- /* Determine the # of bins for metdata read retries */
+ /* Determine the # of bins for metadata read retries */
if (H5F_set_retries(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't set retries and retries_nbins")
@@ -1572,7 +1540,7 @@ H5F__dest(H5F_t *f, hbool_t flush)
/* If this is a VFD SWMR writer, prep for flush or close */
if ((f->shared->vfd_swmr) && (f->shared->vfd_swmr_writer) &&
- (H5F_vfd_swmr_writer__prep_for_flush_or_close(f) < 0))
+ (H5F_vfd_swmr_writer_prep_for_flush_or_close(f) < 0))
/* Push error, but keep going*/
HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "vfd swmr prep for flush or close failed")
@@ -1874,7 +1842,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* When configured with VFD SWMR */
if (vfd_swmr_config_ptr->version) {
- /* Verify that file access flags are consistent with VFD SWMR configuartion */
+ /* Verify that file access flags are consistent with VFD SWMR configuration */
if ((flags & H5F_ACC_RDWR) && !vfd_swmr_config_ptr->writer)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "file access is writer but VFD SWMR config is reader")
if ((flags & H5F_ACC_RDWR) == 0 && vfd_swmr_config_ptr->writer)
@@ -1910,7 +1878,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
* or creating it) so we can compare it with files that are already
* open. If that fails then we try again with the full set of flags
* (only if they're different than the original failed attempt).
- * However, if the file driver can't distinquish between files then
+ * However, if the file driver can't distinguish between files then
* there's no reason to open the file tentatively because it's the
* application's responsibility to prevent this situation (there's no
* way for us to detect it here anyway).
@@ -2020,8 +1988,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Short cuts */
shared = file->shared;
-
- lf = shared->lf;
+ lf = shared->lf;
/* Set the file locking flag. If the file is already open, the file
* requested file locking flag must match that of the open file.
@@ -2102,7 +2069,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
if (H5F_VFD_SWMR_CONFIG(file)) {
/* Set up the VFD SWMR LOG file */
- /* Kent*/
if (HDstrlen(vfd_swmr_config_ptr->log_file_path) > 0)
shared->vfd_swmr_log_on = TRUE;
if (TRUE == shared->vfd_swmr_log_on) {
@@ -2114,7 +2080,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
if (H5_timer_start(&(shared->vfd_swmr_log_start_time)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't obtain the time from the HDF5 timer.")
}
- /* End of Kent */
/* Initialization for VFD SWMR writer and reader */
if (1 == shared->nrefs) {
@@ -2237,14 +2202,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Success */
ret_value = file;
-#if 1 /*Kent: write to the log file when H5F_open ends. Tested, can be commented out if necessary.*/
+ /* Write to the log file when H5F_open ends.
+ * TODO: Tested, can be commented out if necessary.
+ */
H5F_POST_VFD_SWMR_LOG_ENTRY(file, FILE_OPEN, "File open ends");
-#endif
+
done:
if ((NULL == ret_value) && file) {
if (file->shared->root_grp && file->shared->nrefs == 1) {
- if (H5AC_expunge_tag_type_metadata(file, H5G_oloc(file->shared->root_grp)->addr, H5AC_OHDR_ID,
- H5AC__NO_FLAGS_SET, FALSE) < 0)
+ if (H5AC_expunge_all_tagged_metadata(file, H5G_oloc(file->shared->root_grp)->addr, H5AC_OHDR_ID,
+ H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTEXPUNGE, NULL, "unable to expunge root group tagged entries")
}
@@ -2390,7 +2357,7 @@ H5F__flush_phase2(H5F_t *f, hbool_t closing)
/* If this is a VFD SWMR writer, prep for flush or close */
if ((f->shared->vfd_swmr) && (f->shared->vfd_swmr_writer) &&
- (H5F_vfd_swmr_writer__prep_for_flush_or_close(f) < 0))
+ (H5F_vfd_swmr_writer_prep_for_flush_or_close(f) < 0))
/* Push error, but keep going*/
HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "vfd swmr prep for flush or close failed")
@@ -3304,7 +3271,7 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len, size_t *image_le
* file driver. However, this test will not work if there is some
* other file driver sitting on top of the multi file driver.
*
- * I'm not sure if this is possible at present, but in all likelyhood,
+ * I'm not sure if this is possible at present, but in all likelihood,
* it will become possible in the future. On the other hand, we may
* remove the split/multi file drivers before then.
*
@@ -3324,7 +3291,7 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len, size_t *image_le
*
* While this problem is quite solvable, the required time and
* resources are lacking at present. Hence, for now, we don't
- * allow the get file image operation to be perfomed on files
+ * allow the get file image operation to be performed on files
* opened with the family file driver.
*
* Observe that the following test only looks at the top level
@@ -3755,7 +3722,7 @@ done:
* 1) The file being opened has v3 superblock
* 2) The file is opened with H5F_ACC_RDWR
* 3) The file is not already marked for SWMR writing
- * 4) Current implementaion for opened objects:
+ * 4) Current implementation for opened objects:
* --only allow datasets and groups without attributes
* --disallow named datatype with/without attributes
* --disallow opened attributes attached to objects
@@ -3774,7 +3741,7 @@ herr_t
H5F__start_swmr_write(H5F_t *f)
{
hbool_t ci_load = FALSE; /* whether MDC ci load requested */
- hbool_t ci_write = FALSE; /* whether MDC ci write requested */
+ hbool_t ci_write = FALSE; /* whether MDC CI write requested */
size_t grp_dset_count = 0; /* # of open objects: groups & datasets */
size_t nt_attr_count = 0; /* # of opened named datatypes + opened attributes */
hid_t * obj_ids = NULL; /* List of ids */
@@ -4146,142 +4113,3 @@ H5F_set_min_dset_ohdr(H5F_t *f, hbool_t minimize)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5F_set_min_dset_ohdr() */
-
-/*-------------------------------------------------------------------------
- * Function: H5F__vfd_swmr_end_tick()
- *
- * Purpose: To trigger end of tick processing
- *
- * Return: Non-negative on success/Negative on errors
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F__vfd_swmr_end_tick(H5F_t *f)
-{
- eot_queue_entry_t *curr;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
-
- /* Sanity check */
- HDassert(f);
- HDassert(f->shared);
-
- /* The file should be opened with VFD SWMR configured.*/
- if (!(H5F_USE_VFD_SWMR(f)))
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must have VFD SWMR configured for this public routine")
-
- /* Search EOT queue */
- TAILQ_FOREACH(curr, &eot_queue_g, link)
- {
- if (curr->vfd_swmr_file == f)
- break;
- }
-
- /* If the file does not exist on the EOT queue, flag an error */
- if (curr == NULL)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "EOT for the file has been disabled")
-
- if (f->shared->vfd_swmr_writer) {
- if (H5F_vfd_swmr_writer_end_of_tick(f, true) < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR writer");
- }
- else if (H5F_vfd_swmr_reader_end_of_tick(f, true) < 0) {
- HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR reader");
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__vfd_swmr_end_tick() */
-
-/*-------------------------------------------------------------------------
- * Function: H5F__vfd_swmr_disable_end_of_tick()
- *
- * Purpose: To disable end of tick processing
- *
- * Return: Non-negative on success/Negative on errors
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F__vfd_swmr_disable_end_of_tick(H5F_t *f)
-{
- eot_queue_entry_t *curr;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
-
- /* Sanity check */
- HDassert(f);
- HDassert(f->shared);
-
- /* The file should be opened with VFD SWMR configured.*/
- if (!(H5F_USE_VFD_SWMR(f)))
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must have VFD SWMR configured for this public routine")
-
- /* Search EOT queue */
- TAILQ_FOREACH(curr, &eot_queue_g, link)
- {
- if (curr->vfd_swmr_file == f)
- break;
- }
-
- /* If the file does not exist on the EOT queue, flag an error */
- if (curr == NULL)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "EOT for the file has already been disabled")
-
- /* Remove the entry that corresponds to "f" from the EOT queue */
- if (H5F_vfd_swmr_remove_entry_eot(f) < 0)
- HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to remove entry from EOT queue")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__vfd_swmr_disable_end_of_tick() */
-
-/*-------------------------------------------------------------------------
- * Function: H5F__vfd_swmr_enable_end_of_tick()
- *
- * Purpose: To enable end of tick processing
- *
- * Return: Non-negative on success/Negative on errors
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F__vfd_swmr_enable_end_of_tick(H5F_t *f)
-{
- eot_queue_entry_t *curr;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
-
- /* Sanity check */
- HDassert(f);
- HDassert(f->shared);
-
- /* The file should be opened with VFD SWMR configured.*/
- if (!(H5F_USE_VFD_SWMR(f)))
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must have VFD SWMR configured for this public routine")
-
- /* Search EOT queue */
- TAILQ_FOREACH(curr, &eot_queue_g, link)
- {
- if (curr->vfd_swmr_file == f)
- break;
- }
-
- /* If the file already exists on the EOT queue, flag an error */
- if (curr != NULL)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "EOT for the file has already been enabled")
-
- /* Insert the entry that corresponds to "f" onto the EOT queue */
- if (H5F_vfd_swmr_insert_entry_eot(f) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue")
-
- /* Check if the tick has expired, if so call end of tick processing */
- if (H5F_vfd_swmr_process_eot_queue(true) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "error processing EOT queue")
-
- /* FUNC_LEAVE_API could do the check, but not so for reader_end_of_tick() */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__vfd_swmr_enable_end_of_tick() */
diff --git a/src/H5Fmount.c b/src/H5Fmount.c
index 4b90ea3..7d27234 100644
--- a/src/H5Fmount.c
+++ b/src/H5Fmount.c
@@ -104,7 +104,7 @@ H5F_mount(const H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UN
H5F_t * parent = NULL; /*file containing mount point */
unsigned lt, rt, md; /*binary search indices */
int cmp; /*binary search comparison value*/
- H5G_loc_t mp_loc; /* entry of moint point to be opened */
+ H5G_loc_t mp_loc; /* entry of mount point to be opened */
H5G_name_t mp_path; /* Mount point group hier. path */
H5O_loc_t mp_oloc; /* Mount point object location */
H5G_loc_t root_loc; /* Group location of root of file to mount */
diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c
index 53d2d78..02d8d52 100644
--- a/src/H5Fmpi.c
+++ b/src/H5Fmpi.c
@@ -31,11 +31,12 @@
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fpkg.h" /* File access */
-#include "H5FDprivate.h" /* File drivers */
-#include "H5Iprivate.h" /* IDs */
+#include "H5private.h" /* Generic Functions */
+#include "H5CXprivate.h" /* API Contexts */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FDprivate.h" /* File drivers */
+#include "H5Iprivate.h" /* IDs */
#include "H5VLnative_private.h" /* Native VOL connector */
@@ -402,4 +403,189 @@ H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_mpi_retrieve_comm */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_coll_metadata_reads
+ *
+ * Purpose: Determines whether collective metadata reads should be
+ * performed. This routine is meant to be the single source of
+ * truth for the collective metadata reads status, as it
+ * coordinates between the file-global flag and the flag set
+ * for the current operation in the current API context.
+ *
+ * Return: TRUE/FALSE (can't fail)
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_get_coll_metadata_reads(const H5F_t *file)
+{
+ H5P_coll_md_read_flag_t file_flag = H5P_USER_FALSE;
+ hbool_t ret_value = FALSE;
+
+ FUNC_ENTER_NOAPI_NOERR
+
+ HDassert(file && file->shared);
+
+ /* Retrieve the file-global flag */
+ file_flag = H5F_COLL_MD_READ(file);
+
+ /* If file flag is set to H5P_FORCE_FALSE, exit early
+ * with FALSE, since collective metadata reads have
+ * been explicitly disabled somewhere in the library.
+ */
+ if (H5P_FORCE_FALSE == file_flag)
+ ret_value = FALSE;
+ else {
+ /* If file flag is set to H5P_USER_TRUE, ignore
+ * any settings in the API context. A file-global
+ * setting of H5P_USER_TRUE for collective metadata
+ * reads should ignore any settings on an Access
+ * Property List for an individual operation.
+ */
+ if (H5P_USER_TRUE == file_flag)
+ ret_value = TRUE;
+ else {
+ /* Get the collective metadata reads flag from
+ * the current API context.
+ */
+ ret_value = H5CX_get_coll_metadata_read();
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_get_coll_metadata_reads() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_set_coll_metadata_reads
+ *
+ * Purpose: Used to temporarily modify the collective metadata reads
+ * status. This is useful for cases where either:
+ *
+ * * Collective metadata reads are enabled, but need to be
+ * disabled for an operation about to occur that may trigger
+ * an independent metadata read (such as only rank 0 doing
+ * something)
+ *
+ * * Metadata reads are currently independent, but it is
+ * guaranteed that the application has maintained
+ * collectivity at the interface level (e.g., an operation
+ * that modifies metadata is being performed). In this case,
+ * it should be safe to enable collective metadata reads,
+ * barring any internal library issues that may occur
+ *
+ * After completion, the `file_flag` parameter will be set to
+ * the previous value of the file-global collective metadata
+ * reads flag. The `context_flag` parameter will be set to the
+ * previous value of the API context's collective metadata
+ * reads flag. Another call to this routine should be made to
+ * restore these values (see below warning).
+ *
+ * !! WARNING !!
+ * It is dangerous to modify the collective metadata reads
+ * status, as this can cause crashes, hangs and corruption in
+ * the HDF5 file when improperly done. Therefore, the
+ * `file_flag` and `context_flag` parameters are both
+ * mandatory, and it is assumed that the caller will guarantee
+ * these settings are restored with another call to this
+ * routine once the bracketed operation is complete.
+ * !! WARNING !!
+ *
+ * Return: Nothing
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5F_set_coll_metadata_reads(H5F_t *file, H5P_coll_md_read_flag_t *file_flag, hbool_t *context_flag)
+{
+ H5P_coll_md_read_flag_t prev_file_flag = H5P_USER_FALSE;
+ hbool_t prev_context_flag = FALSE;
+
+ FUNC_ENTER_NOAPI_NOERR
+
+ HDassert(file && file->shared);
+ HDassert(file_flag);
+ HDassert(context_flag);
+
+ /* Save old state */
+ prev_file_flag = H5F_COLL_MD_READ(file);
+ prev_context_flag = H5CX_get_coll_metadata_read();
+
+ /* Set new desired state */
+ if (prev_file_flag != *file_flag) {
+ file->shared->coll_md_read = *file_flag;
+ *file_flag = prev_file_flag;
+ }
+ if (prev_context_flag != *context_flag) {
+ H5CX_set_coll_metadata_read(*context_flag);
+ *context_flag = prev_context_flag;
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5F_set_coll_metadata_reads() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_mpi_get_file_block_type
+ *
+ * Purpose: Creates an MPI derived datatype for communicating an
+ * H5F_block_t structure. If `commit` is specified as TRUE,
+ * the resulting datatype will be committed and ready for
+ * use in communication. Otherwise, the type is only suitable
+ * for building other derived types.
+ *
+ * If TRUE is returned through `new_type_derived`, this lets
+ * the caller know that the datatype has been derived and
+ * should be freed with MPI_Type_free once it is no longer
+ * needed.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_mpi_get_file_block_type(hbool_t commit, MPI_Datatype *new_type, hbool_t *new_type_derived)
+{
+ MPI_Datatype types[2];
+ MPI_Aint displacements[2];
+ int block_lengths[2];
+ int field_count;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(new_type);
+ HDassert(new_type_derived);
+
+ *new_type_derived = FALSE;
+
+ field_count = 2;
+ HDassert(field_count == sizeof(types) / sizeof(MPI_Datatype));
+
+ block_lengths[0] = 1;
+ block_lengths[1] = 1;
+ displacements[0] = offsetof(H5F_block_t, offset);
+ displacements[1] = offsetof(H5F_block_t, length);
+ types[0] = HADDR_AS_MPI_TYPE;
+ types[1] = HSIZE_AS_MPI_TYPE;
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Type_create_struct(field_count, block_lengths, displacements, types, new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ *new_type_derived = TRUE;
+
+ if (commit && MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+done:
+ if (ret_value < 0) {
+ if (*new_type_derived) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_free(new_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ *new_type_derived = FALSE;
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_mpi_get_file_block_type() */
+
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index ca26941..ca714c1 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -79,7 +79,7 @@
#define H5F_SUPERBLOCK_FIXED_SIZE (H5F_SIGNATURE_LEN + 1) /* superblock version */
/* The H5F_SUPERBLOCK_MINIMAL_VARLEN_SIZE is the minimal amount of super block
- * variable length data guarnateed to load the sizeof offsets and the sizeof
+ * variable length data guaranteed to load the sizeof offsets and the sizeof
* lengths fields in all versions of the superblock.
*
* This is necessary in the V3 cache, as on the initial load, we need to
@@ -153,6 +153,62 @@
/* Size of file consistency flags (status_flags) in the superblock */
#define H5F_SUPER_STATUS_FLAGS_SIZE(v) (v >= 2 ? 1 : 4)
+/* VFD SMWR LOG REPORTING MACROS */
+
+/* H5F_POST_VFD_SWMR_LOG_ENTRY is the macro that can help the developers debug VFD SWMR features.
+ * It calls an internal reporting function H5F_post_vfd_swmr_log_entry() that receives
+ * a log entry_type_code, which generates a log tag, and the message log_info, which
+ * the developers want to save into a log file.
+ *
+ * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, number_entry_production, m) is
+ * called by H5F_POST_VFD_SWMR_LOG_ENTRY when the HDF5 library is built with the
+ * production mode. Number_entry_production will control the number of entry tags that
+ * applications can receive. Currently this number is set to 1 and is subject to change
+ * when more tags are useful to be present to applications.
+ *
+ * The first argument of the macro is the HDF5 file pointer(H5F_t *).
+ * Its value needs to be checked to avoid a failure caused by "Low-Level File I/O "
+ * in the testhdf5 program, which involves the test of a non-existing HDF5 file.
+ */
+
+#define H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp, entry_type_code, log_info) \
+ do { \
+ if (fp != NULL) { \
+ if (fp->shared != NULL) { \
+ if (fp->shared->vfd_swmr_log_on == TRUE) { \
+ H5F__post_vfd_swmr_log_entry(fp, entry_type_code, log_info); \
+ } \
+ } \
+ } \
+ } while (0)
+
+#define H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(fp, entry_type_code, max_code, log_info) \
+ do { \
+ if (entry_type_code < max_code) { \
+ H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp, entry_type_code, log_info); \
+ } \
+ } while (0)
+
+/* Note: change H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m) on the following lines to
+ * H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, your_number_entry_production, m)
+ * as necessary.
+ */
+#ifndef NDEBUG
+#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(f, c, m)
+#else
+#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m)
+#endif
+
+/* Macros for VFD SWMR log entry code
+ * Note: this should be consistent with const char *H5Fvfd_swmr_log_tags[] declared at
+ * H5Fvfd_swmr.c .
+ */
+#define EOT_PROCESSING_TIME 0
+#define FILE_OPEN 1
+#define FILE_CLOSE 2
+#define EOT_TRIGGER_TIME 3
+#define EOT_META_FILE_INDEX 4
+
/* Forward declaration external file cache struct used below (defined in
* H5Fefc.c) */
typedef struct H5F_efc_t H5F_efc_t;
@@ -218,10 +274,10 @@ typedef struct H5F_mtab_t {
* the shadow file to release after max_lag ticks.
*/
typedef struct shadow_defree {
- uint64_t offset; // offset of the region in *bytes*
- uint32_t length; // length of the region in *bytes*
- uint64_t tick_num; // tick number when the free was deferred
- TAILQ_ENTRY(shadow_defree) link; // deferred-free queue linkage
+ uint64_t offset; /* offset of the region in *bytes* */
+ uint32_t length; /* length of the region in *bytes* */
+ uint64_t tick_num; /* tick number when the free was deferred */
+ TAILQ_ENTRY(shadow_defree) link; /* deferred-free queue linkage */
} shadow_defree_t;
/* Structure specifically to store superblock. This was originally
@@ -247,10 +303,10 @@ typedef struct H5F_super_t {
* the file below the SWMR VFD to release after a delay.
*/
typedef struct lower_defree {
- SIMPLEQ_ENTRY(lower_defree) link; // deferred-free queue linkage
- H5FD_mem_t alloc_type; // type with which the region was allocated
- haddr_t addr; // start of the region *in bytes*
- hsize_t size; // length of the region *in bytes*
+ SIMPLEQ_ENTRY(lower_defree) link; /* deferred-free queue linkage */
+ H5FD_mem_t alloc_type; /* type with which the region was allocated */
+ haddr_t addr; /* start of the region *in bytes* */
+ hsize_t size; /* length of the region *in bytes* */
uint64_t free_after_tick; /* the region may be reused on tick
* free_after_tick + 1 at the earliest
*/
@@ -385,7 +441,7 @@ struct H5F_shared_t {
/* Metadata retry info */
unsigned read_attempts; /* The # of reads to try when reading metadata with checksum */
unsigned retries_nbins; /* # of bins for each retries[] */
- uint32_t *retries[H5AC_NTYPES]; /* Track # of read retries for metdata items with checksum */
+ uint32_t *retries[H5AC_NTYPES]; /* Track # of read retries for metadata items with checksum */
/* Object flush info */
H5F_object_flush_t object_flush; /* Information for object flush callback */
@@ -441,7 +497,7 @@ struct H5F_shared_t {
*/
uint32_t mdf_idx_entries_used; /* Number of entries in *mdf_idx
* that are in use -- these will
- * be contiguous at indicies 0
+ * be contiguous at indices 0
* through mdf_idx_entries_used - 1.
*/
@@ -482,7 +538,7 @@ struct H5F_shared_t {
* file
*/
uint64_t updater_seq_num; /* Sequence number of the next updater file to be
- * genereated. This field must be initialized to zero,
+ * generated. This field must be initialized to zero,
* and incremented after each updater file is generated.
*/
@@ -564,6 +620,8 @@ H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t hi
H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info);
H5_DLL herr_t H5F__parse_file_lock_env_var(htri_t *use_locks);
H5_DLL herr_t H5F__delete(const char *filename, hid_t fapl_id);
+
+/* VFD SWMR routines */
H5_DLL herr_t H5F__vfd_swmr_end_tick(H5F_t *f);
H5_DLL herr_t H5F__vfd_swmr_disable_end_of_tick(H5F_t *f);
H5_DLL herr_t H5F__vfd_swmr_enable_end_of_tick(H5F_t *f);
@@ -626,6 +684,9 @@ H5_DLL herr_t H5F__get_max_eof_eoa(const H5F_t *f, haddr_t *max_eof_eoa);
/* Functions that flush or evict */
H5_DLL herr_t H5F__evict_cache_entries(H5F_t *f);
+/* VFD SWMR log functions */
+H5_DLL void H5F__post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, const char *log_info);
+
/* Testing functions */
#ifdef H5F_TESTING
H5_DLL herr_t H5F__get_sohm_mesg_count_test(hid_t fid, unsigned type_id, size_t *mesg_count);
@@ -641,61 +702,4 @@ H5_DLL htri_t H5F__same_file_test(hid_t file_id1, hid_t file_id2);
H5_DLL herr_t H5F__reparse_file_lock_variable_test(void);
#endif /* H5F_TESTING */
-/* VFD SMWR LOG REPORTING MACROS */
-
-/* H5F_POST_VFD_SWMR_LOG_ENTRY is the macro that can help the developers debug VFD SWMR features.
- * It calls an internal reporting function H5F_post_vfd_swmr_log_entry() that receives
- * a log entry_type_code, which generates a log tag, and the message log_info, which
- * the developers want to save into a log file.
- *
- * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, number_entry_production, m) is
- * called by H5F_POST_VFD_SWMR_LOG_ENTRY when the HDF5 library is built with the
- * production mode. Number_entry_production will control the number of entry tags that
- * applications can receive. Currently this number is set to 1 and is subject to change
- * when more tags are useful to be present to applications.
- *
- * The first argument of the macro is the HDF5 file pointer(H5F_t *).
- * Its value needs to be checked to avoid a failure caused by "Low-Level File I/O "
- * in the testhdf5 program, which involves the test of a non-existing HDF5 file.
- */
-
-H5_DLL void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info);
-
-#define H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp, entry_type_code, log_info) \
- do { \
- if (fp != NULL) { \
- if (fp->shared != NULL) { \
- if (fp->shared->vfd_swmr_log_on == TRUE) { \
- H5F_post_vfd_swmr_log_entry(fp, entry_type_code, log_info); \
- } \
- } \
- } \
- } while (0)
-
-#define H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(fp, entry_type_code, max_code, log_info) \
- do { \
- if (entry_type_code < max_code) { \
- H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp, entry_type_code, log_info); \
- } \
- } while (0)
-
-/* Note: change H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m) on the following lines to
- * H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, your_number_entry_production, m)
- * as necessary.
- */
-#ifndef NDEBUG
-#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(f, c, m)
-#else
-#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m)
-#endif
-
-/* Macros for VFD SWMR log entry code
- * Note: this should be consistent with const char *H5Fvfd_swmr_log_tags[] declared at
- * H5Fvfd_swmr.c .
- */
-#define EOT_PROCESSING_TIME 0
-#define FILE_OPEN 1
-#define FILE_CLOSE 2
-#define EOT_TRIGGER_TIME 3
-#define EOT_META_FILE_INDEX 4
#endif /* H5Fpkg_H */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 9a4f363..ffc369b 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -24,11 +24,9 @@ typedef struct H5F_t H5F_t;
/* Include package's public header */
#include "H5Fpublic.h"
-/* Public headers needed by this file */
-#include "H5FDpublic.h" /* File drivers */
-
/* Private headers needed by this file */
#include "H5MMprivate.h" /* Memory management */
+#include "H5FDprivate.h" /* File drivers */
#ifdef H5_HAVE_PARALLEL
#include "H5Pprivate.h" /* Property lists */
#endif /* H5_HAVE_PARALLEL */
@@ -240,20 +238,6 @@ typedef struct H5F_t H5F_t;
(p) += 8; \
}
-static inline uint64_t
-uint64_decode(uint8_t **pp)
-{
- int i;
- uint8_t *p = *pp;
- uint64_t v = 0;
-
- for (i = 0; i < 8; i++) {
- v = (v << 8) | p[7 - i];
- }
- *pp += 8;
- return v;
-}
-
#define UINT64DECODE(p, n) \
{ \
/* WE DON'T CHECK FOR OVERFLOW! */ \
@@ -390,10 +374,7 @@ uint64_decode(uint8_t **pp)
#define H5F_THRESHOLD(F) ((F)->shared->threshold)
#define H5F_PGEND_META_THRES(F) ((F)->shared->fs.pgend_meta_thres)
#define H5F_POINT_OF_NO_RETURN(F) ((F)->shared->fs.point_of_no_return)
-#define H5F_FIRST_ALLOC_DEALLOC(F) ((F)->shared->first_alloc_dealloc)
-#define H5F_EOA_PRE_FSM_FSALLOC(F) ((F)->shared->eoa_pre_fsm_fsalloc)
#define H5F_USE_VFD_SWMR(F) ((F)->shared->vfd_swmr)
-#define H5F_VFD_SWMR_MD_EOA(F) ((F)->shared->vfd_swmr_md_eoa)
#define H5F_NULL_FSM_ADDR(F) ((F)->shared->null_fsm_addr)
#define H5F_GET_MIN_DSET_OHDR(F) ((F)->shared->crt_dset_min_ohdr_flag)
#define H5F_SET_MIN_DSET_OHDR(F, V) ((F)->shared->crt_dset_min_ohdr_flag = (V))
@@ -457,9 +438,7 @@ uint64_decode(uint8_t **pp)
#define H5F_THRESHOLD(F) (H5F_get_threshold(F))
#define H5F_PGEND_META_THRES(F) (H5F_get_pgend_meta_thres(F))
#define H5F_POINT_OF_NO_RETURN(F) (H5F_get_point_of_no_return(F))
-#define H5F_FIRST_ALLOC_DEALLOC(F) (H5F_get_first_alloc_dealloc(F))
-#define H5F_EOA_PRE_FSM_FSALLOC(F) (H5F_get_eoa_pre_fsm_fsalloc(F))
-#define H5F_USE_VFD_SWMR(F) (H5F_use_vfd_swmr(F))
+#define H5F_USE_VFD_SWMR(F) (H5F_get_use_vfd_swmr(F))
#define H5F_NULL_FSM_ADDR(F) (H5F_get_null_fsm_addr(F))
#define H5F_GET_MIN_DSET_OHDR(F) (H5F_get_min_dset_ohdr(F))
#define H5F_SET_MIN_DSET_OHDR(F, V) (H5F_set_min_dset_ohdr((F), (V)))
@@ -643,16 +622,23 @@ uint64_decode(uint8_t **pp)
/* Default configuration for VFD SWMR: not configured */
#define H5F_ACS_VFD_SWMR_CONFIG_NAME "vfd_swmr_config"
+/* clang-format off */
#define H5F__DEFAULT_VFD_SWMR_CONFIG \
{ \
- /* int32_t version = */ 0, /* int32_t tick_len = */ 0, \
- /* int32_t max_lag = */ 0, /* hbool_t vfd_swmr_writer = */ FALSE, \
- /* hbool_t maintain_metadata_file = */ FALSE, \
- /* hbool_t generate_updater_files = */ FALSE, \
- /* hbool_t flush_raw_data = */ FALSE, /* int32_t md_pages_reserved = */ 0, \
- /* int32_t pb_expansion_threshold = */ 0, /* char md_file_path[] = */ "", \
- /* char updater_file_path[] = */ "", /* char log_file_path[] = */ "" \
+ /* int32_t version = */ 0, \
+ /* int32_t tick_len = */ 0, \
+ /* int32_t max_lag = */ 0, \
+ /* hbool_t vfd_swmr_writer = */ FALSE, \
+ /* hbool_t maintain_metadata_file = */ FALSE, \
+ /* hbool_t generate_updater_files = */ FALSE, \
+ /* hbool_t flush_raw_data = */ FALSE, \
+ /* int32_t md_pages_reserved = */ 0, \
+ /* int32_t pb_expansion_threshold = */ 0, \
+ /* char md_file_path[] = */ "", \
+ /* char updater_file_path[] = */ "", \
+ /* char log_file_path[] = */ "" \
}
+/* clang-format on */
/* For VFD SWMR testing only: private property to generate checksum for metadata file via callback */
#define H5F_ACS_GENERATE_MD_CK_CB_NAME "generate md ck callback"
@@ -843,18 +829,6 @@ uint64_decode(uint8_t **pp)
+ H5F_SIZEOF_CHKSUM /* Updater file change list checksum */ \
)
-/*
- * For VFD SWMR testing only:
- */
-
-/* Callback routine to generate checksum for metadata file specified by md_path */
-typedef herr_t (*H5F_generate_md_ck_t)(char *md_path, uint64_t updater_seq_num);
-
-/* Structure for "generate checksum callback" private property */
-typedef struct H5F_generate_md_ck_cb_t {
- H5F_generate_md_ck_t func;
-} H5F_generate_md_ck_cb_t;
-
/****************************/
/* Library Private Typedefs */
/****************************/
@@ -867,6 +841,7 @@ struct H5O_loc_t;
struct H5HG_heap_t;
struct H5VL_class_t;
struct H5P_genplist_t;
+struct H5FD_vfd_swmr_idx_entry_t;
/* Forward declarations for anonymous H5F objects */
@@ -931,6 +906,44 @@ typedef enum H5F_prefix_open_t {
/*----------------------------------------------------------------------------
*
+ * struct eot_queue_entry_t
+ *
+ * This is the structure for an entry on the end-of-tick queue (EOT queue) of files
+ * opened in either VFD SWMR write or VFD SWMR read mode. This queue is maintained
+ * in increasing end of tick time order.
+ * The structure contains all information required to determine whether the end
+ * of tick has arrived for the specified file, and to initiate end of tick processing
+ * if it has.
+ *
+ * The fields of eot_queue_entry_t are discussed below:
+ *
+ * vfd_swmr_file: Pointer to the instance of H5F_shared_t containing the shared
+ * fields of the associated file that has been opened in VFD SWMR mode
+ * NOTE: for the time being use H5F_t instead of H5F_shared_t
+ *
+ * vfd_swmr_writer: Boolean flag that is set to TRUE if the associated file
+ * has been opened in VFD SWMR writer mode, and FALSE if it has been
+ * opened in VFD SWMR reader mode.
+ *
+ * tick_num: Number of the current tick of the target file.
+ *
+ * end_of_tick: Expiration time of the current tick of the target file.
+ *
+ * link: Forward and backward linkage between the next element and the previous
+ * element (or the queue head). Note that if there is a following entry,
+ * `next`, then `next->end_of_tick` must be greater than or equal to
+ * `end_of_tick`.
+ */
+typedef struct eot_queue_entry {
+ hbool_t vfd_swmr_writer;
+ uint64_t tick_num;
+ struct timespec end_of_tick;
+ H5F_t * vfd_swmr_file;
+ TAILQ_ENTRY(eot_queue_entry) link;
+} eot_queue_entry_t;
+
+/*----------------------------------------------------------------------------
+ *
* struct H5F_vfd_swmr_updater_cl_entry_t
*
* An array of instances of H5F_vfd_swmr_updater_cl_entry_t of length equal to
@@ -938,7 +951,7 @@ typedef enum H5F_prefix_open_t {
* the past tick is used to assemble the associated data in preparation for
* writing an updater file.
*
- * Each entry in this array pertains to a given modified metdata page or
+ * Each entry in this array pertains to a given modified metadata page or
* multi-page metadata entry, and contains the following fields:
*
* entry_image_ptr: void pointer to a buffer containing the image of the
@@ -1099,6 +1112,14 @@ typedef struct H5F_vfd_swmr_updater_t {
H5F_vfd_swmr_updater_cl_entry_t *change_list;
} H5F_vfd_swmr_updater_t;
+/* Callback routine to generate checksum for metadata file specified by md_path */
+typedef herr_t (*H5F_generate_md_ck_t)(char *md_path, uint64_t updater_seq_num);
+
+/* Structure for "generate checksum callback" private property */
+typedef struct H5F_generate_md_ck_cb_t {
+ H5F_generate_md_ck_t func;
+} H5F_generate_md_ck_cb_t;
+
/*****************************/
/* Library-private Variables */
/*****************************/
@@ -1187,10 +1208,26 @@ H5_DLL hbool_t H5F_shared_has_feature(const H5F_shared_t *f, unsigned feature);
H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature);
H5_DLL haddr_t H5F_shared_get_eoa(const H5F_shared_t *f_sh, H5FD_mem_t type);
H5_DLL haddr_t H5F_get_eoa(const H5F_t *f, H5FD_mem_t type);
+H5_DLL herr_t H5F_shared_get_file_driver(const H5F_shared_t *f_sh, H5FD_t **file_handle);
H5_DLL herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void **file_handle);
/* VFD SWMR functions */
-H5_DLL hbool_t H5F_use_vfd_swmr(const H5F_t *f);
+H5_DLL hbool_t H5F_get_use_vfd_swmr(const H5F_t *f);
+H5_DLL herr_t H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create);
+H5_DLL herr_t H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing);
+H5_DLL herr_t H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t index_len,
+ H5FD_vfd_swmr_idx_entry_t *index);
+H5_DLL herr_t H5F_vfd_swmr_writer_delay_write(H5F_shared_t *shared, uint64_t page, uint64_t *untilp);
+H5_DLL herr_t H5F_vfd_swmr_writer_prep_for_flush_or_close(H5F_t *f);
+H5_DLL herr_t H5F_vfd_swmr_writer_end_of_tick(H5F_t *f);
+H5_DLL herr_t H5F_vfd_swmr_writer_dump_index(H5F_shared_t *shared);
+H5_DLL herr_t H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api);
+H5_DLL herr_t H5F_vfd_swmr_remove_entry_eot(H5F_t *f);
+H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(H5F_t *f);
+H5_DLL void H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *entry);
+H5_DLL herr_t H5F_dump_eot_queue(void);
+H5_DLL herr_t H5F_shadow_image_defer_free(H5F_shared_t *shared, const H5FD_vfd_swmr_idx_entry_t *entry);
+H5_DLL H5FD_vfd_swmr_idx_entry_t *H5F_vfd_swmr_enlarge_shadow_index(H5F_t *f);
/* File mounting routines */
H5_DLL herr_t H5F_mount(const struct H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id);
@@ -1247,6 +1284,9 @@ H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f);
H5_DLL int H5F_shared_mpi_get_size(const H5F_shared_t *f_sh);
H5_DLL int H5F_mpi_get_size(const H5F_t *f);
H5_DLL herr_t H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm);
+H5_DLL herr_t H5F_mpi_get_file_block_type(hbool_t commit, MPI_Datatype *new_type, hbool_t *new_type_derived);
+H5_DLL hbool_t H5F_get_coll_metadata_reads(const H5F_t *f);
+H5_DLL void H5F_set_coll_metadata_reads(H5F_t *f, H5P_coll_md_read_flag_t *file_flag, hbool_t *context_flag);
#endif /* H5_HAVE_PARALLEL */
/* External file cache routines */
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 7120085..e9d3340 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -322,7 +322,7 @@ typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata);
* An integer field indicating the threshold for the page buffer size.
* During a tick, the page buffer must expand as necessary to retain copies
* of all modified metadata pages and multi-page metadata entries.
- * If the page buffer size exceeds this thresold, an early end of tick
+ * If the page buffer size exceeds this threshold, an early end of tick
* will be triggered.
* Note that this is not a limit on the maximum page buffer size, as the
* metadata cache is flushed as part of end of tick processing.
@@ -1727,7 +1727,7 @@ H5_DLL herr_t H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2], u
* \brief Obtains information about a cache image if it exists
*
* \file_id
- * \param[out] image_addr Offset of the cache image if it exists, or \c HADDR_UNDEF if it does not
+ * \param[out] image_addr Offset of the cache image if it exists, or #HADDR_UNDEF if it does not
* \param[out] image_size Length of the cache image if it exists, or 0 if it does not
* \returns \herr_t
*
@@ -1806,7 +1806,6 @@ H5_DLL herr_t H5Fget_dset_no_attrs_hint(hid_t file_id, hbool_t *minimize);
*
*/
H5_DLL herr_t H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize);
-H5_DLL herr_t H5Fwait(hid_t file_id);
/* VFD SWMR */
/**
@@ -1821,14 +1820,6 @@ H5_DLL herr_t H5Fvfd_swmr_disable_end_of_tick(hid_t file_id);
* \todo Add missing documentation
*/
H5_DLL herr_t H5Fvfd_swmr_enable_end_of_tick(hid_t file_id);
-/**
- * \todo Add missing documentation
- */
-H5_DLL bool vfd_swmr_writer_may_increase_tick_to(uint64_t, bool);
-/**
- * \todo Add missing documentation
- */
-H5_DLL void vfd_swmr_reader_did_increase_tick_to(uint64_t);
#ifdef H5_HAVE_PARALLEL
/**
@@ -2022,6 +2013,7 @@ H5_DLL herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *file_info);
*
* \deprecated When?
*
+ * \todo In which version was this function introduced?
* \todo In which version was this function deprecated?
*
*/
@@ -2040,6 +2032,7 @@ H5_DLL herr_t H5Fset_latest_format(hid_t file_id, hbool_t latest_format);
* \details H5Fis_hdf5() determines whether a file is in the HDF5 format.
*
* \todo In which version was this function deprecated?
+ * \todo In which version was this function introduced?
*
*/
H5_DLL htri_t H5Fis_hdf5(const char *file_name);
diff --git a/src/H5Fquery.c b/src/H5Fquery.c
index 24b25ff..acdf521 100644
--- a/src/H5Fquery.c
+++ b/src/H5Fquery.c
@@ -950,6 +950,29 @@ done:
} /* end H5F_get_eoa() */
/*-------------------------------------------------------------------------
+ * Function: H5F_shared_get_file_driver
+ *
+ * Purpose: Returns a pointer to the file driver structure of the
+ * file's 'shared' structure.
+ *
+ * Return: file handle on success/abort on failure (shouldn't fail)
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_shared_get_file_driver(const H5F_shared_t *f_sh, H5FD_t **file_handle)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(f_sh);
+ HDassert(file_handle);
+
+ *file_handle = f_sh->lf;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5F_shared_get_file_driver() */
+
+/*-------------------------------------------------------------------------
* Function: H5F_get_vfd_handle
*
* Purpose: Returns a pointer to the file handle of the low-level file
@@ -1321,18 +1344,15 @@ H5F_get_file_locking(const H5F_t *f)
} /* end H5F_get_file_locking */
/*-------------------------------------------------------------------------
- * Function: H5F_use_vfd_swmr
+ * Function: H5F_get_use_vfd_swmr
*
- * Purpose: Quick and dirty routine to determine if VFD SWMR is
- * enabled for this file.
- * (Mainly added to stop non-file routines from poking about in the
- * H5F_t data structure)
+ * Purpose: Determine if VFD SWMR is enabled for this file.
*
- * Return: TRUE/FALSE on success/abort on failure (shouldn't fail)
+ * Return: TRUE/FALSE
*-------------------------------------------------------------------------
*/
hbool_t
-H5F_use_vfd_swmr(const H5F_t *f)
+H5F_get_use_vfd_swmr(const H5F_t *f)
{
/* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOERR
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index e7a3b53..bf02b06 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -375,7 +375,7 @@ H5F__super_read(H5F_t *f, H5P_genplist_t *fa_plist, hbool_t initial_read)
if (0 == mpi_rank) {
herr_t status;
- /* Try detecting file's siganture */
+ /* Try detecting file's signature */
/* (Don't leave before Bcast, to avoid hang on error) */
H5E_BEGIN_TRY
{
@@ -467,7 +467,7 @@ H5F__super_read(H5F_t *f, H5P_genplist_t *fa_plist, hbool_t initial_read)
*
* After upgrading low_bound, the library will check to ensure that the
* superblock version does not exceed the version allowed by high_bound.
- * Otherise fail file open.
+ * Otherwise fail file open.
*
* For details, please see RFC:Setting Bounds for Object Creation in HDF5 1.10.0.
*/
@@ -1043,7 +1043,7 @@ done:
HDONE_ERROR(H5E_FILE, H5E_CANTUNPIN, FAIL, "unable to unpin driver info")
/* Evict the driver info block from the cache */
- if (H5AC_expunge_entry(f, H5AC_DRVRINFO, sblock->driver_addr, H5AC__NO_FLAGS_SET) < 0)
+ if (sblock && H5AC_expunge_entry(f, H5AC_DRVRINFO, sblock->driver_addr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTEXPUNGE, FAIL, "unable to expunge driver info block")
} /* end if */
diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c
index 7d1ff86..258570e 100644
--- a/src/H5Fsuper_cache.c
+++ b/src/H5Fsuper_cache.c
@@ -701,7 +701,7 @@ H5F__cache_superblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNU
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
H5F_addr_encode(f, &image, (rel_eof + sblock->base_addr));
- /* Encode the driver informaton block address */
+ /* Encode the driver information block address */
H5F_addr_encode(f, &image, sblock->driver_addr);
/* Encode the root group object entry, including the cached stab info */
@@ -800,7 +800,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5F__cache_drvrinfo_get_initial_load_size
*
- * Purpose: Compute the intiial size of the data structure on disk.
+ * Purpose: Compute the initial size of the data structure on disk.
*
* Return: Non-negative on success/Negative on failure
*
diff --git a/src/H5Ftest.c b/src/H5Ftest.c
index f4a89fd..01c9706 100644
--- a/src/H5Ftest.c
+++ b/src/H5Ftest.c
@@ -416,9 +416,10 @@ H5F__vfd_swmr_decode_md_hdr(int md_fd, H5FD_vfd_swmr_md_header *md_hdr)
UINT32DECODE(p, md_hdr->fs_page_size);
UINT64DECODE(p, md_hdr->tick_num);
UINT64DECODE(p, md_hdr->index_offset);
- if ((index_length = uint64_decode(&p)) > SIZE_MAX) {
+ UINT64DECODE(p, index_length);
+ if (index_length > SIZE_MAX)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "index is too long")
- }
+
md_hdr->index_length = (size_t)index_length;
done:
@@ -568,16 +569,27 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F__vfd_swmr_verify_md_hdr_and_idx() */
+/*-------------------------------------------------------------------------
+ * Function: H5F__count_shadow_defrees
+ *
+ * Purpose:
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
static unsigned
-count_shadow_defrees(shadow_defree_queue_t *shadow_defrees)
+H5F__count_shadow_defrees(shadow_defree_queue_t *shadow_defrees)
{
shadow_defree_t *shadow_defree;
unsigned count = 0;
+ FUNC_ENTER_STATIC_NOERR
+
TAILQ_FOREACH(shadow_defree, shadow_defrees, link)
count++;
- return count;
+ FUNC_LEAVE_NOAPI(count)
}
/*-------------------------------------------------------------------------
@@ -618,7 +630,7 @@ H5F__vfd_swmr_writer_md_test(hid_t file_id, unsigned num_entries, H5FD_vfd_swmr_
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "error updating the md file with the index")
/* Verify the number of entries in the delayed list is as expected */
- if (count_shadow_defrees(&f->shared->shadow_defrees) == nshadow_defrees)
+ if (H5F__count_shadow_defrees(&f->shared->shadow_defrees) == nshadow_defrees)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect # of entries in the delayed list")
/* Open the metadata file */
diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c
index e5189b7..64cc378 100644
--- a/src/H5Fvfd_swmr.c
+++ b/src/H5Fvfd_swmr.c
@@ -11,12 +11,9 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*-------------------------------------------------------------------------
+ * Created: H5Fvfd_swmr.c
*
- * Created: H5Fvfd_swmr.c
- * Oct 10 2019
- *
- * Purpose: Functions for VFD SWMR.
- *
+ * Purpose: File functions for VFD SWMR
*-------------------------------------------------------------------------
*/
@@ -52,8 +49,8 @@
/* Local Macros */
/****************/
-#define nanosecs_per_second 1000000000 /* nanoseconds per second */
-#define nanosecs_per_tenth_sec 100000000 /* nanoseconds per 0.1 second */
+#define NANOSECS_PER_SECOND 1000000000 /* nanoseconds per second */
+#define NANOSECS_PER_TENTH_SEC 100000000 /* nanoseconds per 0.1 second */
/* Declare an array of string to identify the VFD SMWR Log tags.
* Note this array is used to generate the entry tag by the log reporting macro
@@ -103,7 +100,7 @@ static herr_t H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *, uint32_t,
struct H5FD_vfd_swmr_idx_entry_t[], uint8_t *);
static herr_t H5F__idx_entry_cmp(const void *_entry1, const void *_entry2);
static herr_t H5F__vfd_swmr_create_index(H5F_shared_t *);
-static herr_t H5F__vfd_swmr_writer__wait_a_tick(H5F_t *);
+static herr_t H5F__vfd_swmr_writer_wait_a_tick(H5F_t *);
static herr_t H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater);
static herr_t H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater);
@@ -116,20 +113,15 @@ static herr_t H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_
/* Package Variables */
/*********************/
-/*
- * Globals for VFD SWMR
+/* Globals for VFD SWMR */
+
+/* Times the library was entered and re-entered minus the times it was exited.
+ * We only perform the end-of-tick processing on the 0->1 and 1->0 transitions.
*/
+unsigned int vfd_swmr_api_entries_g = 0;
-unsigned int vfd_swmr_api_entries_g = 0; /* Times the library was entered
- * and re-entered minus the times
- * it was exited. We only perform
- * the end-of-tick processing
- * on the 0->1 and 1->0
- * transitions.
- */
-/*
- * The head of the end of tick queue (EOT queue) for files opened in either
- * VFD SWMR write or VFD SWMR read mode
+/* The head of the end of tick queue (EOT queue) for files opened in either
+ * VFD SWMR write or VFD SWMR read mode
*/
eot_queue_t eot_queue_g = TAILQ_HEAD_INITIALIZER(eot_queue_g);
@@ -144,7 +136,6 @@ H5FL_DEFINE(shadow_defree_t);
H5FL_DEFINE(eot_queue_entry_t);
/*-------------------------------------------------------------------------
- *
* Function: H5F_vfd_swmr_init
*
* Purpose: Initialize globals and the corresponding fields in
@@ -166,13 +157,7 @@ H5FL_DEFINE(eot_queue_entry_t);
* --set f->shared->tick_num to the current tick read from the
* metadata file
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 10/??/18
- *
- * Changes: None.
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
herr_t
@@ -208,9 +193,9 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create)
md_size = (hsize_t)shared->vfd_swmr_config.md_pages_reserved * shared->fs_page_size;
- if ((hdr_addr = H5MV_alloc(f, md_size)) == HADDR_UNDEF) {
- HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error allocating shadow-file header");
- }
+ if ((hdr_addr = H5MV_alloc(f, md_size)) == HADDR_UNDEF)
+ HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error allocating shadow-file header")
+
HDassert(H5F_addr_eq(hdr_addr, H5FD_MD_HEADER_OFF));
shared->writer_index_offset = H5FD_MD_HEADER_SIZE;
@@ -222,10 +207,10 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create)
if (!file_create) {
if (H5F__vfd_swmr_construct_write_md_idx(shared, 0, NULL, md_idx_image) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create index in md");
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create index in md")
if (H5F__vfd_swmr_construct_write_md_hdr(shared, 0, md_hdr_image) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create header in md");
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create header in md")
}
/* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */
@@ -274,28 +259,18 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create)
/* allocate an index to save the initial index */
if (H5F__vfd_swmr_create_index(shared) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate metadata file index");
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate metadata file index")
/* Set tick_num to the current tick read from the metadata file */
shared->mdf_idx_entries_used = shared->mdf_idx_len;
if (H5FD_vfd_swmr_get_tick_and_idx(shared->lf, FALSE, &shared->tick_num,
&(shared->mdf_idx_entries_used), shared->mdf_idx) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTLOAD, FAIL, "unable to load/decode metadata file");
-
- vfd_swmr_reader_did_increase_tick_to(shared->tick_num);
-
-#if 0 /* JRM */
- HDfprintf(stderr,
- "##### initialized index: tick/used/len = %lld/%d/%d #####\n",
- shared->tick_num, shared->mdf_idx_entries_used,
- shared->mdf_idx_len);
-#endif /* JRM */
+ HGOTO_ERROR(H5E_FILE, H5E_CANTLOAD, FAIL, "unable to load/decode metadata file")
}
/* Update end_of_tick */
- if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, FALSE) < 0) {
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick");
- }
+ if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, FALSE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick")
done:
@@ -304,7 +279,6 @@ done:
} /* H5F_vfd_swmr_init() */
/*-------------------------------------------------------------------------
- *
* Function: H5F_vfd_swmr_close_or_flush
*
* Purpose: Used by the VFD SWMR writer when the HDF5 file is closed
@@ -323,13 +297,7 @@ done:
* --start a new tick (??check with JM for sure)
* ??update end_of_tick
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 11/??/18
- *
- * Changes: None.
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
herr_t
@@ -348,17 +316,17 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing)
/* Write empty index to the md file */
if (H5F__vfd_swmr_construct_write_md_idx(shared, 0, NULL, md_idx_image) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create index in md");
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create index in md")
/* Write header to the md file */
if (H5F__vfd_swmr_construct_write_md_hdr(shared, 0, md_hdr_image) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create header in md");
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create header in md")
if (closing) { /* For file close */
/* Close the md file */
if (HDclose(shared->vfd_swmr_md_fd) < 0)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close the metadata file");
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close the metadata file")
shared->vfd_swmr_md_fd = -1;
/* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */
@@ -369,12 +337,12 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing)
/* Unlink the md file */
if (HDunlink(shared->vfd_swmr_config.md_file_path) < 0)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTREMOVE, FAIL, "unable to unlink the metadata file");
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTREMOVE, FAIL, "unable to unlink the metadata file")
/* Close the free-space manager for the metadata file */
if (H5MV_close(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL,
- "unable to close the free-space manager for the metadata file");
+ "unable to close the free-space manager for the metadata file")
/* Free the delayed list */
while ((curr = TAILQ_FIRST(&shared->shadow_defrees)) != NULL) {
@@ -394,51 +362,68 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing)
else { /* For file flush */
/* Update end_of_tick */
if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, TRUE) < 0)
- HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick");
+ HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick")
}
-#if 1 /*Kent Save the end of close info. to the log file, subject to comment out. */
+#if 1 /* Save the end of close info. to the log file, subject to comment out. */
if (closing)
H5F_POST_VFD_SWMR_LOG_ENTRY(f, FILE_CLOSE, "VFD SWMR File close ends");
#endif
done:
- /* Kent: Stop the timer and close the VFD SWMR log file if it is turned on.
- * Please REVIEW to ensure this is the right place to
+ /* Stop the timer and close the VFD SWMR log file if it is turned on.
+ * TODO: Please REVIEW to ensure this is the right place to
* close the log file.
*/
if (shared->vfd_swmr_log_on && closing) {
H5_timer_stop(&(shared->vfd_swmr_log_start_time));
HDfclose(shared->vfd_swmr_log_file_ptr);
}
- /* Kent */
+
FUNC_LEAVE_NOAPI(ret_value)
}
-static int
-shadow_range_defer_free(H5F_shared_t *shared, uint64_t offset, uint32_t length)
+/*-------------------------------------------------------------------------
+ * Function: H5F__shadow_image_defer_free
+ *
+ * Purpose:
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__shadow_range_defer_free(H5F_shared_t *shared, uint64_t offset, uint32_t length)
{
shadow_defree_t *shadow_defree;
if (NULL == (shadow_defree = H5FL_CALLOC(shadow_defree_t)))
- return -1;
+ return FAIL;
shadow_defree->offset = offset;
shadow_defree->length = length;
shadow_defree->tick_num = shared->tick_num;
TAILQ_INSERT_HEAD(&shared->shadow_defrees, shadow_defree, link);
- return 0;
+
+ return SUCCEED;
}
-int
-shadow_image_defer_free(H5F_shared_t *shared, const H5FD_vfd_swmr_idx_entry_t *entry)
+/*-------------------------------------------------------------------------
+ * Function: H5F_shadow_image_defer_free
+ *
+ * Purpose:
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_shadow_image_defer_free(H5F_shared_t *shared, const H5FD_vfd_swmr_idx_entry_t *entry)
{
- return shadow_range_defer_free(shared, entry->md_file_page_offset * shared->fs_page_size, entry->length);
+ return H5F__shadow_range_defer_free(shared, entry->md_file_page_offset * shared->fs_page_size,
+ entry->length);
}
/*-------------------------------------------------------------------------
- *
- * Function: H5F_update_vfd_swmr_metadata_file()
+ * Function: H5F_update_vfd_swmr_metadata_file
*
* Purpose: Update the metadata file with the input index
*
@@ -462,12 +447,6 @@ shadow_image_defer_free(H5F_shared_t *shared, const H5FD_vfd_swmr_idx_entry_t *e
* free-space manager
*
* Return: SUCCEED/FAIL
- *
- * Programmer: Vailin Choi 11/??/18
- *
- * Changes: None.
- *
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -513,7 +492,7 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_
/* Prepend previous image of the entry to the delayed list */
if (index[i].md_file_page_offset) {
- if (shadow_image_defer_free(shared, &index[i]) == -1) {
+ if (H5F_shadow_image_defer_free(shared, &index[i]) == -1) {
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate the delayed entry")
}
}
@@ -528,22 +507,6 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_
index[i].md_file_page_offset = md_addr / shared->fs_page_size;
index[i].checksum = H5_checksum_metadata(index[i].entry_ptr, index[i].length, 0);
-#if 0 /* JRM */
- HDfprintf(stderr,
- "writing index[%d] fo/mdfo/l/checksum/fc/lc = %lld/%lld/%ld/%lx/%lx/%lx\n",
- i,
- index[i].hdf5_page_offset,
- index[i].md_file_page_offset,
- index[i].length,
- index[i].checksum,
- (((char*)(index[i].entry_ptr))[0]),
- (((char*)(index[i].entry_ptr))[4095]));
-
- HDassert(md_addr == index[i].md_file_page_offset *
- shared->fs_page_size);
- HDassert(shared->fs_page_size == 4096);
-#endif /* JRM */
-
if (shared->vfd_swmr_config.maintain_metadata_file) {
/* Seek and write the entry to the metadata file */
@@ -594,13 +557,11 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_
TAILQ_FOREACH_REVERSE_SAFE(shadow_defree, &shared->shadow_defrees, shadow_defree_queue, link, prev)
{
- if (shadow_defree->tick_num + shared->vfd_swmr_config.max_lag > shared->tick_num) {
+ if (shadow_defree->tick_num + shared->vfd_swmr_config.max_lag > shared->tick_num)
break; // No more entries are due for reclamation.
- }
- if (H5MV_free(f, shadow_defree->offset, shadow_defree->length) < 0) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush clean entry");
- }
+ if (H5MV_free(f, shadow_defree->offset, shadow_defree->length) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush clean entry")
TAILQ_REMOVE(&shared->shadow_defrees, shadow_defree, link);
@@ -622,16 +583,14 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_
done:
- if (md_idx_image)
- HDfree(md_idx_image);
+ HDfree(md_idx_image);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_update_vfd_swmr_metadata_file() */
/*-------------------------------------------------------------------------
- *
- * Function: H5F_vfd_swmr_writer__delay_write
+ * Function: H5F_vfd_swmr_writer_delay_write
*
* Purpose: Given the base address of a page of metadata, or of a multi-
* page metadata entry, determine whether the write must be
@@ -662,15 +621,10 @@ done:
* or equal to the current tick, or zero otherwise.
*
* Return: SUCCEED/FAIL
- *
- * Programmer: John Mainzer 11/4/18
- *
- * Changes: None.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5F_vfd_swmr_writer__delay_write(H5F_shared_t *shared, uint64_t page, uint64_t *untilp)
+H5F_vfd_swmr_writer_delay_write(H5F_shared_t *shared, uint64_t page, uint64_t *untilp)
{
uint64_t until;
H5FD_vfd_swmr_idx_entry_t *ie_ptr;
@@ -687,16 +641,14 @@ H5F_vfd_swmr_writer__delay_write(H5F_shared_t *shared, uint64_t page, uint64_t *
HDassert(idx != NULL || shared->tick_num <= 1);
- /* do a binary search on the metadata file index to see if
- * it already contains an entry for `page`.
+ /* Do a binary search on the metadata file index to see if
+ * it already contains an entry for `page`
*/
- if (idx == NULL) {
+ if (idx == NULL)
ie_ptr = NULL;
- }
- else {
- ie_ptr = vfd_swmr_pageno_to_mdf_idx_entry(idx, shared->mdf_idx_entries_used, page, FALSE);
- }
+ else
+ ie_ptr = H5FD_vfd_swmr_pageno_to_mdf_idx_entry(idx, shared->mdf_idx_entries_used, page, FALSE);
if (ie_ptr == NULL)
until = shared->tick_num + shared->vfd_swmr_config.max_lag;
@@ -715,11 +667,10 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F_vfd_swmr_writer__delay_write() */
+} /* H5F_vfd_swmr_writer_delay_write() */
/*-------------------------------------------------------------------------
- *
- * Function: H5F_vfd_swmr_writer__prep_for_flush_or_close
+ * Function: H5F_vfd_swmr_writer_prep_for_flush_or_close
*
* Purpose: In the context of the VFD SWMR writer, two issues must be
* addressed before the page buffer can be flushed -- as is
@@ -735,15 +686,10 @@ done:
* This function manages these details.
*
* Return: SUCCEED/FAIL
- *
- * Programmer: John Mainzer 11/27/18
- *
- * Changes: None.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f)
+H5F_vfd_swmr_writer_prep_for_flush_or_close(H5F_t *f)
{
herr_t ret_value = SUCCEED; /* Return value */
H5F_shared_t *shared = f->shared;
@@ -758,14 +704,11 @@ H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f)
* tick so as to avoid attempts to flush entries on the page buffer
* tick list that were modified during the current tick.
*/
- if (H5F_vfd_swmr_writer_end_of_tick(f, TRUE) < 0)
-
+ if (H5F_vfd_swmr_writer_end_of_tick(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "H5F_vfd_swmr_writer_end_of_tick() failed.")
while (shared->page_buf->dwl_len > 0) {
-
- if (H5F__vfd_swmr_writer__wait_a_tick(f) < 0)
-
+ if (H5F__vfd_swmr_writer_wait_a_tick(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "wait a tick failed.")
}
@@ -773,10 +716,10 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F_vfd_swmr_writer__prep_for_flush_or_close() */
+} /* H5F_vfd_swmr_writer_prep_for_flush_or_close() */
static int
-clean_shadow_index(H5F_t *f, uint32_t nentries, H5FD_vfd_swmr_idx_entry_t *idx, uint32_t *ndeletedp)
+H5F__clean_shadow_index(H5F_t *f, uint32_t nentries, H5FD_vfd_swmr_idx_entry_t *idx, uint32_t *ndeletedp)
{
H5F_shared_t * shared = f->shared;
uint32_t i, j, ndeleted, max_lag = shared->vfd_swmr_config.max_lag;
@@ -792,7 +735,7 @@ clean_shadow_index(H5F_t *f, uint32_t nentries, H5FD_vfd_swmr_idx_entry_t *idx,
HDassert(ie->entry_ptr == NULL);
if (ie->md_file_page_offset != 0) {
- if (shadow_image_defer_free(shared, ie) == -1)
+ if (H5F_shadow_image_defer_free(shared, ie) == -1)
return -1;
ie->md_file_page_offset = 0;
}
@@ -808,7 +751,6 @@ clean_shadow_index(H5F_t *f, uint32_t nentries, H5FD_vfd_swmr_idx_entry_t *idx,
}
/*-------------------------------------------------------------------------
- *
* Function: H5F_vfd_swmr_writer_end_of_tick
*
* Purpose: Main routine for managing the end of tick for the VFD
@@ -828,7 +770,7 @@ clean_shadow_index(H5F_t *f, uint32_t nentries, H5FD_vfd_swmr_idx_entry_t *idx,
* dirty the first page in the HDF5 file. However, the
* metadata cache will no longer exist at this point.
*
- * Thus, we must check for the existance of the metadata
+ * Thus, we must check for the existence of the metadata
* cache, and only attempt to flush it if it exists.
*
* 3) If this is the first tick (i.e. tick == 1), create the
@@ -858,15 +800,10 @@ clean_shadow_index(H5F_t *f, uint32_t nentries, H5FD_vfd_swmr_idx_entry_t *idx,
* In passing, generate log entries as appropriate.
*
* Return: SUCCEED/FAIL
- *
- * Programmer: John Mainzer 11/4/18
- *
- * Changes: None.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader)
+H5F_vfd_swmr_writer_end_of_tick(H5F_t *f)
{
H5F_shared_t *shared = f->shared;
uint32_t idx_entries_added = 0;
@@ -877,10 +814,10 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader)
herr_t ret_value = SUCCEED; /* Return value */
hbool_t incr_tick = FALSE;
- /* Kent: define the local variables to calculate the EOT time
- and write them to the log file. */
+ /* Local variables to calculate the EOT time and write to the log file */
H5_timevals_t current_time;
- double start_elapsed_time, end_elapsed_time;
+ double start_elapsed_time = 0.0;
+ double end_elapsed_time = 0.0;
unsigned int temp_time;
char * log_msg;
@@ -890,17 +827,12 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader)
HDassert(shared->page_buf);
HDassert(shared->vfd_swmr_writer);
- /* Kent */
/* Obtain the starting time for the logging info: the processing time of this function. */
- if (shared->vfd_swmr_log_on == true) {
+ if (shared->vfd_swmr_log_on == TRUE) {
if (H5_timer_get_times(shared->vfd_swmr_log_start_time, &current_time) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time from H5_timer_get_times")
start_elapsed_time = current_time.elapsed;
}
- /* Kent */
-
- if (!vfd_swmr_writer_may_increase_tick_to(shared->tick_num + 1, wait_for_reader))
- goto update_eot;
incr_tick = TRUE;
@@ -966,8 +898,8 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader)
* to the HDF5 file more than max_lag ticks ago, and haven't
* been modified since.
*/
- if (clean_shadow_index(f, shared->mdf_idx_entries_used + idx_entries_added, shared->mdf_idx,
- &idx_entries_removed) < 0)
+ if (H5F__clean_shadow_index(f, shared->mdf_idx_entries_used + idx_entries_added, shared->mdf_idx,
+ &idx_entries_removed) < 0)
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't clean shadow file index")
/* 6) Update the metadata file. Must do this before we
@@ -989,27 +921,18 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader)
HDassert(shared->mdf_idx_entries_used <= shared->mdf_idx_len);
-#if 0 /* JRM */
- H5F__vfd_swmr_writer__dump_index(f);
-#endif /* JRM */
-
/* 7) Release the page buffer tick list. */
if (H5PB_vfd_swmr__release_tick_list(shared) < 0)
-
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't release tick list")
/* 8) Release any delayed writes whose delay has expired */
if (H5PB_vfd_swmr__release_delayed_writes(shared) < 0)
-
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't release delayed writes")
-update_eot:
-
/* 9) Increment the tick, and update the end of tick. */
/* Update end_of_tick */
if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, incr_tick) < 0)
-
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick")
/* Remove the entry from the EOT queue */
@@ -1021,8 +944,8 @@ update_eot:
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue")
done:
- /* Kent: Calcuate the processing time and write the time info to the log file */
- if (shared->vfd_swmr_log_on == true) {
+ /* Calculate the processing time and write the time info to the log file */
+ if (shared->vfd_swmr_log_on == TRUE) {
if (H5_timer_get_times(shared->vfd_swmr_log_start_time, &current_time) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time from H5_timer_get_times")
end_elapsed_time = current_time.elapsed;
@@ -1033,26 +956,20 @@ done:
HDfree(log_msg);
}
}
- /* Kent */
+
FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
- *
- * Function: H5F_vfd_swmr_writer__dump_index
+ * Function: H5F_vfd_swmr_writer_dump_index
*
* Purpose: Dump a summary of the metadata file index.
*
* Return: SUCCEED/FAIL
- *
- * Programmer: John Mainzer 12/14/19
- *
- * Changes: None.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5F_vfd_swmr_writer__dump_index(H5F_shared_t *shared)
+H5F_vfd_swmr_writer_dump_index(H5F_shared_t *shared)
{
unsigned int i;
uint32_t mdf_idx_len;
@@ -1060,7 +977,7 @@ H5F_vfd_swmr_writer__dump_index(H5F_shared_t *shared)
H5FD_vfd_swmr_idx_entry_t *index = NULL;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(shared);
HDassert(shared->vfd_swmr);
@@ -1074,17 +991,13 @@ H5F_vfd_swmr_writer__dump_index(H5F_shared_t *shared)
HDfprintf(stderr, "index len / entries used = %" PRIu32 " / %" PRIu32 "\n\n", mdf_idx_len,
mdf_idx_entries_used);
- for (i = 0; i < mdf_idx_entries_used; i++) {
-
+ for (i = 0; i < mdf_idx_entries_used; i++)
HDfprintf(stderr, "%u: %" PRIu64 " %" PRIu64 " %" PRIu32 "\n", i, index[i].hdf5_page_offset,
index[i].md_file_page_offset, index[i].length);
- }
-
-done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_vfd_swmr_writer__dump_index() */
+} /* end H5F_vfd_swmr_writer_dump_index() */
/*-------------------------------------------------------------------------
* Function: H5F_vfd_swmr_reader_end_of_tick
@@ -1105,11 +1018,11 @@ done:
*
* If any such pages or multi-page metadata entries are found:
*
- * a) direct the page buffer to evict any such superceeded
+ * a) direct the page buffer to evict any such superseded
* pages, and
*
* b) direct the metadata cache to either evict or refresh
- * any entries residing in the superceeded pages.
+ * any entries residing in the superseded pages.
*
* Note that this operation MUST be performed in this order,
* as the metadata cache will refer to the page buffer
@@ -1118,11 +1031,6 @@ done:
* 9) Increment the tick, and update the end of tick.
*
* Return: SUCCEED/FAIL
- *
- * Programmer: John Mainzer 12/29/18
- *
- * Changes: None.
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1170,23 +1078,17 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api)
/* This is ok if we're entering the API, but it should
* not happen if we're exiting the API.
*/
- /* JRM review this */
+ /* TODO: review this */
/* The following line is added for more meaningful error message when
* the long running API on the reader side exceeds the max_lag of ticks.
- * KY 2021-09-02
- * */
+ */
if (!entering_api && tmp_tick_num >= shared->tick_num + shared->vfd_swmr_config.max_lag) {
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL,
"Reader's API time exceeds max_lag ticks, suggest to increase the value of max_lag.");
}
-#if 0 /* Kent */
- /* The original code */
- HDassert(entering_api || tmp_tick_num < shared->tick_num + shared->vfd_swmr_config.max_lag);
-#endif
- if (!entering_api) {
+ if (!entering_api)
H5FD_vfd_swmr_record_elapsed_ticks(shared->lf, tmp_tick_num - shared->tick_num);
- }
if (tmp_tick_num != shared->tick_num) {
const H5FD_vfd_swmr_idx_entry_t *new_mdf_idx;
@@ -1241,11 +1143,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api)
mdf_idx_entries_used = shared->mdf_idx_len;
-#if 0 /* JRM */
- HDfprintf(stderr, "--- reader EOT mdf_idx_entries_used = %d ---\n",
- mdf_idx_entries_used);
-#endif /* JRM */
-
if (H5FD_vfd_swmr_get_tick_and_idx(file, FALSE, NULL, &mdf_idx_entries_used, shared->mdf_idx) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "error in retrieving tick_num from driver");
@@ -1253,18 +1150,12 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api)
shared->mdf_idx_entries_used = mdf_idx_entries_used;
-#if 0 /* JRM */
- HDfprintf(stderr,
- "--- reader EOT index used / len = %" PRIu32 "/%" PRIu32 " ---\n",
- shared->mdf_idx_entries_used, shared->mdf_idx_len);
-#endif /* JRM */
-
new_mdf_idx = shared->mdf_idx;
old_mdf_idx = shared->old_mdf_idx;
new_mdf_idx_entries_used = shared->mdf_idx_entries_used;
old_mdf_idx_entries_used = shared->old_mdf_idx_entries_used;
- change = malloc(sizeof(change[0]) * (old_mdf_idx_entries_used + new_mdf_idx_entries_used));
+ change = HDmalloc(sizeof(change[0]) * (old_mdf_idx_entries_used + new_mdf_idx_entries_used));
if (change == NULL) {
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate removed pages list");
@@ -1298,13 +1189,7 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api)
* extension could overlap with a second entry.
*/
- /* JRM review this */
- /* Kent: need to comment out the line to make reader iterate
- * a large number of groups
- * */
-#if 0 /*Kent*/
- HDassert(oent->length == nent->length);
-#endif
+ /* TODO: review this */
/* This is a bug uncovered by issue #1 of the
* group test failures. See Kent's documentation
* "Designed to Fail Tests and Issues".
@@ -1388,11 +1273,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api)
}
}
-#if 0 /* JRM */
- HDfprintf(stderr, "--- reader EOT pre new tick index "
- "used/len = %" PRIu32 "/ %" PRIu32 " ---\n",
- shared->mdf_idx_entries_used, shared->mdf_idx_len);
-#endif /* JRM */
shared->max_jump_ticks = MAX(shared->max_jump_ticks, (tmp_tick_num - shared->tick_num));
/* At this point, we should have evicted or refreshed all stale
@@ -1402,8 +1282,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api)
*/
shared->tick_num = tmp_tick_num;
- vfd_swmr_reader_did_increase_tick_to(tmp_tick_num);
-
/* Update end_of_tick */
if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, FALSE) < 0) {
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick");
@@ -1411,29 +1289,37 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api)
}
/* Remove the entry from the EOT queue */
- if (H5F_vfd_swmr_remove_entry_eot(f) < 0) {
+ if (H5F_vfd_swmr_remove_entry_eot(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to remove entry from EOT queue")
- }
/* Re-insert the entry that corresponds to f onto the EOT queue */
- if (H5F_vfd_swmr_insert_entry_eot(f) < 0) {
+ if (H5F_vfd_swmr_insert_entry_eot(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue")
- }
done:
if (change != NULL)
- free(change);
+ HDfree(change);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_vfd_swmr_reader_end_of_tick() */
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_insert_eot_entry
+ *
+ * Purpose: Insert an entry in the EOT queue
+ *
+ * Return: void
+ *-------------------------------------------------------------------------
+ */
static void
-insert_eot_entry(eot_queue_entry_t *entry_ptr)
+H5F__vfd_swmr_insert_eot_entry(eot_queue_entry_t *entry_ptr)
{
eot_queue_entry_t *prec_ptr; /* The predecessor entry on the EOT end of tick queue */
+ FUNC_ENTER_STATIC_NOERR
+
/* Find the insertion point for the entry on the EOT queue */
TAILQ_FOREACH_REVERSE(prec_ptr, &eot_queue_g, eot_queue, link)
{
@@ -1446,9 +1332,17 @@ insert_eot_entry(eot_queue_entry_t *entry_ptr)
TAILQ_INSERT_AFTER(&eot_queue_g, prec_ptr, entry_ptr, link);
else
TAILQ_INSERT_HEAD(&eot_queue_g, entry_ptr, link);
-}
-/* Update an entry on the EOT queue and move it to its proper place.
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5F__vfd_swmr_insert_eot_entry() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_vfd_swmr_update_entry_eot
+ *
+ * Purpose: Update an entry on the EOT queue and move it to its proper place
+ *
+ * Return: void
+ *-------------------------------------------------------------------------
*/
void
H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *entry)
@@ -1456,6 +1350,8 @@ H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *entry)
H5F_t * f = entry->vfd_swmr_file;
H5F_shared_t *shared = f->shared;
+ FUNC_ENTER_NOAPI_NOERR
+
/* Free the entry on the EOT queue that corresponds to f */
TAILQ_REMOVE(&eot_queue_g, entry, link);
@@ -1464,20 +1360,17 @@ H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *entry)
entry->tick_num = shared->tick_num;
entry->end_of_tick = shared->end_of_tick;
- insert_eot_entry(entry);
-}
+ H5F__vfd_swmr_insert_eot_entry(entry);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5F_vfd_swmr_update_entry_eot() */
/*-------------------------------------------------------------------------
- *
* Function: H5F__vfd_swmr_remove_entry_eot
*
* Purpose: Remove an entry from the EOT queue
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 11/18/2019
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
herr_t
@@ -1501,19 +1394,14 @@ H5F_vfd_swmr_remove_entry_eot(H5F_t *f)
}
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5F_vfd_swmr_remove_entry_eot() */
+} /* end H5F_vfd_swmr_remove_entry_eot() */
/*-------------------------------------------------------------------------
- *
* Function: H5F_vfd_swmr_insert_entry_eot
*
* Purpose: Insert an entry onto the EOT queue
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 11/18/2019
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
herr_t
@@ -1535,24 +1423,18 @@ H5F_vfd_swmr_insert_entry_eot(H5F_t *f)
entry_ptr->end_of_tick = shared->end_of_tick;
entry_ptr->vfd_swmr_file = f;
- insert_eot_entry(entry_ptr);
+ H5F__vfd_swmr_insert_eot_entry(entry_ptr);
done:
FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5F_vfd_swmr_insert_entry_eot() */
+} /* end H5F_vfd_swmr_insert_entry_eot() */
/*-------------------------------------------------------------------------
- *
* Function: H5F_dump_eot_queue()
*
* Purpose: Dump the contents of the EOT queue
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 11/18/2019
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
herr_t
@@ -1573,27 +1455,15 @@ H5F_dump_eot_queue(void)
HDfprintf(stderr, "EOT head is null\n");
FUNC_LEAVE_NOAPI(SUCCEED)
-
-} /* H5F_dump_eot_queue() */
-
-/*
- * Beginning of static functions
- */
+} /* end H5F_dump_eot_queue() */
/*-------------------------------------------------------------------------
- *
* Function: H5F__vfd_swmr_update_end_of_tick_and_tick_num
*
* Purpose: Update end_of_tick (shared->end_of_tick)
* Update tick_num (shared->tick_num)
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 11/??/18
- *
- * Changes: None.
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1610,7 +1480,7 @@ H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_shared_t *shared, hbool_t incr
/* Get current time in struct timespec */
#ifdef H5_HAVE_WIN32_API
- if (timespec_get(&curr, TIME_UTC) != TIME_UTC)
+ if (HDtimespec_get(&curr, TIME_UTC) != TIME_UTC)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via timespec_get");
#else
if (HDclock_gettime(CLOCK_MONOTONIC, &curr) < 0) {
@@ -1619,20 +1489,17 @@ H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_shared_t *shared, hbool_t incr
#endif
/* Convert curr to nsecs */
- curr_nsecs = curr.tv_sec * nanosecs_per_second + curr.tv_nsec;
+ curr_nsecs = curr.tv_sec * NANOSECS_PER_SECOND + curr.tv_nsec;
/* Convert tick_len to nanosecs */
- tlen_nsecs = shared->vfd_swmr_config.tick_len * nanosecs_per_tenth_sec;
+ tlen_nsecs = shared->vfd_swmr_config.tick_len * NANOSECS_PER_TENTH_SEC;
- /*
- * Update shared->tick_num
- */
+ /* Update shared->tick_num */
if (incr_tick_num) {
shared->tick_num++;
if (H5PB_vfd_swmr__set_tick(shared) < 0)
-
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "Can't update page buffer current tick")
}
@@ -1643,13 +1510,11 @@ H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_shared_t *shared, hbool_t incr
/* TODO: The modulo operation is very expensive on most machines --
* re-work this code so as to avoid it.
- *
- * JRM -- 11/12/18
*/
new_end_nsecs = curr_nsecs + tlen_nsecs;
- new_end_of_tick.tv_nsec = (long)(new_end_nsecs % nanosecs_per_second);
- new_end_of_tick.tv_sec = new_end_nsecs / nanosecs_per_second;
+ new_end_of_tick.tv_nsec = (long)(new_end_nsecs % NANOSECS_PER_SECOND);
+ new_end_of_tick.tv_sec = new_end_nsecs / NANOSECS_PER_SECOND;
shared->end_of_tick = new_end_of_tick;
@@ -1660,7 +1525,6 @@ done:
} /* H5F__vfd_swmr_update_end_of_tick_and_tick_num() */
/*-------------------------------------------------------------------------
- *
* Function: H5F__vfd_swmr_construct_write_md_hdr
*
* Purpose: Encode and write header to the metadata file.
@@ -1672,13 +1536,7 @@ done:
* --after flushing an HDF5 file
* --when updating the metadata file
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 11/??/18
- *
- * Changes: None.
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1693,9 +1551,7 @@ H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *shared, uint32_t num_entries,
FUNC_ENTER_STATIC
- /*
- * Encode metadata file header
- */
+ /* Encode metadata file header */
p = image;
/* Encode magic for header */
@@ -1720,24 +1576,20 @@ H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *shared, uint32_t num_entries,
if (shared->vfd_swmr_config.maintain_metadata_file) {
/* Set to beginning of the file */
if (HDlseek(shared->vfd_swmr_md_fd, H5FD_MD_HEADER_OFF, SEEK_SET) < 0)
-
HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file")
nwritten = HDwrite(shared->vfd_swmr_md_fd, image, hdr_size);
+
/* Write header to the metadata file */
- if (nwritten != (ssize_t)hdr_size) {
+ if (nwritten != (ssize_t)hdr_size)
HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing header to metadata file")
- }
}
done:
-
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5F__vfd_swmr_construct_write_md_hdr() */
/*-------------------------------------------------------------------------
-
* Function: H5F__vfd_swmr_construct_write_md_idx
*
* Purpose: Encode and write index to the metadata file.
@@ -1749,13 +1601,7 @@ done:
* --after flushing an HDF5 file
* --when updating the metadata file
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 11/??/18
- *
- * Changes: None.
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1774,9 +1620,7 @@ H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries,
HDassert(num_entries == 0 || index != NULL);
- /*
- * Encode metadata file index
- */
+ /* Encode metadata file index */
p = image;
/* Encode magic for index */
@@ -1815,27 +1659,24 @@ H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries,
HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file")
nwritten = HDwrite(shared->vfd_swmr_md_fd, image, idx_size);
+
/* Write index to the metadata file */
- if (nwritten != (ssize_t)idx_size) {
+ if (nwritten != (ssize_t)idx_size)
HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing index to metadata file")
- }
}
done:
-
FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5F__vfd_swmr_construct_write_idx() */
+} /* end H5F__vfd_swmr_construct_write_idx() */
/*-------------------------------------------------------------------------
- * Function: H5F__idx_entry_cmp()
- *
- * Purpose: Callback used by HDqsort to sort entries in the index
+ * Function: H5F__idx_entry_cmp()
*
- * Return: 0 if the entries are the same
- * -1 if entry1's offset is less than that of entry2
- * 1 if entry1's offset is greater than that of entry2
+ * Purpose: Callback used by HDqsort to sort entries in the index
*
+ * Return: 0 if the entries are the same
+ * -1 if entry1's offset is less than that of entry2
+ * 1 if entry1's offset is greater than that of entry2
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1858,21 +1699,15 @@ H5F__idx_entry_cmp(const void *_entry1, const void *_entry2)
ret_value = 1;
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__idx_entry_cmp() */
+} /* end H5F__idx_entry_cmp() */
/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_create_index
*
- * Function: H5F__vfd_swmr_create_index
- *
- * Purpose: Allocate and initialize the index for the VFD SWMR metadata
- * file.
- *
- * Return: SUCCEED/FAIL
- *
- * Programmer: John Mainzer 11/5/18
- *
- * Changes: None.
+ * Purpose: Allocate and initialize the index for the VFD SWMR metadata
+ * file.
*
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1900,29 +1735,37 @@ H5F__vfd_swmr_create_index(H5F_shared_t *shared)
index = H5MM_calloc(entries_in_index * sizeof(index[0]));
- if (index == NULL) {
+ if (index == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for md index")
- }
HDassert(entries_in_index <= UINT32_MAX);
shared->mdf_idx = index;
shared->mdf_idx_len = (uint32_t)entries_in_index;
shared->mdf_idx_entries_used = 0;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F__vfd_swmr_create_index() */
+/*-------------------------------------------------------------------------
+ * Function: H5F_vfd_swmr_enlarge_shadow_index
+ *
+ * Purpose: Enlarge the shadow index
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
H5FD_vfd_swmr_idx_entry_t *
-vfd_swmr_enlarge_shadow_index(H5F_t *f)
+H5F_vfd_swmr_enlarge_shadow_index(H5F_t *f)
{
- H5F_shared_t * shared = f->shared;
- H5FD_vfd_swmr_idx_entry_t *ret_value = NULL;
+ H5F_shared_t * shared = f->shared;
haddr_t idx_addr;
haddr_t old_writer_index_offset;
hsize_t idx_size;
H5FD_vfd_swmr_idx_entry_t *new_mdf_idx = NULL, *old_mdf_idx;
uint32_t new_mdf_idx_len, old_mdf_idx_len;
+ H5FD_vfd_swmr_idx_entry_t *ret_value = NULL;
FUNC_ENTER_NOAPI(NULL)
@@ -1939,9 +1782,8 @@ vfd_swmr_enlarge_shadow_index(H5F_t *f)
idx_addr = H5MV_alloc(f, idx_size);
- if (idx_addr == HADDR_UNDEF) {
+ if (idx_addr == HADDR_UNDEF)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "shadow-file allocation failed for index")
- }
new_mdf_idx = H5MM_calloc(new_mdf_idx_len * sizeof(new_mdf_idx[0]));
@@ -1974,35 +1816,30 @@ vfd_swmr_enlarge_shadow_index(H5F_t *f)
* trade-off for simplicity.
*/
/* Fix: use the saved old_writer_index_offset not the current one */
- if (shadow_range_defer_free(shared, old_writer_index_offset, H5FD_MD_INDEX_SIZE(old_mdf_idx_len)) == -1) {
+ if (H5F__shadow_range_defer_free(shared, old_writer_index_offset, H5FD_MD_INDEX_SIZE(old_mdf_idx_len)) ==
+ -1) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "could not schedule index reclamation");
}
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_vfd_swmr_enlarge_shadow_index() */
/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_writer_wait_a_tick
*
- * Function: H5F__vfd_swmr_writer__wait_a_tick
- *
- * Purpose: Before a file that has been opened by a VFD SWMR writer,
- * all pending delayed writes must be allowed drain.
- *
- * This function facilitates this by sleeping for a tick, and
- * then running the writer end of tick function.
- *
- * It should only be called as part the flush or close operations.
+ * Purpose: Before a file that has been opened by a VFD SWMR writer,
+ * all pending delayed writes must be allowed drain.
*
- * Return: SUCCEED/FAIL
- *
- * Programmer: John Mainzer 11/23/18
+ * This function facilitates this by sleeping for a tick, and
+ * then running the writer end of tick function.
*
- * Changes: None.
+ * It should only be called as part the flush or close operations.
*
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
-H5F__vfd_swmr_writer__wait_a_tick(H5F_t *f)
+H5F__vfd_swmr_writer_wait_a_tick(H5F_t *f)
{
uint64_t tick_in_nsec;
H5F_shared_t *shared;
@@ -2015,17 +1852,25 @@ H5F__vfd_swmr_writer__wait_a_tick(H5F_t *f)
HDassert(shared->vfd_swmr);
HDassert(shared->vfd_swmr_writer);
- tick_in_nsec = shared->vfd_swmr_config.tick_len * nanosecs_per_tenth_sec;
+ tick_in_nsec = shared->vfd_swmr_config.tick_len * NANOSECS_PER_TENTH_SEC;
H5_nanosleep(tick_in_nsec);
- if (H5F_vfd_swmr_writer_end_of_tick(f, FALSE) < 0)
+ if (H5F_vfd_swmr_writer_end_of_tick(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "H5F_vfd_swmr_writer_end_of_tick() failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__vfd_swmr_writer__wait_a_tick() */
+} /* H5F__vfd_swmr_writer_wait_a_tick() */
+/*-------------------------------------------------------------------------
+ * Function: H5F_vfd_swmr_process_eot_queue
+ *
+ * Purpose: Process end-of-tick queue
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
herr_t
H5F_vfd_swmr_process_eot_queue(hbool_t entering_api)
{
@@ -2042,12 +1887,11 @@ H5F_vfd_swmr_process_eot_queue(hbool_t entering_api)
H5F_shared_t *shared = f->shared;
#ifdef H5_HAVE_WIN32_API
- if (timespec_get(&now, TIME_UTC) != TIME_UTC)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via timespec_get");
+ if (HDtimespec_get(&now, TIME_UTC) != TIME_UTC)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via timespec_get")
#else
- if (HDclock_gettime(CLOCK_MONOTONIC, &now) < 0) {
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime");
- }
+ if (HDclock_gettime(CLOCK_MONOTONIC, &now) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime")
#endif
if (HDtimespeccmp(&now, &head->end_of_tick, <))
break;
@@ -2061,21 +1905,20 @@ H5F_vfd_swmr_process_eot_queue(hbool_t entering_api)
H5F_vfd_swmr_update_entry_eot(head);
}
else if (shared->vfd_swmr_writer) {
- if (H5F_vfd_swmr_writer_end_of_tick(f, FALSE) < 0)
- HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR writer");
+ if (H5F_vfd_swmr_writer_end_of_tick(f) < 0)
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR writer")
}
else if (H5F_vfd_swmr_reader_end_of_tick(f, entering_api) < 0) {
- HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR reader");
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR reader")
}
} while ((head = TAILQ_FIRST(&eot_queue_g)) != NULL && head != first_head);
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_vfd_swmr_process_eot_queue() */
/*-------------------------------------------------------------------------
- *
- * Function: H5F_post_vfd_swmr_log_entry
+ * Function: H5F__post_vfd_swmr_log_entry
*
* Purpose: Write the log information to the log file.
*
@@ -2085,22 +1928,22 @@ done:
* log entry tag.
* char *log_info IN: The information to be stored in the
* log file.
- * Return: None
- *
+ * Return: void
*-------------------------------------------------------------------------
*/
-
void
-H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info)
+H5F__post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, const char *log_info)
{
double temp_time;
H5_timevals_t current_time;
- char * gettime_error;
+ char * gettime_error = NULL;
- /* Obtain the current time.
- If failed, write an error message to the log file.
- else obtain the elapsed time in seconds since the log file
- was created and write the time to the log file. */
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Obtain the current time. If failed, write an error message to the log
+ * file, else obtain the elapsed time in seconds since the log file was
+ * created and write the time to the log file.
+ */
if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time, &current_time) < 0) {
if (NULL != (gettime_error = HDmalloc(log_err_mesg_length * sizeof(char)))) {
HDsprintf(gettime_error, "gettime_error");
@@ -2114,22 +1957,16 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info)
HDfprintf(f->shared->vfd_swmr_log_file_ptr, log_fmt_str, H5Fvfd_swmr_log_tags[entry_type_code],
temp_time, log_info);
}
- return;
-}
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5F__post_vfd_swmr_log_entry() */
/*-------------------------------------------------------------------------
- *
* Function: H5F__vfd_swmr_construct_ud_hdr
*
* Purpose: Encode updater header in the buffer updater->header_image_ptr
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 10/2021
- *
- * Changes: None.
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
@@ -2142,17 +1979,16 @@ H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater)
FUNC_ENTER_STATIC_NOERR
- /*
- * Encode metadata file header
- */
+ /* Encode metadata file header */
p = image;
/* Encode magic for header */
HDmemcpy(p, H5F_UD_HEADER_MAGIC, (size_t)H5_SIZEOF_MAGIC);
p += H5_SIZEOF_MAGIC;
- /* Encode version number, flags, page size, sequence number, tick number, change list offset, change list
- * length */
+ /* Encode version number, flags, page size, sequence number, tick number,
+ * change list offset, change list length
+ */
UINT16ENCODE(p, H5F_UD_VERSION);
UINT16ENCODE(p, updater->flags);
UINT32ENCODE(p, updater->page_size);
@@ -2173,22 +2009,15 @@ H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater)
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5F__vfd_swmr_construct_ud_hdr() */
+} /* end H5F__vfd_swmr_construct_ud_hdr() */
/*-------------------------------------------------------------------------
- *
* Function: H5F__vfd_swmr_construct_ud_cl
*
* Purpose: Encode updater change list in the buffer
* updater->change_list_image_ptr
*
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Vailin Choi -- 10/2021
- *
- * Changes: None.
- *
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
@@ -2202,9 +2031,7 @@ H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater)
FUNC_ENTER_STATIC_NOERR
- /*
- * Encode ud cl
- */
+ /* Encode ud cl */
p = image;
/* Encode magic for ud cl */
@@ -2264,37 +2091,14 @@ H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater)
HDassert(p - image == (ptrdiff_t)updater->change_list_len);
FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5F__vfd_swmr_construct_ud_cl() */
+} /* end H5F__vfd_swmr_construct_ud_cl() */
/*-------------------------------------------------------------------------
+ * Function: H5F__generate_updater_file
*
- * Function: H5F_generate_updater_file()
- *
- * Purpose: Generate updater file:
- * --assemble and initialize data in the updater struct
- * --determine num_change_list entries
- * --allocate buffers
- * --construct on disk image (serialize) of the updater header and change list
- * --create updater file using a temporay file name:
- * --<shared->vfd_swmr_config.updater_file_path>.ud_tmp
- * --allocate space and write the following to the updater file
- * --updater file header
- * --updater file change list
- * --metadata entries
- * --metadata file index
- * --metadata file header
- * --close the updater file
- * --rename the updater file with the correct name:
- * <shared->vfd_swmr_config.updater_file_path>.<shared->updater_seq_num>
- *
- * --increment shared->updater_seq_num
- * --free buffers
- *
- * Return: SUCCEED/FAIL
- *
- * Programmer: Vailin Choi 8/24/2021
+ * Purpose: Generate updater file
*
+ * Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
@@ -2310,9 +2114,10 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, uint8
char newname[H5F__MAX_VFD_SWMR_FILE_NAME_LEN];
unsigned i, j;
hsize_t alloc_size;
+ int sz;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Updater file header fields */
updater.version = H5F_UD_VERSION;
@@ -2359,7 +2164,13 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, uint8
}
/* Create the updater file with a temporary file name */
- HDsprintf(namebuf, "%s.ud_tmp", shared->vfd_swmr_config.updater_file_path);
+ sz = HDsnprintf(namebuf, H5F__MAX_VFD_SWMR_FILE_NAME_LEN, "%s.ud_tmp",
+ shared->vfd_swmr_config.updater_file_path);
+ if (sz < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "error processing snprintf format string")
+ if (sz > H5F__MAX_VFD_SWMR_FILE_NAME_LEN)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "string passed to snprintf would be truncated")
+ namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN - 1] = '\0';
if ((ud_file = H5FD_open(namebuf, H5F_ACC_TRUNC | H5F_ACC_RDWR | H5F_ACC_CREAT, H5P_FILE_ACCESS_DEFAULT,
HADDR_UNDEF)) == NULL)
@@ -2487,7 +2298,13 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, uint8
/* Close the updater file and rename the file */
if (H5FD_close(ud_file) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close updater file")
- HDsprintf(newname, "%s.%lu", shared->vfd_swmr_config.updater_file_path, shared->updater_seq_num);
+ sz = HDsnprintf(newname, H5F__MAX_VFD_SWMR_FILE_NAME_LEN, "%s.%lu",
+ shared->vfd_swmr_config.updater_file_path, shared->updater_seq_num);
+ if (sz < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "error processing snprintf format string")
+ if (sz > H5F__MAX_VFD_SWMR_FILE_NAME_LEN)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "string passed to snprintf would be truncated")
+ newname[H5F__MAX_VFD_SWMR_FILE_NAME_LEN - 1] = '\0';
HDrename(namebuf, newname);
++shared->updater_seq_num;
@@ -2501,5 +2318,143 @@ done:
HDfree(updater.change_list);
FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__generate_updater_file() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_end_tick()
+ *
+ * Purpose: To trigger end of tick processing
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F__vfd_swmr_end_tick(H5F_t *f)
+{
+ eot_queue_entry_t *curr;
+ herr_t ret_value = SUCCEED; /* Return value */
-} /* H5F__generate_updater_file() */
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* The file should be opened with VFD SWMR configured.*/
+ if (!(H5F_USE_VFD_SWMR(f)))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must have VFD SWMR configured for this public routine")
+
+ /* Search EOT queue */
+ TAILQ_FOREACH(curr, &eot_queue_g, link)
+ {
+ if (curr->vfd_swmr_file == f)
+ break;
+ }
+
+ /* If the file does not exist on the EOT queue, flag an error */
+ if (curr == NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "EOT for the file has been disabled")
+
+ if (f->shared->vfd_swmr_writer) {
+ if (H5F_vfd_swmr_writer_end_of_tick(f) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR writer")
+ }
+ else if (H5F_vfd_swmr_reader_end_of_tick(f, TRUE) < 0) {
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR reader")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__vfd_swmr_end_tick() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_disable_end_of_tick()
+ *
+ * Purpose: To disable end of tick processing
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F__vfd_swmr_disable_end_of_tick(H5F_t *f)
+{
+ eot_queue_entry_t *curr;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* The file should be opened with VFD SWMR configured.*/
+ if (!(H5F_USE_VFD_SWMR(f)))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must have VFD SWMR configured for this public routine")
+
+ /* Search EOT queue */
+ TAILQ_FOREACH(curr, &eot_queue_g, link)
+ {
+ if (curr->vfd_swmr_file == f)
+ break;
+ }
+
+ /* If the file does not exist on the EOT queue, flag an error */
+ if (curr == NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "EOT for the file has already been disabled")
+
+ /* Remove the entry that corresponds to "f" from the EOT queue */
+ if (H5F_vfd_swmr_remove_entry_eot(f) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to remove entry from EOT queue")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__vfd_swmr_disable_end_of_tick() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__vfd_swmr_enable_end_of_tick()
+ *
+ * Purpose: To enable end of tick processing
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F__vfd_swmr_enable_end_of_tick(H5F_t *f)
+{
+ eot_queue_entry_t *curr;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* The file should be opened with VFD SWMR configured.*/
+ if (!(H5F_USE_VFD_SWMR(f)))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must have VFD SWMR configured for this public routine")
+
+ /* Search EOT queue */
+ TAILQ_FOREACH(curr, &eot_queue_g, link)
+ {
+ if (curr->vfd_swmr_file == f)
+ break;
+ }
+
+ /* If the file already exists on the EOT queue, flag an error */
+ if (curr != NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "EOT for the file has already been enabled")
+
+ /* Insert the entry that corresponds to "f" onto the EOT queue */
+ if (H5F_vfd_swmr_insert_entry_eot(f) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue")
+
+ /* Check if the tick has expired, if so call end of tick processing */
+ if (H5F_vfd_swmr_process_eot_queue(TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "error processing EOT queue")
+
+ /* FUNC_LEAVE_API could do the check, but not so for reader_end_of_tick() */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__vfd_swmr_enable_end_of_tick() */
diff --git a/src/H5Gcache.c b/src/H5Gcache.c
index df9943f..0ad3de0 100644
--- a/src/H5Gcache.c
+++ b/src/H5Gcache.c
@@ -135,7 +135,7 @@ H5G__cache_node_get_initial_load_size(void *_udata, size_t *image_len)
* Function: H5G__cache_node_deserialize
*
* Purpose: Given a buffer containing the on disk image of a symbol table
- * node, allocate an instance of H5G_node_t, load the contence of the
+ * node, allocate an instance of H5G_node_t, load the contents of the
* image into it, and return a pointer to the instance.
*
* Note that deserializing the image requires access to the file
@@ -241,7 +241,7 @@ H5G__cache_node_image_len(const void *_thing, size_t *image_len)
/*-------------------------------------------------------------------------
* Function: H5G__cache_node_serialize
*
- * Purpose: Given a correctly sized buffer and an instace of H5G_node_t,
+ * Purpose: Given a correctly sized buffer and an instance of H5G_node_t,
* serialize the contents of the instance of H5G_node_t, and write
* this data into the supplied buffer. This buffer will be written
* to disk.
diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c
index 0c0b5db..4988738 100644
--- a/src/H5Gcompact.c
+++ b/src/H5Gcompact.c
@@ -419,7 +419,7 @@ done:
* Function: H5G__compact_lookup_cb
*
* Purpose: Callback routine for searching 'link' messages for a particular
- * name & gettting object location for it
+ * name & getting object location for it
*
* Return: SUCCEED/FAIL
*
diff --git a/src/H5Gint.c b/src/H5Gint.c
index 90a2c6b..ba0cb6d 100644
--- a/src/H5Gint.c
+++ b/src/H5Gint.c
@@ -91,9 +91,6 @@ static herr_t H5G__close_cb(H5VL_object_t *grp_vol_obj, void **request);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declare a free list to manage the H5G_t struct */
H5FL_DEFINE(H5G_t);
H5FL_DEFINE(H5G_shared_t);
@@ -117,9 +114,6 @@ static const H5I_class_t H5I_GROUP_CLS[1] = {{
(H5I_free_t)H5G__close_cb /* Callback routine for closing objects of this class */
}};
-/* Flag indicating "top" of interface has been initialized */
-static hbool_t H5G_top_package_initialize_s = FALSE;
-
/*-------------------------------------------------------------------------
* Function: H5G_init
*
@@ -136,48 +130,13 @@ H5G_init(void)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_init() */
-
-/*-------------------------------------------------------------------------
- * Function: H5G__init_package
- *
- * Purpose: Initializes the H5G interface.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Monday, January 5, 1998
- *
- * Notes: The group creation properties are registered in the property
- * list interface initialization routine (H5P_init_package)
- * so that the file creation property class can inherit from it
- * correctly. (Which allows the file creation property list to
- * control the group creation properties of the root group of
- * a file) QAK - 24/10/2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G__init_package(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
-
/* Initialize the ID group for the group IDs */
if (H5I_register_type(H5I_GROUP_CLS) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface")
- /* Mark "top" of interface as initialized, too */
- H5G_top_package_initialize_s = TRUE;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G__init_package() */
+} /* end H5G_init() */
/*-------------------------------------------------------------------------
* Function: H5G_top_term_package
@@ -200,16 +159,10 @@ H5G_top_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5G_top_package_initialize_s) {
- if (H5I_nmembers(H5I_GROUP) > 0) {
- (void)H5I_clear_type(H5I_GROUP, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
-
- /* Mark closed */
- if (0 == n)
- H5G_top_package_initialize_s = FALSE;
- } /* end if */
+ if (H5I_nmembers(H5I_GROUP) > 0) {
+ (void)H5I_clear_type(H5I_GROUP, FALSE, FALSE);
+ n++;
+ }
FUNC_LEAVE_NOAPI(n)
} /* end H5G_top_term_package() */
@@ -238,18 +191,11 @@ H5G_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Sanity checks */
- HDassert(0 == H5I_nmembers(H5I_GROUP));
- HDassert(FALSE == H5G_top_package_initialize_s);
-
- /* Destroy the group object id group */
- n += (H5I_dec_type_ref(H5I_GROUP) > 0);
+ /* Sanity checks */
+ HDassert(0 == H5I_nmembers(H5I_GROUP));
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Destroy the group object id group */
+ n += (H5I_dec_type_ref(H5I_GROUP) > 0);
FUNC_LEAVE_NOAPI(n)
} /* end H5G_term_package() */
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index ba29b78..d73888e 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -1210,7 +1210,7 @@ H5G__node_copy(H5F_t *f, const void H5_ATTR_UNUSED *_lt_key, haddr_t addr, const
&(sn->entry[i]); /* Convenience variable to refer to current source group entry */
H5O_link_t lnk; /* Link to insert */
const char * name; /* Name of source object */
- H5G_entry_t tmp_src_ent; /* Temperary copy. Change will not affect the cache */
+ H5G_entry_t tmp_src_ent; /* Temporary copy. Change will not affect the cache */
H5O_type_t obj_type = H5O_TYPE_UNKNOWN; /* Target object type */
H5G_copy_file_ud_t *cpy_udata; /* Copy file udata */
H5G_obj_create_t gcrt_info; /* Group creation info */
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index d9c29f6..ce36b84 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -1113,7 +1113,7 @@ H5_DLL herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link
* actual object name length, the object name is truncated to
* \Code{max_size - 1} characters.
*
- * Note that if the size of the object's name is unkown, a preliminary
+ * Note that if the size of the object's name is unknown, a preliminary
* call to H5Gget_objname_by_idx() with \p name set to \c NULL will
* return the length of the object's name. A second call to
* H5Gget_objname_by_idx() can then be used to retrieve the actual
diff --git a/src/H5HF.c b/src/H5HF.c
index 6c6b101..7904af9 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -63,9 +63,6 @@
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -358,7 +355,7 @@ H5HF_insert(H5HF_t *fh, size_t size, const void *obj, void *id /*out*/)
if (size > hdr->max_man_size) {
/* Store 'huge' object in heap
*
- * Although not ideal, we can quiet the const warning here becuase no
+ * Although not ideal, we can quiet the const warning here because no
* obj pointer that was originally const should ever arrive here.
*/
H5_GCC_CLANG_DIAG_OFF("cast-qual")
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index 654fa36..3a48018 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -799,7 +799,7 @@ H5HF__cache_hdr_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_NDEBUG_UN
/* Encode I/O filter information */
if (H5O_msg_encode(hdr->f, H5O_PLINE_ID, FALSE, image, &(hdr->pline)) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "can't encode I/O pipeline fiters")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "can't encode I/O pipeline filters")
image += hdr->filter_len;
} /* end if */
@@ -898,7 +898,7 @@ H5HF__cache_iblock_get_initial_load_size(void *_udata, size_t *image_len)
* Function: H5HF__cache_iblock_verify_chksum
*
* Purpose: Verify the computed checksum of the data structure is the
- * same as the stored chksum.
+ * same as the stored checksum.
*
* Return: Success: TRUE/FALSE
* Failure: Negative
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index 8dbb3f4..d38ae20 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -50,7 +50,7 @@
/* User data for direct block debugging iterator callback */
typedef struct {
FILE * stream; /* Stream for output */
- int indent; /* Indention amount */
+ int indent; /* Indentation amount */
int fwidth; /* Field width mount */
haddr_t dblock_addr; /* Direct block's address */
hsize_t dblock_size; /* Direct block's size */
@@ -63,7 +63,7 @@ typedef struct {
typedef struct {
H5FS_t *fspace; /* Free space manager */
FILE * stream; /* Stream for output */
- int indent; /* Indention amount */
+ int indent; /* Indentation amount */
int fwidth; /* Field width mount */
} H5HF_debug_iter_ud2_t;
diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c
index 4adb47a..749b973 100644
--- a/src/H5HFdblock.c
+++ b/src/H5HFdblock.c
@@ -432,7 +432,7 @@ H5HF__man_dblock_protect(H5HF_hdr_t *hdr, haddr_t dblock_addr, size_t dblock_siz
H5HF_indirect_t *par_iblock, unsigned par_entry, unsigned flags)
{
H5HF_direct_t * dblock; /* Direct block from cache */
- H5HF_dblock_cache_ud_t udata; /* parent and other infor for deserializing direct block */
+ H5HF_dblock_cache_ud_t udata; /* parent and other info for deserializing direct block */
H5HF_direct_t * ret_value = NULL; /* Return value */
FUNC_ENTER_PACKAGE
diff --git a/src/H5HFspace.c b/src/H5HFspace.c
index d62267c..67f9b6f 100644
--- a/src/H5HFspace.c
+++ b/src/H5HFspace.c
@@ -383,7 +383,7 @@ H5HF__space_create_root(const H5HF_hdr_t *hdr, H5HF_indirect_t *root_iblock)
/* Only need to scan the sections if the free space has been initialized */
if (hdr->fspace)
- /* Iterate over all sections, seting the parent pointers in 'single' sections to the new indirect
+ /* Iterate over all sections, setting the parent pointers in 'single' sections to the new indirect
* block */
if (H5FS_sect_iterate(hdr->f, hdr->fspace, H5HF__space_create_root_cb, root_iblock) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to set parent pointers")
diff --git a/src/H5HG.c b/src/H5HG.c
index f474748..101d90a 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -84,9 +84,6 @@ static size_t H5HG__alloc(H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned *h
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declare a free list to manage the H5HG_heap_t struct */
H5FL_DEFINE(H5HG_heap_t);
@@ -132,7 +129,7 @@ H5HG__create(H5F_t *f, size_t size)
size_t n;
haddr_t ret_value = HADDR_UNDEF; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__GLOBALHEAP_TAG)
+ FUNC_ENTER_STATIC
/* Check args */
HDassert(f);
@@ -221,7 +218,7 @@ done:
} /* end if */
} /* end if */
- FUNC_LEAVE_NOAPI_TAG(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5HG__create() */
/*-------------------------------------------------------------------------
diff --git a/src/H5HL.c b/src/H5HL.c
index 1f2369a..eb25875 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -64,9 +64,6 @@ static herr_t H5HL__dirty(H5HL_t *heap);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declare a free list to manage the H5HL_free_t struct */
H5FL_DEFINE(H5HL_free_t);
diff --git a/src/H5HP.c b/src/H5HP.c
deleted file mode 100644
index d164223..0000000
--- a/src/H5HP.c
+++ /dev/null
@@ -1,904 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * 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: Provides a heap abstract data type.
- *
- * (See chapter 11 - "Priority Queues" of _Algorithms_, by
- * Sedgewick for additional information)
- *
- */
-
-/* Private headers needed */
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5HPprivate.h" /* Heap routines */
-#include "H5FLprivate.h" /* Memory management functions */
-
-/* Local Macros */
-#define H5HP_START_SIZE 16 /* Initial number of entries for heaps */
-
-/* Private typedefs & structs */
-
-/* Data structure for entries in the internal heap array */
-typedef struct {
- int val; /* Value to be used for heap condition */
- H5HP_info_t *obj; /* Pointer to object stored in heap */
-} H5HP_ent_t;
-
-/* Main heap data structure */
-struct H5HP_t {
- H5HP_type_t type; /* Type of heap (minimum or maximum value at "top") */
- size_t nobjs; /* Number of active objects in heap array */
- size_t nalloc; /* Number of allocated locations in heap array */
- H5HP_ent_t *heap; /* Pointer to array containing heap entries */
-};
-
-/* Static functions */
-static herr_t H5HP__swim_max(H5HP_t *heap, size_t loc);
-static herr_t H5HP__swim_min(H5HP_t *heap, size_t loc);
-static herr_t H5HP__sink_max(H5HP_t *heap, size_t loc);
-static herr_t H5HP__sink_min(H5HP_t *heap, size_t loc);
-
-/* Declare a free list to manage the H5HP_t struct */
-H5FL_DEFINE_STATIC(H5HP_t);
-
-/* Declare a free list to manage sequences of H5HP_ent_t */
-H5FL_SEQ_DEFINE_STATIC(H5HP_ent_t);
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP__swim_max
- PURPOSE
- Restore heap condition by moving an object upward
- USAGE
- herr_t H5HP__swim_max(heap, loc)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- size_t loc; IN: Location to start from
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Restore the heap condition for the heap's array by "swimming" the object
- at a location upward.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- This routine is for "maximum" value heaps.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5HP__swim_max(H5HP_t *heap, size_t loc)
-{
- int val; /* Temporary copy value of object to move in heap */
- H5HP_info_t *obj; /* Temporary pointer to object to move in heap */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC_NOERR
-
- /* Get copies of the information about the object to move in the heap */
- val = heap->heap[loc].val;
- obj = heap->heap[loc].obj;
-
- /* Move object up in heap until it's reached the maximum location possible */
- while (heap->heap[loc / 2].val < val) {
- /* Move object "above" current location in heap down */
- heap->heap[loc].val = heap->heap[loc / 2].val;
- heap->heap[loc].obj = heap->heap[loc / 2].obj;
-
- /* Update heap location for object which moved */
- heap->heap[loc].obj->heap_loc = loc;
-
- /* Move to location "above" current location */
- loc = loc / 2;
- } /* end while */
-
- /* Put object into heap at correct location */
- heap->heap[loc].val = val;
- heap->heap[loc].obj = obj;
-
- /* Update heap location for object */
- heap->heap[loc].obj->heap_loc = loc;
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP__swim_max() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP__swim_min
- PURPOSE
- Restore heap condition by moving an object upward
- USAGE
- herr_t H5HP__swim_min(heap, loc)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- size_t loc; IN: Location to start from
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Restore the heap condition for the heap's array by "swimming" the object
- at a location upward.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- This routine is for "minimum" value heaps.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5HP__swim_min(H5HP_t *heap, size_t loc)
-{
- int val; /* Temporary copy value of object to move in heap */
- H5HP_info_t *obj; /* Temporary pointer to object to move in heap */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC_NOERR
-
- /* Get copies of the information about the object to move in the heap */
- val = heap->heap[loc].val;
- obj = heap->heap[loc].obj;
-
- /* Move object up in heap until it's reached the minimum location possible */
- while (heap->heap[loc / 2].val > val) {
- /* Move object "above" current location in heap down */
- heap->heap[loc].val = heap->heap[loc / 2].val;
- heap->heap[loc].obj = heap->heap[loc / 2].obj;
-
- /* Update heap location for object which moved */
- heap->heap[loc].obj->heap_loc = loc;
-
- /* Move to location "above" current location */
- loc = loc / 2;
- } /* end while */
-
- /* Put object into heap at correct location */
- heap->heap[loc].val = val;
- heap->heap[loc].obj = obj;
-
- /* Update heap location for object */
- heap->heap[loc].obj->heap_loc = loc;
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP__swim_min() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP__sink_max
- PURPOSE
- Restore heap condition by moving an object downward
- USAGE
- herr_t H5HP__sink_max(heap, loc)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- size_t loc; IN: Location to start from
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Restore the heap condition for the heap's array by "sinking" the object
- at a location downward.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- This routine is for "maximum" value heaps.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5HP__sink_max(H5HP_t *heap, size_t loc)
-{
- int val; /* Temporary copy value of object to move in heap */
- void * obj; /* Temporary pointer to object to move in heap */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC_NOERR
-
- /* Get copies of the information about the object to move in the heap */
- val = heap->heap[loc].val;
- obj = heap->heap[loc].obj;
-
- /* Move object up in heap until it's reached the maximum location possible */
- while ((2 * loc) <= heap->nobjs) {
- size_t new_loc = loc * 2; /* New object's potential location area */
-
- /* Get the greater of the two objects below the location in heap */
- if (new_loc < heap->nobjs && (heap->heap[new_loc].val < heap->heap[new_loc + 1].val))
- new_loc++;
-
- /* Check if the object is smaller than the larger of the objects below it */
- /* If so, its in the correct location now, and we can get out */
- if (val >= heap->heap[new_loc].val)
- break;
-
- /* Move the greater of the two objects below the current location up */
- heap->heap[loc].val = heap->heap[new_loc].val;
- heap->heap[loc].obj = heap->heap[new_loc].obj;
-
- /* Update heap location for object which moved */
- heap->heap[loc].obj->heap_loc = loc;
-
- /* Move to location "below" current location */
- loc = new_loc;
- } /* end while */
-
- /* Put object into heap at correct location */
- heap->heap[loc].val = val;
- heap->heap[loc].obj = (H5HP_info_t *)obj;
-
- /* Update heap location for object */
- heap->heap[loc].obj->heap_loc = loc;
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP__sink_max() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP__sink_min
- PURPOSE
- Restore heap condition by moving an object downward
- USAGE
- herr_t H5HP__sink_min(heap, loc)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- size_t loc; IN: Location to start from
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Restore the heap condition for the heap's array by "sinking" the object
- at a location downward.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- This routine is for "minimum" value heaps.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5HP__sink_min(H5HP_t *heap, size_t loc)
-{
- int val; /* Temporary copy value of object to move in heap */
- void * obj; /* Temporary pointer to object to move in heap */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC_NOERR
-
- /* Get copies of the information about the object to move in the heap */
- val = heap->heap[loc].val;
- obj = heap->heap[loc].obj;
-
- /* Move object up in heap until it's reached the maximum location possible */
- while ((2 * loc) <= heap->nobjs) {
- size_t new_loc = loc * 2; /* New object's potential location area */
-
- /* Get the lesser of the two objects below the location in heap */
- if (new_loc < heap->nobjs && (heap->heap[new_loc].val > heap->heap[new_loc + 1].val))
- new_loc++;
-
- /* Check if the object is greater than the larger of the objects below it */
- /* If so, its in the correct location now, and we can get out */
- if (val <= heap->heap[new_loc].val)
- break;
-
- /* Move the greater of the two objects below the current location up */
- heap->heap[loc].val = heap->heap[new_loc].val;
- heap->heap[loc].obj = heap->heap[new_loc].obj;
-
- /* Update heap location for object which moved */
- heap->heap[loc].obj->heap_loc = loc;
-
- /* Move to location "below" current location */
- loc = new_loc;
- } /* end while */
-
- /* Put object into heap at correct location */
- heap->heap[loc].val = val;
- heap->heap[loc].obj = (H5HP_info_t *)obj;
-
- /* Update heap location for object */
- heap->heap[loc].obj->heap_loc = loc;
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP__sink_min() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_create
- PURPOSE
- Create a heap
- USAGE
- H5HP_t *H5HP_create(heap_type)
- H5HP_type_t heap_type; IN: Type of heap to create
-
- RETURNS
- Returns a pointer to a heap on success, NULL on failure.
- DESCRIPTION
- Create a priority queue. The SIZE is used to set the initial number of
- entries allocated.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-H5HP_t *
-H5HP_create(H5HP_type_t heap_type)
-{
- H5HP_t *new_heap = NULL; /* Pointer to new heap object created */
- H5HP_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(NULL)
-
- /* Check args */
- HDassert(heap_type == H5HP_MIN_HEAP || heap_type == H5HP_MAX_HEAP);
-
- /* Allocate ref-counted string structure */
- if ((new_heap = H5FL_MALLOC(H5HP_t)) == NULL)
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "memory allocation failed");
-
- /* Allocate the array to store the heap entries */
- if ((new_heap->heap = H5FL_SEQ_MALLOC(H5HP_ent_t, (size_t)(H5HP_START_SIZE + 1))) == NULL)
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "memory allocation failed");
-
- /* Set the internal fields */
- new_heap->type = heap_type;
- new_heap->nobjs = 0;
- new_heap->nalloc = H5HP_START_SIZE + 1;
-
- /* Set the information in the 0'th location based on the type of heap */
- if (heap_type == H5HP_MIN_HEAP) {
- /* Set the value in the '0' location to be the minimum value, to
- * simplify the algorithms
- */
- new_heap->heap[0].val = INT_MIN;
- new_heap->heap[0].obj = NULL;
- } /* end if */
- else {
- /* Set the value in the '0' location to be the maximum value, to
- * simplify the algorithms
- */
- new_heap->heap[0].val = INT_MAX;
- new_heap->heap[0].obj = NULL;
- } /* end else */
-
- /* Set the return value */
- ret_value = new_heap;
-
-done:
- /* Error cleanup */
- if (NULL == ret_value) {
- if (NULL != new_heap) {
- if (NULL != new_heap->heap)
- new_heap->heap = H5FL_SEQ_FREE(H5HP_ent_t, new_heap->heap);
- new_heap = H5FL_FREE(H5HP_t, new_heap);
- } /* end if */
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP_create() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_count
- PURPOSE
- Check the number of elements in a heap
- USAGE
- ssize_t H5HP_count(heap)
- const H5HP_t *heap; IN: Pointer to heap to query
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Checks the number of elements in heap
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-ssize_t
-H5HP_count(const H5HP_t *heap)
-{
- ssize_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check args */
- HDassert(heap);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- /* Return the number of objects in the heap */
- H5_CHECK_OVERFLOW(heap->nobjs, size_t, ssize_t);
- ret_value = (ssize_t)heap->nobjs;
-
- /* No post-condition check necessary, since heap is constant */
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP_count() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_insert
- PURPOSE
- Insert an object into a heap, with an initial value
- USAGE
- herr_t H5HP_insert(heap, val, obj)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- int val; IN: Initial value for object in heap
- void *obj; IN: Pointer to object to insert into heap
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Inserts a OBJ into a HEAP, with an initial VALue.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5HP_insert(H5HP_t *heap, int val, void *obj)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Check args */
- HDassert(heap);
- HDassert(obj);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- /* Increment number of objects in heap */
- heap->nobjs++;
-
- /* Check if we need to allocate more room for heap array */
- if (heap->nobjs >= heap->nalloc) {
- size_t n = MAX(H5HP_START_SIZE, 2 * (heap->nalloc - 1)) + 1;
- H5HP_ent_t *new_heap = H5FL_SEQ_REALLOC(H5HP_ent_t, heap->heap, n);
-
- if (!new_heap)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend heap array");
- heap->heap = new_heap;
- heap->nalloc = n;
- } /* end if */
-
- /* Insert new object at end of heap */
- heap->heap[heap->nobjs].val = val;
- heap->heap[heap->nobjs].obj = (H5HP_info_t *)obj;
- heap->heap[heap->nobjs].obj->heap_loc = heap->nobjs;
-
- /* Restore heap condition */
- if (heap->type == H5HP_MAX_HEAP) {
- if (H5HP__swim_max(heap, heap->nobjs) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to restore heap condition");
- } /* end if */
- else {
- if (H5HP__swim_min(heap, heap->nobjs) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to restore heap condition");
- } /* end else */
-
-done:
-
- /* Check internal consistency */
- /* (Post-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP_insert() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_top
- PURPOSE
- Check the value of the top object in the heap
- USAGE
- herr_t H5HP_top(heap, val)
- const H5HP_t *heap; IN: Pointer to heap to modify
- int val; IN/OUT: Initial value for object in heap
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Checks the value of the top object in a heap
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5HP_top(const H5HP_t *heap, int *val)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check args */
- HDassert(heap);
- HDassert(val);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- /* Get value of the top object in the heap */
- *val = heap->heap[1].val;
-
- /* No post-condition check necessary, since heap is constant */
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* end H5HP_top() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_remove
- PURPOSE
- Remove an object into a heap
- USAGE
- herr_t H5HP_remove(heap, val, obj)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- int *val; OUT: Pointer to value of object removed from heap
- void **obj; OUT: Pointer to object removed from heap
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Removes the top object on a heap, returning its value and object pointer
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5HP_remove(H5HP_t *heap, int *val, void **obj)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Check args */
- HDassert(heap);
- HDassert(val);
- HDassert(obj);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- /* Check if there are any objects on the heap to remove */
- if (heap->nobjs == 0)
- HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "heap is empty");
-
- /* Get the information for the top object on the heap */
- HDassert(heap->heap[1].obj->heap_loc == 1);
- *val = heap->heap[1].val;
- *obj = heap->heap[1].obj;
-
- /* Move the last element in the heap to the top */
- heap->heap[1].val = heap->heap[heap->nobjs].val;
- heap->heap[1].obj = heap->heap[heap->nobjs].obj;
- heap->heap[1].obj->heap_loc = 1;
-
- /* Decrement number of objects in heap */
- heap->nobjs--;
-
- /* Restore heap condition, if there are objects on the heap */
- if (heap->nobjs > 0) {
- if (heap->type == H5HP_MAX_HEAP) {
- if (H5HP__sink_max(heap, (size_t)1) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to restore heap condition");
- } /* end if */
- else {
- if (H5HP__sink_min(heap, (size_t)1) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to restore heap condition");
- } /* end else */
- } /* end if */
-
-done:
-
- /* Check internal consistency */
- /* (Post-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP_remove() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_change
- PURPOSE
- Change the priority of an object on a heap
- USAGE
- herr_t H5HP_change(heap, val, obj)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- int val; IN: New priority value for object
- void *obj; IN: Pointer to object to modify
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Changes the priority of an object on a heap.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5HP_change(H5HP_t *heap, int val, void *_obj)
-{
- H5HP_info_t *obj = (H5HP_info_t *)_obj; /* Alias for object */
- size_t obj_loc; /* Location of object in heap */
- int old_val; /* Object's old priority value */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Check args */
- HDassert(heap);
- HDassert(obj);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- /* Get the location of the object in the heap */
- obj_loc = obj->heap_loc;
- HDassert(obj_loc > 0 && obj_loc <= heap->nobjs);
-
- /* Change the heap object's priority */
- old_val = heap->heap[obj_loc].val;
- heap->heap[obj_loc].val = val;
-
- /* Restore heap condition */
- if (val < old_val) {
- if (heap->type == H5HP_MAX_HEAP) {
- if (H5HP__sink_max(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
- } /* end if */
- else {
- if (H5HP__swim_min(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
- } /* end else */
- } /* end if */
- else {
- if (heap->type == H5HP_MAX_HEAP) {
- if (H5HP__swim_max(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
- } /* end if */
- else {
- if (H5HP__sink_min(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
- } /* end else */
- } /* end else */
-
-done:
-
- /* Check internal consistency */
- /* (Post-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP_change() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_incr
- PURPOSE
- Increment the priority of an object on a heap
- USAGE
- herr_t H5HP_incr(heap, amt, obj)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- unsigned amt; IN: Amount to increase priority by
- void *obj; IN: Pointer to object to modify
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Increments the priority of an object on a heap by one.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5HP_incr(H5HP_t *heap, unsigned amt, void *_obj)
-{
- H5HP_info_t *obj = (H5HP_info_t *)_obj; /* Alias for object */
- size_t obj_loc; /* Location of object in heap */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Check args */
- HDassert(heap);
- HDassert(obj);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- /* Get the location of the object in the heap */
- obj_loc = obj->heap_loc;
- HDassert(obj_loc > 0 && obj_loc <= heap->nobjs);
-
- /* Change the heap object's priority */
- heap->heap[obj_loc].val += (int)amt;
-
- /* Restore heap condition */
- if (H5HP_MAX_HEAP == heap->type) {
- if (H5HP__swim_max(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition")
- } /* end if */
- else {
- if (H5HP__sink_min(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition")
- } /* end else */
-
-done:
-
- /* Check internal consistency */
- /* (Post-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP_incr() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_decr
- PURPOSE
- Decrement the priority of an object on a heap
- USAGE
- herr_t H5HP_dec(heap, amt, obj)
- H5HP_t *heap; IN/OUT: Pointer to heap to modify
- unsigned amt; IN: Amount to decrease priority by
- void *obj; IN: Pointer to object to modify
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Decrements the priority of an object on a heap by one.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5HP_decr(H5HP_t *heap, unsigned amt, void *_obj)
-{
- H5HP_info_t *obj = (H5HP_info_t *)_obj; /* Alias for object */
- size_t obj_loc; /* Location of object in heap */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Check args */
- HDassert(heap);
- HDassert(obj);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- /* Get the location of the object in the heap */
- obj_loc = obj->heap_loc;
- HDassert(obj_loc > 0 && obj_loc <= heap->nobjs);
-
- /* Change the heap object's priority */
- H5_CHECK_OVERFLOW(amt, unsigned, int);
- heap->heap[obj_loc].val -= (int)amt;
-
- /* Restore heap condition */
- if (heap->type == H5HP_MAX_HEAP) {
- if (H5HP__sink_max(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
- } /* end if */
- else {
- if (H5HP__swim_min(heap, obj_loc) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRESTORE, FAIL, "unable to restore heap condition");
- } /* end else */
-
-done:
-
- /* Check internal consistency */
- /* (Post-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(heap->heap[0].obj == NULL);
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5HP_decr() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5HP_close
- PURPOSE
- Close a heap, deallocating it.
- USAGE
- herr_t H5HP_close(heap)
- H5HP_t *heap; IN/OUT: Pointer to heap to close
-
- RETURNS
- Returns non-negative on success, negative on failure.
- DESCRIPTION
- Close a heap, freeing all internal information. Any objects left in
- the heap are not deallocated.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5HP_close(H5HP_t *heap)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check args */
- HDassert(heap);
-
- /* Check internal consistency */
- /* (Pre-condition) */
- HDassert(heap->nobjs < heap->nalloc);
- HDassert(heap->heap);
- HDassert((heap->type == H5HP_MAX_HEAP && heap->heap[0].val == INT_MAX) ||
- (heap->type == H5HP_MIN_HEAP && heap->heap[0].val == INT_MIN));
- HDassert(NULL == heap->heap[0].obj);
-
- /* Free internal structures for heap */
- heap->heap = H5FL_SEQ_FREE(H5HP_ent_t, heap->heap);
-
- /* Free actual heap object */
- heap = H5FL_FREE(H5HP_t, heap);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5HP_close() */
diff --git a/src/H5HPprivate.h b/src/H5HPprivate.h
deleted file mode 100644
index 50020bc..0000000
--- a/src/H5HPprivate.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*
- * This file contains private information about the H5HP module
- */
-#ifndef H5HPprivate_H
-#define H5HPprivate_H
-
-/**************************************/
-/* Public headers needed by this file */
-/**************************************/
-#ifdef LATER
-#include "H5HPpublic.h"
-#endif /* LATER */
-
-/***************************************/
-/* Private headers needed by this file */
-/***************************************/
-#include "H5private.h"
-
-/************/
-/* Typedefs */
-/************/
-
-/* Typedef for heap struct (defined in H5HP.c) */
-typedef struct H5HP_t H5HP_t;
-
-/* Typedef for objects which can be inserted into heaps */
-/* This _must_ be the first field in objects which can be inserted into heaps */
-typedef struct H5HP_info_t {
- size_t heap_loc; /* Location of object in heap */
-} H5HP_info_t;
-
-/* Typedef for type of heap to create */
-typedef enum {
- H5HP_MIN_HEAP, /* Minimum values in heap are at the "top" */
- H5HP_MAX_HEAP /* Maximum values in heap are at the "top" */
-} H5HP_type_t;
-
-/**********/
-/* Macros */
-/**********/
-
-/********************/
-/* Private routines */
-/********************/
-H5_DLL H5HP_t *H5HP_create(H5HP_type_t heap_type);
-H5_DLL herr_t H5HP_insert(H5HP_t *heap, int val, void *obj);
-H5_DLL ssize_t H5HP_count(const H5HP_t *heap);
-H5_DLL herr_t H5HP_top(const H5HP_t *heap, int *val);
-H5_DLL herr_t H5HP_remove(H5HP_t *heap, int *val, void **ptr);
-H5_DLL herr_t H5HP_change(H5HP_t *heap, int val, void *obj);
-H5_DLL herr_t H5HP_incr(H5HP_t *heap, unsigned amt, void *obj);
-H5_DLL herr_t H5HP_decr(H5HP_t *heap, unsigned amt, void *obj);
-H5_DLL herr_t H5HP_close(H5HP_t *heap);
-
-#endif /* H5HPprivate_H */
diff --git a/src/H5I.c b/src/H5I.c
index 954a86b..0a4fa10 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -814,7 +814,7 @@ H5I__iterate_pub_cb(void H5_ATTR_UNUSED *obj, hid_t id, void *_udata)
/*-------------------------------------------------------------------------
* Function: H5Iiterate
*
- * Purpose: Call the callback funciton op for each member of the id
+ * Purpose: Call the callback function op for each member of the id
* type type. op takes as parameters the id and a
* passthrough of op_data, and returns an herr_t. A positive
* return from op will cause the iteration to stop and
diff --git a/src/H5Iint.c b/src/H5Iint.c
index 86a2810..1ea2ad7 100644
--- a/src/H5Iint.c
+++ b/src/H5Iint.c
@@ -85,9 +85,6 @@ static int H5I__find_id_cb(void *_item, void *_key, void *_udata);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declared extern in H5Ipkg.h and documented there */
H5I_type_info_t *H5I_type_info_array_g[H5I_MAX_NUM_TYPES];
int H5I_next_type_g = (int)H5I_NTYPES;
@@ -127,30 +124,24 @@ H5I_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- H5I_type_info_t *type_info = NULL; /* Pointer to ID type */
- int i;
-
- /* Count the number of types still in use */
- for (i = 0; i < H5I_next_type_g; i++)
- if ((type_info = H5I_type_info_array_g[i]) && type_info->hash_table)
+ H5I_type_info_t *type_info = NULL; /* Pointer to ID type */
+ int i;
+
+ /* Count the number of types still in use */
+ for (i = 0; i < H5I_next_type_g; i++)
+ if ((type_info = H5I_type_info_array_g[i]) && type_info->hash_table)
+ in_use++;
+
+ /* If no types are still being used then clean up */
+ if (0 == in_use) {
+ for (i = 0; i < H5I_next_type_g; i++) {
+ type_info = H5I_type_info_array_g[i];
+ if (type_info) {
+ HDassert(NULL == type_info->hash_table);
+ type_info = H5MM_xfree(type_info);
+ H5I_type_info_array_g[i] = NULL;
in_use++;
-
- /* If no types are still being used then clean up */
- if (0 == in_use) {
- for (i = 0; i < H5I_next_type_g; i++) {
- type_info = H5I_type_info_array_g[i];
- if (type_info) {
- HDassert(NULL == type_info->hash_table);
- type_info = H5MM_xfree(type_info);
- H5I_type_info_array_g[i] = NULL;
- in_use++;
- }
}
-
- /* Mark interface closed */
- if (0 == in_use)
- H5_PKG_INIT_VAR = FALSE;
}
}
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 8d4dbf8..d6892bb 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -508,7 +508,7 @@ H5_DLL int H5Idec_type_ref(H5I_type_t type);
*
* \brief Retrieves the reference count on an ID type
*
- * \param[in] type The identifier of the type whose reference count is to be retieved
+ * \param[in] type The identifier of the type whose reference count is to be retrieved
*
* \return Returns the current reference count on success, negative on failure.
*
diff --git a/src/H5Lint.c b/src/H5Lint.c
index 346c37d..9e45124 100644
--- a/src/H5Lint.c
+++ b/src/H5Lint.c
@@ -175,9 +175,6 @@ static herr_t H5L__get_name_by_idx_cb(H5G_loc_t *grp_loc /*in*/, const char *nam
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -211,30 +208,6 @@ H5L_init(void)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5L_init() */
-
-/*-------------------------------------------------------------------------
- * Function: H5L__init_package
- *
- * Purpose: Initialize information specific to H5L interface.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: James Laird
- * Tuesday, January 24, 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5L__init_package(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
/* Initialize user-defined link classes */
if (H5L_register_external() < 0)
@@ -242,12 +215,12 @@ H5L__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5L_init_package() */
+} /* end H5L_init() */
/*-------------------------------------------------------------------------
* Function: H5L_term_package
*
- * Purpose: Terminate any resources allocated in H5L__init_package.
+ * Purpose: Terminate any resources allocated in H5L_init.
*
* Return: Non-negative on success/Negative on failure
*
@@ -263,17 +236,11 @@ H5L_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Free the table of link types */
- if (H5L_table_g) {
- H5L_table_g = (H5L_class_t *)H5MM_xfree(H5L_table_g);
- H5L_table_used_g = H5L_table_alloc_g = 0;
- n++;
- } /* end if */
-
- /* Mark the interface as uninitialized */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
+ /* Free the table of link types */
+ if (H5L_table_g) {
+ H5L_table_g = (H5L_class_t *)H5MM_xfree(H5L_table_g);
+ H5L_table_used_g = H5L_table_alloc_g = 0;
+ n++;
} /* end if */
FUNC_LEAVE_NOAPI(n)
diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h
index 72b0182..ca5f6e6 100644
--- a/src/H5Lpublic.h
+++ b/src/H5Lpublic.h
@@ -462,7 +462,7 @@ H5_DLL herr_t H5Ldelete_by_idx_async(const char *app_file, const char *app_func,
*
* \return \herr_t
*
- * \details H5Lget_val() returns tha value of link \p name. For smbolic links,
+ * \details H5Lget_val() returns the value of link \p name. For smbolic links,
* this is the path to which the link points, including the null
* terminator. For external and user-defined links, it is the link
* buffer.
@@ -492,7 +492,7 @@ H5_DLL herr_t H5Ldelete_by_idx_async(const char *app_file, const char *app_func,
*
* This function should be used only after H5Lget_info() has been
* called to verify that \p name is a symbolic link. This can be
- * deteremined from the \c link_type field of the \ref H5L_info_t
+ * determined from the \c link_type field of the \ref H5L_info_t
* \c struct.
*
* \note This function will fail if called on a hard link.
@@ -580,7 +580,7 @@ H5_DLL herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t
* name includes either a relative path or an absolute path to the
* target link, intermediate steps along the path must be verified
* before the existence of the target link can be safely checked. If
- * the path is not verified and an intermediate element of the path
+ * the path is not verified, and an intermediate element of the path
* does not exist, H5Lexists() will fail. The example in the next
* paragraph illustrates one step-by-step method for verifying the
* existence of a link with a relative or absolute path.
@@ -620,13 +620,13 @@ H5_DLL herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t
* H5Lexists() with arguments \c file, \c "/", and \c lapl
* returns a positive value; in other words,
* \Code{H5Lexists(file, "/", lapl)} returns a positive value.
- * In HDF5 version 1.8.16, this function returns 0.</li>
+ * In the HDF5 1.8 release, this function returns 0.</li>
* <li>Let \c root denote a valid HDF5 group identifier that refers to the
* root group of an HDF5 file, and let \c lapl denote a valid link
* access property list identifier. A call to H5Lexists() with
* arguments c root, \c "/", and \c lapl returns a positive value;
- * in other words, \Code{H5Lexists(root, "/", lapl)} returns a postive
- * value. In HDF5 version 1.8.16, this function returns 0.</li>
+ * in other words, \Code{H5Lexists(root, "/", lapl)} returns a positive
+ * value. In the HDF5 1.8 release, this function returns 0.</li>
* </ol>
* Note that the function accepts link names and path names. This is
* potentially misleading to callers, and we plan to separate the
@@ -1094,7 +1094,7 @@ H5_DLL herr_t H5Lvisit2(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order
* \p idx_type specifies the index to be used. If the links have not
* been indexed by the index type, they will first be sorted by that
* index then the iteration will begin; if the links have been so
- * indexed, the sorting step will be unnecesary, so the iteration may
+ * indexed, the sorting step will be unnecessary, so the iteration may
* begin more quickly. Valid values include the following:
* \indexes
*
@@ -1853,7 +1853,7 @@ H5_DLL herr_t H5Lvisit1(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order
* \p idx_type specifies the index to be used. If the links have not
* been indexed by the index type, they will first be sorted by that
* index then the iteration will begin; if the links have been so
- * indexed, the sorting step will be unnecesary, so the iteration may
+ * indexed, the sorting step will be unnecessary, so the iteration may
* begin more quickly. Valid values include the following:
* \indexes
*
diff --git a/src/H5M.c b/src/H5M.c
index 845c054..59ce615 100644
--- a/src/H5M.c
+++ b/src/H5M.c
@@ -58,9 +58,6 @@ static herr_t H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const voi
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -77,9 +74,6 @@ static const H5I_class_t H5I_MAP_CLS[1] = {{
(H5I_free_t)H5M__close_cb /* Callback routine for closing objects of this class */
}};
-/* Flag indicating "top" of interface has been initialized */
-static hbool_t H5M_top_package_initialize_s = FALSE;
-
/*-------------------------------------------------------------------------
* Function: H5M_init
*
@@ -96,41 +90,14 @@ H5M_init(void)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5M_init() */
-
-/*-------------------------------------------------------------------------
-NAME
- H5M__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5M__init_package()
-
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
----------------------------------------------------------------------------
-*/
-herr_t
-H5M__init_package(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
/* Initialize the ID group for the map IDs */
if (H5I_register_type(H5I_MAP_CLS) < 0)
HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, FAIL, "unable to initialize interface")
- /* Mark "top" of interface as initialized, too */
- H5M_top_package_initialize_s = TRUE;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5M__init_package() */
+} /* end H5M_init() */
/*-------------------------------------------------------------------------
* Function: H5M_top_term_package
@@ -149,16 +116,10 @@ H5M_top_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5M_top_package_initialize_s) {
- if (H5I_nmembers(H5I_MAP) > 0) {
- (void)H5I_clear_type(H5I_MAP, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
-
- /* Mark closed */
- if (0 == n)
- H5M_top_package_initialize_s = FALSE;
- } /* end if */
+ if (H5I_nmembers(H5I_MAP) > 0) {
+ (void)H5I_clear_type(H5I_MAP, FALSE, FALSE);
+ n++;
+ }
FUNC_LEAVE_NOAPI(n)
} /* end H5M_top_term_package() */
@@ -183,18 +144,11 @@ H5M_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Sanity checks */
- HDassert(0 == H5I_nmembers(H5I_MAP));
- HDassert(FALSE == H5M_top_package_initialize_s);
+ /* Sanity checks */
+ HDassert(0 == H5I_nmembers(H5I_MAP));
- /* Destroy the dataset object id group */
- n += (H5I_dec_type_ref(H5I_MAP) > 0);
-
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Destroy the dataset object id group */
+ n += (H5I_dec_type_ref(H5I_MAP) > 0);
FUNC_LEAVE_NOAPI(n)
} /* end H5M_term_package() */
diff --git a/src/H5MF.c b/src/H5MF.c
index ca780c3..3428661 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -119,9 +119,6 @@ static herr_t H5MF__defer_free(H5F_shared_t *shared, H5FD_mem_t alloc_type, hadd
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -448,7 +445,7 @@ H5MF__create_fstype(H5F_t *f, H5F_mem_page_t type)
H5AC_ring_t fsm_ring; /* Ring of FSM */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
/*
* Check arguments.
@@ -501,7 +498,7 @@ done:
if (orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__create_fstype() */
/*-------------------------------------------------------------------------
@@ -523,7 +520,7 @@ H5MF__start_fstype(H5F_t *f, H5F_mem_page_t type)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_PACKAGE
/*
* Check arguments.
@@ -550,7 +547,7 @@ H5MF__start_fstype(H5F_t *f, H5F_mem_page_t type)
} /* end else */
done:
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__start_fstype() */
/*-------------------------------------------------------------------------
@@ -574,7 +571,7 @@ H5MF__delete_fstype(H5F_t *f, H5F_mem_page_t type)
haddr_t tmp_fs_addr; /* Temporary holder for free space manager address */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
/* check args */
HDassert(f);
@@ -621,7 +618,7 @@ done:
if (orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__delete_fstype() */
/*-------------------------------------------------------------------------
@@ -642,7 +639,7 @@ H5MF__close_fstype(H5F_t *f, H5F_mem_page_t type)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
/*
* Check arguments.
@@ -667,7 +664,7 @@ H5MF__close_fstype(H5F_t *f, H5F_mem_page_t type)
f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
done:
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__close_fstype() */
/*-------------------------------------------------------------------------
@@ -691,7 +688,7 @@ H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_sectio
H5F_mem_page_t fs_type; /* Free space type (mapped from allocation type) */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(fspace);
@@ -713,8 +710,10 @@ H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_sectio
H5AC_set_ring(fsm_ring, &orig_ring);
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: adding node, node->sect_info.addr = %a, node->sect_info.size = %Hu\n", __func__,
- node->sect_info.addr, node->sect_info.size);
+ HDfprintf(stderr,
+ "%s: adding node, node->sect_info.addr = %" PRIuHADDR ", node->sect_info.size = %" PRIuHSIZE
+ "\n",
+ __func__, node->sect_info.addr, node->sect_info.size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Add the section */
if (H5FS_sect_add(f, fspace, (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
@@ -725,7 +724,7 @@ done:
if (orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__add_sect() */
/*-------------------------------------------------------------------------
@@ -749,7 +748,7 @@ H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, h
H5MF_free_section_t *node; /* Free space section pointer */
htri_t ret_value = FAIL; /* Whether an existing free list node was found */
- FUNC_ENTER_PACKAGE_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(fspace);
@@ -766,7 +765,7 @@ H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, h
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "error locating free space in file")
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: section found = %t\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: section found = %d\n", __func__, ret_value);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Check for actually finding section */
@@ -794,7 +793,7 @@ H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace, h
node->sect_info.size -= size;
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: re-adding node, node->sect_info.size = %Hu\n", __func__,
+ HDfprintf(stderr, "%s: re-adding node, node->sect_info.size = %" PRIuHSIZE "\n", __func__,
node->sect_info.size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
@@ -809,7 +808,7 @@ done:
if (orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__find_sect() */
/*-------------------------------------------------------------------------
@@ -838,7 +837,7 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, HADDR_UNDEF)
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", __func__, (unsigned)alloc_type, size);
+ HDfprintf(stderr, "%s: alloc_type = %u, size = %" PRIuHSIZE "\n", __func__, (unsigned)alloc_type, size);
#endif /* H5MF_ALLOC_DEBUG */
/* check arguments */
@@ -916,7 +915,8 @@ done:
H5AC_set_ring(orig_ring, NULL);
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", __func__, ret_value, size);
+ HDfprintf(stderr, "%s: Leaving: ret_value = %" PRIuHADDR ", size = %" PRIuHSIZE "\n", __func__, ret_value,
+ size);
#endif /* H5MF_ALLOC_DEBUG */
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF__sects_dump(f, stderr);
@@ -953,10 +953,10 @@ H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
H5MF_free_section_t *node = NULL; /* Free space section pointer */
haddr_t ret_value = HADDR_UNDEF; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", __func__, (unsigned)alloc_type, size);
+ HDfprintf(stderr, "%s: alloc_type = %u, size = %" PRIuHSIZE "\n", __func__, (unsigned)alloc_type, size);
#endif /* H5MF_ALLOC_DEBUG */
H5MF__alloc_to_fs_type(f->shared, alloc_type, size, &ptype);
@@ -1053,7 +1053,8 @@ H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
done:
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", __func__, ret_value, size);
+ HDfprintf(stderr, "%s: Leaving: ret_value = %" PRIuHADDR ", size = %" PRIuHSIZE "\n", __func__, ret_value,
+ size);
#endif /* H5MF_ALLOC_DEBUG */
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF__sects_dump(f, stderr);
@@ -1064,7 +1065,7 @@ done:
if (H5MF__sect_free((H5FS_section_info_t *)node) < 0)
HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, HADDR_UNDEF, "can't free section node")
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__alloc_pagefs() */
/*-------------------------------------------------------------------------
@@ -1099,7 +1100,7 @@ H5MF_alloc_tmp(H5F_t *f, hsize_t size)
FUNC_ENTER_NOAPI(HADDR_UNDEF)
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: size = %Hu\n", __func__, size);
+ HDfprintf(stderr, "%s: size = %" PRIuHSIZE "\n", __func__, size);
#endif /* H5MF_ALLOC_DEBUG */
/* check args */
@@ -1146,8 +1147,8 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size)
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", __func__,
- (unsigned)alloc_type, addr, size);
+ HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %" PRIuHADDR ", size = %" PRIuHSIZE "\n",
+ __func__, (unsigned)alloc_type, addr, size);
#endif /* H5MF_ALLOC_DEBUG */
/* check arguments */
@@ -1224,7 +1225,7 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si
* space is at the end of the file
*/
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: fs_addr = %a\n", __func__, f->shared->fs_addr[fs_type]);
+ HDfprintf(stderr, "%s: fs_addr = %" PRIuHADDR "\n", __func__, f->shared->fs_addr[fs_type]);
#endif /* H5MF_ALLOC_DEBUG_MORE */
if (!H5F_addr_defined(f->shared->fs_addr[fs_type])) {
htri_t status; /* "can absorb" status for section into */
@@ -1240,8 +1241,9 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si
HGOTO_DONE(SUCCEED)
else if (size < f->shared->fs_threshold) {
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", __func__, addr,
- size);
+ HDfprintf(stderr,
+ "%s: dropping addr = %" PRIuHADDR ", size = %" PRIuHSIZE ", on the floor!\n",
+ __func__, addr, size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
HGOTO_DONE(SUCCEED)
} /* end else-if */
@@ -1258,7 +1260,8 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si
*/
if (f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING || !H5F_HAVE_FREE_SPACE_MANAGER(f)) {
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", __func__, addr, size);
+ HDfprintf(stderr, "%s: dropping addr = %" PRIuHADDR ", size = %" PRIuHSIZE ", on the floor!\n",
+ __func__, addr, size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
HGOTO_DONE(SUCCEED)
} /* end if */
@@ -1352,7 +1355,7 @@ H5MF__xfree_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size)
* Further, in the VFD SWMR case, the large metadata entry will typically
* be buffered in the page buffer. If an intersecting entry is left
* in the page buffer, in addition to causing potential corruption in
- * the HDF5 file, it may also result in overlaping entries in the page
+ * the HDF5 file, it may also result in overlapping entries in the page
* buffer and metadata file index.
*
* It's ok to remove the page from the PB without flushing to
@@ -1416,7 +1419,9 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: Entering: alloc_type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n",
+ HDfprintf(stderr,
+ "%s: Entering: alloc_type = %u, addr = %" PRIuHADDR ", size = %" PRIuHSIZE
+ ", extra_requested = %" PRIuHSIZE "\n",
__func__, (unsigned)alloc_type, addr, size, extra_requested);
#endif /* H5MF_ALLOC_DEBUG */
@@ -1469,7 +1474,7 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi
if ((ret_value = H5F__try_extend(f, map_type, end, extra_requested + frag_size)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending file")
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: extended = %t\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: extended = %d\n", __func__, ret_value);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* If extending at EOA succeeds: */
@@ -1507,7 +1512,7 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending aggregation block")
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: H5MF__aggr_try_extend = %t\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: H5MF__aggr_try_extend = %d\n", __func__, ret_value);
#endif /* H5MF_ALLOC_DEBUG_MORE */
} /* end if */
@@ -1533,7 +1538,7 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL,
"error extending block in free space manager")
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: Try to H5FS_sect_try_extend = %t\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: Try to H5FS_sect_try_extend = %d\n", __func__, ret_value);
#endif /* H5MF_ALLOC_DEBUG_MORE */
} /* end if */
@@ -1544,7 +1549,7 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi
if (frag_size <= H5F_PGEND_META_THRES(f) && extra_requested <= frag_size)
ret_value = TRUE;
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: Try to extend into the page end threshold = %t\n", __func__,
+ HDfprintf(stderr, "%s: Try to extend into the page end threshold = %d\n", __func__,
ret_value);
#endif /* H5MF_ALLOC_DEBUG_MORE */
} /* end if */
@@ -1557,7 +1562,7 @@ done:
H5AC_set_ring(orig_ring, NULL);
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: Leaving: ret_value = %d\n", __func__, ret_value);
#endif /* H5MF_ALLOC_DEBUG */
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF__sects_dump(f, stderr);
@@ -1592,8 +1597,8 @@ H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size)
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
- HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", __func__,
- (unsigned)alloc_type, addr, size);
+ HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %" PRIuHADDR ", size = %" PRIuHSIZE "\n",
+ __func__, (unsigned)alloc_type, addr, size);
#endif /* H5MF_ALLOC_DEBUG */
/* check arguments */
@@ -1715,7 +1720,7 @@ H5MF__close_delete_fstype(H5F_t *f, H5F_mem_page_t type)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", __func__);
#endif /* H5MF_ALLOC_DEBUG */
@@ -1729,8 +1734,9 @@ H5MF__close_delete_fstype(H5F_t *f, H5F_mem_page_t type)
HDassert((H5FD_mem_t)type < H5FD_MEM_NTYPES);
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: Check 1.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", __func__,
- (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]);
+ HDfprintf(stderr, "%s: Check 1.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %" PRIuHADDR "\n",
+ __func__, (unsigned)type, (void *)f->shared->fs_man[type], (unsigned)type,
+ f->shared->fs_addr[type]);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* If the free space manager for this type is open, close it */
@@ -1739,8 +1745,9 @@ H5MF__close_delete_fstype(H5F_t *f, H5F_mem_page_t type)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't close the free space manager")
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: Check 2.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", __func__,
- (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]);
+ HDfprintf(stderr, "%s: Check 2.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %" PRIuHADDR "\n",
+ __func__, (unsigned)type, (void *)f->shared->fs_man[type], (unsigned)type,
+ f->shared->fs_addr[type]);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* If there is free space manager info for this type, delete it */
@@ -1752,7 +1759,7 @@ done:
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", __func__);
#endif /* H5MF_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5MF__close_delete() */
/*-------------------------------------------------------------------------
@@ -1884,7 +1891,7 @@ H5MF__close_aggrfs(H5F_t *f)
H5FD_mem_t type; /* Memory type for iteration */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", __func__);
#endif /* H5MF_ALLOC_DEBUG */
@@ -2026,7 +2033,7 @@ done:
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", __func__);
#endif /* H5MF_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__close_aggrfs() */
/*-------------------------------------------------------------------------
@@ -2050,7 +2057,7 @@ H5MF__close_pagefs(H5F_t *f)
H5O_fsinfo_t fsinfo; /* File space info message */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", __func__);
#endif /* H5MF_ALLOC_DEBUG */
@@ -2201,7 +2208,7 @@ done:
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", __func__);
#endif /* H5MF_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__close_pagefs() */
/*-------------------------------------------------------------------------
@@ -2229,7 +2236,7 @@ H5MF__close_shrink_eoa(H5F_t *f)
H5MF_sect_ud_t udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
+ FUNC_ENTER_STATIC
/* check args */
HDassert(f);
@@ -2310,7 +2317,7 @@ done:
if (orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__close_shrink_eoa() */
/*-------------------------------------------------------------------------
diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c
index 4684ee2..e7b966c 100644
--- a/src/H5MFaggr.c
+++ b/src/H5MFaggr.c
@@ -92,7 +92,7 @@ H5MF_aggr_vfd_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
FUNC_ENTER_NOAPI(HADDR_UNDEF)
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", __func__, (unsigned)alloc_type, size);
+ HDfprintf(stderr, "%s: alloc_type = %u, size = %" PRIuHSIZE "\n", __func__, (unsigned)alloc_type, size);
#endif /* H5MF_AGGR_DEBUG */
/* check arguments */
@@ -120,7 +120,8 @@ H5MF_aggr_vfd_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
done:
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", __func__, ret_value, size);
+ HDfprintf(stderr, "%s: Leaving: ret_value = %" PRIuHADDR ", size = %" PRIuHSIZE "\n", __func__, ret_value,
+ size);
#endif /* H5MF_AGGR_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
@@ -150,7 +151,7 @@ H5MF__aggr_alloc(H5F_t *f, H5F_blk_aggr_t *aggr, H5F_blk_aggr_t *other_aggr, H5F
FUNC_ENTER_STATIC
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: type = %u, size = %Hu\n", __func__, (unsigned)type, size);
+ HDfprintf(stderr, "%s: type = %u, size = %" PRIuHSIZE "\n", __func__, (unsigned)type, size);
#endif /* H5MF_AGGR_DEBUG */
/* check args */
@@ -195,12 +196,12 @@ H5MF__aggr_alloc(H5F_t *f, H5F_blk_aggr_t *aggr, H5F_blk_aggr_t *other_aggr, H5F
haddr_t aggr_frag_addr = HADDR_UNDEF; /* Address of aggregrator fragment */
hsize_t aggr_frag_size = 0; /* Size of aggregator fragment */
hsize_t alignment; /* Alignment of this section */
- hsize_t aggr_mis_align = 0; /* Mis-alignment of aggregator */
+ hsize_t aggr_mis_align = 0; /* Misalignment of aggregator */
H5FD_mem_t alloc_type, other_alloc_type; /* Current aggregator & 'other' aggregator types */
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", __func__, aggr->addr, aggr->tot_size,
- aggr->size);
+ HDfprintf(stderr, "%s: aggr = {%" PRIuHADDR ", %" PRIuHSIZE ", %" PRIuHSIZE "}\n", __func__,
+ aggr->addr, aggr->tot_size, aggr->size);
#endif /* H5MF_AGGR_DEBUG */
/* Turn off alignment if allocation < threshold */
@@ -388,7 +389,7 @@ H5MF__aggr_alloc(H5F_t *f, H5F_blk_aggr_t *aggr, H5F_blk_aggr_t *other_aggr, H5F
done:
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: ret_value = %a\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: ret_value = %" PRIuHADDR "\n", __func__, ret_value);
#endif /* H5MF_AGGR_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF__aggr_alloc() */
@@ -537,8 +538,11 @@ done:
if (H5F_addr_eq((sect->sect_info.addr + sect->sect_info.size), aggr->addr) ||
H5F_addr_eq((aggr->addr + aggr->size), sect->sect_info.addr)) {
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: section {%a, %Hu} adjoins aggr = {%a, %Hu}\n", "H5MF__aggr_can_absorb",
- sect->sect_info.addr, sect->sect_info.size, aggr->addr, aggr->size);
+ HDfprintf(stderr,
+ "%s: section {%" PRIuHADDR ", %" PRIuHSIZE "} adjoins aggr = {%" PRIuHADDR
+ ", %" PRIuHSIZE "}\n",
+ "H5MF__aggr_can_absorb", sect->sect_info.addr, sect->sect_info.size, aggr->addr,
+ aggr->size);
#endif /* H5MF_AGGR_DEBUG */
/* Check if aggregator would get too large and should be absorbed into section */
if ((aggr->size + sect->sect_info.size) >= aggr->alloc_size)
@@ -587,7 +591,9 @@ done:
/* Check if the section adjoins the beginning or end of the aggregator */
if (H5F_addr_eq((sect->sect_info.addr + sect->sect_info.size), aggr->addr)) {
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: aggr {%a, %Hu} adjoins front of section = {%a, %Hu}\n",
+ HDfprintf(stderr,
+ "%s: aggr {%" PRIuHADDR ", %" PRIuHSIZE "} adjoins front of section = {%" PRIuHADDR
+ ", %" PRIuHSIZE "}\n",
"H5MF__aggr_absorb", aggr->addr, aggr->size, sect->sect_info.addr,
sect->sect_info.size);
#endif /* H5MF_AGGR_DEBUG */
@@ -599,7 +605,9 @@ done:
HDassert(H5F_addr_eq((aggr->addr + aggr->size), sect->sect_info.addr));
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: aggr {%a, %Hu} adjoins end of section = {%a, %Hu}\n",
+ HDfprintf(stderr,
+ "%s: aggr {%" PRIuHADDR ", %" PRIuHSIZE "} adjoins end of section = {%" PRIuHADDR
+ ", %" PRIuHSIZE "}\n",
"H5MF__aggr_absorb", aggr->addr, aggr->size, sect->sect_info.addr,
sect->sect_info.size);
#endif /* H5MF_AGGR_DEBUG */
@@ -617,7 +625,9 @@ done:
/* Check if the section adjoins the beginning or end of the aggregator */
if (H5F_addr_eq((sect->sect_info.addr + sect->sect_info.size), aggr->addr)) {
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: section {%a, %Hu} adjoins front of aggr = {%a, %Hu}\n",
+ HDfprintf(stderr,
+ "%s: section {%" PRIuHADDR ", %" PRIuHSIZE "} adjoins front of aggr = {%" PRIuHADDR
+ ", %" PRIuHSIZE "}\n",
"H5MF__aggr_absorb", sect->sect_info.addr, sect->sect_info.size, aggr->addr,
aggr->size);
#endif /* H5MF_AGGR_DEBUG */
@@ -635,7 +645,9 @@ done:
HDassert(H5F_addr_eq((aggr->addr + aggr->size), sect->sect_info.addr));
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: section {%a, %Hu} adjoins end of aggr = {%a, %Hu}\n",
+ HDfprintf(stderr,
+ "%s: section {%" PRIuHADDR ", %" PRIuHSIZE "} adjoins end of aggr = {%" PRIuHADDR
+ ", %" PRIuHSIZE "}\n",
"H5MF__aggr_absorb", sect->sect_info.addr, sect->sect_info.size, aggr->addr,
aggr->size);
#endif /* H5MF_AGGR_DEBUG */
@@ -723,7 +735,8 @@ done:
tmp_addr = aggr->addr;
tmp_size = aggr->size;
#ifdef H5MF_AGGR_DEBUG
- HDfprintf(stderr, "%s: tmp_addr = %a, tmp_size = %Hu\n", __func__, tmp_addr, tmp_size);
+ HDfprintf(stderr, "%s: tmp_addr = %" PRIuHADDR ", tmp_size = %" PRIuHSIZE "\n", __func__,
+ tmp_addr, tmp_size);
#endif /* H5MF_AGGR_DEBUG */
/* Reset aggregator block information */
diff --git a/src/H5MFdbg.c b/src/H5MFdbg.c
index 6ccbe78..60d7779 100644
--- a/src/H5MFdbg.c
+++ b/src/H5MFdbg.c
@@ -50,7 +50,7 @@
typedef struct {
H5FS_t *fspace; /* Free space manager */
FILE * stream; /* Stream for output */
- int indent; /* Indention amount */
+ int indent; /* Indentation amount */
int fwidth; /* Field width amount */
} H5MF_debug_iter_ud_t;
diff --git a/src/H5MFsection.c b/src/H5MFsection.c
index e686842d..2f5103f 100644
--- a/src/H5MFsection.c
+++ b/src/H5MFsection.c
@@ -472,8 +472,9 @@ H5MF__sect_simple_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
/* Set the shrinking type */
udata->shrink = H5MF_SHRINK_EOA;
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: section {%a, %Hu}, shrinks file, eoa = %a\n", __func__, sect->sect_info.addr,
- sect->sect_info.size, eoa);
+ HDfprintf(stderr,
+ "%s: section {%" PRIuHADDR ", %" PRIuHSIZE "}, shrinks file, eoa = %" PRIuHADDR "\n",
+ __func__, sect->sect_info.addr, sect->sect_info.size, eoa);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Indicate shrinking can occur */
@@ -496,8 +497,9 @@ H5MF__sect_simple_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
/* Set the aggregator to operate on */
udata->aggr = &(udata->f->shared->meta_aggr);
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: section {%a, %Hu}, adjoins metadata aggregator\n", __func__,
- sect->sect_info.addr, sect->sect_info.size);
+ HDfprintf(stderr,
+ "%s: section {%" PRIuHADDR ", %" PRIuHSIZE "}, adjoins metadata aggregator\n",
+ __func__, sect->sect_info.addr, sect->sect_info.size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Indicate shrinking can occur */
@@ -517,8 +519,9 @@ H5MF__sect_simple_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
/* Set the aggregator to operate on */
udata->aggr = &(udata->f->shared->sdata_aggr);
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: section {%a, %Hu}, adjoins small data aggregator\n", __func__,
- sect->sect_info.addr, sect->sect_info.size);
+ HDfprintf(stderr,
+ "%s: section {%" PRIuHADDR ", %" PRIuHSIZE "}, adjoins small data aggregator\n",
+ __func__, sect->sect_info.addr, sect->sect_info.size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Indicate shrinking can occur */
@@ -625,8 +628,8 @@ H5MF__sect_small_add(H5FS_section_info_t **_sect, unsigned *flags, void *_udata)
FUNC_ENTER_STATIC
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: Entering, section {%a, %Hu}\n", __func__, (*sect)->sect_info.addr,
- (*sect)->sect_info.size);
+ HDfprintf(stderr, "%s: Entering, section {%" PRIuHADDR ", %" PRIuHSIZE "}\n", __func__,
+ (*sect)->sect_info.addr, (*sect)->sect_info.size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Do not adjust the section raw data or global heap data */
@@ -653,8 +656,8 @@ H5MF__sect_small_add(H5FS_section_info_t **_sect, unsigned *flags, void *_udata)
else if (prem <= H5F_PGEND_META_THRES(udata->f)) {
(*sect)->sect_info.size += prem;
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: section is adjusted {%a, %Hu}\n", __func__, (*sect)->sect_info.addr,
- (*sect)->sect_info.size);
+ HDfprintf(stderr, "%s: section is adjusted {%" PRIuHADDR ", %" PRIuHSIZE "}\n", __func__,
+ (*sect)->sect_info.addr, (*sect)->sect_info.size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
} /* end if */
@@ -702,7 +705,7 @@ H5MF__sect_small_can_merge(const H5FS_section_info_t *_sect1, const H5FS_section
ret_value = FALSE;
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: Leaving: ret_value = %d\n", __func__, ret_value);
#endif /* H5MF_ALLOC_DEBUG_MORE */
FUNC_LEAVE_NOAPI(ret_value)
@@ -798,30 +801,20 @@ H5MF__sect_large_can_merge(const H5FS_section_info_t *_sect1, const H5FS_section
const H5MF_free_section_t *sect2 = (const H5MF_free_section_t *)_sect2; /* File free section */
htri_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
/* Check arguments. */
HDassert(sect1);
HDassert(sect2);
HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
- if (!H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)) {
- HDfprintf(stderr,
- "%s.%d: sect1->sect_info.addr %" PRIuHADDR ", sect2->sect_info.addr %" PRIuHADDR "\n",
- __func__, __LINE__, sect1->sect_info.addr, sect2->sect_info.addr);
- HDfprintf(stderr,
- "%s.%d: sect1->sect_info.size %" PRIuHSIZE ", sect2->sect_info.size %" PRIuHSIZE "\n",
- __func__, __LINE__, sect1->sect_info.size, sect2->sect_info.size);
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't merge")
- }
HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
ret_value = H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", __func__, ret_value);
+ HDfprintf(stderr, "%s: Leaving: ret_value = %d\n", __func__, ret_value);
#endif /* H5MF_ALLOC_DEBUG_MORE */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5MF__sect_large_can_merge() */
@@ -907,8 +900,9 @@ H5MF__sect_large_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
/* Set the shrinking type */
udata->shrink = H5MF_SHRINK_EOA;
#ifdef H5MF_ALLOC_DEBUG_MORE
- HDfprintf(stderr, "%s: section {%a, %Hu}, shrinks file, eoa = %a\n", __func__, sect->sect_info.addr,
- sect->sect_info.size, eoa);
+ HDfprintf(stderr,
+ "%s: section {%" PRIuHADDR ", %" PRIuHSIZE "}, shrinks file, eoa = %" PRIuHADDR "\n",
+ __func__, sect->sect_info.addr, sect->sect_info.size, eoa);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Indicate shrinking can occur */
diff --git a/src/H5MP.c b/src/H5MP.c
deleted file mode 100644
index 474a995..0000000
--- a/src/H5MP.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*-------------------------------------------------------------------------
- *
- * Created: H5MP.c
- * May 2 2005
- * Quincey Koziol
- *
- * Purpose: Implements memory pools. (Similar to Apache's APR
- * memory pools)
- *
- * Please see the documentation in:
- * doc/html/TechNotes/MemoryPools.html for a full description
- * of how they work, etc.
- *
- *-------------------------------------------------------------------------
- */
-
-#include "H5MPmodule.h" /* This source code file is part of the H5MP module */
-
-/* Private headers */
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5MMprivate.h" /* Memory management */
-#include "H5MPpkg.h" /* Memory Pools */
-
-/****************/
-/* Local Macros */
-/****************/
-
-/* Minimum sized block */
-#define H5MP_MIN_BLOCK (H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)) + H5MP_BLOCK_ALIGNMENT)
-
-/* First block in page */
-#define H5MP_PAGE_FIRST_BLOCK(p) \
- (H5MP_page_blk_t *)((void *)((unsigned char *)(p) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
-
-/******************/
-/* Local Typedefs */
-/******************/
-
-/********************/
-/* Local Prototypes */
-/********************/
-
-/********************************/
-/* Package Variable Definitions */
-/********************************/
-
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
-/********************/
-/* Static Variables */
-/********************/
-
-/* Declare a free list to manage the H5MP_pool_t struct */
-H5FL_DEFINE(H5MP_pool_t);
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_create
- *
- * Purpose: Create a new memory pool
- *
- * Return: Pointer to the memory pool "header" on success/NULL on failure
- *
- * Programmer: Quincey Koziol
- * May 2 2005
- *
- *-------------------------------------------------------------------------
- */
-H5MP_pool_t *
-H5MP_create(size_t page_size, unsigned flags)
-{
- H5MP_pool_t *mp = NULL; /* New memory pool header */
- H5MP_pool_t *ret_value = NULL; /* Return value */
-
- FUNC_ENTER_NOAPI(NULL)
-
- /* Allocate space for the pool header */
- if (NULL == (mp = H5FL_MALLOC(H5MP_pool_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for memory pool header")
-
- /* Assign information */
- mp->page_size = H5MP_BLOCK_ALIGN(page_size);
- mp->flags = flags;
-
- /* Initialize information */
- mp->free_size = 0;
- mp->first = NULL;
- mp->max_size = mp->page_size - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t));
-
- /* Create factory for pool pages */
- if (NULL == (mp->page_fac = H5FL_fac_init(page_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't create page factory")
-
- /* Set return value */
- ret_value = mp;
-
-done:
- if (NULL == ret_value && mp)
- if (H5MP_close(mp) < 0)
- HDONE_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "unable to free memory pool header")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MP_create() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP__new_page
- *
- * Purpose: Allocate new page for a memory pool
- *
- * Return: Pointer to the page allocated on success/NULL on failure
- *
- * Programmer: Quincey Koziol
- * May 4 2005
- *
- *-------------------------------------------------------------------------
- */
-static H5MP_page_t *
-H5MP__new_page(H5MP_pool_t *mp, size_t page_size)
-{
- H5MP_page_t * new_page; /* New page created */
- H5MP_page_blk_t *first_blk; /* Pointer to first block in page */
- H5MP_page_t * ret_value = NULL; /* Return value */
-
- FUNC_ENTER_STATIC
-
- /* Sanity check */
- HDassert(mp);
- HDassert(page_size >= mp->page_size);
-
- /* Allocate page */
- if (page_size > mp->page_size) {
- if (NULL == (new_page = (H5MP_page_t *)H5MM_malloc(page_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
- new_page->free_size = page_size - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t));
- new_page->fac_alloc = FALSE;
- } /* end if */
- else {
- if (NULL == (new_page = (H5MP_page_t *)H5FL_FAC_MALLOC(mp->page_fac)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
- new_page->free_size = mp->max_size;
- new_page->fac_alloc = TRUE;
- } /* end else */
-
- /* Initialize page information */
- first_blk = H5MP_PAGE_FIRST_BLOCK(new_page);
- first_blk->size = new_page->free_size;
- first_blk->page = new_page;
- first_blk->is_free = TRUE;
- first_blk->prev = NULL;
- first_blk->next = NULL;
-
- /* Insert into page list */
- new_page->prev = NULL;
- new_page->next = mp->first;
- if (mp->first)
- mp->first->prev = new_page;
- mp->first = new_page;
-
- /* Account for new free space */
- new_page->free_blk = first_blk;
- mp->free_size += new_page->free_size;
-
- /* Assign return value */
- ret_value = new_page;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MP__new_page() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_malloc
- *
- * Purpose: Allocate space in a memory pool
- *
- * Return: Pointer to the space allocated on success/NULL on failure
- *
- * Programmer: Quincey Koziol
- * May 2 2005
- *
- *-------------------------------------------------------------------------
- */
-void *
-H5MP_malloc(H5MP_pool_t *mp, size_t request)
-{
- H5MP_page_t * alloc_page = NULL; /* Page to allocate space from */
- H5MP_page_blk_t *alloc_free; /* Pointer to free space in page */
- size_t needed; /* Size requested, plus block header and alignment */
- void * ret_value = NULL; /* Return value */
-
- FUNC_ENTER_NOAPI(NULL)
-
- /* Sanity check */
- HDassert(mp);
- HDassert(request > 0);
-
- /* Compute actual size needed */
- needed = H5MP_BLOCK_ALIGN(request) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t));
-
- /* See if the request can be handled by existing free space */
- if (needed <= mp->free_size) {
- size_t pool_free_avail; /* Amount of free space possibly available in pool */
-
- /* Locate page with enough free space */
- alloc_page = mp->first;
- pool_free_avail = mp->free_size;
- while (alloc_page && pool_free_avail >= needed) {
- /* If we found a page with enough free space, search for large
- * enough free block on that page */
- if (alloc_page->free_size >= needed) {
- size_t page_free_avail; /* Amount of free space possibly available */
-
- /* Locate large enough block */
- alloc_free = alloc_page->free_blk;
- page_free_avail = alloc_page->free_size;
- while (alloc_free && page_free_avail >= needed) {
- if (alloc_free->is_free) {
- /* If we found a large enough block, leave now */
- if (alloc_free->size >= needed)
- goto found; /* Needed to escape double "while" loop */
-
- /* Decrement amount of potential space left */
- page_free_avail -= alloc_free->size;
- } /* end if */
-
- /* Go to next block */
- alloc_free = alloc_free->next;
- } /* end while */
- } /* end if */
-
- /* Decrement amount of potential space left */
- pool_free_avail -= alloc_page->free_size;
-
- /* Go to next page */
- alloc_page = alloc_page->next;
- } /* end while */
- } /* end if */
-
- {
- size_t page_size; /* Size of page needed */
-
- /* Check if the request is too large for a standard page */
- page_size =
- (needed > mp->max_size) ? (needed + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))) : mp->page_size;
-
- /* Allocate new page */
- if (NULL == (alloc_page = H5MP__new_page(mp, page_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page")
-
- /* Set the block to allocate from */
- alloc_free = alloc_page->free_blk;
- } /* end block */
-
- /* Allocate space in page */
-found:
-
- /* Sanity check */
- HDassert(alloc_page);
- HDassert(alloc_free);
-
- /* Check if we can subdivide the free space */
- if (alloc_free->size > (needed + H5MP_MIN_BLOCK)) {
- H5MP_page_blk_t *new_free; /* New free block created */
-
- /* Carve out new free block after block to allocate */
- new_free = (H5MP_page_blk_t *)((void *)(((unsigned char *)alloc_free) + needed));
-
- /* Link into existing lists */
- new_free->next = alloc_free->next;
- if (alloc_free->next)
- alloc_free->next->prev = new_free;
- new_free->prev = alloc_free;
- alloc_free->next = new_free;
-
- /* Set blocks' information */
- new_free->size = alloc_free->size - needed;
- new_free->is_free = TRUE;
- new_free->page = alloc_free->page;
- alloc_free->size = needed;
- alloc_free->is_free = FALSE;
- } /* end if */
- else {
- /* Use whole free space block for new block */
- alloc_free->is_free = FALSE;
- } /* end else */
-
- /* Update page & pool's free size information */
- alloc_page->free_size -= alloc_free->size;
- if (alloc_page->free_blk == alloc_free)
- alloc_page->free_blk = alloc_free->next;
- mp->free_size -= alloc_free->size;
-
- /* Set new space pointer for the return value */
- ret_value = ((unsigned char *)alloc_free) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t));
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MP_malloc() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_free
- *
- * Purpose: Release space in a memory pool
- *
- * Return: NULL on success/NULL on failure
- *
- * Programmer: Quincey Koziol
- * May 3 2005
- *
- * Note: Should we release pages that have no used blocks?
- *
- *-------------------------------------------------------------------------
- */
-void *
-H5MP_free(H5MP_pool_t *mp, void *spc)
-{
- H5MP_page_blk_t *spc_blk; /* Block for space to free */
- H5MP_page_t * spc_page; /* Page containing block to free */
- void * ret_value = NULL; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Sanity check */
- HDassert(mp);
- HDassert(spc);
-
- /* Get block header for space to free */
- spc_blk =
- (H5MP_page_blk_t *)((void *)(((unsigned char *)spc) - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t))));
-
- /* Mark block as free */
- HDassert(spc_blk->is_free == FALSE);
- spc_blk->is_free = TRUE;
-
- /* Add it's space to the amount of free space in the page & pool */
- spc_page = spc_blk->page;
- spc_page->free_size += spc_blk->size;
- mp->free_size += spc_blk->size;
-
- /* Move page with newly freed space to front of list of pages in pool */
- if (spc_page != mp->first) {
- /* Remove page from list */
- spc_page->prev->next = spc_page->next;
- if (spc_page->next)
- spc_page->next->prev = spc_page->prev;
-
- /* Insert page at beginning of list */
- spc_page->prev = NULL;
- spc_page->next = mp->first;
- mp->first->prev = spc_page;
- mp->first = spc_page;
- } /* end if */
-
- /* Check if block can be merged with free space after it on page */
- if (spc_blk->next != NULL) {
- H5MP_page_blk_t *next_blk; /* Block following space to free */
-
- next_blk = spc_blk->next;
- HDassert(next_blk->prev == spc_blk);
- if (next_blk->is_free) {
- spc_blk->size += next_blk->size;
- spc_blk->next = next_blk->next;
- } /* end if */
- } /* end if */
-
- /* Check if block can be merged with free space before it on page */
- if (spc_blk->prev != NULL) {
- H5MP_page_blk_t *prev_blk; /* Block before space to free */
-
- prev_blk = spc_blk->prev;
- HDassert(prev_blk->next == spc_blk);
- if (prev_blk->is_free) {
- prev_blk->size += spc_blk->size;
- prev_blk->next = spc_blk->next;
- } /* end if */
- } /* end if */
-
- /* Check if the block freed becomes the first free block on the page */
- if (spc_page->free_blk == NULL || spc_blk < spc_page->free_blk)
- spc_page->free_blk = spc_blk;
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MP_free() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_close
- *
- * Purpose: Release all memory for a pool and destroy pool
- *
- * Return: Non-negative on success/negative on failure
- *
- * Programmer: Quincey Koziol
- * May 3 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5MP_close(H5MP_pool_t *mp)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Release memory for pool pages */
- if (mp->first != NULL) {
- H5MP_page_t *page, *next_page; /* Pointer to pages in pool */
-
- /* Iterate through pages, releasing them */
- page = mp->first;
- while (page) {
- next_page = page->next;
-
- /* Free the page appropriately */
- if (page->fac_alloc)
- page = (H5MP_page_t *)H5FL_FAC_FREE(mp->page_fac, page);
- else
- page = (H5MP_page_t *)H5MM_xfree(page);
-
- page = next_page;
- } /* end while */
- } /* end if */
-
- /* Release page factory */
- if (mp->page_fac)
- if (H5FL_fac_term(mp->page_fac) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy page factory")
-
-done:
- /* Free the memory pool itself */
- mp = H5FL_FREE(H5MP_pool_t, mp);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5MP_close() */
diff --git a/src/H5MPmodule.h b/src/H5MPmodule.h
deleted file mode 100644
index 8e34598..0000000
--- a/src/H5MPmodule.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*
- * Programmer: Quincey Koziol
- * Saturday, September 12, 2015
- *
- * Purpose: This file contains declarations which define macros for the
- * H5MP package. Including this header means that the source file
- * is part of the H5MP package.
- */
-#ifndef H5MPmodule_H
-#define H5MPmodule_H
-
-/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error
- * reporting macros.
- */
-#define H5MP_MODULE
-#define H5_MY_PKG H5MP
-#define H5_MY_PKG_ERR H5E_RESOURCE
-#define H5_MY_PKG_INIT NO
-
-#endif /* H5MPmodule_H */
diff --git a/src/H5MPpkg.h b/src/H5MPpkg.h
deleted file mode 100644
index 64c5293..0000000
--- a/src/H5MPpkg.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*
- * Programmer: Quincey Koziol
- * Monday, May 2, 2005
- *
- * Purpose: This file contains declarations which are visible only within
- * the H5MP package. Source files outside the H5MP package should
- * include H5MPprivate.h instead.
- */
-#if !(defined H5MP_FRIEND || defined H5MP_MODULE)
-#error "Do not include this file outside the H5MP package!"
-#endif
-
-#ifndef H5MPpkg_H
-#define H5MPpkg_H
-
-/* Get package's private header */
-#include "H5MPprivate.h" /* Memory Pools */
-
-/* Other private headers needed by this file */
-#include "H5FLprivate.h" /* Free Lists */
-
-/**************************/
-/* Package Private Macros */
-/**************************/
-
-/* Alignment macros */
-/* (Ideas from Apache APR :-) */
-
-/* Default alignment necessary */
-#define H5MP_BLOCK_ALIGNMENT 8
-
-/* General alignment macro */
-/* (this only works for aligning to power of 2 boundary) */
-#define H5MP_ALIGN(x, a) (((x) + ((size_t)(a)) - 1) & ~(((size_t)(a)) - 1))
-
-/* Default alignment */
-#define H5MP_BLOCK_ALIGN(x) H5MP_ALIGN(x, H5MP_BLOCK_ALIGNMENT)
-
-/****************************/
-/* Package Private Typedefs */
-/****************************/
-
-/* Free block in pool */
-typedef struct H5MP_page_blk_t {
- size_t size; /* Size of block (includes this H5MP_page_blk_t info) */
- unsigned is_free : 1; /* Flag to indicate the block is free */
- struct H5MP_page_t * page; /* Pointer to page block is located in */
- struct H5MP_page_blk_t *prev; /* Pointer to previous block in page */
- struct H5MP_page_blk_t *next; /* Pointer to next block in page */
-} H5MP_page_blk_t;
-
-/* Memory pool page */
-typedef struct H5MP_page_t {
- size_t free_size; /* Total amount of free space in page */
- unsigned fac_alloc : 1; /* Flag to indicate the page was allocated by the pool's factory */
- H5MP_page_blk_t * free_blk; /* Pointer to first free block in page */
- struct H5MP_page_t *next; /* Pointer to next page in pool */
- struct H5MP_page_t *prev; /* Pointer to previous page in pool */
-} H5MP_page_t;
-
-/* Memory pool header */
-struct H5MP_pool_t {
- H5FL_fac_head_t *page_fac; /* Free-list factory for pages */
- size_t page_size; /* Page size for pool */
- size_t free_size; /* Total amount of free space in pool */
- size_t max_size; /* Maximum block that will fit in a standard page */
- H5MP_page_t * first; /* Pointer to first page in pool */
- unsigned flags; /* Bit flags for pool settings */
-};
-
-/*****************************************/
-/* Package Private Variable Declarations */
-/*****************************************/
-
-/******************************/
-/* Package Private Prototypes */
-/******************************/
-#ifdef H5MP_TESTING
-H5_DLL herr_t H5MP_get_pool_free_size(const H5MP_pool_t *mp, size_t *free_size);
-H5_DLL htri_t H5MP_pool_is_free_size_correct(const H5MP_pool_t *mp);
-H5_DLL herr_t H5MP_get_pool_first_page(const H5MP_pool_t *mp, H5MP_page_t **page);
-H5_DLL herr_t H5MP_get_page_free_size(const H5MP_page_t *mp, size_t *page);
-H5_DLL herr_t H5MP_get_page_next_page(const H5MP_page_t *page, H5MP_page_t **next_page);
-#endif /* H5MP_TESTING */
-
-#endif /* H5MPpkg_H */
diff --git a/src/H5MPprivate.h b/src/H5MPprivate.h
deleted file mode 100644
index 2b06650..0000000
--- a/src/H5MPprivate.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*-------------------------------------------------------------------------
- *
- * Created: H5MPprivate.h
- * May 2 2005
- * Quincey Koziol
- *
- * Purpose: Private header for memory pool routines.
- *
- *-------------------------------------------------------------------------
- */
-
-#ifndef H5MPprivate_H
-#define H5MPprivate_H
-
-/* Include package's public header (not yet) */
-/* #include "H5MPpublic.h" */
-
-/* Private headers needed by this file */
-
-/**************************/
-/* Library Private Macros */
-/**************************/
-
-/* Pool creation flags */
-/* Default settings */
-#define H5MP_FLG_DEFAULT 0
-#define H5MP_PAGE_SIZE_DEFAULT 4096 /* (bytes) */
-
-/****************************/
-/* Library Private Typedefs */
-/****************************/
-
-/* Memory pool header (defined in H5MPpkg.c) */
-typedef struct H5MP_pool_t H5MP_pool_t;
-
-/***************************************/
-/* Library-private Function Prototypes */
-/***************************************/
-H5_DLL H5MP_pool_t *H5MP_create(size_t page_size, unsigned flags);
-H5_DLL void * H5MP_malloc(H5MP_pool_t *mp, size_t request);
-H5_DLL void * H5MP_free(H5MP_pool_t *mp, void *spc);
-H5_DLL herr_t H5MP_close(H5MP_pool_t *mp);
-
-#endif /* H5MPprivate_H */
diff --git a/src/H5MPtest.c b/src/H5MPtest.c
deleted file mode 100644
index 27e7bbe..0000000
--- a/src/H5MPtest.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * 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. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* Programmer: Quincey Koziol
- * Tuesday, May 3, 2005
- *
- * Purpose: Memory pool testing functions.
- */
-
-#include "H5MPmodule.h" /* This source code file is part of the H5MP module */
-#define H5MP_TESTING /*include H5MP testing funcs*/
-
-/* Private headers */
-#include "H5private.h" /* Generic Functions */
-#include "H5MPpkg.h" /* Memory Pools */
-#include "H5Eprivate.h" /* Error handling */
-
-/* Static Prototypes */
-
-/* Package variables */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_get_pool_free_size
- *
- * Purpose: Retrieve the total amount of free space in entire pool
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Tuesday, May 3, 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5MP_get_pool_free_size(const H5MP_pool_t *mp, size_t *free_size)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check arguments. */
- HDassert(mp);
- HDassert(free_size);
-
- /* Get memory pool's free space */
- *free_size = mp->free_size;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5MP_get_pool_free_size() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_get_pool_first_page
- *
- * Purpose: Retrieve the first page in a memory pool
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Tuesday, May 3, 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5MP_get_pool_first_page(const H5MP_pool_t *mp, H5MP_page_t **page)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check arguments. */
- HDassert(mp);
- HDassert(page);
-
- /* Get memory pool's first page */
- *page = mp->first;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5MP_get_pool_first_page() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_pool_is_free_size_correct
- *
- * Purpose: Check that the free space reported in each page corresponds
- * to the free size in each page and that the free space in the
- * free blocks for a page corresponds with the free space for
- * the page.
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Wednesday, May 3, 2005
- *
- *-------------------------------------------------------------------------
- */
-htri_t
-H5MP_pool_is_free_size_correct(const H5MP_pool_t *mp)
-{
- H5MP_page_t *page; /* Pointer to current page */
- size_t pool_free; /* Size of pages' free space */
- htri_t ret_value = TRUE; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check arguments. */
- HDassert(mp);
-
- /* Iterate through pages, checking the free size & accumulating the
- * free space for all the pages */
- page = mp->first;
- pool_free = 0;
- while (page != NULL) {
- H5MP_page_blk_t *blk; /* Pointer to current free block */
- size_t page_free; /* Size of blocks on free list */
-
- /* Iterate through the blocks in page, accumulating free space */
- blk = (H5MP_page_blk_t *)((void *)((unsigned char *)page + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))));
- page_free = 0;
- while (blk != NULL) {
- if (blk->is_free)
- page_free += blk->size;
- blk = blk->next;
- } /* end while */
-
- /* Check that the free space from the blocks on the free list
- * corresponds to space in page */
- if (page_free != page->free_size)
- HGOTO_DONE(FALSE)
-
- /* Increment the amount of free space in pool */
- pool_free += page->free_size;
-
- /* Advance to next page */
- page = page->next;
- } /* end while */
-
- /* Check that the free space from the pages
- * corresponds to free space in pool */
- if (pool_free != mp->free_size)
- HGOTO_DONE(FALSE)
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5MP_pool_is_free_size_correct() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_get_page_free_size
- *
- * Purpose: Retrieve the amount of free space in given page
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Tuesday, May 3, 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5MP_get_page_free_size(const H5MP_page_t *page, size_t *free_size)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check arguments. */
- HDassert(page);
- HDassert(free_size);
-
- /* Get memory page's free space */
- *free_size = page->free_size;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5MP_get_page_free_size() */
-
-/*-------------------------------------------------------------------------
- * Function: H5MP_get_page_next_page
- *
- * Purpose: Retrieve the next page in the pool
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Tuesday, May 3, 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5MP_get_page_next_page(const H5MP_page_t *page, H5MP_page_t **next_page)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check arguments. */
- HDassert(page);
- HDassert(next_page);
-
- /* Get next memory page */
- *next_page = page->next;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5MP_get_page_next_page() */
diff --git a/src/H5MV.c b/src/H5MV.c
index 3d2bd80..28ae37d 100644
--- a/src/H5MV.c
+++ b/src/H5MV.c
@@ -77,9 +77,6 @@ H5_DLL htri_t H5MV__try_extend_md(H5F_shared_t *, haddr_t, hsize_t);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
diff --git a/src/H5MVprivate.h b/src/H5MVprivate.h
index c02c6ae..b2a5458 100644
--- a/src/H5MVprivate.h
+++ b/src/H5MVprivate.h
@@ -14,7 +14,7 @@
*
* Created: H5MVprivate.h
*
- * Purpose: Private header file for VFD SWMR free space mangement
+ * Purpose: Private header file for VFD SWMR free space management
*
*-------------------------------------------------------------------------
*/
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index 10c9ede..03ea3df 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -52,7 +52,7 @@ const H5O_msg_class_t H5O_MSG_AINFO[1] = {{
H5O_AINFO_ID, /*message id number */
"ainfo", /*message name for debugging */
sizeof(H5O_ainfo_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__ainfo_decode, /*decode message */
H5O__ainfo_encode, /*encode message */
H5O__ainfo_copy, /*copy the native value */
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index db53eaf..83c0370 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -65,7 +65,7 @@ const H5O_msg_class_t H5O_MSG_ATTR[1] = {{
H5O_ATTR_ID, /* message id number */
"attribute", /* message name for debugging */
sizeof(H5A_t), /* native message size */
- H5O_SHARE_IS_SHARABLE, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE, /* messages are shareable? */
H5O__attr_shared_decode, /* decode message */
H5O__attr_shared_encode, /* encode message */
H5O__attr_copy, /* copy the native value */
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 56f7145..b83b57e 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -248,19 +248,19 @@ H5O__attr_create(const H5O_loc_t *loc, H5A_t *attr)
/* Check if switching to "dense" attribute storage is possible */
if (!H5F_addr_defined(ainfo.fheap_addr)) {
- htri_t sharable; /* Whether the attribute will be shared */
+ htri_t shareable; /* Whether the attribute will be shared */
size_t raw_size = 0; /* Raw size of message */
- /* Check for attribute being sharable */
- if ((sharable = H5SM_can_share(loc->file, NULL, NULL, H5O_ATTR_ID, attr)) < 0)
+ /* Check for attribute being shareable */
+ if ((shareable = H5SM_can_share(loc->file, NULL, NULL, H5O_ATTR_ID, attr)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't determine attribute sharing status")
- else if (sharable == FALSE) {
+ else if (shareable == FALSE) {
/* Compute the size needed to encode the attribute */
raw_size = (H5O_MSG_ATTR->raw_size)(loc->file, FALSE, attr);
} /* end if */
/* Check for condititions for switching to "dense" attribute storage are met */
- if (ainfo.nattrs == oh->max_compact || (!sharable && raw_size >= H5O_MESG_MAX_SIZE)) {
+ if (ainfo.nattrs == oh->max_compact || (!shareable && raw_size >= H5O_MESG_MAX_SIZE)) {
H5O_iter_cvt_t udata; /* User data for callback */
H5O_mesg_operator_t op; /* Wrapper for operator */
@@ -1679,7 +1679,7 @@ H5O__attr_count_real(H5F_t *f, H5O_t *oh, hsize_t *nattrs)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE_TAG(oh->cache_info.addr)
+ FUNC_ENTER_PACKAGE
/* Check arguments */
HDassert(f);
@@ -1712,7 +1712,7 @@ H5O__attr_count_real(H5F_t *f, H5O_t *oh, hsize_t *nattrs)
} /* end else */
done:
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O__attr_count_real */
/*-------------------------------------------------------------------------
diff --git a/src/H5Obogus.c b/src/H5Obogus.c
index c7fcdb9..ea231d6 100644
--- a/src/H5Obogus.c
+++ b/src/H5Obogus.c
@@ -47,7 +47,7 @@ const H5O_msg_class_t H5O_MSG_BOGUS_VALID[1] = {{
H5O_BOGUS_VALID_ID, /*message id number */
"bogus valid", /*message name for debugging */
0, /*native message size */
- H5O_SHARE_IS_SHARABLE, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE, /* messages are shareable? */
H5O__bogus_decode, /*decode message */
H5O__bogus_encode, /*encode message */
NULL, /*copy the native value */
@@ -71,7 +71,7 @@ const H5O_msg_class_t H5O_MSG_BOGUS_INVALID[1] = {{
H5O_BOGUS_INVALID_ID, /*message id number */
"bogus invalid", /*message name for debugging */
0, /*native message size */
- H5O_SHARE_IS_SHARABLE, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE, /* messages are shareable? */
H5O__bogus_decode, /*decode message */
H5O__bogus_encode, /*encode message */
NULL, /*copy the native value */
diff --git a/src/H5Obtreek.c b/src/H5Obtreek.c
index a783366..1eaf3e5 100644
--- a/src/H5Obtreek.c
+++ b/src/H5Obtreek.c
@@ -37,7 +37,7 @@ const H5O_msg_class_t H5O_MSG_BTREEK[1] = {{
H5O_BTREEK_ID, /*message id number */
"v1 B-tree 'K' values", /*message name for debugging */
sizeof(H5O_btreek_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__btreek_decode, /*decode message */
H5O__btreek_encode, /*encode message */
H5O__btreek_copy, /*copy the native value */
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index 8eed092..ccaf004 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -277,7 +277,7 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata)
*
* Note that the object header is read with with a speculative read.
* If the initial read is too small, make note of this fact and return
- * without error. H5C__load_entry() will note the size discrepency
+ * without error. H5C__load_entry() will note the size discrepancy
* and retry the deserialize operation with the correct size read.
*
* Return: Success: Pointer to in core representation
@@ -348,7 +348,7 @@ H5O__cache_deserialize(const void *image, size_t len, void *_udata, hbool_t *dir
done:
/* Release the [possibly partially initialized] object header on errors */
if (!ret_value && oh)
- if (H5O__free(oh) < 0)
+ if (H5O__free(oh, FALSE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, NULL, "unable to destroy object header data")
FUNC_LEAVE_NOAPI(ret_value)
@@ -641,7 +641,7 @@ H5O__cache_free_icr(void *_thing)
HDassert(oh->cache_info.type == H5AC_OHDR);
/* Destroy object header */
- if (H5O__free(oh) < 0)
+ if (H5O__free(oh, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't destroy object header")
done:
@@ -1244,7 +1244,7 @@ H5O__prefix_deserialize(const uint8_t *_image, H5O_cache_ud_t *udata)
/* Save the object header for later use in 'deserialize' callback */
udata->oh = oh;
- if (H5O__free(saved_oh) < 0)
+ if (H5O__free(saved_oh, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't destroy object header")
udata->free_oh = FALSE;
}
@@ -1257,7 +1257,7 @@ H5O__prefix_deserialize(const uint8_t *_image, H5O_cache_ud_t *udata)
done:
/* Release the [possibly partially initialized] object header on errors */
if (ret_value < 0 && oh)
- if (H5O__free(oh) < 0)
+ if (H5O__free(oh, FALSE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to destroy object header data")
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Ocache_image.c b/src/H5Ocache_image.c
index 2603f71..8f60a0e 100644
--- a/src/H5Ocache_image.c
+++ b/src/H5Ocache_image.c
@@ -51,7 +51,7 @@ const H5O_msg_class_t H5O_MSG_MDCI[1] = {{
H5O_MDCI_MSG_ID, /* message id number */
"mdci", /* message name for debugging */
sizeof(H5O_mdci_t), /* native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__mdci_decode, /* decode message */
H5O__mdci_encode, /* encode message */
H5O__mdci_copy, /* copy method */
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index 080225a..9dd04fe 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -47,7 +47,7 @@ const H5O_msg_class_t H5O_MSG_CONT[1] = {{
H5O_CONT_ID, /*message id number */
"hdr continuation", /*message name for debugging */
sizeof(H5O_cont_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__cont_decode, /*decode message */
H5O__cont_encode, /*encode message */
NULL, /*no copy method */
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index 6716769..0b0bb55 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -771,7 +771,7 @@ done:
/* Free destination object header on failure */
if (ret_value < 0) {
if (oh_dst && !inserted) {
- if (H5O__free(oh_dst) < 0)
+ if (H5O__free(oh_dst, TRUE) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
if (H5O_loc_reset(oloc_dst) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
@@ -962,7 +962,7 @@ H5O__copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t
if (H5P_get(ocpy_plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag")
- /* Retrieve the marge committed datatype list */
+ /* Retrieve the merge committed datatype list */
if (H5P_peek(ocpy_plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge committed datatype list")
diff --git a/src/H5Ocopy_ref.c b/src/H5Ocopy_ref.c
index e06e699..1cda3ea 100644
--- a/src/H5Ocopy_ref.c
+++ b/src/H5Ocopy_ref.c
@@ -170,31 +170,32 @@ H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, H5O_loc_t
H5O_token_t tmp_token = {0};
/* If data is not initialized, copy zeros and skip */
- if (0 == HDmemcmp(src_buf, zeros, buf_size)) {
+ if (0 == HDmemcmp(src_buf, zeros, buf_size))
HDmemset(dst_buf, 0, buf_size);
- continue;
- }
-
- /* Set up for the object copy for the reference */
- if (H5R__decode_token_obj_compat(src_buf, &buf_size, &tmp_token, token_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode src object address")
- if (H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address")
-
- if (!H5F_addr_defined(src_oloc->addr) || src_oloc->addr == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer")
- dst_oloc->addr = HADDR_UNDEF;
-
- /* Attempt to copy object from source to destination file */
- if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
-
- /* Set the object reference info for the destination file */
- if (H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token")
- if (H5R__encode_token_obj_compat((const H5O_token_t *)&tmp_token, token_size, dst_buf, &buf_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to encode dst object address")
- } /* end for */
+ else {
+ /* Set up for the object copy for the reference */
+ if (H5R__decode_token_obj_compat(src_buf, &buf_size, &tmp_token, token_size) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode src object address")
+ if (H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL,
+ "can't deserialize object token into address")
+
+ if (!H5F_addr_defined(src_oloc->addr) || src_oloc->addr == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer")
+ dst_oloc->addr = HADDR_UNDEF;
+
+ /* Attempt to copy object from source to destination file */
+ if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* Set the object reference info for the destination file */
+ if (H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token")
+ if (H5R__encode_token_obj_compat((const H5O_token_t *)&tmp_token, token_size, dst_buf,
+ &buf_size) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to encode dst object address")
+ } /* end else */
+ } /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -232,43 +233,42 @@ H5O__copy_expand_ref_region1(H5O_loc_t *src_oloc, const void *buf_src, H5O_loc_t
uint8_t * q;
/* If data is not initialized, copy zeros and skip */
- if (0 == HDmemcmp(src_buf, zeros, buf_size)) {
+ if (0 == HDmemcmp(src_buf, zeros, buf_size))
HDmemset(dst_buf, 0, buf_size);
- continue;
- }
-
- /* Read from heap */
- if (H5R__decode_heap(src_oloc->file, src_buf, &buf_size, &data, &data_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode dataset region information")
-
- /* Get object address */
- p = (const uint8_t *)data;
- H5F_addr_decode(src_oloc->file, &p, &src_oloc->addr);
- if (!H5F_addr_defined(src_oloc->addr) || src_oloc->addr == 0) {
- H5MM_free(data);
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer")
- }
- dst_oloc->addr = HADDR_UNDEF;
-
- /* Attempt to copy object from source to destination file */
- if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0) {
- H5MM_free(data);
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
- } /* end if */
-
- /* Serialize object addr */
- q = (uint8_t *)data;
- H5F_addr_encode(dst_oloc->file, &q, dst_oloc->addr);
-
- /* Write to heap */
- if (H5R__encode_heap(dst_oloc->file, dst_buf, &buf_size, data, (size_t)data_size) < 0) {
+ else {
+ /* Read from heap */
+ if (H5R__decode_heap(src_oloc->file, src_buf, &buf_size, &data, &data_size) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode dataset region information")
+
+ /* Get object address */
+ p = (const uint8_t *)data;
+ H5F_addr_decode(src_oloc->file, &p, &src_oloc->addr);
+ if (!H5F_addr_defined(src_oloc->addr) || src_oloc->addr == 0) {
+ H5MM_free(data);
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer")
+ }
+ dst_oloc->addr = HADDR_UNDEF;
+
+ /* Attempt to copy object from source to destination file */
+ if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0) {
+ H5MM_free(data);
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+ } /* end if */
+
+ /* Serialize object addr */
+ q = (uint8_t *)data;
+ H5F_addr_encode(dst_oloc->file, &q, dst_oloc->addr);
+
+ /* Write to heap */
+ if (H5R__encode_heap(dst_oloc->file, dst_buf, &buf_size, data, (size_t)data_size) < 0) {
+ H5MM_free(data);
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode dataset region information")
+ }
+
+ /* Free the buffer allocated in H5R__decode_heap() */
H5MM_free(data);
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode dataset region information")
- }
-
- /* Free the buffer allocated in H5R__decode_heap() */
- H5MM_free(data);
- } /* end for */
+ } /* end else */
+ } /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -288,21 +288,22 @@ H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, const H5T_t *dt
size_t nbytes_src, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, void *buf_dst,
size_t ref_count, H5O_copy_t *cpy_info)
{
- H5T_t * dt_mem = NULL; /* Memory datatype */
- H5T_t * dt_dst = NULL; /* Destination datatype */
- hid_t tid_mem = H5I_INVALID_HID; /* Datatype ID for memory datatype */
- hid_t tid_dst = H5I_INVALID_HID; /* Datatype ID for memory datatype */
- H5T_path_t *tpath_src_mem = NULL, *tpath_mem_dst = NULL; /* Datatype conversion paths */
- size_t i; /* Local index variable */
- hbool_t reg_tid_src = (tid_src == H5I_INVALID_HID);
- hid_t dst_loc_id = H5I_INVALID_HID;
- void * conv_buf = NULL; /* Buffer for converting data */
- size_t conv_buf_size = 0; /* Buffer size */
- void * reclaim_buf = NULL; /* Buffer for reclaiming data */
- H5S_t * buf_space = NULL; /* Dataspace describing buffer */
- hsize_t buf_dim[1] = {ref_count}; /* Dimension for buffer */
- size_t token_size = H5F_SIZEOF_ADDR(src_oloc->file);
- herr_t ret_value = SUCCEED;
+ H5T_t * dt_mem = NULL; /* Memory datatype */
+ H5T_t * dt_dst = NULL; /* Destination datatype */
+ hid_t tid_mem = H5I_INVALID_HID; /* Datatype ID for memory datatype */
+ hid_t tid_dst = H5I_INVALID_HID; /* Datatype ID for memory datatype */
+ H5T_path_t * tpath_src_mem = NULL, *tpath_mem_dst = NULL; /* Datatype conversion paths */
+ size_t i; /* Local index variable */
+ hbool_t reg_tid_src = (tid_src == H5I_INVALID_HID);
+ hid_t dst_loc_id = H5I_INVALID_HID;
+ void * conv_buf = NULL; /* Buffer for converting data */
+ size_t conv_buf_size = 0; /* Buffer size */
+ void * reclaim_buf = NULL; /* Buffer for reclaiming data */
+ H5S_t * buf_space = NULL; /* Dataspace describing buffer */
+ hsize_t buf_dim[1] = {ref_count}; /* Dimension for buffer */
+ size_t token_size = H5F_SIZEOF_ADDR(src_oloc->file);
+ const unsigned char zeros[H5R_REF_BUF_SIZE] = {0};
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
@@ -353,29 +354,34 @@ H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, const H5T_t *dt
/* Making equivalent references in the destination file */
for (i = 0; i < ref_count; i++) {
- H5R_ref_t * ref_ptr = (H5R_ref_t *)conv_buf;
- H5R_ref_priv_t *ref = (H5R_ref_priv_t *)&ref_ptr[i];
- H5O_token_t tmp_token = {0};
-
- /* Get src object address */
- if (H5R__get_obj_token(ref, &tmp_token, &token_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object token")
- if (H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token into address")
-
- /* Attempt to copy object from source to destination file */
- if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
-
- /* Set dst object address */
- if (H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token")
- if (H5R__set_obj_token(ref, (const H5O_token_t *)&tmp_token, token_size) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set object token")
- /* Do not set app_ref since references are released once the copy is done */
- if (H5R__set_loc_id(ref, dst_loc_id, TRUE, FALSE) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set destination loc id")
- } /* end for */
+ H5R_ref_t * ref_ptr = (H5R_ref_t *)conv_buf;
+ H5R_ref_priv_t *ref = (H5R_ref_priv_t *)&ref_ptr[i];
+
+ /* Check for null reference - only expand reference if it is not null */
+ if (HDmemcmp(ref, zeros, H5R_REF_BUF_SIZE)) {
+ H5O_token_t tmp_token = {0};
+
+ /* Get src object address */
+ if (H5R__get_obj_token(ref, &tmp_token, &token_size) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object token")
+ if (H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL,
+ "can't deserialize object token into address")
+
+ /* Attempt to copy object from source to destination file */
+ if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* Set dst object address */
+ if (H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token")
+ if (H5R__set_obj_token(ref, (const H5O_token_t *)&tmp_token, token_size) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set object token")
+ /* Do not set app_ref since references are released once the copy is done */
+ if (H5R__set_loc_id(ref, dst_loc_id, TRUE, FALSE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set destination loc id")
+ } /* end if */
+ } /* end for */
/* Copy into another buffer, to reclaim memory later */
if (NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, conv_buf_size)))
diff --git a/src/H5Odrvinfo.c b/src/H5Odrvinfo.c
index 8bebc6d..69ab5b2 100644
--- a/src/H5Odrvinfo.c
+++ b/src/H5Odrvinfo.c
@@ -38,7 +38,7 @@ const H5O_msg_class_t H5O_MSG_DRVINFO[1] = {{
H5O_DRVINFO_ID, /*message id number */
"driver info", /*message name for debugging */
sizeof(H5O_drvinfo_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__drvinfo_decode, /*decode message */
H5O__drvinfo_encode, /*encode message */
H5O__drvinfo_copy, /*copy the native value */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 1be9522..9af79f4 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -89,7 +89,7 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
H5O_DTYPE_ID, /* message id number */
"datatype", /* message name for debugging */
sizeof(H5T_t), /* native message size */
- H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are shareable? */
H5O__dtype_shared_decode, /* decode message */
H5O__dtype_shared_encode, /* encode message */
H5O__dtype_copy, /* copy the native value */
@@ -1731,7 +1731,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_NO_CLASS:
case H5T_NCLASSES:
default:
- HDsprintf(buf, "H5T_CLASS_%d", (int)(dt->shared->type));
+ HDsnprintf(buf, sizeof(buf), "H5T_CLASS_%d", (int)(dt->shared->type));
s = buf;
break;
} /* end switch */
@@ -1746,7 +1746,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Number of members:", dt->shared->u.compnd.nmembs);
for (i = 0; i < dt->shared->u.compnd.nmembs; i++) {
- HDsprintf(buf, "Member %u:", i);
+ HDsnprintf(buf, sizeof(buf), "Member %u:", i);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, buf, dt->shared->u.compnd.memb[i].name);
HDfprintf(stream, "%*s%-*s %lu\n", indent + 3, "", MAX(0, fwidth - 3),
"Byte offset:", (unsigned long)(dt->shared->u.compnd.memb[i].offset));
@@ -1759,7 +1759,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Number of members:", dt->shared->u.enumer.nmembs);
for (i = 0; i < dt->shared->u.enumer.nmembs; i++) {
- HDsprintf(buf, "Member %u:", i);
+ HDsnprintf(buf, sizeof(buf), "Member %u:", i);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, buf, dt->shared->u.enumer.name[i]);
HDfprintf(stream, "%*s%-*s 0x", indent, "", fwidth, "Raw bytes of value:");
for (k = 0; k < dt->shared->parent->shared->size; k++)
@@ -1799,13 +1799,14 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_CSET_RESERVED_13:
case H5T_CSET_RESERVED_14:
case H5T_CSET_RESERVED_15:
- HDsprintf(buf, "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.cset));
+ HDsnprintf(buf, sizeof(buf), "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.cset));
s = buf;
break;
case H5T_CSET_ERROR:
default:
- HDsprintf(buf, "Unknown character set: %d", (int)(dt->shared->u.atomic.u.s.cset));
+ HDsnprintf(buf, sizeof(buf), "Unknown character set: %d",
+ (int)(dt->shared->u.atomic.u.s.cset));
s = buf;
break;
} /* end switch */
@@ -1837,13 +1838,14 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_STR_RESERVED_13:
case H5T_STR_RESERVED_14:
case H5T_STR_RESERVED_15:
- HDsprintf(buf, "H5T_STR_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.pad));
+ HDsnprintf(buf, sizeof(buf), "H5T_STR_RESERVED_%d", (int)(dt->shared->u.atomic.u.s.pad));
s = buf;
break;
case H5T_STR_ERROR:
default:
- HDsprintf(buf, "Unknown string padding: %d", (int)(dt->shared->u.atomic.u.s.pad));
+ HDsnprintf(buf, sizeof(buf), "Unknown string padding: %d",
+ (int)(dt->shared->u.atomic.u.s.pad));
s = buf;
break;
} /* end switch */
@@ -1862,7 +1864,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_VLEN_BADTYPE:
case H5T_VLEN_MAXTYPE:
default:
- HDsprintf(buf, "H5T_VLEN_%d", dt->shared->u.vlen.type);
+ HDsnprintf(buf, sizeof(buf), "H5T_VLEN_%d", dt->shared->u.vlen.type);
s = buf;
break;
} /* end switch */
@@ -1880,7 +1882,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_LOC_BADLOC:
case H5T_LOC_MAXLOC:
default:
- HDsprintf(buf, "H5T_LOC_%d", (int)dt->shared->u.vlen.loc);
+ HDsnprintf(buf, sizeof(buf), "H5T_LOC_%d", (int)dt->shared->u.vlen.loc);
s = buf;
break;
} /* end switch */
@@ -1911,13 +1913,13 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_CSET_RESERVED_13:
case H5T_CSET_RESERVED_14:
case H5T_CSET_RESERVED_15:
- HDsprintf(buf, "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.vlen.cset));
+ HDsnprintf(buf, sizeof(buf), "H5T_CSET_RESERVED_%d", (int)(dt->shared->u.vlen.cset));
s = buf;
break;
case H5T_CSET_ERROR:
default:
- HDsprintf(buf, "Unknown character set: %d", (int)(dt->shared->u.vlen.cset));
+ HDsnprintf(buf, sizeof(buf), "Unknown character set: %d", (int)(dt->shared->u.vlen.cset));
s = buf;
break;
} /* end switch */
@@ -1949,13 +1951,13 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_STR_RESERVED_13:
case H5T_STR_RESERVED_14:
case H5T_STR_RESERVED_15:
- HDsprintf(buf, "H5T_STR_RESERVED_%d", (int)(dt->shared->u.vlen.pad));
+ HDsnprintf(buf, sizeof(buf), "H5T_STR_RESERVED_%d", (int)(dt->shared->u.vlen.pad));
s = buf;
break;
case H5T_STR_ERROR:
default:
- HDsprintf(buf, "Unknown string padding: %d", (int)(dt->shared->u.vlen.pad));
+ HDsnprintf(buf, sizeof(buf), "Unknown string padding: %d", (int)(dt->shared->u.vlen.pad));
s = buf;
break;
} /* end switch */
@@ -1995,7 +1997,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_ORDER_ERROR:
default:
- HDsprintf(buf, "H5T_ORDER_%d", dt->shared->u.atomic.order);
+ HDsnprintf(buf, sizeof(buf), "H5T_ORDER_%d", dt->shared->u.atomic.order);
s = buf;
break;
} /* end switch */
@@ -2069,9 +2071,9 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_NPAD:
default:
if (dt->shared->u.atomic.u.f.pad < 0)
- HDsprintf(buf, "H5T_PAD_%d", -(dt->shared->u.atomic.u.f.pad));
+ HDsnprintf(buf, sizeof(buf), "H5T_PAD_%d", -(dt->shared->u.atomic.u.f.pad));
else
- HDsprintf(buf, "bit-%d", dt->shared->u.atomic.u.f.pad);
+ HDsnprintf(buf, sizeof(buf), "bit-%d", dt->shared->u.atomic.u.f.pad);
s = buf;
break;
} /* end switch */
@@ -2092,7 +2094,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_NORM_ERROR:
default:
- HDsprintf(buf, "H5T_NORM_%d", (int)(dt->shared->u.atomic.u.f.norm));
+ HDsnprintf(buf, sizeof(buf), "H5T_NORM_%d", (int)(dt->shared->u.atomic.u.f.norm));
s = buf;
} /* end switch */
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Normalization:", s);
@@ -2129,7 +2131,7 @@ H5O__dtype_debug(H5F_t *f, const void *mesg, FILE *stream, int indent, int fwidt
case H5T_SGN_ERROR:
case H5T_NSGN:
default:
- HDsprintf(buf, "H5T_SGN_%d", (int)(dt->shared->u.atomic.u.i.sign));
+ HDsnprintf(buf, sizeof(buf), "H5T_SGN_%d", (int)(dt->shared->u.atomic.u.i.sign));
s = buf;
break;
} /* end switch */
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index d950249..931fe0b 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -41,7 +41,7 @@ const H5O_msg_class_t H5O_MSG_EFL[1] = {{
H5O_EFL_ID, /*message id number */
"external file list", /*message name for debugging */
sizeof(H5O_efl_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__efl_decode, /*decode message */
H5O__efl_encode, /*encode message */
H5O__efl_copy, /*copy native value */
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index 5068039..d905352 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -107,7 +107,7 @@ const H5O_msg_class_t H5O_MSG_FILL[1] = {{
H5O_FILL_ID, /*message id number */
"fill", /*message name for debugging */
sizeof(H5O_fill_t), /*native message size */
- H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are shareable? */
H5O__fill_shared_decode, /*decode message */
H5O__fill_shared_encode, /*encode message */
H5O__fill_copy, /*copy the native value */
@@ -131,7 +131,7 @@ const H5O_msg_class_t H5O_MSG_FILL_NEW[1] = {{
H5O_FILL_NEW_ID, /*message id number */
"fill_new", /*message name for debugging */
sizeof(H5O_fill_t), /*native message size */
- H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are shareable? */
H5O__fill_new_shared_decode, /*decode message */
H5O__fill_new_shared_encode, /*encode message */
H5O__fill_copy, /*copy the native value */
diff --git a/src/H5Oflush.c b/src/H5Oflush.c
index f2eacd6..ba1fa3e 100644
--- a/src/H5Oflush.c
+++ b/src/H5Oflush.c
@@ -239,7 +239,7 @@ H5O_refresh_metadata(H5O_loc_t *oloc, hid_t oid)
case H5I_DATASET:
ds = (H5D_t *)vol_obj->data;
state.dapl_id = ds->shared->dapl_id;
- if (H5I_inc_ref(state.dapl_id, false) < 0)
+ if (H5I_inc_ref(state.dapl_id, FALSE) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not increase refcnt");
break;
default:
@@ -405,6 +405,7 @@ H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, const H5O_refresh_sta
break;
case H5I_DATASET:
+ /* Re-open the dataset */
object = H5D_open(obj_loc, (state == NULL) ? H5P_DATASET_ACCESS_DEFAULT : state->dapl_id);
if (NULL == object)
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset")
diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c
index b60f589..7253f3e 100644
--- a/src/H5Ofsinfo.c
+++ b/src/H5Ofsinfo.c
@@ -44,7 +44,7 @@ const H5O_msg_class_t H5O_MSG_FSINFO[1] = {{
H5O_FSINFO_ID, /* message id number */
"fsinfo", /* message name for debugging */
sizeof(H5O_fsinfo_t), /* native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__fsinfo_decode, /* decode message */
H5O__fsinfo_encode, /* encode message */
H5O__fsinfo_copy, /* copy the native value */
@@ -176,7 +176,7 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU
H5F_DECODE_LENGTH(f, p, fsinfo->threshold); /* Free-space section threshold */
H5F_DECODE_LENGTH(f, p, fsinfo->page_size); /* File space page size */
- UINT16DECODE(p, fsinfo->pgend_meta_thres); /* Page end metdata threshold */
+ UINT16DECODE(p, fsinfo->pgend_meta_thres); /* Page end metadata threshold */
H5F_addr_decode(f, &p,
&(fsinfo->eoa_pre_fsm_fsalloc)); /* EOA before free-space header and section info */
diff --git a/src/H5Oginfo.c b/src/H5Oginfo.c
index 8540cc4..304890c 100644
--- a/src/H5Oginfo.c
+++ b/src/H5Oginfo.c
@@ -43,7 +43,7 @@ const H5O_msg_class_t H5O_MSG_GINFO[1] = {{
H5O_GINFO_ID, /*message id number */
"ginfo", /*message name for debugging */
sizeof(H5O_ginfo_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__ginfo_decode, /*decode message */
H5O__ginfo_encode, /*encode message */
H5O__ginfo_copy, /*copy the native value */
diff --git a/src/H5Oint.c b/src/H5Oint.c
index f24d0bb..2348790 100644
--- a/src/H5Oint.c
+++ b/src/H5Oint.c
@@ -82,9 +82,6 @@ static herr_t H5O__reset_info2(H5O_info2_t *oinfo);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Header message ID to class mapping
*
* Remember to increment H5O_MSG_TYPES in H5Opkg.h when adding a new
@@ -178,21 +175,20 @@ static const H5O_obj_class_t *const H5O_obj_class_g[] = {
};
/*-------------------------------------------------------------------------
- * Function: H5O__init_package
- *
- * Purpose: Initialize information specific to H5O interface.
- *
- * Return: Non-negative on success/Negative on failure
+ * Function: H5O_init
*
- * Programmer: Quincey Koziol
- * Thursday, January 18, 2007
+ * Purpose: Initialize the interface from some other layer.
*
+ * Return: Success: non-negative
+ * Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
-H5O__init_package(void)
+H5O_init(void)
{
- FUNC_ENTER_PACKAGE_NOERR
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOERR
/* H5O interface sanity checks */
HDcompile_assert(H5O_MSG_TYPES == NELMTS(H5O_msg_class_g));
@@ -200,8 +196,8 @@ H5O__init_package(void)
HDcompile_assert(H5O_UNKNOWN_ID < H5O_MSG_TYPES);
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5O__init_package() */
+ FUNC_LEAVE_NOAPI(ret_value)
+}
/*-------------------------------------------------------------------------
* Function: H5O__set_version
@@ -293,7 +289,7 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5O_loc
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "Can't apply object header to file")
done:
- if ((FAIL == ret_value) && (NULL != oh) && (H5O__free(oh) < 0))
+ if ((FAIL == ret_value) && (NULL != oh) && (H5O__free(oh, TRUE) < 0))
HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "can't delete object header")
FUNC_LEAVE_NOAPI(ret_value)
@@ -357,7 +353,7 @@ H5O_create_ohdr(H5F_t *f, hid_t ocpl_id)
ret_value = oh;
done:
- if ((NULL == ret_value) && (NULL != oh) && (H5O__free(oh) < 0))
+ if ((NULL == ret_value) && (NULL != oh) && (H5O__free(oh, TRUE) < 0))
HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "can't delete object header")
FUNC_LEAVE_NOAPI(ret_value)
@@ -567,7 +563,7 @@ H5O_open(H5O_loc_t *loc)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Check args */
HDassert(loc);
@@ -584,7 +580,6 @@ H5O_open(H5O_loc_t *loc)
else
H5F_INCR_NOPEN_OBJS(loc->file);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_open() */
@@ -3019,7 +3014,7 @@ H5O_get_proxy(const H5O_t *oh)
*-------------------------------------------------------------------------
*/
herr_t
-H5O__free(H5O_t *oh)
+H5O__free(H5O_t *oh, hbool_t force)
{
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3043,10 +3038,12 @@ H5O__free(H5O_t *oh)
for (u = 0; u < oh->nmesgs; u++) {
#ifndef NDEBUG
/* Verify that message is clean, unless it could have been marked
- * dirty by decoding */
+ * dirty by decoding, or if this is a forced free (in case of
+ * failure during creation of the object some messages may be dirty)
+ */
if (oh->ndecode_dirtied && oh->mesg[u].dirty)
oh->ndecode_dirtied--;
- else
+ else if (!force)
HDassert(oh->mesg[u].dirty == 0);
#endif /* NDEBUG */
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 651e317..c939e72 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -51,7 +51,7 @@ const H5O_msg_class_t H5O_MSG_LAYOUT[1] = {{
H5O_LAYOUT_ID, /* message id number */
"layout", /* message name for debugging */
sizeof(H5O_layout_t), /* native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__layout_decode, /* decode message */
H5O__layout_encode, /* encode message */
H5O__layout_copy, /* copy the native value */
diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c
index 711f199..eacc916 100644
--- a/src/H5Olinfo.c
+++ b/src/H5Olinfo.c
@@ -53,7 +53,7 @@ const H5O_msg_class_t H5O_MSG_LINFO[1] = {{
H5O_LINFO_ID, /*message id number */
"linfo", /*message name for debugging */
sizeof(H5O_linfo_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__linfo_decode, /*decode message */
H5O__linfo_encode, /*encode message */
H5O__linfo_copy, /*copy the native value */
diff --git a/src/H5Olink.c b/src/H5Olink.c
index 75456f4..51c44a3 100644
--- a/src/H5Olink.c
+++ b/src/H5Olink.c
@@ -56,7 +56,7 @@ const H5O_msg_class_t H5O_MSG_LINK[1] = {{
H5O_LINK_ID, /*message id number */
"link", /*message name for debugging */
sizeof(H5O_link_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__link_decode, /*decode message */
H5O__link_encode, /*encode message */
H5O__link_copy, /*copy the native value */
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 15edf1e..fa20aa1 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -371,7 +371,7 @@ H5O__msg_write_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, unsigned m
HDassert(((H5O_shared_t *)idx_msg->native)->type != H5O_SHARE_TYPE_COMMITTED);
/* Also, sanity check that a message doesn't switch status from being
- * shared (or sharable) to being unsharable. (Which could cause
+ * shared (or shareable) to being unshareable. (Which could cause
* a message to increase in size in the object header)
*/
HDassert(!(mesg_flags & H5O_MSG_FLAG_DONTSHARE));
@@ -1131,7 +1131,7 @@ done:
* Nov 19 2004
*
* Description:
- * This function interates over the object headers of an object
+ * This function iterates over the object headers of an object
* specified with 'loc' of type 'type_id'. For each object header of the
* object, the 'op_data' and some additional information (specified below) are
* passed to the 'op' function.
@@ -1194,7 +1194,7 @@ done:
* Sep 6 2005
*
* Description:
- * This function interates over the object headers of an object
+ * This function iterates over the object headers of an object
* specified with 'ent' of type 'type_id'. For each object header of the
* object, the 'op_data' and some additional information (specified below) are
* passed to the 'op' function.
@@ -1544,7 +1544,7 @@ H5O_msg_is_shared(unsigned type_id, const void *mesg)
HDassert(type);
HDassert(mesg);
- /* If messages in a class aren't sharable, then obviously this message isn't shared! :-) */
+ /* If messages in a class aren't shareable, then obviously this message isn't shared! :-) */
if (type->share_flags & H5O_SHARE_IS_SHARABLE)
ret_value = H5O_IS_STORED_SHARED(((const H5O_shared_t *)mesg)->type);
else
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index 163ea32..7d3c56a 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -43,7 +43,7 @@ const H5O_msg_class_t H5O_MSG_MTIME[1] = {{
H5O_MTIME_ID, /*message id number */
"mtime", /*message name for debugging */
sizeof(time_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__mtime_decode, /*decode message */
H5O__mtime_encode, /*encode message */
H5O__mtime_copy, /*copy the native value */
@@ -68,7 +68,7 @@ const H5O_msg_class_t H5O_MSG_MTIME_NEW[1] = {{
H5O_MTIME_NEW_ID, /*message id number */
"mtime_new", /*message name for debugging */
sizeof(time_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__mtime_new_decode, /*decode message */
H5O__mtime_new_encode, /*encode message */
H5O__mtime_copy, /*copy the native value */
diff --git a/src/H5Oname.c b/src/H5Oname.c
index 1636a0e..35578a9 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -43,7 +43,7 @@ const H5O_msg_class_t H5O_MSG_NAME[1] = {{
H5O_NAME_ID, /*message id number */
"name", /*message name for debugging */
sizeof(H5O_name_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__name_decode, /*decode message */
H5O__name_encode, /*encode message */
H5O__name_copy, /*copy the native value */
diff --git a/src/H5Onull.c b/src/H5Onull.c
index 9b377fb..0f3143c 100644
--- a/src/H5Onull.c
+++ b/src/H5Onull.c
@@ -31,7 +31,7 @@ const H5O_msg_class_t H5O_MSG_NULL[1] = {{
H5O_NULL_ID, /*message id number */
"null", /*message name for debugging */
0, /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
NULL, /*no decode method */
NULL, /*no encode method */
NULL, /*no copy method */
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 331fcf6..1fe918d 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -378,7 +378,7 @@ typedef struct H5O_chunk_proxy_t {
H5O_t * oh; /* Object header for this chunk */
unsigned chunkno; /* Chunk number for this chunk */
- /* Flush depencency parent information (not stored)
+ /* Flush dependency parent information (not stored)
*
* The following field is used to store a pointer
* to the in-core representation of a new chunk proxy's flush dependency
@@ -551,7 +551,7 @@ H5_DLL herr_t H5O__visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_ty
H5O_iterate2_t op, void *op_data, unsigned fields);
H5_DLL herr_t H5O__inc_rc(H5O_t *oh);
H5_DLL herr_t H5O__dec_rc(H5O_t *oh);
-H5_DLL herr_t H5O__free(H5O_t *oh);
+H5_DLL herr_t H5O__free(H5O_t *oh, hbool_t force);
/* Object header message routines */
H5_DLL herr_t H5O__msg_alloc(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, unsigned *mesg_flags,
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 221e323..243f454 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -67,7 +67,7 @@ const H5O_msg_class_t H5O_MSG_PLINE[1] = {{
H5O_PLINE_ID, /* message id number */
"filter pipeline", /* message name for debugging */
sizeof(H5O_pline_t), /* native message size */
- H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are shareable? */
H5O__pline_shared_decode, /* decode message */
H5O__pline_shared_encode, /* encode message */
H5O__pline_copy, /* copy the native value */
@@ -86,7 +86,7 @@ const H5O_msg_class_t H5O_MSG_PLINE[1] = {{
H5O__pline_shared_debug /* debug the message */
}};
-/* Format version bounds for filter pipleline */
+/* Format version bounds for filter pipeline */
const unsigned H5O_pline_ver_bounds[] = {
H5O_PLINE_VERSION_1, /* H5F_LIBVER_EARLIEST */
H5O_PLINE_VERSION_2, /* H5F_LIBVER_V18 */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 72306df..d5d1972 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -251,7 +251,7 @@ typedef struct H5O_copy_t {
#define H5O_SHARE_TYPE_UNSHARED 0 /* Message is not shared */
#define H5O_SHARE_TYPE_SOHM 1 /* Message is stored in SOHM heap */
#define H5O_SHARE_TYPE_COMMITTED 2 /* Message is stored in another object header */
-#define H5O_SHARE_TYPE_HERE 3 /* Message is stored in this object header, but is sharable */
+#define H5O_SHARE_TYPE_HERE 3 /* Message is stored in this object header, but is shareable */
/* Detect messages that aren't stored in message's object header */
#define H5O_IS_STORED_SHARED(T) \
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index d9d0500..70f451e 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -80,7 +80,7 @@
#define H5O_SHMESG_MAX_LIST_SIZE 5000
/* Flags for H5Oget_info.
- * Theses flags determine which fields will be filled in in the H5O_info_t
+ * These flags determine which fields will be filled in the H5O_info_t
* struct.
*/
#define H5O_INFO_BASIC 0x0001u /**< Fill in the fileno, addr, type, and rc fields */
@@ -90,8 +90,8 @@
//! <!-- [H5O_native_info_fields_snip] -->
/**
- * Flags for H5Oget_native_info(). Theses flags determine which fields will be
- * filled in in the \ref H5O_native_info_t struct.
+ * Flags for H5Oget_native_info(). These flags determine which fields will be
+ * filled in the \ref H5O_native_info_t struct.
*/
#define H5O_NATIVE_INFO_HDR 0x0008u /**< Fill in the hdr field */
#define H5O_NATIVE_INFO_META_SIZE 0x0010u /**< Fill in the meta_size field */
@@ -510,7 +510,7 @@ H5_DLL herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields);
* location and relative name
*
* \fgdta_loc_obj_id{loc_id}
- * \param[in] name Name of group, relative to \p loc_id
+ * \param[in] name Name of object, relative to \p loc_id
* \param[out] oinfo Buffer in which to return object information
* \param[in] fields Flags specifying the fields to include in \p oinfo
* \lapl_id
@@ -1166,7 +1166,7 @@ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comm
* <em>best effort</em> setting. If the application passes in
* a value indicating iteration in creation order and a group is
* encountered that was not tracked in creation order, that group
- * will be iterated over in alpha-numeric order by name, or
+ * will be iterated over in alphanumeric order by name, or
* <em>name order</em>. (<em>Name order</em> is the native order
* used by the HDF5 library and is always available.)
*
@@ -1265,7 +1265,7 @@ H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order
* <em>best effort</em> setting. If the application passes in a
* value indicating iteration in creation order and a group is
* encountered that was not tracked in creation order, that group
- * will be iterated over in alpha-numeric order by name, or
+ * will be iterated over in alphanumeric order by name, or
* <em>name order</em>. (<em>Name order</em> is the native order
* used by the HDF5 library and is always available.)
*
@@ -1834,7 +1834,7 @@ H5_DLL herr_t H5Oget_info1(hid_t loc_id, H5O_info1_t *oinfo);
* by location and relative name
*
* \fgdta_loc_obj_id{loc_id}
- * \param[in] name Name of group, relative to \p loc_id
+ * \param[in] name Name of object, relative to \p loc_id
* \param[out] oinfo Buffer in which to return object information
* \lapl_id
*
@@ -1960,7 +1960,7 @@ H5_DLL herr_t H5Oget_info2(hid_t loc_id, H5O_info1_t *oinfo, unsigned fields);
* by location and relative name
*
* \fgdta_loc_obj_id{loc_id}
- * \param[in] name Name of group, relative to \p loc_id
+ * \param[in] name Name of object, relative to \p loc_id
* \param[out] oinfo Buffer in which to return object information
* \param[in] fields Flags specifying the fields to include in \p oinfo
* \lapl_id
@@ -1978,7 +1978,7 @@ H5_DLL herr_t H5Oget_info2(hid_t loc_id, H5O_info1_t *oinfo, unsigned fields);
* in the H5Oget_info1() function entry.
*
* The \p fields parameter contains flags to determine which fields
- * will be filled in in the H5O_info1_t \c struct returned in
+ * will be filled in the H5O_info1_t \c struct returned in
* \p oinfo. These flags are defined in the H5Opublic.h file:
*
* \obj_info_fields
@@ -2096,7 +2096,7 @@ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index
* <em>best effort</em> setting. If the application passes in
* a value indicating iteration in creation order and a group is
* encountered that was not tracked in creation order, that group
- * will be iterated over in alpha-numeric order by name, or
+ * will be iterated over in alphanumeric order by name, or
* <em>name order</em>. (<em>Name order</em> is the native order
* used by the HDF5 library and is always available.)
*
@@ -2188,7 +2188,7 @@ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order
* <em>best effort</em> setting. If the application passes in a
* value indicating iteration in creation order and a group is
* encountered that was not tracked in creation order, that group
- * will be iterated over in alpha-numeric order by name, or
+ * will be iterated over in alphanumeric order by name, or
* <em>name order</em>. (<em>Name order</em> is the native order
* used by the HDF5 library and is always available.)
*
@@ -2291,7 +2291,7 @@ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t i
* <em>best effort</em> setting. If the application passes in
* a value indicating iteration in creation order and a group is
* encountered that was not tracked in creation order, that group
- * will be iterated over in alpha-numeric order by name, or
+ * will be iterated over in alphanumeric order by name, or
* <em>name order</em>. (<em>Name order</em> is the native order
* used by the HDF5 library and is always available.)
*
@@ -2385,7 +2385,7 @@ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order
* <em>best effort</em> setting. If the application passes in a
* value indicating iteration in creation order and a group is
* encountered that was not tracked in creation order, that group
- * will be iterated over in alpha-numeric order by name, or
+ * will be iterated over in alphanumeric order by name, or
* <em>name order</em>. (<em>Name order</em> is the native order
* used by the HDF5 library and is always available.)
*
diff --git a/src/H5Orefcount.c b/src/H5Orefcount.c
index 52eee14..500ab0f 100644
--- a/src/H5Orefcount.c
+++ b/src/H5Orefcount.c
@@ -45,7 +45,7 @@ const H5O_msg_class_t H5O_MSG_REFCOUNT[1] = {{
H5O_REFCOUNT_ID, /*message id number */
"refcount", /*message name for debugging */
sizeof(H5O_refcount_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__refcount_decode, /*decode message */
H5O__refcount_encode, /*encode message */
H5O__refcount_copy, /*copy the native value */
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index dab989f..574103d 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -61,7 +61,7 @@ const H5O_msg_class_t H5O_MSG_SDSPACE[1] = {{
H5O_SDSPACE_ID, /* message id number */
"dataspace", /* message name for debugging */
sizeof(H5S_extent_t), /* native message size */
- H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are sharable? */
+ H5O_SHARE_IS_SHARABLE | H5O_SHARE_IN_OHDR, /* messages are shareable? */
H5O__sdspace_shared_decode, /* decode message */
H5O__sdspace_shared_encode, /* encode message */
H5O__sdspace_copy, /* copy the native value */
diff --git a/src/H5Oshmesg.c b/src/H5Oshmesg.c
index 1c894a5..a4e8b8f 100644
--- a/src/H5Oshmesg.c
+++ b/src/H5Oshmesg.c
@@ -37,7 +37,7 @@ const H5O_msg_class_t H5O_MSG_SHMESG[1] = {{
H5O_SHMESG_ID, /*message id number */
"shared message table", /*message name for debugging */
sizeof(H5O_shmesg_table_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__shmesg_decode, /*decode message */
H5O__shmesg_encode, /*encode message */
H5O__shmesg_copy, /*copy the native value */
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index fa030bd..213b8a0 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -51,7 +51,7 @@ const H5O_msg_class_t H5O_MSG_STAB[1] = {{
H5O_STAB_ID, /*message id number */
"stab", /*message name for debugging */
sizeof(H5O_stab_t), /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
H5O__stab_decode, /*decode message */
H5O__stab_encode, /*encode message */
H5O__stab_copy, /*copy the native value */
diff --git a/src/H5Ounknown.c b/src/H5Ounknown.c
index 2b8a7bb..dc43a6c 100644
--- a/src/H5Ounknown.c
+++ b/src/H5Ounknown.c
@@ -37,7 +37,7 @@ const H5O_msg_class_t H5O_MSG_UNKNOWN[1] = {{
H5O_UNKNOWN_ID, /*message id number */
"unknown", /*message name for debugging */
0, /*native message size */
- 0, /* messages are sharable? */
+ 0, /* messages are shareable? */
NULL, /*decode message */
NULL, /*encode message */
NULL, /*copy the native value */
diff --git a/src/H5P.c b/src/H5P.c
index a2d9cfc..c671ea0 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -54,9 +54,6 @@ typedef struct {
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -678,7 +675,7 @@ done:
NAME
H5Pexist
PURPOSE
- Routine to query the existance of a property in a property object.
+ Routine to query the existence of a property in a property object.
USAGE
htri_t H5P_exist(id, name)
hid_t id; IN: Property object ID to check
@@ -712,7 +709,7 @@ H5Pexist(hid_t id, const char *name)
if (!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
- /* Check for the existance of the property in the list or class */
+ /* Check for the existence of the property in the list or class */
if (H5I_GENPROP_LST == H5I_get_type(id)) {
if (NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
@@ -858,7 +855,7 @@ done:
Failure: H5I_INVALID_HID (negative)
DESCRIPTION
Decodes a property list from a binary buffer. The contents of the buffer
- contain the values for the correponding properties of the plist. The decode
+ contain the values for the corresponding properties of the plist. The decode
callback of a certain property decodes its value from the buffer and sets it
in the property list.
GLOBAL VARIABLES
@@ -1299,7 +1296,7 @@ done:
Returns non-negative on success, negative on failure.
DESCRIPTION
Removes a property from a property list. Both properties which were
- in existance when the property list was created (i.e. properties registered
+ in existence when the property list was created (i.e. properties registered
with H5Pregister2) and properties added to the list after it was created
(i.e. added with H5Pinsert2) may be removed from a property list.
Properties do not need to be removed a property list before the list itself
diff --git a/src/H5PB.c b/src/H5PB.c
index ef93bd7..c528fd8 100644
--- a/src/H5PB.c
+++ b/src/H5PB.c
@@ -50,14 +50,14 @@
/* Round _x down to nearest _size. */
/* not used at present */
/*
-#ifndef rounddown
-#define rounddown(_x, _size) (((_x) / (_size)) * (_size))
+#ifndef H5PB_ROUNDDOWN
+#define H5PB_ROUNDDOWN(_x, _size) (((_x) / (_size)) * (_size))
#endif
*/
/* Round _x up to nearest _size. */
-#ifndef roundup
-#define roundup(_x, _size) ((((_x) + (_size)-1) / (_size)) * (_size))
+#ifndef H5PB_ROUNDUP
+#define H5PB_ROUNDUP(_x, _size) ((((_x) + (_size)-1) / (_size)) * (_size))
#endif
/******************/
@@ -109,9 +109,6 @@ static herr_t H5PB__write_raw(H5F_shared_t *, H5FD_mem_t, haddr_t, size_t, const
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -119,7 +116,6 @@ hbool_t H5_PKG_INIT_VAR = FALSE;
/*******************/
/* Local Variables */
/*******************/
-
/* Declare a free list to manage the H5PB_t struct */
H5FL_DEFINE_STATIC(H5PB_t);
@@ -297,7 +293,7 @@ H5PB_print_stats(const H5PB_t *page_buf)
(page_buf->bypasses[0] + page_buf->bypasses[1] + page_buf->bypasses[2]), page_buf->bypasses[0],
page_buf->bypasses[1], page_buf->bypasses[2]);
- HDfprintf(stdout, "acesses = %" PRIi64 " (%" PRIi64 "/%" PRIi64 "/%" PRIi64 ")\n",
+ HDfprintf(stdout, "accesses = %" PRIi64 " (%" PRIi64 "/%" PRIi64 "/%" PRIi64 ")\n",
(page_buf->accesses[0] + page_buf->accesses[1] + page_buf->accesses[2]), page_buf->accesses[0],
page_buf->accesses[1], page_buf->accesses[2]);
@@ -924,7 +920,7 @@ H5PB_count_meta_access_by_size(H5PB_t *pb, size_t size)
* max_pages), simply read from the HDF5 file and return.
*
* The free space manager guarantees that allocations larger
- * than one page will be page alligned, and that allocations
+ * than one page will be page aligned, and that allocations
* of size less than or equal to page size will not cross page
* boundaries. Further, unlike raw data, metadata is always
* written and read atomically.
@@ -1052,7 +1048,7 @@ H5PB_count_meta_access_by_size(H5PB_t *pb, size_t size)
* Changes: Updated for discovery of the fact that the fixed and
* extensible array data structures allocate multiple
* metadata cache entries in a single block, and thus
- * violate that invarient that metadata entries either
+ * violate that invariant that metadata entries either
* do not cross page boundaries, or are page aligned.
*
* JRM -- 3/28/20
@@ -1205,7 +1201,7 @@ H5PB_read(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size, void
* empty.
*
* Since we know that the read crosses at least one
- * page boundary, and we have aleady filtered out the
+ * page boundary, and we have already filtered out the
* body only case, at least two of the above must be
* non-empty.
*/
@@ -1362,18 +1358,18 @@ done:
* this routine performs an O(n) copy of index entries.
*/
static int
-shadow_idx_entry_remove(H5F_shared_t *shared, uint64_t page, hbool_t only_mark)
+H5PB__shadow_idx_entry_remove(H5F_shared_t *shared, uint64_t page, hbool_t only_mark)
{
ptrdiff_t i;
H5FD_vfd_swmr_idx_entry_t *entry;
- entry = vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page, FALSE);
+ entry = H5FD_vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page, FALSE);
if (entry == NULL)
return 0;
if (shared->vfd_swmr_writer && entry->md_file_page_offset != 0) {
- if (shadow_image_defer_free(shared, entry) != 0)
+ if (H5F_shadow_image_defer_free(shared, entry) != 0)
return -1;
entry->md_file_page_offset = 0;
}
@@ -1496,8 +1492,8 @@ H5PB_remove_entry(H5F_shared_t *shared, haddr_t addr)
HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, "forced eviction failed")
HDassert(!shared->vfd_swmr_writer ||
- vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page,
- FALSE) == NULL);
+ H5FD_vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page,
+ FALSE) == NULL);
}
done:
@@ -1542,7 +1538,7 @@ done:
* In all contexts, there is no guarantee that the page buffer
* will contain any of the possible entries.
*
- * Space allocations larger than one page must be page alligned.
+ * Space allocations larger than one page must be page aligned.
* Further, any space between the end of a multi-page allocation
* and the next page boundary will remain un-allocated until after
* the original allocation is freed. This implies that:
@@ -1900,7 +1896,7 @@ H5PB_vfd_swmr__release_tick_list(H5F_shared_t *shared)
}
}
/* if the entry is not a multi-page metadata entry, it must already
- * be on either the replacment policy or the delayed write list.
+ * be on either the replacement policy or the delayed write list.
* In either case, it will be flush when possible and necessary.
*/
}
@@ -2102,7 +2098,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, uint32_t *idx_ent_added_ptr, uint32_t *idx
/* see if the shadow index already contains an entry for *entry. */
- ie_ptr = vfd_swmr_pageno_to_mdf_idx_entry(idx, shared->mdf_idx_entries_used, target_page, FALSE);
+ ie_ptr = H5FD_vfd_swmr_pageno_to_mdf_idx_entry(idx, shared->mdf_idx_entries_used, target_page, FALSE);
if (ie_ptr == NULL) { /* alloc new entry in the metadata file index*/
uint32_t new_index_entry_index;
@@ -2110,7 +2106,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, uint32_t *idx_ent_added_ptr, uint32_t *idx
new_index_entry_index = shared->mdf_idx_entries_used + idx_ent_added++;
if (new_index_entry_index >= shared->mdf_idx_len &&
- (idx = vfd_swmr_enlarge_shadow_index(f)) == NULL) {
+ (idx = H5F_vfd_swmr_enlarge_shadow_index(f)) == NULL) {
HDfprintf(stderr, "\n\nmax mdf index len (%" PRIu32 ") exceeded.\n\n", shared->mdf_idx_len);
HDfprintf(stderr, "tick = %" PRIu64 ".\n", tick_num);
HDexit(EXIT_FAILURE);
@@ -2140,7 +2136,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, uint32_t *idx_ent_added_ptr, uint32_t *idx
if (ie_ptr->length != (uint32_t)entry->size) {
int ret;
- ret = shadow_image_defer_free(shared, ie_ptr);
+ ret = H5F_shadow_image_defer_free(shared, ie_ptr);
HDassert(ret == 0);
ie_ptr->md_file_page_offset = 0;
@@ -2236,7 +2232,7 @@ done:
* max_pages), simply write to the HDF5 file and return.
*
* The free space manager guarantees that allocations larger
- * than one page will be page alligned, and that allocations
+ * than one page will be page aligned, and that allocations
* of size less than or equal to page size will not cross page
* boundaries. Further, unlike raw data, metadata is always
* written and read atomically.
@@ -2256,7 +2252,7 @@ done:
* structures, it complicates the metadata cache and the page
* buffer.
*
- * From the page buffer perspective, it breaks the invarient
+ * From the page buffer perspective, it breaks the invariant
* that metadata entries of less than page size don't cross
* page boundaries, and those of size greater than or equal
* to page size start on page boundaries -- which is important
@@ -2511,7 +2507,7 @@ H5PB_write(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size, con
* empty.
*
* Since we know that the write crosses at least one
- * page boundary, and we have aleady filtered out the
+ * page boundary, and we have already filtered out the
* body only case, at least two of the above must be
* non-empty.
*/
@@ -2718,7 +2714,7 @@ H5PB__allocate_page(H5PB_t *page_buf, size_t size, hbool_t clean_image)
void * image_ptr = NULL;
H5PB_entry_t *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_STATIC
/* sanity checks */
HDassert(page_buf);
@@ -2790,7 +2786,7 @@ done:
image_ptr = H5MM_xfree(image_ptr);
}
- } /* end if */
+ }
FUNC_LEAVE_NOAPI(ret_value)
@@ -2926,7 +2922,7 @@ done:
static void
H5PB__deallocate_page(H5PB_entry_t *entry_ptr)
{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC_NOERR
/* sanity checks */
HDassert(entry_ptr);
@@ -2993,7 +2989,7 @@ H5PB__evict_entry(H5F_shared_t *shared, H5PB_entry_t *entry_ptr, hbool_t force,
H5PB_t *page_buf = shared->page_buf;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* sanity checks */
HDassert(page_buf);
@@ -3067,7 +3063,7 @@ H5PB__evict_entry(H5F_shared_t *shared, H5PB_entry_t *entry_ptr, hbool_t force,
* the image will be bigger. So the shadow file will never see the
* entire image written, just the first page of the image.
*/
- if (shared->vfd_swmr_writer && shadow_idx_entry_remove(shared, entry_ptr->page, only_mark) == -1) {
+ if (shared->vfd_swmr_writer && H5PB__shadow_idx_entry_remove(shared, entry_ptr->page, only_mark) == -1) {
HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, "failed to remove shadow index entry")
}
@@ -3112,7 +3108,7 @@ H5PB__flush_entry(H5F_shared_t *shared, H5PB_t *page_buf, H5PB_entry_t *const en
haddr_t eoa; /* Current EOA for the file */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* sanity checks */
HDassert(shared);
@@ -3139,7 +3135,7 @@ H5PB__flush_entry(H5F_shared_t *shared, H5PB_t *page_buf, H5PB_entry_t *const en
* true in all cases.
*/
- /* Verify that the base addresss of the page is within the EOA. If it
+ /* Verify that the base address of the page is within the EOA. If it
* isn't, the associated page has been discarded and should have been
* removed from the page buffer. This is a bug in the HDF5 library, so
* an assertion is adequate here.
@@ -3219,7 +3215,7 @@ H5PB__load_page(H5F_shared_t *shared, H5PB_t *page_buf, haddr_t addr, H5FD_mem_t
void * image_ptr = NULL;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* sanity checks */
HDassert(shared);
@@ -3228,18 +3224,6 @@ H5PB__load_page(H5F_shared_t *shared, H5PB_t *page_buf, haddr_t addr, H5FD_mem_t
HDassert(page_buf->magic == H5PB__H5PB_T_MAGIC);
HDassert((entry_ptr_ptr == NULL) || (*entry_ptr_ptr == NULL));
-#if 0 /* JRM */
- haddr_t eoa;
- /* Retrieve the 'eoa' for the file */
- if ( HADDR_UNDEF == (eoa = H5FD_get_eoa(shared->lf, type)))
-
- HGOTO_ERROR(H5E_PAGEBUF, H5E_CANTGET, FAIL, \
- "driver get_eoa request failed")
- if ( addr + ((haddr_t)(page_buf->page_size)) > eoa )
-
- HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \
- "Attempt to load page that extends past EOA")
-#endif /* JRM */
if (HADDR_UNDEF == (eof = H5FD_get_eof(shared->lf, H5FD_MEM_DEFAULT)))
HGOTO_ERROR(H5E_PAGEBUF, H5E_CANTGET, FAIL, "driver get_eof request failed")
@@ -3354,7 +3338,7 @@ done:
*
* evict the entry and test to see if page_buf->curr_pages <
* page_buf->max_pages. If it is, return. Otherwise, continue
- * the scan until either the above condidtion is fulfilled,
+ * the scan until either the above condition is fulfilled,
* or the head of the LRU is reach.
*
* Under normal circumstances, it should always be possible
@@ -3388,7 +3372,7 @@ H5PB__make_space(H5F_shared_t *shared, H5PB_t *page_buf, H5FD_mem_t inserted_typ
H5PB_entry_t *evict_ptr;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* sanity checks */
HDassert(page_buf);
@@ -3502,7 +3486,7 @@ H5PB__mark_entry_clean(H5PB_t *page_buf, H5PB_entry_t *entry_ptr)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* sanity checks */
HDassert(page_buf);
@@ -3562,7 +3546,7 @@ H5PB__mark_entry_dirty(H5F_shared_t *shared, H5PB_t *page_buf, H5PB_entry_t *ent
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* sanity checks */
HDassert(page_buf);
@@ -3586,7 +3570,7 @@ H5PB__mark_entry_dirty(H5F_shared_t *shared, H5PB_t *page_buf, H5PB_entry_t *ent
HDassert(entry_ptr->delay_write_until == 0);
if ((page_buf->vfd_swmr_writer) && (entry_ptr->loaded) && (entry_ptr->mem_type != H5FD_MEM_DRAW) &&
- (H5F_vfd_swmr_writer__delay_write(shared, entry_ptr->page, &(entry_ptr->delay_write_until)) < 0))
+ (H5F_vfd_swmr_writer_delay_write(shared, entry_ptr->page, &(entry_ptr->delay_write_until)) < 0))
HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, "get delayed write request failed")
@@ -3725,7 +3709,7 @@ done:
* Y | Y | MPMDE | N | X | Error (case 9)
* ------+------+--------+------+---------+-------------------------------------
* Y | Y | MPMDE | Y | X | Clip read to MPE size if required.
- * | | | | | Satify read from MPE (case 9)
+ * | | | | | Satisfy read from MPE (case 9)
* ------+------+--------+------+---------+-------------------------------------
* | | | | |
* ------+------+--------+------+---------+-------------------------------------
@@ -3778,7 +3762,7 @@ H5PB__read_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size
size_t clipped_size; /* possibley clipped size */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(shared);
@@ -4086,7 +4070,7 @@ H5PB__read_raw(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size,
hsize_t i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(shared);
@@ -4195,7 +4179,7 @@ H5PB__read_raw(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size,
else {
/* this is an internal page -- copy it in its
- * entireity.
+ * entirety.
*/
offset =
@@ -4375,11 +4359,11 @@ H5PB__write_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t siz
H5PB_t * page_buf; /* Page buffer for this file */
H5PB_entry_t *entry_ptr; /* Pointer to page buffer entry */
uint64_t page; /* page offset of addr */
- haddr_t page_addr; /* page containg addr */
+ haddr_t page_addr; /* page containing addr */
size_t offset; /* offset of write in page */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(shared);
@@ -4436,7 +4420,7 @@ H5PB__write_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t siz
H5PB_entry_t *overlap;
void * new_image = H5MM_malloc(size);
uint64_t iter_page;
- uint64_t last_page = page + roundup(size, page_buf->page_size) / page_buf->page_size;
+ uint64_t last_page = page + H5PB_ROUNDUP(size, page_buf->page_size) / page_buf->page_size;
for (iter_page = page + 1; iter_page < last_page; iter_page++) {
H5PB__SEARCH_INDEX(page_buf, iter_page, overlap, FAIL)
@@ -4596,7 +4580,7 @@ H5PB__write_raw(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size
size_t offset; /* offset of write in a page */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(shared);
diff --git a/src/H5PBpkg.h b/src/H5PBpkg.h
index f06206b..03c75bd 100644
--- a/src/H5PBpkg.h
+++ b/src/H5PBpkg.h
@@ -153,7 +153,7 @@
/* successor at head of list -- prepend */ \
H5PB__DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \
\
- else /* sucessor in body of list -- insert before it */ \
+ else /* successor in body of list -- insert before it */ \
{ \
H5PB__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \
HDassert(suc_ptr->prev->magic == H5PB__H5PB_ENTRY_T_MAGIC); \
@@ -278,7 +278,7 @@
/* successor at head of list -- prepend */ \
H5PB__IL_DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \
\
- else /* sucessor in body of list -- insert before it */ \
+ else /* successor in body of list -- insert before it */ \
{ \
H5PB__IL_DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \
HDassert(suc_ptr->il_prev->magic == H5PB__H5PB_ENTRY_T_MAGIC); \
@@ -1458,7 +1458,7 @@
* Macro: H5PB__INSERT_IN_DWL
*
* Insert the supplied page buffer entry in the delayed write list
- * maintaining the invarient:
+ * maintaining the invariant:
*
* entry_ptr->next == NULL ||
* entry_ptr->delay_write_until >= entry_ptr->next->delay_write_until
@@ -1599,7 +1599,7 @@
* Fields supporting the hash table:
*
* Entries in the page buffer are indexed by a more or less conventional
- * hash table with chaining (see header comment on H5PB_t for futher details).
+ * hash table with chaining (see header comment on H5PB_t for further details).
* If there are multiple entries in any hash bin, they are stored in a doubly
* linked list.
*
@@ -1647,7 +1647,7 @@
* Fields supporting VFD SWMR:
*
* is_mpmde: Boolean flag that is set to TRUE iff the entry
- * is a multi-page metadata entry. In the absense of VFD
+ * is a multi-page metadata entry. In the absence of VFD
* SWMR, the field should always be set to FALSE.
*
* Observe that:
@@ -1668,15 +1668,15 @@
*
* delay_write_until: Unsigned 64 bit integer containing the first tick
* in which the entry may be written to file, or 0 if there
- * is no such constraint. It should be set ot 0 when VFD
+ * is no such constraint. It should be set to 0 when VFD
* is not enabled.
*
* tl_next: Next pointer on the list of entries modified in the current
- * tick, If the enty is not on the tick list, or if there is
+ * tick, If the entry is not on the tick list, or if there is
* no next entry on the list, this field should be set to NULL.
*
* tl_prev: Prev pointer on the list of entries modified in the current
- * tick, If the enty is not on the tick list, or if there is
+ * tick, If the entry is not on the tick list, or if there is
* no previous entry on the list, this field should be set to
* NULL.
*
diff --git a/src/H5PBprivate.h b/src/H5PBprivate.h
index 15ee749..ad59150 100644
--- a/src/H5PBprivate.h
+++ b/src/H5PBprivate.h
@@ -24,10 +24,6 @@
#ifndef H5PBprivate_H
#define H5PBprivate_H
-/* Include package's public header */
-
-/* no H5PBpublic.h at present */
-
/* Private headers needed by this header */
#include "H5private.h" /* Generic Functions */
@@ -308,7 +304,7 @@ typedef struct H5PB_entry_t H5PB_entry_t;
*
* To facilitate identification of entries that must be removed from the
* DWL during the end of tick scan, the list always observes the following
- * invarient for any entry on the list:
+ * invariant for any entry on the list:
*
* entry_ptr->next == NULL ||
* entry_ptr->delay_write_until >= entry_ptr->next->delay_write_until
@@ -528,7 +524,7 @@ typedef struct H5PB_entry_t H5PB_entry_t;
* max_dwl_size: int64_t containing the maximum value of dwl_size.
*
* total_dwl_ins_depth: int64_t containing the total insertion depth
- * required to maintain the odering invarient on the
+ * required to maintain the odering invariant on the
* delayed write list.
*
* md_read_splits: int64_t containing the number of metadata reads that
diff --git a/src/H5PL.c b/src/H5PL.c
index 30b6c52..b052078 100644
--- a/src/H5PL.c
+++ b/src/H5PL.c
@@ -67,7 +67,7 @@
* the special "::" string.
*
* Return: Success: Non-negative
- * Failture: Negative
+ * Failure: Negative
*
*-------------------------------------------------------------------------
*/
@@ -99,7 +99,7 @@ done:
* Positive if one or more of the plugin types are enabled
*
* Return: Success: Non-negative
- * Failture: Negative
+ * Failure: Negative
*
*-------------------------------------------------------------------------
*/
@@ -128,7 +128,7 @@ done:
* Purpose: Insert a plugin search path at the end of the list.
*
* Return: Success: Non-negative
- * Failture: Negative
+ * Failure: Negative
*
*-------------------------------------------------------------------------
*/
@@ -160,7 +160,7 @@ done:
* Purpose: Insert a plugin search path at the beginning of the list.
*
* Return: Success: Non-negative
- * Failture: Negative
+ * Failure: Negative
*
*-------------------------------------------------------------------------
*/
@@ -234,7 +234,7 @@ done:
* other paths after the index.
*
* Return: Success: Non-negative
- * Failture: Negative
+ * Failure: Negative
*
*-------------------------------------------------------------------------
*/
@@ -270,11 +270,11 @@ done:
/*-------------------------------------------------------------------------
* Function: H5PLremove
*
- * Purpose: Remove the plugin path at the specifed index and compact
+ * Purpose: Remove the plugin path at the specified index and compact
* the list.
*
* Return: Success: Non-negative
- * Failture: Negative
+ * Failure: Negative
*
* Return: Non-negative or success.
*
diff --git a/src/H5PLint.c b/src/H5PLint.c
index d20401e..fe9d3c1 100644
--- a/src/H5PLint.c
+++ b/src/H5PLint.c
@@ -46,9 +46,6 @@
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -123,28 +120,27 @@ H5PL__set_plugin_control_mask(unsigned int mask)
} /* end H5PL__set_plugin_control_mask() */
/*-------------------------------------------------------------------------
- * Function: H5PL__init_package
- *
- * Purpose: Initialize any package-specific data and call any init
- * routines for the package.
+ * Function: H5PL_init
*
- * Return: SUCCEED/FAIL
+ * Purpose: Initialize the interface from some other layer.
*
+ * Return: Success: non-negative
+ * Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
-H5PL__init_package(void)
+H5PL_init(void)
{
char * env_var = NULL;
herr_t ret_value = SUCCEED;
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI(FAIL)
/* Check the environment variable to determine if the user wants
* to ignore plugins. The special symbol H5PL_NO_PLUGIN (defined in
* H5PLpublic.h) means we don't want to load plugins.
*/
- if (NULL != (env_var = HDgetenv("HDF5_PLUGIN_PRELOAD")))
+ if (NULL != (env_var = HDgetenv(HDF5_PLUGIN_PRELOAD)))
if (!HDstrcmp(env_var, H5PL_NO_PLUGIN)) {
H5PL_plugin_control_mask_g = 0;
H5PL_allow_plugins_g = FALSE;
@@ -160,7 +156,7 @@ H5PL__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5PL__init_package() */
+}
/*-------------------------------------------------------------------------
* Function: H5PL_term_package
@@ -183,24 +179,17 @@ H5PL_term_package(void)
FUNC_ENTER_NOAPI_NOINIT
- if (H5_PKG_INIT_VAR) {
-
- /* Close the plugin cache.
- * We need to bump the return value if we did any real work here.
- */
- if (H5PL__close_plugin_cache(&already_closed) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing plugin cache")
- if (!already_closed)
- ret_value++;
-
- /* Close the search path table and free the paths */
- if (H5PL__close_path_table() < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing search path table")
+ /* Close the plugin cache.
+ * We need to bump the return value if we did any real work here.
+ */
+ if (H5PL__close_plugin_cache(&already_closed) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing plugin cache")
+ if (!already_closed)
+ ret_value++;
- /* Mark the interface as uninitialized */
- if (0 == ret_value)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Close the search path table and free the paths */
+ if (H5PL__close_path_table() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing search path table")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -243,6 +232,11 @@ H5PL_load(H5PL_type_t type, const H5PL_key_t *key)
"Virtual Object Layer (VOL) driver plugins disabled")
break;
+ case H5PL_TYPE_VFD:
+ if ((H5PL_plugin_control_mask_g & H5PL_VFD_PLUGIN) == 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "Virtual File Driver (VFD) plugins disabled")
+ break;
+
case H5PL_TYPE_ERROR:
case H5PL_TYPE_NONE:
default:
@@ -275,9 +269,31 @@ done:
*
* Purpose: Opens a plugin.
*
- * The success parameter will be set to TRUE and the plugin_info
- * parameter will be filled in on success. Otherwise, they
- * will be FALSE and NULL, respectively.
+ * `path` specifies the path to the plugin library file.
+ *
+ * `type` specifies the type of plugin being searched for and
+ * will be used to verify that a loaded plugin matches the
+ * type requested. H5PL_TYPE_NONE may be passed, in which case
+ * no plugin type verification is performed. This is most
+ * useful when iterating over available plugins without regard
+ * to their types.
+ *
+ * `key` specifies the information that will be used to find a
+ * specific plugin. For filter plugins, this is typically an
+ * integer identifier. For VOL connector and VFD plugins, this
+ * is typically either an integer identifier or a name string.
+ * After a plugin has been opened, this information will be
+ * compared against the relevant information provided by the
+ * plugin to ensure that the plugin is a match. If
+ * H5PL_TYPE_NONE is provided for `type`, then `key` should be
+ * NULL.
+ *
+ * On successful open of a plugin, the `success` parameter
+ * will be set to TRUE and the `plugin_type` and `plugin_info`
+ * parameters will be filled appropriately. On failure, the
+ * `success` parameter will be set to FALSE, the `plugin_type`
+ * parameter will be set to H5PL_TYPE_ERROR and the
+ * `plugin_info` parameter will be set to NULL.
*
* Return: SUCCEED/FAIL
*
@@ -308,6 +324,8 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s
/* Check args - Just assert on package functions */
HDassert(path);
+ if (type == H5PL_TYPE_NONE)
+ HDassert(!key);
HDassert(success);
HDassert(plugin_info);
@@ -396,6 +414,34 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s
break;
}
+ case H5PL_TYPE_VFD: {
+ const void *cls;
+
+ /* Get the plugin info */
+ if (NULL == (cls = (const void *)(*get_plugin_info)()))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get VFD info from plugin")
+
+ /* Setup temporary plugin key if one wasn't supplied */
+ if (!key) {
+ tmp_key.vfd.kind = H5FD_GET_DRIVER_BY_NAME;
+ tmp_key.vfd.u.name = ((const H5FD_class_t *)cls)->name;
+ key = &tmp_key;
+ }
+
+ /* Ask VFD interface if this class is the one we are looking for and is compatible, etc */
+ if (H5FD_check_plugin_load(cls, key, success) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, FAIL, "VFD compatibility check failed")
+
+ /* Check for finding the correct plugin */
+ if (*success) {
+ if (plugin_type)
+ *plugin_type = H5PL_TYPE_VFD;
+ *plugin_info = cls;
+ }
+
+ break;
+ }
+
case H5PL_TYPE_ERROR:
case H5PL_TYPE_NONE:
default:
@@ -453,10 +499,9 @@ H5PL_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_dat
{
herr_t ret_value = H5_ITER_CONT;
- FUNC_ENTER_NOAPI(H5_ITER_ERROR)
+ FUNC_ENTER_NOAPI_NOERR
ret_value = H5PL__path_table_iterate(iter_type, iter_op, op_data);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL_iterate() */
diff --git a/src/H5PLpath.c b/src/H5PLpath.c
index 39a7d0d..b86fd6e 100644
--- a/src/H5PLpath.c
+++ b/src/H5PLpath.c
@@ -248,7 +248,7 @@ H5PL__create_path_table(void)
/* Retrieve paths from HDF5_PLUGIN_PATH if the user sets it
* or from the default paths if it isn't set.
*/
- env_var = HDgetenv("HDF5_PLUGIN_PATH");
+ env_var = HDgetenv(HDF5_PLUGIN_PATH);
if (NULL == env_var)
paths = H5MM_strdup(H5PL_DEFAULT_PATH);
else
@@ -322,7 +322,7 @@ H5PL__close_path_table(void)
* Purpose: Gets the number of plugin paths that have been stored.
*
* Return: Success: The number of paths
- * Failture: Can't fail
+ * Failure: Can't fail
*-------------------------------------------------------------------------
*/
unsigned
@@ -571,12 +571,12 @@ H5PL__path_table_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op,
FUNC_ENTER_PACKAGE
- for (u = 0; (u < H5PL_num_paths_g) && (ret_value == H5_ITER_CONT); u++)
- ret_value = H5PL__path_table_iterate_process_path(H5PL_paths_g[u], iter_type, iter_op, op_data);
-
- if (ret_value < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_BADITER, H5_ITER_ERROR, "can't iterate over plugins in plugin path '%s'",
- H5PL_paths_g[u]);
+ for (u = 0; (u < H5PL_num_paths_g) && (ret_value == H5_ITER_CONT); u++) {
+ if ((ret_value =
+ H5PL__path_table_iterate_process_path(H5PL_paths_g[u], iter_type, iter_op, op_data)) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_BADITER, H5_ITER_ERROR,
+ "can't iterate over plugins in plugin path '%s'", H5PL_paths_g[u]);
+ }
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -615,9 +615,9 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
HDassert(plugin_path);
HDassert(iter_op);
- /* Open the directory */
+ /* Open the directory - skip the path if the directory can't be opened */
if (!(dirp = HDopendir(plugin_path)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, H5_ITER_ERROR, "can't open directory: %s", plugin_path)
+ HGOTO_DONE(H5_ITER_CONT)
/* Iterate through all entries in the directory */
while (NULL != (dp = HDreaddir(dirp))) {
@@ -663,7 +663,8 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
/* Determine if we should process this plugin */
plugin_matches = (iter_type == H5PL_ITER_TYPE_ALL) ||
((iter_type == H5PL_ITER_TYPE_FILTER) && (plugin_type == H5PL_TYPE_FILTER)) ||
- ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL));
+ ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL)) ||
+ ((iter_type == H5PL_ITER_TYPE_VFD) && (plugin_type == H5PL_TYPE_VFD));
/* If the plugin was successfully loaded, call supplied callback function on plugin */
if (plugin_loaded && plugin_matches && (ret_value = iter_op(plugin_type, plugin_info, op_data)))
@@ -706,10 +707,11 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
HDassert(plugin_path);
HDassert(iter_op);
- /* Specify a file mask. *.* = We want everything! */
- HDsprintf(service, "%s\\*.dll", plugin_path);
+ /* Specify a file mask. *.* = We want everything! -
+ * skip the path if the directory can't be opened */
+ HDsnprintf(service, sizeof(service), "%s\\*.dll", plugin_path);
if ((hFind = FindFirstFileA(service, &fdFile)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, H5_ITER_ERROR, "can't open directory")
+ HGOTO_DONE(H5_ITER_CONT)
/* Loop over all the files */
do {
@@ -740,7 +742,8 @@ H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type
/* Determine if we should process this plugin */
plugin_matches = (iter_type == H5PL_ITER_TYPE_ALL) ||
((iter_type == H5PL_ITER_TYPE_FILTER) && (plugin_type == H5PL_TYPE_FILTER)) ||
- ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL));
+ ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL)) ||
+ ((iter_type == H5PL_ITER_TYPE_VFD) && (plugin_type == H5PL_TYPE_VFD));
/* If the plugin was successfully loaded, call supplied callback function on plugin */
if (plugin_loaded && plugin_matches && (ret_value = iter_op(plugin_type, plugin_info, op_data)))
@@ -931,7 +934,7 @@ H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *fo
*found = FALSE;
/* Specify a file mask. *.* = We want everything! */
- HDsprintf(service, "%s\\*.dll", dir);
+ HDsnprintf(service, sizeof(service), "%s\\*.dll", dir);
if ((hFind = FindFirstFileA(service, &fdFile)) == INVALID_HANDLE_VALUE)
HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory")
diff --git a/src/H5PLplugin_cache.c b/src/H5PLplugin_cache.c
index b7cdac0..25e373f 100644
--- a/src/H5PLplugin_cache.c
+++ b/src/H5PLplugin_cache.c
@@ -263,59 +263,99 @@ H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *f
/* Loop over all the plugins, looking for one that matches */
for (u = 0; u < H5PL_num_plugins_g; u++) {
- /* If the plugin type (filter, VOL connector, etc.) match, proceed */
- if (search_params->type == H5PL_cache_g[u].type) {
- hbool_t matched = FALSE; /* Whether cached plugin info matches */
+ hbool_t matched = FALSE; /* Whether cached plugin info matches */
- switch (search_params->type) {
- case H5PL_TYPE_FILTER:
- if (search_params->key->id == H5PL_cache_g[u].key.id)
+ /* Determine if the plugin types match */
+ if (search_params->type != H5PL_cache_g[u].type)
+ continue;
+
+ /* Determine if cache entry matches based on type-specific information */
+ switch (search_params->type) {
+ case H5PL_TYPE_FILTER:
+ /* Check if specified filter plugin ID matches cache entry's ID */
+ if (search_params->key->id == H5PL_cache_g[u].key.id)
+ matched = TRUE;
+
+ break;
+
+ case H5PL_TYPE_VOL:
+ if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) {
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vol.kind != H5VL_GET_CONNECTOR_BY_NAME)
+ continue;
+
+ /* Check if specified VOL connector name matches cache entry's name */
+ if (!HDstrcmp(search_params->key->vol.u.name, H5PL_cache_g[u].key.vol.u.name))
+ matched = TRUE;
+ }
+ else {
+ HDassert(search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE);
+
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vol.kind != H5VL_GET_CONNECTOR_BY_VALUE)
+ continue;
+
+ /* Check if specified VOL connector ID matches cache entry's ID */
+ if (search_params->key->vol.u.value == H5PL_cache_g[u].key.vol.u.value)
+ matched = TRUE;
+ }
+
+ break;
+
+ case H5PL_TYPE_VFD:
+ if (search_params->key->vfd.kind == H5FD_GET_DRIVER_BY_NAME) {
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vfd.kind != H5FD_GET_DRIVER_BY_NAME)
+ continue;
+
+ /* Check if specified VFD name matches cache entry's name */
+ if (!HDstrcmp(search_params->key->vfd.u.name, H5PL_cache_g[u].key.vfd.u.name))
matched = TRUE;
- break;
-
- case H5PL_TYPE_VOL:
- if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE) {
- if (search_params->key->vol.u.value == H5PL_cache_g[u].key.vol.u.value)
- matched = TRUE;
- } /* end if */
- else if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) {
- if (0 == HDstrcmp(search_params->key->vol.u.name, H5PL_cache_g[u].key.vol.u.name))
- matched = TRUE;
- } /* end else-if */
- else
- HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad VOL plugin search key type")
- break;
-
- case H5PL_TYPE_ERROR:
- case H5PL_TYPE_NONE:
- default:
- HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad plugin type")
- } /* end switch */
-
- /* If the plugin type (filter, VOL connector, etc.) and key match, query the plugin for its info
- */
- if (matched) {
- H5PL_get_plugin_info_t get_plugin_info_function;
- const void * info;
-
- /* Get the "get plugin info" function from the plugin. */
- if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(
- (H5PL_cache_g[u]).handle, "H5PLget_plugin_info")))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info")
-
- /* Call the "get plugin info" function */
- if (NULL == (info = (*get_plugin_info_function)()))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info")
-
- /* Set output parameters */
- *found = TRUE;
- *plugin_info = info;
-
- /* No need to continue processing */
+ }
+ else {
+ HDassert(search_params->key->vfd.kind == H5FD_GET_DRIVER_BY_VALUE);
+
+ /* Make sure the plugin cache entry key type matches our search key type */
+ if (H5PL_cache_g[u].key.vfd.kind != H5FD_GET_DRIVER_BY_VALUE)
+ continue;
+
+ /* Check if specified VFD ID matches cache entry's ID */
+ if (search_params->key->vfd.u.value == H5PL_cache_g[u].key.vfd.u.value)
+ matched = TRUE;
+ }
+
break;
- } /* end if */
- } /* end if */
- } /* end for */
+
+ case H5PL_TYPE_ERROR:
+ case H5PL_TYPE_NONE:
+ default:
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "Invalid plugin type specified")
+ }
+
+ /* If the plugin type (filter, VOL connector, VFD plugin, etc.) and key match,
+ * query the plugin for its info.
+ */
+ if (matched) {
+ H5PL_get_plugin_info_t get_plugin_info_function;
+ const void * info;
+
+ /* Get the "get plugin info" function from the plugin. */
+ if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(
+ H5PL_cache_g[u].handle, "H5PLget_plugin_info")))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info")
+
+ /* Call the "get plugin info" function */
+ if (NULL == (info = (*get_plugin_info_function)()))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info")
+
+ /* Set output parameters */
+ *found = TRUE;
+ *plugin_info = info;
+
+ /* No need to continue processing */
+ break;
+ }
+ } /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h
index 7eae513..83cc8a5 100644
--- a/src/H5PLprivate.h
+++ b/src/H5PLprivate.h
@@ -22,6 +22,7 @@
/* Private headers needed by this file */
#include "H5private.h" /* Generic Functions */
+#include "H5FDprivate.h" /* File Drivers */
#include "H5VLprivate.h" /* Virtual Object Layer */
/**************************/
@@ -32,16 +33,29 @@
/* Library Private Typedefs */
/****************************/
+/* Key used to find VOL connector plugins */
+typedef struct H5PL_vol_key_t {
+ H5VL_get_connector_kind_t kind; /* Kind of VOL lookup to do */
+ union {
+ H5VL_class_value_t value; /* VOL connector value */
+ const char * name; /* VOL connector name */
+ } u;
+} H5PL_vol_key_t;
+
+/* Key used to find VFD plugins */
+typedef struct H5PL_vfd_key_t {
+ H5FD_get_driver_kind_t kind; /* Kind of VFD lookup to do */
+ union {
+ H5FD_class_value_t value; /* VFD value */
+ const char * name; /* VFD name */
+ } u;
+} H5PL_vfd_key_t;
+
/* The key that will be used to find the plugin */
typedef union H5PL_key_t {
- int id; /* I/O filters */
- struct {
- H5VL_get_connector_kind_t kind; /* Kind of VOL lookup to do */
- union {
- H5VL_class_value_t value; /* VOL connector value */
- const char * name; /* VOL connector name */
- } u;
- } vol;
+ int id; /* I/O filters */
+ H5PL_vol_key_t vol;
+ H5PL_vfd_key_t vfd;
} H5PL_key_t;
/* Enum dictating the type of plugins to process
@@ -50,6 +64,7 @@ typedef union H5PL_key_t {
typedef enum {
H5PL_ITER_TYPE_FILTER,
H5PL_ITER_TYPE_VOL,
+ H5PL_ITER_TYPE_VFD,
H5PL_ITER_TYPE_ALL,
} H5PL_iterate_type_t;
@@ -67,5 +82,6 @@ typedef herr_t (*H5PL_iterate_t)(H5PL_type_t plugin_type, const void *plugin_inf
/* Internal API routines */
H5_DLL const void *H5PL_load(H5PL_type_t plugin_type, const H5PL_key_t *key);
H5_DLL herr_t H5PL_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_data);
+H5_DLL herr_t H5PL_init(void);
#endif /* H5PLprivate_H */
diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h
index 55ff594..ab24bd5 100644
--- a/src/H5PLpublic.h
+++ b/src/H5PLpublic.h
@@ -35,14 +35,16 @@
typedef enum H5PL_type_t {
H5PL_TYPE_ERROR = -1, /**< Error */
H5PL_TYPE_FILTER = 0, /**< Filter */
- H5PL_TYPE_VOL = 1, /**< VOL driver */
- H5PL_TYPE_NONE = 2 /**< Sentinel: This must be last! */
+ H5PL_TYPE_VOL = 1, /**< VOL connector */
+ H5PL_TYPE_VFD = 2, /**< VFD */
+ H5PL_TYPE_NONE = 3 /**< Sentinel: This must be last! */
} H5PL_type_t;
//! <!-- [H5PL_type_t_snip] -->
/* Common dynamic plugin type flags used by the set/get_loading_state functions */
#define H5PL_FILTER_PLUGIN 0x0001
#define H5PL_VOL_PLUGIN 0x0002
+#define H5PL_VFD_PLUGIN 0x0004
#define H5PL_ALL_PLUGIN 0xFFFF
#ifdef __cplusplus
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index 46dc94c..c901931 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -1991,7 +1991,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Pget_mpio_actual_io_mode
*
- * Purpose: Retrieves the type of I/O actually preformed when collective I/O
+ * Purpose: Retrieves the type of I/O actually performed when collective I/O
* is requested.
*
* Return: Non-negative on success/Negative on failure
@@ -2213,10 +2213,18 @@ H5P__dxfr_dset_io_hyp_sel_cmp(const void *_space1, const void *_space2, size_t H
if (TRUE != H5S_extent_equal(*space1, *space2))
HGOTO_DONE(-1);
- /* Compare the selection "shape" of the dataspaces */
- /* (Error & not-equal count the same) */
- if (TRUE != H5S_select_shape_same(*space1, *space2))
+ /* Compare the selection "shape" of the dataspaces
+ * (Error & not-equal count the same)
+ *
+ * Since H5S_select_shape_same() can result in the dataspaces being
+ * rebuilt, the parameters are not const which makes it impossible
+ * to match the cmp prototype. Since we need to compare them,
+ * we quiet the const warning.
+ */
+ H5_GCC_CLANG_DIAG_OFF("cast-qual")
+ if (TRUE != H5S_select_shape_same((H5S_t *)*space1, (H5S_t *)*space2))
HGOTO_DONE(-1);
+ H5_GCC_CLANG_DIAG_ON("cast-qual")
} /* end if */
done:
diff --git a/src/H5Pencdec.c b/src/H5Pencdec.c
index e2a97f8..01573d1 100644
--- a/src/H5Pencdec.c
+++ b/src/H5Pencdec.c
@@ -663,7 +663,7 @@ done:
on failure.
DESCRIPTION
Decodes a property list from a binary buffer. The contents of the buffer
- contain the values for the correponding properties of the plist. The decode
+ contain the values for the corresponding properties of the plist. The decode
callback of a certain property decodes its value from the buffer and sets it
in the property list.
GLOBAL VARIABLES
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index ff9ff8a..a9f21d1 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -41,8 +41,28 @@
#include "H5VMprivate.h" /* Vector Functions */
/* Includes needed to set default file driver */
-#include "H5FDsec2.h" /* POSIX unbuffered I/O */
+#include "H5FDsec2.h" /* POSIX unbuffered I/O */
+#include "H5FDcore.h"
+#include "H5FDlog.h"
+#include "H5FDfamily.h"
+#include "H5FDmulti.h"
#include "H5FDstdio.h" /* Standard C buffered I/O */
+#include "H5FDsplitter.h"
+#ifdef H5_HAVE_PARALLEL
+#include "H5FDmpio.h"
+#endif
+#ifdef H5_HAVE_DIRECT
+#include "H5FDdirect.h"
+#endif
+#ifdef H5_HAVE_MIRROR_VFD
+#include "H5FDmirror.h"
+#endif
+#ifdef H5_HAVE_LIBHDFS
+#include "H5FDhdfs.h"
+#endif
+#ifdef H5_HAVE_ROS3_VFD
+#include "H5FDros3.h"
+#endif
#ifdef H5_HAVE_WINDOWS
#include "H5FDwindows.h" /* Win32 I/O */
#endif
@@ -114,7 +134,7 @@
#define H5F_ACS_FILE_DRV_SIZE sizeof(H5FD_driver_prop_t)
#define H5F_ACS_FILE_DRV_DEF \
{ \
- H5_DEFAULT_VFD, NULL \
+ H5_DEFAULT_VFD, NULL, NULL \
}
#define H5F_ACS_FILE_DRV_CRT H5P__facc_file_driver_create
#define H5F_ACS_FILE_DRV_SET H5P__facc_file_driver_set
@@ -416,6 +436,9 @@ static int H5P__facc_mpi_info_cmp(const void *value1, const void *value2, siz
static herr_t H5P__facc_mpi_info_close(const char *name, size_t size, void *value);
#endif /* H5_HAVE_PARALLEL */
+/* Internal routines */
+static herr_t H5P__facc_set_def_driver_check_predefined(const char *driver_name, hid_t *driver_id);
+
/*********************/
/* Package Variables */
/*********************/
@@ -518,7 +541,7 @@ static const size_t H5F_def_page_buf_size_g = H5F_ACS_PAGE_BUFFER_SIZE_DEF; /*
static const unsigned H5F_def_page_buf_min_meta_perc_g =
H5F_ACS_PAGE_BUFFER_MIN_META_PERC_DEF; /* Default page buffer minimum metadata size */
static const unsigned H5F_def_page_buf_min_raw_perc_g =
- H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_DEF; /* Default page buffer mininum raw data size */
+ H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_DEF; /* Default page buffer minimum raw data size */
static const hbool_t H5F_def_use_file_locking_g =
H5F_ACS_USE_FILE_LOCKING_DEF; /* Default use file locking flag */
static const hbool_t H5F_def_ignore_disabled_file_locks_g =
@@ -851,6 +874,208 @@ done:
} /* end H5P__facc_reg_prop() */
/*-------------------------------------------------------------------------
+ * Function: H5P__facc_set_def_driver
+ *
+ * Purpose: Parses a string that contains the name of the default VFL
+ * driver for the default FAPL.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__facc_set_def_driver(void)
+{
+ const char *driver_env_var;
+ hbool_t driver_ref_inc = FALSE;
+ hid_t driver_id = H5I_INVALID_HID; /* VFL driver ID */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Check if VFL driver environment variable is set */
+ driver_env_var = HDgetenv(HDF5_DRIVER);
+
+ /* Only parse VFL driver string if it's set */
+ if (driver_env_var && *driver_env_var) {
+ H5FD_driver_prop_t driver_prop;
+ H5P_genplist_t * def_fapl; /* Default file access property list */
+ H5P_genclass_t * def_fapclass; /* Default file access property class */
+ const char * driver_config_env_var;
+ htri_t driver_is_registered;
+
+ /* Check to see if the driver is already registered */
+ if ((driver_is_registered = H5FD_is_driver_registered_by_name(driver_env_var, &driver_id)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFL driver is already registered")
+ if (driver_is_registered) {
+ HDassert(driver_id >= 0);
+
+ if (H5I_inc_ref(driver_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, FAIL, "unable to increment ref count on VFD")
+ driver_ref_inc = TRUE;
+ } /* end else-if */
+ else {
+ /* Check for VFL drivers that ship with the library */
+ if (H5P__facc_set_def_driver_check_predefined(driver_env_var, &driver_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check for predefined VFL driver name")
+ else if (driver_id > 0) {
+ if (H5I_inc_ref(driver_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINC, FAIL, "can't increment VFL driver refcount")
+ driver_ref_inc = TRUE;
+ }
+ else {
+ /* Register the VFL driver */
+ if ((driver_id = H5FD_register_driver_by_name(driver_env_var, TRUE)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "can't register VFL driver")
+ driver_ref_inc = TRUE;
+ } /* end else */
+ } /* end else */
+
+ /* Retrieve driver configuration string from environment variable, if set. */
+ driver_config_env_var = HDgetenv(HDF5_DRIVER_CONFIG);
+
+ driver_prop.driver_id = driver_id;
+ driver_prop.driver_info = NULL;
+ driver_prop.driver_config_str = driver_config_env_var;
+
+ /* Get default file access pclass */
+ if (NULL == (def_fapclass = (H5P_genclass_t *)H5I_object(H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL,
+ "can't find object for default file access property class ID")
+
+ /* Set new default VFL driver for default file access pclass */
+ if (H5P__class_set(def_fapclass, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL,
+ "can't set default VFL driver for default file access property list class")
+
+ /* Get default file access plist */
+ if (NULL == (def_fapl = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL, "can't find object for default fapl ID")
+
+ /* Set new default VFL driver for default FAPL */
+ if (H5P_set_driver(def_fapl, driver_prop.driver_id, driver_prop.driver_info,
+ driver_prop.driver_config_str) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default VFL driver for default FAPL")
+ }
+
+done:
+ /* Clean up on error */
+ if (ret_value < 0) {
+ if (driver_id >= 0 && driver_ref_inc && H5I_dec_app_ref(driver_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "unable to unregister VFL driver")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_set_def_driver() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__facc_set_def_driver_check_predefined
+ *
+ * Purpose: Checks a given driver name against a list of predefined
+ * names for VFL drivers that are internal to HDF5. If a name
+ * is matched, the ID for that driver is returned through
+ * `driver_id`. Otherwise, `driver_id` is set to
+ * H5I_INVALID_HID.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__facc_set_def_driver_check_predefined(const char *driver_name, hid_t *driver_id)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(driver_name);
+ HDassert(driver_id);
+
+ if (!HDstrcmp(driver_name, "sec2")) {
+ if ((*driver_id = H5FD_SEC2) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize sec2 VFD")
+ }
+ else if (!HDstrcmp(driver_name, "core") || !HDstrcmp(driver_name, "core_paged")) {
+ if ((*driver_id = H5FD_CORE) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize core VFD")
+ }
+ else if (!HDstrcmp(driver_name, "log")) {
+ if ((*driver_id = H5FD_LOG) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize log VFD")
+ }
+ else if (!HDstrcmp(driver_name, "family")) {
+ if ((*driver_id = H5FD_FAMILY) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize family VFD")
+ }
+ else if (!HDstrcmp(driver_name, "multi") || !HDstrcmp(driver_name, "split")) {
+ if ((*driver_id = H5FD_MULTI) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize multi VFD")
+ }
+ else if (!HDstrcmp(driver_name, "stdio")) {
+ if ((*driver_id = H5FD_STDIO) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize stdio VFD")
+ }
+ else if (!HDstrcmp(driver_name, "splitter")) {
+ if ((*driver_id = H5FD_SPLITTER) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize splitter VFD")
+ }
+ else if (!HDstrcmp(driver_name, "mpio")) {
+#ifdef H5_HAVE_PARALLEL
+ if ((*driver_id = H5FD_MPIO) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize MPI I/O VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "MPI-I/O VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "direct")) {
+#ifdef H5_HAVE_DIRECT
+ if ((*driver_id = H5FD_DIRECT) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize Direct I/O VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "Direct I/O VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "mirror")) {
+#ifdef H5_HAVE_MIRROR_VFD
+ if ((*driver_id = H5FD_MIRROR) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize mirror VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "Mirror VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "hdfs")) {
+#ifdef H5_HAVE_LIBHDFS
+ if ((*driver_id = H5FD_HDFS) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize HDFS VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "HDFS VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "ros3")) {
+#ifdef H5_HAVE_ROS3_VFD
+ if ((*driver_id = H5FD_ROS3) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize ROS3 VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "ROS3 VFD is not enabled")
+#endif
+ }
+ else if (!HDstrcmp(driver_name, "windows")) {
+#ifdef H5_HAVE_WINDOWS
+ if ((*driver_id = H5FD_WINDOWS) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "couldn't initialize Windows VFD")
+#else
+ HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "Windows VFD is not enabled")
+#endif
+ }
+ else {
+ *driver_id = H5I_INVALID_HID;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__facc_set_def_driver_check_predefined() */
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_alignment
*
* Purpose: Sets the alignment properties of a file access property list
@@ -941,42 +1166,52 @@ done:
} /* end H5Pget_alignment() */
/*-------------------------------------------------------------------------
- * Function: H5P_set_driver
+ * Function: H5P_set_driver
*
- * Purpose: Set the file driver (DRIVER_ID) for a file access
- * property list (PLIST_ID) and supply an optional
- * struct containing the driver-specific properites
- * (DRIVER_INFO). The driver properties will be copied into the
- * property list and the reference count on the driver will be
- * incremented, allowing the caller to close the driver ID but
- * still use the property list.
+ * Purpose: Set the file driver (NEW_DRIVER_ID) for a file access
+ * property list (PLIST). A struct (NEW_DRIVER_INFO) or string
+ * (NEW_DRIVER_CONFIG_STR) containing the driver-specific
+ * properties can optionally be supplied. The driver properties
+ * (struct or string) will be copied into the property list and
+ * the reference count on the driver will be incremented,
+ * allowing the caller to close the driver ID but still use the
+ * property list.
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Note: Only one of either NEW_DRIVER_INFO or NEW_DRIVER_CONFIG_STR
+ * should be specified, but not both.
+ *
+ * Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
- * Tuesday, August 3, 1999
+ * Tuesday, August 3, 1999
*
*-------------------------------------------------------------------------
*/
herr_t
-H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info)
+H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info,
+ const char *new_driver_config_str)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
+ /* If VFD configuration information is supplied, ensure that either binary
+ * configuration data or a configuration string is supplied, but not both.
+ */
+ HDassert(!new_driver_info || !new_driver_config_str);
+
if (NULL == H5I_object_verify(new_driver_id, H5I_VFL))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID")
if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
- H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & config. string */
/* Prepare the driver property */
- driver_prop.driver_id = new_driver_id;
- driver_prop.driver_info = new_driver_info;
+ driver_prop.driver_id = new_driver_id;
+ driver_prop.driver_info = new_driver_info;
+ driver_prop.driver_config_str = new_driver_config_str;
- /* Set the driver ID & info property */
+ /* Set the driver ID, info & config. string property */
if (H5P_set(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver ID & info")
} /* end if */
@@ -1022,7 +1257,7 @@ H5Pset_driver(hid_t plist_id, hid_t new_driver_id, const void *new_driver_info)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID")
/* Set the driver */
- if (H5P_set_driver(plist, new_driver_id, new_driver_info) < 0)
+ if (H5P_set_driver(plist, new_driver_id, new_driver_info, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
done:
@@ -1030,6 +1265,180 @@ done:
} /* end H5Pset_driver() */
/*-------------------------------------------------------------------------
+ * Function: H5P_set_driver_by_name
+ *
+ * Purpose: Set the file driver name (DRIVER_NAME) for a file access
+ * property list (PLIST) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_NAME is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_set_driver_by_name(H5P_genplist_t *plist, const char *driver_name, const char *driver_config,
+ hbool_t app_ref)
+{
+ hid_t new_driver_id = H5I_INVALID_HID;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(plist);
+ HDassert(driver_name);
+
+ /* Register the driver */
+ if ((new_driver_id = H5FD_register_driver_by_name(driver_name, app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register VFD")
+
+ /* Set the driver */
+ if (H5P_set_driver(plist, new_driver_id, NULL, driver_config) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ if (ret_value < 0) {
+ if (new_driver_id >= 0 && H5I_dec_app_ref(new_driver_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't decrement count on VFD ID")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_set_driver_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_driver_by_name
+ *
+ * Purpose: Set the file driver name (DRIVER_NAME) for a file access
+ * property list (PLIST_ID) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_NAME is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_driver_by_name(hid_t plist_id, const char *driver_name, const char *driver_config)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*s*s", plist_id, driver_name, driver_config);
+
+ /* Check arguments */
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ if (!driver_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "driver_name parameter cannot be NULL")
+ if (!*driver_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "driver_name parameter cannot be an empty string")
+
+ /* Set the driver */
+ if (H5P_set_driver_by_name(plist, driver_name, driver_config, TRUE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_driver_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_set_driver_by_value
+ *
+ * Purpose: Set the file driver value (DRIVER_VALUE) for a file access
+ * property list (PLIST) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_VALUE is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_set_driver_by_value(H5P_genplist_t *plist, H5FD_class_value_t driver_value, const char *driver_config,
+ hbool_t app_ref)
+{
+ hid_t new_driver_id = H5I_INVALID_HID;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(plist);
+ HDassert(driver_value >= 0);
+
+ /* Register the driver */
+ if ((new_driver_id = H5FD_register_driver_by_value(driver_value, app_ref)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register VFD")
+
+ /* Set the driver */
+ if (H5P_set_driver(plist, new_driver_id, NULL, driver_config) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ if (ret_value < 0) {
+ if (new_driver_id >= 0 && H5I_dec_app_ref(new_driver_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't decrement count on VFD ID")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_set_driver_by_value() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_driver_by_value
+ *
+ * Purpose: Set the file driver value (DRIVER_VALUE) for a file access
+ * property list (PLIST_ID) and supply an optional string
+ * containing the driver-specific properties (DRIVER_CONFIG).
+ * The driver properties string will be copied into the
+ * property list.
+ *
+ * If the file driver specified by DRIVER_VALUE is not
+ * currently registered, an attempt will be made to load the
+ * driver as a plugin.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_driver_by_value(hid_t plist_id, H5FD_class_value_t driver_value, const char *driver_config)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iDV*s", plist_id, driver_value, driver_config);
+
+ /* Check arguments */
+ if (NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+ if (driver_value < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "negative VFD value is disallowed")
+
+ /* Set the driver */
+ if (H5P_set_driver_by_value(plist, driver_value, driver_config, TRUE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_driver_by_value() */
+
+/*-------------------------------------------------------------------------
* Function: H5P_peek_driver
*
* Purpose: Return the ID of the low-level file driver. PLIST_ID should
@@ -1056,7 +1465,7 @@ H5P_peek_driver(H5P_genplist_t *plist)
/* Get the current driver ID */
if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
- H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & configuration string */
if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID")
@@ -1140,7 +1549,7 @@ H5P_peek_driver_info(H5P_genplist_t *plist)
/* Get the current driver info */
if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
- H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & configuration string */
if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver info")
@@ -1193,13 +1602,104 @@ done:
} /* end H5Pget_driver_info() */
/*-------------------------------------------------------------------------
+ * Function: H5P_peek_driver_config_str
+ *
+ * Purpose: Returns a pointer directly to the file driver configuration
+ * string of a file access property list.
+ *
+ * Return: Success: Ptr to *uncopied* driver configuration string, if
+ * any.
+ *
+ * Failure: NULL. NULL is also returned if the driver has not
+ * been configured with a driver configuration string.
+ *
+ *-------------------------------------------------------------------------
+ */
+const char *
+H5P_peek_driver_config_str(H5P_genplist_t *plist)
+{
+ const char *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* Get the current driver configuration string */
+ if (TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) {
+ H5FD_driver_prop_t driver_prop; /* Property for driver ID, info & configuration string */
+
+ if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver configuration string")
+ ret_value = driver_prop.driver_config_str;
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, "not a file access property list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_peek_driver_config_str() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_driver_config_str
+ *
+ * Purpose: Retrieves a string representation of the configuration for
+ * the driver set on the given FAPL. The returned string can
+ * be used to configure the same driver in an identical way.
+ *
+ * `config_buf` may be NULL, in which case the length of the
+ * driver configuration string is simply returned. The caller
+ * can then allocate a buffer of the appropriate size and call
+ * this routine again.
+ *
+ * Return: Length of the driver configuration string on success (not
+ * including the NUL terminator)
+ * Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5Pget_driver_config_str(hid_t fapl_id, char *config_buf, size_t buf_size)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ const char * config_str = NULL;
+ ssize_t ret_value = -1;
+
+ FUNC_ENTER_API((-1))
+ H5TRACE3("Zs", "i*sz", fapl_id, config_buf, buf_size);
+
+ /* Check arguments */
+ if (!config_buf && buf_size)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "config_buf cannot be NULL if buf_size is non-zero")
+
+ /* Get the plist structure */
+ if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "can't find object for ID")
+
+ /* Retrieve configuration string property */
+ if ((config_str = H5P_peek_driver_config_str(plist))) {
+ size_t config_str_len = HDstrlen(config_str);
+
+ if (config_buf) {
+ HDstrncpy(config_buf, config_str, MIN(config_str_len + 1, buf_size));
+ if (config_str_len >= buf_size)
+ config_buf[buf_size - 1] = '\0';
+ }
+
+ ret_value = (ssize_t)config_str_len;
+ }
+ else
+ ret_value = 0;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pget_driver_config_str() */
+
+/*-------------------------------------------------------------------------
* Function: H5P__file_driver_copy
*
* Purpose: Copy file driver ID & info.
*
* Note: This is an "in-place" copy, since this routine gets called
* after the top-level copy has been performed and this routine
- * finishes the "deep" part of the copy.
+ * finishes the "deep" part of the copy.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -1250,6 +1750,15 @@ H5P__file_driver_copy(void *value)
/* Set the driver info for the copy */
info->driver_info = new_pl;
} /* end if */
+
+ /* Copy driver configuration string, if it exists */
+ if (info->driver_config_str) {
+ char *new_config_str = NULL;
+
+ if (NULL == (new_config_str = H5MM_strdup(info->driver_config_str)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "driver configuration string copy failed")
+ info->driver_config_str = new_config_str;
+ } /* end if */
} /* end if */
} /* end if */
@@ -1280,7 +1789,6 @@ H5P__file_driver_free(void *value)
if (value) {
H5FD_driver_prop_t *info = (H5FD_driver_prop_t *)value; /* Driver ID & info struct */
- /* Copy the driver & info, if there is one */
if (info->driver_id > 0) {
/* Free the driver info, if it exists */
@@ -1288,6 +1796,9 @@ H5P__file_driver_free(void *value)
if (H5FD_free_driver_info(info->driver_id, info->driver_info) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "driver info free request failed")
+ /* Free the driver configuration string, if it exists */
+ H5MM_xfree_const(info->driver_config_str);
+
/* Decrement reference count for driver */
if (H5I_dec_ref(info->driver_id) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't decrement reference count for driver ID")
@@ -1507,6 +2018,16 @@ H5P__facc_file_driver_cmp(const void *_info1, const void *_info2, size_t H5_ATTR
HGOTO_DONE(cmp_value);
} /* end if */
+ /* Compare driver configuration strings */
+ if (info1->driver_config_str == NULL && info2->driver_config_str != NULL)
+ HGOTO_DONE(-1);
+ if (info1->driver_config_str != NULL && info2->driver_config_str == NULL)
+ HGOTO_DONE(1);
+ if (info1->driver_config_str) {
+ if (0 != (cmp_value = HDstrcmp(info1->driver_config_str, info2->driver_config_str)))
+ HGOTO_DONE(cmp_value);
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__facc_file_driver_cmp() */
@@ -2390,7 +2911,7 @@ done:
*
* Currently, the only two valid combinations for this routine are:
* LOW = H5F_FORMAT_EARLIEST and HIGH = H5F_FORMAT_LATEST (the default
- * setting, which creates objects with the ealiest version possible for
+ * setting, which creates objects with the earliest version possible for
* each object, but no upper limit on the version allowed to be created if
* a newer version of an object's format is required to support a feature
* requested with an HDF5 library API routine), and LOW = H5F_FORMAT_LATEST
@@ -2406,7 +2927,7 @@ done:
* Note: Eventually we want to add more values to the H5F_libver_t
* enumerated type that indicate library release values where the file
* format was changed (like "H5F_FORMAT_1_2_0" for the file format changes
- * in the 1.2.x release branch and possily even "H5F_FORMAT_1_4_2" for
+ * in the 1.2.x release branch and possibly even "H5F_FORMAT_1_4_2" for
* a change mid-way through the 1.4.x release branch, etc).
*
* Adding more values will allow applications to make settings like the
@@ -2852,7 +3373,7 @@ H5Pset_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callback
HDassert(callbacks_ptr->udata_copy);
HDassert(callbacks_ptr->udata_free);
if ((info.callbacks.udata = callbacks_ptr->udata_copy(callbacks_ptr->udata)) == NULL)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't copy the suppplied udata")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't copy the supplied udata")
} /* end if */
/* Set values */
@@ -4916,15 +5437,14 @@ H5P__decode_coll_md_read_flag_t(const void **_pp, void *_value)
* Function: H5Pset_all_coll_metadata_ops
*
* Purpose: Tell the library whether the metadata read operations will
- * be done collectively (1) or not (0). Default is independent.
- * With collective mode, the library will optimize access to
- * metadata operations on the file.
+ * be done collectively (1) or not (0). Default is independent.
+ * With collective mode, the library will optimize access to
+ * metadata operations on the file.
*
* Note: This routine accepts file access property lists, link
- * access property lists, attribute access property lists,
- * dataset access property lists, group access property lists,
- * named datatype access property lists,
- * and dataset transfer property lists.
+ * access property lists, attribute access property lists,
+ * dataset access property lists, group access property lists
+ * and named datatype access property lists.
*
* Return: Non-negative on success/Negative on failure
*
@@ -4944,7 +5464,7 @@ H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective)
H5TRACE2("e", "ib", plist_id, is_collective);
/* Compare the property list's class against the other class */
- /* (Dataset, group, attribute, and named datype access property lists
+ /* (Dataset, group, attribute, and named datatype access property lists
* are sub-classes of link access property lists -QAK)
*/
if (TRUE != H5P_isa_class(plist_id, H5P_LINK_ACCESS) && TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS))
@@ -4974,10 +5494,9 @@ done:
* Purpose: Gets information about collective metadata read mode.
*
* Note: This routine accepts file access property lists, link
- * access property lists, attribute access property lists,
- * dataset access property lists, group access property lists,
- * named datatype access property lists,
- * and dataset transfer property lists.
+ * access property lists, attribute access property lists,
+ * dataset access property lists, group access property lists,
+ * and named datatype access property lists.
*
* Return: Non-negative on success/Negative on failure
*
@@ -4995,7 +5514,7 @@ H5Pget_all_coll_metadata_ops(hid_t plist_id, hbool_t *is_collective /*out*/)
H5TRACE2("e", "ix", plist_id, is_collective);
/* Compare the property list's class against the other class */
- /* (Dataset, group, attribute, and named datype access property lists
+ /* (Dataset, group, attribute, and named datatype access property lists
* are sub-classes of link access property lists -QAK)
*/
if (TRUE != H5P_isa_class(plist_id, H5P_LINK_ACCESS) && TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS))
@@ -5764,7 +6283,7 @@ H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr)
if (H5P_set(plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, config_ptr) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache initial config")
- if (H5P_set_driver(plist, H5FD_VFD_SWMR, NULL) < 0)
+ if (H5P_set_driver(plist, H5FD_VFD_SWMR, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set VFD SWMR driver info");
done:
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 90fd1c2..c0f5ee1 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -123,77 +123,78 @@ static herr_t H5P__free_del_name_cb(void *item, void H5_ATTR_UNUSED *key, void H
/*
* Predefined property list classes. These are initialized at runtime by
- * H5P__init_package() in this source file.
+ * H5P_init() in this source file.
*/
-hid_t H5P_CLS_ROOT_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_ROOT_g = NULL;
-hid_t H5P_CLS_OBJECT_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_OBJECT_CREATE_g = NULL;
-hid_t H5P_CLS_FILE_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_FILE_CREATE_g = NULL;
-hid_t H5P_CLS_FILE_ACCESS_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_FILE_ACCESS_g = NULL;
-hid_t H5P_CLS_DATASET_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_DATASET_CREATE_g = NULL;
+hid_t H5P_CLS_ROOT_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_ROOT_g = NULL;
+
+hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_ATTRIBUTE_ACCESS_g = NULL;
+hid_t H5P_CLS_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_ATTRIBUTE_CREATE_g = NULL;
hid_t H5P_CLS_DATASET_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_DATASET_ACCESS_g = NULL;
+hid_t H5P_CLS_DATASET_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_DATASET_CREATE_g = NULL;
hid_t H5P_CLS_DATASET_XFER_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_DATASET_XFER_g = NULL;
+hid_t H5P_CLS_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_DATATYPE_ACCESS_g = NULL;
+hid_t H5P_CLS_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_DATATYPE_CREATE_g = NULL;
+hid_t H5P_CLS_FILE_ACCESS_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_FILE_ACCESS_g = NULL;
+hid_t H5P_CLS_FILE_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_FILE_CREATE_g = NULL;
hid_t H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_FILE_MOUNT_g = NULL;
-hid_t H5P_CLS_GROUP_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_GROUP_CREATE_g = NULL;
hid_t H5P_CLS_GROUP_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_GROUP_ACCESS_g = NULL;
-hid_t H5P_CLS_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_DATATYPE_CREATE_g = NULL;
-hid_t H5P_CLS_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_DATATYPE_ACCESS_g = NULL;
-hid_t H5P_CLS_MAP_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_MAP_CREATE_g = NULL;
+hid_t H5P_CLS_GROUP_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_GROUP_CREATE_g = NULL;
+hid_t H5P_CLS_LINK_ACCESS_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_LINK_ACCESS_g = NULL;
+hid_t H5P_CLS_LINK_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_LINK_CREATE_g = NULL;
hid_t H5P_CLS_MAP_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_MAP_ACCESS_g = NULL;
-hid_t H5P_CLS_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_ATTRIBUTE_CREATE_g = NULL;
-hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_ATTRIBUTE_ACCESS_g = NULL;
+hid_t H5P_CLS_MAP_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_MAP_CREATE_g = NULL;
hid_t H5P_CLS_OBJECT_COPY_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_OBJECT_COPY_g = NULL;
-hid_t H5P_CLS_LINK_CREATE_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_LINK_CREATE_g = NULL;
-hid_t H5P_CLS_LINK_ACCESS_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_LINK_ACCESS_g = NULL;
+hid_t H5P_CLS_OBJECT_CREATE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_OBJECT_CREATE_g = NULL;
+hid_t H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_REFERENCE_ACCESS_g = NULL;
hid_t H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_STRING_CREATE_g = NULL;
hid_t H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_VOL_INITIALIZE_g = NULL;
-hid_t H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID;
-H5P_genclass_t *H5P_CLS_REFERENCE_ACCESS_g = NULL;
/*
* Predefined property lists for each predefined class. These are initialized
- * at runtime by H5P__init_package() in this source file.
+ * at runtime by H5P_init() in this source file.
*/
-hid_t H5P_LST_FILE_CREATE_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_FILE_ACCESS_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_FILE_ACCESS_ANY_VFD_g = H5I_INVALID_HID;
-hid_t H5P_LST_DATASET_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
hid_t H5P_LST_DATASET_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATASET_CREATE_ID_g = H5I_INVALID_HID;
hid_t H5P_LST_DATASET_XFER_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_FILE_ACCESS_ANY_VFD_g = H5I_INVALID_HID;
+hid_t H5P_LST_FILE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_FILE_CREATE_ID_g = H5I_INVALID_HID;
hid_t H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_GROUP_CREATE_ID_g = H5I_INVALID_HID;
hid_t H5P_LST_GROUP_ACCESS_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_MAP_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_GROUP_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID;
hid_t H5P_LST_MAP_ACCESS_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_MAP_CREATE_ID_g = H5I_INVALID_HID;
hid_t H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID;
-hid_t H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
hid_t H5P_LST_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
/* Root property list class library initialization object */
const H5P_libclass_t H5P_CLS_ROOT[1] = {{
@@ -413,48 +414,29 @@ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{
}};
/*-------------------------------------------------------------------------
- * Function: H5P_init
+ * Function: H5P_init_phase1
*
- * Purpose: Initialize the interface from some other layer.
+ * Purpose: Initialize the interface from some other layer. This should
+ * be followed with a call to H5P_init_phase2 after the H5P
+ * interface is completely setup.
*
- * Return: Success: non-negative
- * Failure: negative
+ * Return: Success: non-negative
+ * Failure: negative
*
- * Programmer: Quincey Koziol
+ * Programmer: Quincey Koziol
* Saturday, March 4, 2000
*
*-------------------------------------------------------------------------
*/
herr_t
-H5P_init(void)
+H5P_init_phase1(void)
{
+ size_t tot_init = 0; /* Total # of classes initialized */
+ size_t pass_init; /* # of classes initialized in each pass */
+ size_t u;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P_init() */
-
-/*--------------------------------------------------------------------------
-NAME
- H5P__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5P__init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
---------------------------------------------------------------------------*/
-herr_t
-H5P__init_package(void)
-{
- size_t tot_init; /* Total # of classes initialized */
- size_t pass_init; /* # of classes initialized in each pass */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
/* Sanity check */
HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
@@ -473,8 +455,6 @@ H5P__init_package(void)
*/
tot_init = 0;
do {
- size_t u; /* Local index variable */
-
/* Reset pass initialization counter */
pass_init = 0;
@@ -524,8 +504,59 @@ H5P__init_package(void)
HDassert(tot_init == NELMTS(init_class));
done:
+ if (ret_value < 0 && tot_init > 0) {
+ /* First uninitialize all default property lists */
+ H5I_clear_type(H5I_GENPROP_LST, FALSE, FALSE);
+
+ /* Then uninitialize any initialized libclass */
+ for (u = 0; u < NELMTS(init_class); u++) {
+ H5P_libclass_t const *lib_class = init_class[u]; /* Current class to operate on */
+
+ HDassert(lib_class->class_id);
+ if (*lib_class->class_id >= 0) {
+ /* Close the class ID */
+ if (H5I_dec_ref(*lib_class->class_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list class ID")
+ }
+ else if (lib_class->pclass && *lib_class->pclass) {
+ /* Close a half-initialized pclass */
+ if (H5P__close_class(*lib_class->pclass) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list class")
+ }
+ }
+ }
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P__init_package() */
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_init_phase2
+ *
+ * Purpose: Finish initializing the interface from some other package.
+ *
+ * Note: This is broken out as a separate routine so that the
+ * library's default VFL driver can be chosen and initialized
+ * after the entire H5P interface has been initialized.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_init_phase2(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Set up the default VFL driver */
+ if (H5P__facc_set_def_driver() < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "unable to set default VFL driver")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_init_phase2() */
/*--------------------------------------------------------------------------
NAME
@@ -551,77 +582,109 @@ H5P_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- int64_t nlist, nclass;
-
- /* Destroy HDF5 library property classes & lists */
-
- /* Check if there are any open property list classes or lists */
- nclass = H5I_nmembers(H5I_GENPROP_CLS);
- nlist = H5I_nmembers(H5I_GENPROP_LST);
-
- /* If there are any open classes or groups, attempt to get rid of them. */
- if ((nclass + nlist) > 0) {
- /* Clear the lists */
- if (nlist > 0) {
- (void)H5I_clear_type(H5I_GENPROP_LST, FALSE, FALSE);
-
- /* Reset the default property lists, if they've been closed */
- if (H5I_nmembers(H5I_GENPROP_LST) == 0) {
- H5P_LST_FILE_CREATE_ID_g = H5P_LST_FILE_ACCESS_ID_g = H5P_LST_DATASET_CREATE_ID_g =
- H5P_LST_DATASET_ACCESS_ID_g = H5P_LST_DATASET_XFER_ID_g = H5P_LST_GROUP_CREATE_ID_g =
- H5P_LST_GROUP_ACCESS_ID_g = H5P_LST_DATATYPE_CREATE_ID_g =
- H5P_LST_DATATYPE_ACCESS_ID_g = H5P_LST_MAP_CREATE_ID_g =
- H5P_LST_MAP_ACCESS_ID_g = H5P_LST_ATTRIBUTE_CREATE_ID_g =
- H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5P_LST_OBJECT_COPY_ID_g =
- H5P_LST_LINK_CREATE_ID_g = H5P_LST_LINK_ACCESS_ID_g =
- H5P_LST_VOL_INITIALIZE_ID_g = H5P_LST_REFERENCE_ACCESS_ID_g =
- H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID;
- } /* end if */
- } /* end if */
-
- /* Only attempt to close the classes after all the lists are closed */
- if (nlist == 0 && nclass > 0) {
- (void)H5I_clear_type(H5I_GENPROP_CLS, FALSE, FALSE);
-
- /* Reset the default property classes, if they've been closed */
- if (H5I_nmembers(H5I_GENPROP_CLS) == 0) {
- H5P_CLS_ROOT_g = H5P_CLS_OBJECT_CREATE_g = H5P_CLS_FILE_CREATE_g = H5P_CLS_FILE_ACCESS_g =
- H5P_CLS_DATASET_CREATE_g = H5P_CLS_DATASET_ACCESS_g = H5P_CLS_DATASET_XFER_g =
- H5P_CLS_GROUP_CREATE_g = H5P_CLS_GROUP_ACCESS_g = H5P_CLS_DATATYPE_CREATE_g =
- H5P_CLS_DATATYPE_ACCESS_g = H5P_CLS_MAP_CREATE_g = H5P_CLS_MAP_ACCESS_g =
- H5P_CLS_STRING_CREATE_g = H5P_CLS_ATTRIBUTE_CREATE_g =
- H5P_CLS_ATTRIBUTE_ACCESS_g = H5P_CLS_OBJECT_COPY_g =
- H5P_CLS_LINK_CREATE_g = H5P_CLS_LINK_ACCESS_g =
- H5P_CLS_VOL_INITIALIZE_g = H5P_CLS_REFERENCE_ACCESS_g =
- H5P_CLS_FILE_MOUNT_g = NULL;
-
- H5P_CLS_ROOT_ID_g = H5P_CLS_OBJECT_CREATE_ID_g = H5P_CLS_FILE_CREATE_ID_g =
- H5P_CLS_FILE_ACCESS_ID_g = H5P_CLS_DATASET_CREATE_ID_g = H5P_CLS_DATASET_ACCESS_ID_g =
- H5P_CLS_DATASET_XFER_ID_g = H5P_CLS_GROUP_CREATE_ID_g =
- H5P_CLS_GROUP_ACCESS_ID_g = H5P_CLS_DATATYPE_CREATE_ID_g =
- H5P_CLS_DATATYPE_ACCESS_ID_g = H5P_CLS_MAP_CREATE_ID_g =
- H5P_CLS_MAP_ACCESS_ID_g = H5P_CLS_STRING_CREATE_ID_g =
- H5P_CLS_ATTRIBUTE_CREATE_ID_g = H5P_CLS_ATTRIBUTE_ACCESS_ID_g =
- H5P_CLS_OBJECT_COPY_ID_g = H5P_CLS_LINK_CREATE_ID_g =
- H5P_CLS_LINK_ACCESS_ID_g = H5P_CLS_VOL_INITIALIZE_ID_g =
- H5P_CLS_REFERENCE_ACCESS_ID_g =
- H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID;
- } /* end if */
- } /* end if */
+ int64_t nlist, nclass;
+
+ /* Destroy HDF5 library property classes & lists */
+
+ /* Check if there are any open property list classes or lists */
+ nclass = H5I_nmembers(H5I_GENPROP_CLS);
+ nlist = H5I_nmembers(H5I_GENPROP_LST);
+
+ /* If there are any open classes or groups, attempt to get rid of them. */
+ if ((nclass + nlist) > 0) {
+ /* Clear the lists */
+ if (nlist > 0) {
+ (void)H5I_clear_type(H5I_GENPROP_LST, FALSE, FALSE);
+
+ /* Reset the default property lists, if they've been closed */
+ if (H5I_nmembers(H5I_GENPROP_LST) == 0) {
+ H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_DATASET_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_DATASET_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_DATASET_XFER_ID_g = H5I_INVALID_HID;
+ H5P_LST_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_FILE_ACCESS_ANY_VFD_g = H5I_INVALID_HID;
+ H5P_LST_FILE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_FILE_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID;
+ H5P_LST_GROUP_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_GROUP_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_MAP_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_MAP_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID;
+ H5P_LST_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
+ }
+ }
- n++; /*H5I*/
+ /* Only attempt to close the classes after all the lists are closed */
+ if (nlist == 0 && nclass > 0) {
+ (void)H5I_clear_type(H5I_GENPROP_CLS, FALSE, FALSE);
+
+ /* Reset the default property classes and IDs if they've been closed */
+ if (H5I_nmembers(H5I_GENPROP_CLS) == 0) {
+ H5P_CLS_ROOT_g = NULL;
+
+ H5P_CLS_ATTRIBUTE_ACCESS_g = NULL;
+ H5P_CLS_ATTRIBUTE_CREATE_g = NULL;
+ H5P_CLS_DATASET_ACCESS_g = NULL;
+ H5P_CLS_DATASET_CREATE_g = NULL;
+ H5P_CLS_DATASET_XFER_g = NULL;
+ H5P_CLS_DATATYPE_ACCESS_g = NULL;
+ H5P_CLS_DATATYPE_CREATE_g = NULL;
+ H5P_CLS_FILE_ACCESS_g = NULL;
+ H5P_CLS_FILE_CREATE_g = NULL;
+ H5P_CLS_FILE_MOUNT_g = NULL;
+ H5P_CLS_GROUP_ACCESS_g = NULL;
+ H5P_CLS_GROUP_CREATE_g = NULL;
+ H5P_CLS_LINK_ACCESS_g = NULL;
+ H5P_CLS_LINK_CREATE_g = NULL;
+ H5P_CLS_MAP_ACCESS_g = NULL;
+ H5P_CLS_MAP_CREATE_g = NULL;
+ H5P_CLS_OBJECT_COPY_g = NULL;
+ H5P_CLS_OBJECT_CREATE_g = NULL;
+ H5P_CLS_REFERENCE_ACCESS_g = NULL;
+ H5P_CLS_STRING_CREATE_g = NULL;
+ H5P_CLS_VOL_INITIALIZE_g = NULL;
+
+ H5P_CLS_ROOT_ID_g = H5I_INVALID_HID;
+
+ H5P_CLS_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_DATASET_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_DATASET_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_DATASET_XFER_ID_g = H5I_INVALID_HID;
+ H5P_CLS_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_LST_FILE_ACCESS_ANY_VFD_g = H5I_INVALID_HID;
+ H5P_CLS_FILE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_FILE_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID;
+ H5P_CLS_GROUP_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_GROUP_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_LINK_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_LINK_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_MAP_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_MAP_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_OBJECT_COPY_ID_g = H5I_INVALID_HID;
+ H5P_CLS_OBJECT_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID;
+ H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID;
+ H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
+ }
}
- else {
- /* Destroy the property list and class id groups */
- n += (H5I_dec_type_ref(H5I_GENPROP_LST) > 0);
- n += (H5I_dec_type_ref(H5I_GENPROP_CLS) > 0);
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end else */
- } /* end if */
+ n++; /*H5I*/
+ }
+ else {
+ /* Destroy the property list and class id groups */
+ n += (H5I_dec_type_ref(H5I_GENPROP_LST) > 0);
+ n += (H5I_dec_type_ref(H5I_GENPROP_CLS) > 0);
+ } /* end else */
FUNC_LEAVE_NOAPI(n)
} /* end H5P_term_package() */
@@ -3243,7 +3306,7 @@ done:
NAME
H5P_exist_plist
PURPOSE
- Internal routine to query the existance of a property in a property list.
+ Internal routine to query the existence of a property in a property list.
USAGE
htri_t H5P_exist_plist(plist, name)
const H5P_genplist_t *plist; IN: Property list to check
@@ -3302,7 +3365,7 @@ done:
NAME
H5P__exist_pclass
PURPOSE
- Internal routine to query the existance of a property in a property class.
+ Internal routine to query the existence of a property in a property class.
USAGE
herr_t H5P__exist_pclass(pclass, name)
H5P_genclass_t *pclass; IN: Property class to check
@@ -3502,7 +3565,7 @@ H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, hbool_t recu
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(pclass);
HDassert(nprops);
@@ -3517,7 +3580,6 @@ H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, hbool_t recu
*nprops += pclass->nprops;
} /* end while */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_get_nprops_pclass() */
@@ -3818,7 +3880,7 @@ H5P__cmp_plist_cb(H5P_genprop_t *prop, void *_udata)
/* Check if the property exists in the second property list */
if ((prop2_exist = H5P_exist_plist(udata->plist2, prop->name)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, H5_ITER_ERROR, "can't lookup existance of property?")
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, H5_ITER_ERROR, "can't lookup existence of property?")
if (prop2_exist) {
const H5P_genprop_t *prop2; /* Pointer to property in second plist */
@@ -3948,7 +4010,7 @@ H5P_class_isa(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2)
{
htri_t ret_value = FAIL; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(pclass1);
HDassert(pclass2);
@@ -4769,7 +4831,7 @@ done:
Returns non-negative on success, negative on failure.
DESCRIPTION
Removes a property from a property list. Both properties which were
- in existance when the property list was created (i.e. properties registered
+ in existence when the property list was created (i.e. properties registered
with H5Pregister2) and properties added to the list after it was created
(i.e. added with H5Pinsert2) may be removed from a property list.
Properties do not need to be removed a property list before the list itself
@@ -4850,7 +4912,7 @@ H5P__copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name)
NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_id)))
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist")
- /* If the property exists in the destination alread */
+ /* If the property exists in the destination already */
if (NULL != H5P__find_prop_plist(dst_plist, name)) {
/* Delete the property from the destination list, calling the 'close' callback if necessary */
if (H5P_remove(dst_plist, name) < 0)
@@ -5250,14 +5312,13 @@ H5P_get_class_name(H5P_genclass_t *pclass)
{
char *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(pclass);
/* Get class name */
ret_value = H5MM_xstrdup(pclass->name);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5P_get_class_name() */
diff --git a/src/H5Pmodule.h b/src/H5Pmodule.h
index 6e92e66..66a9574 100644
--- a/src/H5Pmodule.h
+++ b/src/H5Pmodule.h
@@ -111,7 +111,8 @@
*
* \defgroup GAPL General Access Properties
* \ingroup H5P
- * \todo Should this be as standalone page?
+ * The functions in this section can be applied to different kinds of property
+ * lists.
*
* \defgroup GCPL Group Creation Properties
* \ingroup H5P
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index e442030..06d9f85 100644
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
@@ -482,7 +482,7 @@ done:
* transfer property list. The FLAGS argument specifies certain
* general properties of the filter and is documented below.
* The CD_VALUES is an array of CD_NELMTS integers which are
- * auxiliary data for the filter. The integer vlues will be
+ * auxiliary data for the filter. The integer values will be
* stored in the dataset object header as part of the filter
* information.
*
@@ -543,7 +543,7 @@ done:
* transfer property list. The FLAGS argument specifies certain
* general properties of the filter and is documented below.
* The CD_VALUES is an array of CD_NELMTS integers which are
- * auxiliary data for the filter. The integer vlues will be
+ * auxiliary data for the filter. The integer values will be
* stored in the dataset object header as part of the filter
* information.
*
@@ -609,7 +609,7 @@ done:
* creation property list. The FLAGS argument specifies certain
* general properties of the filter and is documented below.
* The CD_VALUES is an array of CD_NELMTS integers which are
- * auxiliary data for the filter. The integer vlues will be
+ * auxiliary data for the filter. The integer values will be
* stored in the dataset object header as part of the filter
* information.
*
@@ -671,7 +671,7 @@ done:
* creation property list. The FLAGS argument specifies certain
* general properties of the filter and is documented below.
* The CD_VALUES is an array of CD_NELMTS integers which are
- * auxiliary data for the filter. The integer vlues will be
+ * auxiliary data for the filter. The integer values will be
* stored in the dataset object header as part of the filter
* information.
*
@@ -782,7 +782,7 @@ done:
* CD_NELMTS indicates the number of entries in the CD_VALUES
* array allocated by the caller while on exit it contains the
* number of values defined by the filter. FILTER_CONFIG is a bit
- * field contaning encode/decode flags from H5Zpublic.h. The IDX
+ * field containing encode/decode flags from H5Zpublic.h. The IDX
* should be a value between zero and N-1 as described for
* H5Pget_nfilters() and the function will return failure if the
* filter number is out of range.
@@ -867,7 +867,7 @@ done:
* CD_NELMTS indicates the number of entries in the CD_VALUES
* array allocated by the caller while on exit it contains the
* number of values defined by the filter. FILTER_CONFIG is a bit
- * field contaning encode/decode flags from H5Zpublic.h. The ID
+ * field containing encode/decode flags from H5Zpublic.h. The ID
* should be the filter ID to retrieve the parameters for. If the
* filter is not set for the property list, an error will be returned.
*
@@ -916,7 +916,7 @@ done:
* CD_NELMTS indicates the number of entries in the CD_VALUES
* array allocated by the caller while on exit it contains the
* number of values defined by the filter. FILTER_CONFIG is a bit
- * field contaning encode/decode flags from H5Zpublic.h. The ID
+ * field containing encode/decode flags from H5Zpublic.h. The ID
* should be the filter ID to retrieve the parameters for. If the
* filter is not set for the property list, an error will be returned.
*
diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h
index dd43f76..2946931 100644
--- a/src/H5Ppkg.h
+++ b/src/H5Ppkg.h
@@ -188,6 +188,9 @@ H5_DLL herr_t H5P__decode_double(const void **_pp, void *value);
H5_DLL herr_t H5P__encode_coll_md_read_flag_t(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__decode_coll_md_read_flag_t(const void **_pp, void *value);
+/* Private FAPL routines */
+H5_DLL herr_t H5P__facc_set_def_driver(void);
+
/* Private OCPL routines */
H5_DLL herr_t H5P__get_filter(const struct H5Z_filter_info_t *filter, unsigned int *flags, size_t *cd_nelmts,
unsigned cd_values[], size_t namelen, char name[], unsigned *filter_config);
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index 6ebe5d3..7cbb397 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -156,8 +156,9 @@ struct H5O_fill_t;
struct H5T_t;
struct H5VL_connector_prop_t;
-/* Package initialization routine */
-H5_DLL herr_t H5P_init(void);
+/* Package initialization routines */
+H5_DLL herr_t H5P_init_phase1(void);
+H5_DLL herr_t H5P_init_phase2(void);
/* Internal versions of API routines */
H5_DLL herr_t H5P_close(H5P_genplist_t *plist);
@@ -181,7 +182,13 @@ H5_DLL char * H5P_get_class_name(H5P_genclass_t *pclass);
H5_DLL herr_t H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, hbool_t recurse);
H5_DLL hid_t H5P_peek_driver(H5P_genplist_t *plist);
H5_DLL const void *H5P_peek_driver_info(H5P_genplist_t *plist);
-H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info);
+H5_DLL const char *H5P_peek_driver_config_str(H5P_genplist_t *plist);
+H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info,
+ const char *new_driver_config_str);
+H5_DLL herr_t H5P_set_driver_by_name(H5P_genplist_t *plist, const char *driver_name,
+ const char *driver_config, hbool_t app_ref);
+H5_DLL herr_t H5P_set_driver_by_value(H5P_genplist_t *plist, H5FD_class_value_t driver_value,
+ const char *driver_config, hbool_t app_ref);
H5_DLL herr_t H5P_set_vol(H5P_genplist_t *plist, hid_t vol_id, const void *vol_info);
H5_DLL herr_t H5P_reset_vol_class(const H5P_genclass_t *pclass, const struct H5VL_connector_prop_t *vol_prop);
H5_DLL herr_t H5P_set_vlen_mem_manager(H5P_genplist_t *plist, H5MM_allocate_t alloc_func, void *alloc_info,
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index ed61646..ed9db10 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -117,21 +117,70 @@ extern "C" {
/* Define property list class callback function pointer types */
//! <!-- [H5P_cls_create_func_t_snip] -->
/**
- * \todo Document me!
+ * \brief Callback function for H5Pcreate_class()
+ *
+ * \param[in] prop_id The identifier of the property list class being created
+ * \param[in] create_data User pointer to any class creation data required
+ * \return \herr_t
+ *
+ * \details This function is called when a new property list of the class
+ * with which this function was registered is being created. The
+ * function is called after any registered parent create function is
+ * called for each property value.
+ *
+ * If the create function returns a negative value, the new list is not
+ * returned to the user and the property list creation routine returns
+ * an error value.
+ *
+ * \since 1.4.0
+ *
*/
typedef herr_t (*H5P_cls_create_func_t)(hid_t prop_id, void *create_data);
//! <!-- [H5P_cls_create_func_t_snip] -->
//! <!-- [H5P_cls_copy_func_t_snip] -->
/**
- * \todo Document me!
+ * \brief Callback function for H5Pcreate_class()
+ *
+ * \param[in] new_prop_id The identifier of the property list copy
+ * \param[in] old_prop_id The identifier of the property list being copied
+ * \param[in] copy_data User pointer to any copy data required
+ * \return \herr_t
+ *
+ * \details This function is called when an existing property list of this
+ * class is copied. The copy callback function is called after any
+ * registered parent copy callback function is called for each property
+ * value.
+ *
+ * If the copy routine returns a negative value, the new list is not
+ * returned to the user and the property list copy function returns an
+ * error value.
+ *
+ * \since 1.4.0
+ *
*/
typedef herr_t (*H5P_cls_copy_func_t)(hid_t new_prop_id, hid_t old_prop_id, void *copy_data);
//! <!-- [H5P_cls_copy_func_t_snip] -->
//! <!-- [H5P_cls_close_func_t_snip] -->
/**
- * \todo Document me!
+ * \brief Callback function for H5Pcreate_class()
+ *
+ * \param[in] prop_id The identifier of the property list class being created
+ * \param[in] close_data User pointer to any close data required
+ * \return \herr_t
+ *
+ * \details This function is called when a property list of the class
+ * with which this function was registered is being closed. The
+ * function is called after any registered parent close function is
+ * called for each property value.
+ *
+ * If the close function returns a negative value, the new list is not
+ * returned to the user and the property list close routine returns
+ * an error value.
+ *
+ * \since 1.4.0
+ *
*/
typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data);
//! <!-- [H5P_cls_close_func_t_snip] -->
@@ -146,8 +195,8 @@ typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data);
* \param[in,out] value The value for the property
* \return \herr_t
*
- * \details The H5P_prp_cb1_t() describes the parameters used by the
- * property create,copy and close callback functions.
+ * \details The H5P_prp_cb1_t() function describes the parameters used by the
+ * property create, copy and close callback functions.
*/
typedef herr_t (*H5P_prp_cb1_t)(const char *name, size_t size, void *value);
//! <!-- [H5P_prp_cb1_t_snip] -->
@@ -162,8 +211,8 @@ typedef herr_t (*H5P_prp_cb1_t)(const char *name, size_t size, void *value);
* \param[in] value The value for the property
* \return \herr_t
*
- * \details The H5P_prp_cb2_t() describes the parameters used by the
- * property set ,copy and delete callback functions.
+ * \details The H5P_prp_cb2_t() function describes the parameters used by the
+ * property set, copy and delete callback functions.
*/
typedef herr_t (*H5P_prp_cb2_t)(hid_t prop_id, const char *name, size_t size, void *value);
//! <!-- [H5P_prp_cb2_t_snip] -->
@@ -173,13 +222,28 @@ typedef H5P_prp_cb2_t H5P_prp_set_func_t;
typedef H5P_prp_cb2_t H5P_prp_get_func_t;
//! <!-- [H5P_prp_encode_func_t_snip] -->
/**
- * \todo Document me!
+ * \brief Callback function for encoding property values
+ *
+ * \param[in] value The property value to be encoded
+ * \param[out] buf The encoded property value
+ * \param[out] size The size of \p buf
+ * \return \herr_t
+ *
+ * \note There is currently no public API which exposes a callback of this type.
+ *
*/
typedef herr_t (*H5P_prp_encode_func_t)(const void *value, void **buf, size_t *size);
//! <!-- [H5P_prp_encode_func_t_snip] -->
//! <!-- [H5P_prp_decode_func_t_snip] -->
/**
- * \todo Document me!
+ * \brief Callback function for decoding property values
+ *
+ * \param[in] buf A buffer containing an encoded property value
+ * \param[out] value The decoded property value
+ * \return \herr_t
+ *
+ * \note There is currently no public API which exposes a callback of this type.
+ *
*/
typedef herr_t (*H5P_prp_decode_func_t)(const void **buf, void *value);
//! <!-- [H5P_prp_decode_func_t_snip] -->
@@ -188,7 +252,16 @@ typedef H5P_prp_cb1_t H5P_prp_copy_func_t;
//! <!-- [H5P_prp_compare_func_t_snip] -->
/**
- * \todo Document me!
+ * \brief Callback function for comparing property values
+ *
+ * \param[in] value1 A property value
+ * \param[in] value2 A property value
+ * \param[in] size The size of the \p value1 and \p value2 buffers
+ * \return Returns a positive value if \c value1 is greater than \c value2, a
+ * negative value if \c value2 is greater than \c value1 and zero if
+ * \c value1 and \c value2 are equal.
+ *
+ * \see H5Pregister(), H5Pinsert()
*/
typedef int (*H5P_prp_compare_func_t)(const void *value1, const void *value2, size_t size);
//! <!-- [H5P_prp_compare_func_t_snip] -->
@@ -198,7 +271,19 @@ typedef H5P_prp_cb1_t H5P_prp_close_func_t;
/* Define property list iteration function type */
//! <!-- [H5P_iterate_t_snip] -->
/**
- * \todo Document me!
+ * \brief Callback function for H5Piterate()
+ *
+ * \param[in] id The identifier of a property list or property list class
+ * \param[in] name The name of the current property
+ * \param[in,out] iter_data The user context passed to H5Piterate()
+ * \return \herr_t_iter
+ *
+ * \details This function is called for each property encountered when
+ * iterating over a property list or property list class
+ * via H5Piterate().
+ *
+ * \since 1.4.0
+ *
*/
typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
//! <!-- [H5P_iterate_t_snip] -->
@@ -265,15 +350,15 @@ typedef enum H5D_mpio_no_collective_cause_t {
H5D_MPIO_DATA_TRANSFORMS = 0x04,
/**< Collective I/O was not performed because data transforms needed to be applied */
H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED = 0x08,
- /**< \todo FIXME! */
+ /**< Collective I/O was disabled by environment variable (\Code{HDF5_MPI_OPT_TYPES}) */
H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES = 0x10,
/**< Collective I/O was not performed because one of the dataspaces was neither simple nor scalar */
H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET = 0x20,
/**< Collective I/O was not performed because the dataset was neither contiguous nor chunked */
H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED = 0x40,
- /**< \todo FIXME! */
+ /**< Collective I/O was not performed because parallel filtered writes are disabled */
H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE = 0x80,
- /**< \todo FIXME! */
+ /**< Error */
H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE = 0x100
/**< Sentinel */
} H5D_mpio_no_collective_cause_t;
@@ -579,77 +664,12 @@ H5_DLL hid_t H5Pcreate(hid_t cls_id);
* those existing properties, only add or remove their own class
* properties. Property list classes defined and supported in the
* HDF5 library distribution are listed and briefly described in
- * H5Pcreate(). The \p create routine is called when a new property
- * list of this class is being created. The #H5P_cls_create_func_t
- * callback function is defined as follows:
+ * H5Pcreate(). The \p create, \p copy, \p close functions are called
+ * when a property list of the new class is created, copied, or closed,
+ * respectively.
*
- * \snippet this H5P_cls_create_func_t_snip
- *
- * The parameters to this callback function are defined as follows:
- * <table>
- * <tr>
- * <td>\ref hid_t \c prop_id</td>
- * <td>IN: The identifier of the property list being created</td>
- * </tr>
- * <tr>
- * <td>\Code{void * create_data}</td>
- * <td>IN: User pointer to any class creation data required</td>
- * </tr>
- * </table>
- *
- * The \p create routine is called after any registered
- * \p create function is called for each property value. If the
- * \p create routine returns a negative value, the new list is not
- * returned to the user and the property list creation routine returns
- * an error value.
- *
- * The \p copy routine is called when an existing property
- * list of this class is copied. The #H5P_cls_copy_func_t callback
- * function is defined as follows:
- * \snippet this H5P_cls_copy_func_t_snip
- *
- * The parameters to this callback function are defined as follows:
- * <table>
- * <tr>
- * <td>\ref hid_t \c prop_id</td>
- * <td>IN: The identifier of the property list created by copying</td>
- * </tr>
- * <tr>
- * <td>\Code{void * copy_data}</td>
- * <td>IN: User pointer to any class copy data required</td>
- * </tr>
- * </table>
- *
- * The \p copy routine is called after any registered \p copy function
- * is called for each property value. If the \p copy routine returns a
- * negative value, the new list is not returned to the user and the
- * property list \p copy routine returns an error value.
- *
- * The \p close routine is called when a property list of this class
- * is being closed. The #H5P_cls_close_func_t callback function is
- * defined as follows:
- * \snippet this H5P_cls_close_func_t_snip
- *
- * The parameters to this callback function are defined as follows:
- * <table>
- * <tr>
- * <td>\ref hid_t \c prop_id</td>
- * <td>IN: The identifier of the property list being closed</td>
- * </tr>
- * <tr>
- * <td>\Code{void * close_data}</td>
- * <td>IN: User pointer to any class close data required</td>
- * </tr>
- * </table>
- *
- * The \p close routine is called before any registered \p close
- * function is called for each property value. If the \p close routine
- * returns a negative value, the property list close routine returns
- * an error value but the property list is still closed.
- *
- * H5Pclose_class() can be used to release the property list class
- * identifier returned by this function so that resources leaks will
- * not develop.
+ * H5Pclose_class() must be used to release the property list class
+ * identifier returned by this function.
*
* \since 1.4.0
*
@@ -1378,35 +1398,12 @@ H5_DLL htri_t H5Pisa_class(hid_t plist_id, hid_t pclass_id);
* returned in this case, the iterator cannot be restarted if
* one of the calls to its operator returns non-zero.
*
- * The prototype for the #H5P_iterate_t operator is as follows:
- * \snippet this H5P_iterate_t_snip
- *
- * The operation receives the property list or class
+ * The operation \p iter_func receives the property list or class
* identifier for the object being iterated over, \p id, the
* name of the current property within the object, \p name,
* and the pointer to the operator data passed in to H5Piterate(),
- * \p iter_data. The valid return values from an operator are
- * as follows:
+ * \p iter_data.
*
- * <table>
- * <tr>
- * <td>Zero</td>
- * <td>Causes the iterator to continue, returning zero when all
- * properties have been processed</td>
- * </tr>
- * <tr>
- * <td>Positive</td>
- * <td>Causes the iterator to immediately return that positive
- * value, indicating short-circuit success. The iterator
- * can be restarted at the index of the next property</td>
- * </tr>
- * <tr>
- * <td>Negative</td>
- * <td>Causes the iterator to immediately return that value,
- * indicating failure. The iterator can be restarted at the
- * index of the next property</td>
- * </tr>
- * </table>
* H5Piterate() assumes that the properties in the object
* identified by \p id remain unchanged through the iteration.
* If the membership changes during the iteration, the function's
@@ -1879,9 +1876,6 @@ H5_DLL herr_t H5Pget_attr_phase_change(hid_t plist_id, unsigned *max_compact, un
*
* \brief Returns information about a filter in a pipeline
*
- * \todo Signature for H5Pget_filter2 is different in H5Pocpl.c than in
- * H5Ppublic.h
- *
* \ocpl_id{plist_id}
* \param[in] idx Sequence number within the filter pipeline of the filter
* for which information is sought
@@ -3450,6 +3444,34 @@ H5_DLL const void *H5Pget_driver_info(hid_t plist_id);
/**
* \ingroup FAPL
*
+ * \brief Retrieves a string representation of the configuration for
+ * the driver set on the given FAPL. The returned string can
+ * be used to configure the same driver in an identical way.
+ *
+ * \fapl_id
+ * \param[out] config_buf Driver configuration string output buffer
+ * \param[in] buf_size Size of driver configuration string output buffer
+ *
+ * \return Returns the length of the driver configuration string on
+ * success (not including the NUL terminator). Returns negative
+ * on failure.
+ *
+ * \details H5Pget_driver_config_str() retrieves a string representation
+ * of the configuration for the driver set on the given FAPL. The
+ * returned string can be used to configure the same driver in
+ * an identical way.
+ *
+ * If \p config_buf is NULL, the length of the driver configuration
+ * string is simply returned. The caller can then allocate a buffer
+ * of the appropriate size and call this routine again.
+ *
+ * \version 1.12.1 Function publicized in this release.
+ *
+ */
+H5_DLL ssize_t H5Pget_driver_config_str(hid_t fapl_id, char *config_buf, size_t buf_size);
+/**
+ * \ingroup FAPL
+ *
* \brief Retrieves the size of the external link open file cache
*
* \fapl_id{plist_id}
@@ -3886,13 +3908,13 @@ H5_DLL herr_t H5Pget_meta_block_size(hid_t fapl_id, hsize_t *size);
*
* The second example illustrates the two cases for retrieving the
* number of read attempts from the file access property list of a file
- * opened with SWMR acccess.
+ * opened with SWMR access.
*
* \include H5Pget_metadata_read_attempts.2.c
*
* The third example illustrates the two cases for retrieving the number
* of read attempts from the file access property list of a file opened
- * with non-SWMR acccess.
+ * with non-SWMR access.
*
* \include H5Pget_metadata_read_attempts.3.c
*
@@ -4183,17 +4205,14 @@ H5_DLL herr_t H5Pset_alignment(hid_t fapl_id, hsize_t threshold, hsize_t alignme
*
* \note Note: Raw dataset chunk caching is not currently
* supported when using the MPI I/O and MPI POSIX file drivers
- * in read/write mode; see H5Pset_fapl_mpio() and
- * H5Pset_fapl_mpiposix(), respectively. When using one of these
- * file drivers, all calls to H5Dread() and H5Dwrite() will access
+ * in read/write mode; see H5Pset_fapl_mpio(). When using this
+ * file driver, all calls to H5Dread() and H5Dwrite() will access
* the disk directly, and H5Pset_cache() will have no effect on
* performance.
*
* \note Raw dataset chunk caching is supported when these drivers are
* used in read-only mode.
*
- * \todo Check on H5Pset_fapl_mpio() and H5Pset_fapl_mpiposix().
- *
* \version 1.8.0 The use of the \p mdc_nelmts parameter was discontinued.
* Metadata cache configuration is managed with
* H5Pset_mdc_config() and H5Pget_mdc_config().
@@ -4293,6 +4312,57 @@ H5_DLL herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_
/**
* \ingroup FAPL
*
+ * \brief Sets a file driver according to a given driver name
+ *
+ * \plist_id
+ * \param[in] driver_name The new driver name
+ * \param[in] driver_config Optional string containing driver properties
+ *
+ * \return \herr_t
+ *
+ * \details H5Pset_driver_by_name() sets the file driver, by the name
+ * driver_name, for a file access or data transfer property list,
+ * \p plist_id, and supplies an optional string containing the
+ * driver-specific properties, \p driver_config. The driver
+ * properties string will be copied into the property list.
+ *
+ * If the driver specified by \p driver_name is not currently
+ * registered, an attempt will be made to load the driver as a
+ * plugin.
+ *
+ * \version 1.12.1 Function publicized in this release.
+ *
+ */
+H5_DLL herr_t H5Pset_driver_by_name(hid_t plist_id, const char *driver_name, const char *driver_config);
+/**
+ * \ingroup FAPL
+ *
+ * \brief Sets a file driver according to a given driver value (ID).
+ *
+ * \plist_id
+ * \param[in] driver_value The new driver value (ID)
+ * \param[in] driver_config Optional string containing driver properties
+ *
+ * \return \herr_t
+ *
+ * \details H5Pset_driver_by_value() sets the file driver, by the value
+ * driver_value, for a file access or data transfer property list,
+ * \p plist_id, and supplies an optional string containing the
+ * driver-specific properties, \p driver_config. The driver
+ * properties string will be copied into the property list.
+ *
+ * If the driver specified by \p driver_value is not currently
+ * registered, an attempt will be made to load the driver as a
+ * plugin.
+ *
+ * \version 1.12.1 Function publicized in this release.
+ *
+ */
+H5_DLL herr_t H5Pset_driver_by_value(hid_t plist_id, H5FD_class_value_t driver_value,
+ const char *driver_config);
+/**
+ * \ingroup FAPL
+ *
* \brief Sets the number of files that can be held open in an external
* link open file cache
*
@@ -4301,7 +4371,7 @@ H5_DLL herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_
* The <em>external link open file cache</em> holds files open after
* they have been accessed via an external link. This cache reduces
* the number of times such files are opened when external links are
- * accessed repeatedly and can siginificantly improves performance in
+ * accessed repeatedly and can significantly improves performance in
* certain heavy-use situations and when low-level file opens or closes
* are expensive.
*
@@ -5410,12 +5480,38 @@ H5_DLL herr_t H5Pset_coll_metadata_write(hid_t plist_id, hbool_t is_collective);
H5_DLL herr_t H5Pget_coll_metadata_write(hid_t plist_id, hbool_t *is_collective);
/**
- * \todo Add missing documentation
+ * \ingroup FAPL
+ *
+ * \brief Get the MPI communicator and info
+ *
+ * \fapl_id
+ * \param[out] comm MPI communicator
+ * \param[out] info MPI info object
+ * \return \herr_t
+ *
+ * \details H5Pget_mpi_params() gets the MPI communicator and info stored in
+ * the file access property list \p fapl_id.
+ *
+ * \todo When was this introduced?
+ *
*/
H5_DLL herr_t H5Pget_mpi_params(hid_t fapl_id, MPI_Comm *comm, MPI_Info *info);
/**
- * \todo Add missing documentation
+ * \ingroup FAPL
+ *
+ * \brief Set the MPI communicator and info
+ *
+ * \fapl_id
+ * \param[in] comm MPI communicator
+ * \param[in] info MPI info object
+ * \return \herr_t
+ *
+ * \details H5Pset_mpi_params() sets the MPI communicator and info stored in
+ * the file access property list \p fapl_id.
+ *
+ * \todo When was this introduced?
+ *
*/
H5_DLL herr_t H5Pset_mpi_params(hid_t fapl_id, MPI_Comm comm, MPI_Info info);
#endif /* H5_HAVE_PARALLEL */
@@ -7031,9 +7127,6 @@ H5_DLL herr_t H5Pget_virtual_printf_gap(hid_t dapl_id, hsize_t *gap_size);
*
* \dapl_id
* \param[out] view The flag specifying the view of the virtual dataset.
- * Valid values are:
- * \li #H5D_VDS_FIRST_MISSING
- * \li #H5D_VDS_LAST_AVAILABLE
*
* \return \herr_t
*
@@ -7387,11 +7480,7 @@ H5_DLL herr_t H5Pset_virtual_printf_gap(hid_t dapl_id, hsize_t gap_size);
*
* \dapl_id
* \param[in] view Flag specifying the extent of the data to be included
- * in the view. Valid values are:
- * \li #H5D_VDS_FIRST_MISSING: View includes all data
- * before the first missing mapped data
- * \li #H5D_VDS_LAST_AVAILABLE View includes all
- * available mapped data
+ * in the view.
*
* \return \herr_t
*
@@ -7559,8 +7648,11 @@ H5_DLL herr_t H5Pget_hyper_vector_size(hid_t fapl_id, size_t *size /*out*/);
* \details H5Pget_preserve() checks the status of the dataset transfer
* property list.
*
+ * \since 1.0.0
+ *
* \version 1.6.0 The flag parameter was changed from INTEGER to LOGICAL to
* better match the C API. (Fortran 90)
+ * \version 1.8.2 Deprecated.
*
*/
H5_DLL int H5Pget_preserve(hid_t plist_id);
@@ -7588,6 +7680,8 @@ H5_DLL int H5Pget_preserve(hid_t plist_id);
*
* Please refer to the function H5Pset_type_conv_cb() for more details.
*
+ * \since 1.8.0
+ *
*/
H5_DLL herr_t H5Pget_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t *op, void **operate_data);
/**
@@ -7611,6 +7705,8 @@ H5_DLL herr_t H5Pget_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t *op, voi
* H5Pset_vlen_mem_manager(), returning the parameters set by
* that function.
*
+ * \since 1.0.0
+ *
*/
H5_DLL herr_t H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func, void **alloc_info,
H5MM_free_t *free_func, void **free_info);
@@ -7854,8 +7950,9 @@ H5_DLL herr_t H5Pset_hyper_vector_size(hid_t plist_id, size_t size);
* I/O pipeline treats the destination datapoints as completely
* uninitialized.
*
- * \todo Add missing version information: introduction, deprecation, etc.
- * Why is the declaration not in the deprecated section?
+ * \since 1.0.0
+ *
+ * \version 1.8.2 Deprecated.
*
*/
H5_DLL herr_t H5Pset_preserve(hid_t plist_id, hbool_t status);
@@ -7883,7 +7980,7 @@ H5_DLL herr_t H5Pset_preserve(hid_t plist_id, hbool_t status);
* function prototype is as follows:
* \snippet H5Tpublic.h H5T_conv_except_func_t_snip
*
- * \todo Add version information.
+ * \since 1.8.0
*
*/
H5_DLL herr_t H5Pset_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t op, void *operate_data);
@@ -7933,7 +8030,8 @@ H5_DLL herr_t H5Pset_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t op, void
* set to \c NULL and the \p alloc_info and \p free_info parameters are
* ignored.
*
- * \todo Add version information.
+ * \since 1.0.0
+ *
*/
H5_DLL herr_t H5Pset_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t alloc_func, void *alloc_info,
H5MM_free_t free_func, void *free_info);
diff --git a/src/H5RS.c b/src/H5RS.c
index 65cfd38..16c2356 100644
--- a/src/H5RS.c
+++ b/src/H5RS.c
@@ -69,9 +69,6 @@ static herr_t H5RS__resize_for_append(H5RS_str_t *rs, size_t len);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -353,7 +350,7 @@ done:
*/
/* Disable warning for "format not a string literal" here -QAK */
/*
- * This pragma only needs to surround the sprintf() calls with
+ * This pragma only needs to surround the snprintf() calls with
* format_templ in the code below, but early (4.4.7, at least) gcc only
* allows diagnostic pragmas to be toggled outside of functions.
*/
diff --git a/src/H5Rint.c b/src/H5Rint.c
index 7ee4ecc..65bd485 100644
--- a/src/H5Rint.c
+++ b/src/H5Rint.c
@@ -141,9 +141,6 @@ static herr_t H5R__decode_string(const unsigned char *buf, size_t *nbytes, char
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -152,106 +149,27 @@ hbool_t H5_PKG_INIT_VAR = FALSE;
/* Local Variables */
/*******************/
-/* Flag indicating "top" of interface has been initialized */
-static hbool_t H5R_top_package_initialize_s = FALSE;
-
-/*--------------------------------------------------------------------------
-NAME
- H5R__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5R__init_package()
-
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
-
---------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------
+ * Function: H5R_init
+ *
+ * Purpose: Initialize the interface from some other layer.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5R__init_package(void)
+H5R_init(void)
{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ herr_t ret_value = SUCCEED;
- /* Mark "top" of interface as initialized */
- H5R_top_package_initialize_s = TRUE;
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Sanity check, if assert fails, H5R_REF_BUF_SIZE must be increased */
HDcompile_assert(sizeof(H5R_ref_priv_t) <= H5R_REF_BUF_SIZE);
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5R__init_package() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5R_top_term_package
- PURPOSE
- Terminate various H5R objects
- USAGE
- void H5R_top_term_package()
- RETURNS
- void
- DESCRIPTION
- Release IDs for the ID group, deferring full interface shutdown
- until later (in H5R_term_package).
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- Can't report errors...
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-int
-H5R_top_term_package(void)
-{
- int n = 0;
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Mark closed if initialized */
- if (H5R_top_package_initialize_s)
- if (0 == n)
- H5R_top_package_initialize_s = FALSE;
-
- FUNC_LEAVE_NOAPI(n)
-} /* end H5R_top_term_package() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5R_term_package
- PURPOSE
- Terminate various H5R objects
- USAGE
- void H5R_term_package()
- RETURNS
- void
- DESCRIPTION
- Release the ID group and any other resources allocated.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- Can't report errors...
-
- Finishes shutting down the interface, after H5R_top_term_package()
- is called
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-int
-H5R_term_package(void)
-{
- int n = 0;
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- if (H5_PKG_INIT_VAR) {
- /* Sanity checks */
- HDassert(FALSE == H5R_top_package_initialize_s);
-
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- }
-
- FUNC_LEAVE_NOAPI(n)
-} /* end H5R_term_package() */
+ FUNC_LEAVE_NOAPI(ret_value)
+}
/*-------------------------------------------------------------------------
* Function: H5R__create_object
diff --git a/src/H5Rprivate.h b/src/H5Rprivate.h
index 6d6fcd5..59d2ed2 100644
--- a/src/H5Rprivate.h
+++ b/src/H5Rprivate.h
@@ -39,4 +39,6 @@
/* Library Private Prototypes */
/******************************/
+H5_DLL herr_t H5R_init(void);
+
#endif /* H5Rprivate_H */
diff --git a/src/H5S.c b/src/H5S.c
index 13d32cf..75d3399 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -55,9 +55,6 @@ static htri_t H5S__is_simple(const H5S_t *sdim);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Format version bounds for dataspace */
const unsigned H5O_sdspace_ver_bounds[] = {
H5O_SDSPACE_VERSION_1, /* H5F_LIBVER_EARLIEST */
@@ -96,9 +93,6 @@ static const H5I_class_t H5I_SPACE_SEL_ITER_CLS[1] = {{
(H5I_free_t)H5S__sel_iter_close_cb /* Callback routine for closing objects of this class */
}};
-/* Flag indicating "top" of interface has been initialized */
-static hbool_t H5S_top_package_initialize_s = FALSE;
-
/*-------------------------------------------------------------------------
* Function: H5S_init
*
@@ -114,44 +108,19 @@ H5S_init(void)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_init() */
-
-/*--------------------------------------------------------------------------
-NAME
- H5S__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5S__init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
---------------------------------------------------------------------------*/
-herr_t
-H5S__init_package(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
/* Initialize the ID group for the dataspace IDs */
if (H5I_register_type(H5I_DATASPACE_CLS) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize dataspace ID class")
- /* Initialize the ID group for the dataspace selction iterator IDs */
+ /* Initialize the ID group for the dataspace selection iterator IDs */
if (H5I_register_type(H5I_SPACE_SEL_ITER_CLS) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL,
"unable to initialize dataspace selection iterator ID class")
- /* Mark "top" of interface as initialized, too */
- H5S_top_package_initialize_s = TRUE;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S__init_package() */
+} /* end H5S_init() */
/*--------------------------------------------------------------------------
NAME
@@ -178,21 +147,14 @@ H5S_top_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5S_top_package_initialize_s) {
- if (H5I_nmembers(H5I_DATASPACE) > 0) {
- (void)H5I_clear_type(H5I_DATASPACE, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
-
- if (H5I_nmembers(H5I_SPACE_SEL_ITER) > 0) {
- (void)H5I_clear_type(H5I_SPACE_SEL_ITER, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
-
- /* Mark "top" of interface as closed */
- if (0 == n)
- H5S_top_package_initialize_s = FALSE;
- } /* end if */
+ if (H5I_nmembers(H5I_DATASPACE) > 0) {
+ (void)H5I_clear_type(H5I_DATASPACE, FALSE, FALSE);
+ n++;
+ }
+ if (H5I_nmembers(H5I_SPACE_SEL_ITER) > 0) {
+ (void)H5I_clear_type(H5I_SPACE_SEL_ITER, FALSE, FALSE);
+ n++;
+ }
FUNC_LEAVE_NOAPI(n)
} /* end H5S_top_term_package() */
@@ -224,22 +186,15 @@ H5S_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Sanity checks */
- HDassert(0 == H5I_nmembers(H5I_DATASPACE));
- HDassert(0 == H5I_nmembers(H5I_SPACE_SEL_ITER));
- HDassert(FALSE == H5S_top_package_initialize_s);
-
- /* Destroy the dataspace object id group */
- n += (H5I_dec_type_ref(H5I_DATASPACE) > 0);
+ /* Sanity checks */
+ HDassert(0 == H5I_nmembers(H5I_DATASPACE));
+ HDassert(0 == H5I_nmembers(H5I_SPACE_SEL_ITER));
- /* Destroy the dataspace selection iterator object id group */
- n += (H5I_dec_type_ref(H5I_SPACE_SEL_ITER) > 0);
+ /* Destroy the dataspace object id group */
+ n += (H5I_dec_type_ref(H5I_DATASPACE) > 0);
- /* Mark interface as closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Destroy the dataspace selection iterator object id group */
+ n += (H5I_dec_type_ref(H5I_SPACE_SEL_ITER) > 0);
FUNC_LEAVE_NOAPI(n)
} /* end H5S_term_package() */
@@ -759,7 +714,7 @@ H5S_get_simple_extent_npoints(const H5S_t *ds)
{
hssize_t ret_value = -1; /* Return value */
- FUNC_ENTER_NOAPI(-1)
+ FUNC_ENTER_NOAPI_NOERR
/* check args */
HDassert(ds);
@@ -767,7 +722,6 @@ H5S_get_simple_extent_npoints(const H5S_t *ds)
/* Get the number of elements in extent */
ret_value = (hssize_t)ds->extent.nelem;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_get_simple_extent_npoints() */
@@ -1740,13 +1694,12 @@ H5S_get_simple_extent_type(const H5S_t *space)
{
H5S_class_t ret_value = H5S_NO_CLASS; /* Return value */
- FUNC_ENTER_NOAPI(H5S_NO_CLASS)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(space);
ret_value = H5S_GET_EXTENT_TYPE(space);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_get_simple_extent_type() */
diff --git a/src/H5SL.c b/src/H5SL.c
index b4fbf99..e12e21a 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -239,7 +239,7 @@
}
/* Macro used to reduce the level of a node by 1. Does not update the head node
- * "current level". PREV is the previous node of the currrent height of X. */
+ * "current level". PREV is the previous node of the current height of X. */
#define H5SL_DEMOTE(X, PREV) \
{ \
size_t _lvl = X->level; \
@@ -255,7 +255,7 @@
#define H5SL_INSERT(CMP, SLIST, X, TYPE, KEY, HASHVAL) \
{ \
H5SL_node_t *_last = X; /* Lowest node in the current gap */ \
- H5SL_node_t *_next = NULL; /* Highest node in the currect gap */ \
+ H5SL_node_t *_next = NULL; /* Highest node in the current gap */ \
H5SL_node_t *_drop; /* Low node of the gap to drop into */ \
int _count; /* Number of nodes in the current gap */ \
int _i; \
@@ -311,7 +311,7 @@
{ \
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 *_next = NULL; /* Highest node in the current 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 */ \
@@ -510,9 +510,6 @@ static H5SL_node_t *H5SL__insert_common(H5SL_t *slist, void *item, const void *k
static herr_t H5SL__release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
static herr_t H5SL__close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Declare a free list to manage the H5SL_t struct */
H5FL_DEFINE_STATIC(H5SL_t);
@@ -524,26 +521,21 @@ static H5FL_fac_head_t **H5SL_fac_g;
static size_t H5SL_fac_nused_g;
static size_t H5SL_fac_nalloc_g;
-/*--------------------------------------------------------------------------
- NAME
- H5SL__init_package
- PURPOSE
- Initialize interface-specific information
- USAGE
- herr_t H5SL__init_package()
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- Initializes any interface-specific data or routines.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------
+ * Function: H5SL_init
+ *
+ * Purpose: Initialize the interface from some other layer.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5SL__init_package(void)
+H5SL_init(void)
{
- FUNC_ENTER_PACKAGE_NOERR
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOERR
/* Allocate space for array of factories */
H5SL_fac_g = (H5FL_fac_head_t **)H5MM_malloc(sizeof(H5FL_fac_head_t *));
@@ -555,8 +547,8 @@ H5SL__init_package(void)
HDassert(H5SL_fac_g[0]);
H5SL_fac_nused_g = 1;
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5SL__init_package() */
+ FUNC_LEAVE_NOAPI(ret_value)
+}
/*--------------------------------------------------------------------------
NAME
@@ -584,32 +576,26 @@ H5SL_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Terminate all the factories */
- if (H5SL_fac_nused_g > 0) {
- size_t i;
- herr_t H5_ATTR_NDEBUG_UNUSED ret;
-
- for (i = 0; i < H5SL_fac_nused_g; i++) {
- ret = H5FL_fac_term(H5SL_fac_g[i]);
- HDassert(ret >= 0);
- }
- H5SL_fac_nused_g = 0;
+ /* Terminate all the factories */
+ if (H5SL_fac_nused_g > 0) {
+ size_t i;
+ herr_t H5_ATTR_NDEBUG_UNUSED ret;
- n++;
+ for (i = 0; i < H5SL_fac_nused_g; i++) {
+ ret = H5FL_fac_term(H5SL_fac_g[i]);
+ HDassert(ret >= 0);
}
+ H5SL_fac_nused_g = 0;
- /* Free the list of factories */
- if (H5SL_fac_g) {
- H5SL_fac_g = (H5FL_fac_head_t **)H5MM_xfree((void *)H5SL_fac_g);
- H5SL_fac_nalloc_g = 0;
+ n++;
+ }
- n++;
- }
+ /* Free the list of factories */
+ if (H5SL_fac_g) {
+ H5SL_fac_g = (H5FL_fac_head_t **)H5MM_xfree((void *)H5SL_fac_g);
+ H5SL_fac_nalloc_g = 0;
- /* Mark the interface as uninitialized */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
+ n++;
}
FUNC_LEAVE_NOAPI(n)
@@ -1943,7 +1929,7 @@ H5SL_next(H5SL_node_t *slist_node)
NAME
H5SL_prev
PURPOSE
- Gets a pointer to the previos node in a skip list
+ Gets a pointer to the previous node in a skip list
USAGE
H5SL_node_t *H5SL_prev(slist_node)
H5SL_node_t *slist_node; IN: Pointer to skip list node
diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h
index be6f7b6..f4f7506 100644
--- a/src/H5SLprivate.h
+++ b/src/H5SLprivate.h
@@ -85,6 +85,7 @@ 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_close(H5SL_t *slist);
H5_DLL herr_t H5SL_destroy(H5SL_t *slist, H5SL_operator_t op, void *op_data);
+H5_DLL herr_t H5SL_init(void);
H5_DLL int H5SL_term_interface(void);
#endif /* H5SLprivate_H */
diff --git a/src/H5SM.c b/src/H5SM.c
index 03fb08c..d7ae84b 100644
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -76,9 +76,6 @@ static herr_t H5SM__read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap,
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
H5FL_DEFINE(H5SM_master_table_t);
H5FL_ARR_DEFINE(H5SM_index_header_t, H5O_SHMESG_MAX_NINDEXES);
H5FL_DEFINE(H5SM_list_t);
@@ -117,7 +114,7 @@ H5SM_init(H5F_t *f, H5P_genplist_t *fc_plist, const H5O_loc_t *ext_loc)
haddr_t table_addr = HADDR_UNDEF; /* Address of SOHM master table in file */
unsigned list_max, btree_min; /* Phase change limits for SOHM indices */
unsigned index_type_flags[H5O_SHMESG_MAX_NINDEXES]; /* Messages types stored in each index */
- unsigned minsizes[H5O_SHMESG_MAX_NINDEXES]; /* Message size sharing threshhold for each index */
+ unsigned minsizes[H5O_SHMESG_MAX_NINDEXES]; /* Message size sharing threshold for each index */
unsigned type_flags_used; /* Message type flags used, for sanity checking */
unsigned x; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -629,7 +626,7 @@ H5SM__create_list(H5F_t *f, H5SM_index_header_t *header)
haddr_t addr = HADDR_UNDEF; /* Address of the list on disk */
haddr_t ret_value = HADDR_UNDEF; /* Return value */
- FUNC_ENTER_STATIC_TAG(H5AC__SOHM_TAG)
+ FUNC_ENTER_STATIC
HDassert(f);
HDassert(header);
@@ -671,7 +668,7 @@ done:
H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, addr, (hsize_t)header->list_size);
} /* end if */
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM__create_list */
/*-------------------------------------------------------------------------
@@ -851,7 +848,7 @@ H5SM__convert_btree_to_list(H5F_t *f, H5SM_index_header_t *header)
haddr_t btree_addr;
herr_t ret_value = SUCCEED;
- FUNC_ENTER_STATIC_TAG(H5AC__SOHM_TAG)
+ FUNC_ENTER_STATIC
/* Remember the address of the old B-tree, but change the header over to be
* a list..
@@ -885,7 +882,7 @@ done:
if (list && H5AC_unprotect(f, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0)
HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to unprotect SOHM index")
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM__convert_btree_to_list() */
/*-------------------------------------------------------------------------
@@ -1274,7 +1271,7 @@ H5SM__write_mesg(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, hbool_t
size_t empty_pos = SIZE_MAX; /* Empty entry in list */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_STATIC_TAG(H5AC__SOHM_TAG)
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(header);
@@ -1538,7 +1535,7 @@ done:
if (encoding_buf)
encoding_buf = H5MM_xfree(encoding_buf);
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM__write_mesg() */
/*-------------------------------------------------------------------------
@@ -1599,7 +1596,7 @@ H5SM_delete(H5F_t *f, H5O_t *open_oh, H5O_shared_t *sh_mesg)
*/
if (H5SM__delete_from_index(f, open_oh, &(table->indexes[index_num]), sh_mesg, &cache_flags, &mesg_size,
&mesg_buf) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete mesage from SOHM index")
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete message from SOHM index")
/* Release the master SOHM table */
if (H5AC_unprotect(f, H5AC_SOHM_TABLE, H5F_SOHM_ADDR(f), table, cache_flags) < 0)
@@ -1785,7 +1782,7 @@ H5SM__delete_from_index(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, c
unsigned type_id; /* Message type to operate on */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_STATIC_TAG(H5AC__SOHM_TAG)
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(f);
@@ -1951,7 +1948,7 @@ done:
*mesg_size = 0;
}
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM__delete_from_index() */
/*-------------------------------------------------------------------------
@@ -2387,7 +2384,7 @@ H5SM__read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, H5O_t *open_oh
H5O_t * oh = NULL; /* Object header for message in object header */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_STATIC_TAG(H5AC__SOHM_TAG)
+ FUNC_ENTER_STATIC
HDassert(f);
HDassert(mesg);
@@ -2461,7 +2458,7 @@ done:
if (ret_value < 0 && udata.encoding_buf)
udata.encoding_buf = H5MM_xfree(udata.encoding_buf);
- FUNC_LEAVE_NOAPI_TAG(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM__read_mesg */
/*-------------------------------------------------------------------------
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 35ddf3d..4dcc83a 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -49,22 +49,22 @@
static herr_t H5S__all_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
static herr_t H5S__all_release(H5S_t *space);
static htri_t H5S__all_is_valid(const H5S_t *space);
-static hssize_t H5S__all_serial_size(const H5S_t *space);
-static herr_t H5S__all_serialize(const H5S_t *space, uint8_t **p);
+static hssize_t H5S__all_serial_size(H5S_t *space);
+static herr_t H5S__all_serialize(H5S_t *space, uint8_t **p);
static herr_t H5S__all_deserialize(H5S_t **space, const uint8_t **p);
static herr_t H5S__all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S__all_offset(const H5S_t *space, hsize_t *off);
static int H5S__all_unlim_dim(const H5S_t *space);
static htri_t H5S__all_is_contiguous(const H5S_t *space);
static htri_t H5S__all_is_single(const H5S_t *space);
-static htri_t H5S__all_is_regular(const H5S_t *space);
-static htri_t H5S__all_shape_same(const H5S_t *space1, const H5S_t *space2);
-static htri_t H5S__all_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end);
+static htri_t H5S__all_is_regular(H5S_t *space);
+static htri_t H5S__all_shape_same(H5S_t *space1, H5S_t *space2);
+static htri_t H5S__all_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end);
static herr_t H5S__all_adjust_u(H5S_t *space, const hsize_t *offset);
static herr_t H5S__all_adjust_s(H5S_t *space, const hssize_t *offset);
static herr_t H5S__all_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__all_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
-static herr_t H5S__all_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
+static herr_t H5S__all_iter_init(H5S_t *space, H5S_sel_iter_t *iter);
/* Selection iteration callbacks */
static herr_t H5S__all_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords);
@@ -144,7 +144,7 @@ static const H5S_sel_iter_class_t H5S_sel_iter_all[1] = {{
*-------------------------------------------------------------------------
*/
static herr_t
-H5S__all_iter_init(const H5S_t H5_ATTR_UNUSED *space, H5S_sel_iter_t *iter)
+H5S__all_iter_init(H5S_t H5_ATTR_UNUSED *space, H5S_sel_iter_t *iter)
{
FUNC_ENTER_STATIC_NOERR
@@ -557,7 +557,7 @@ H5S__all_is_valid(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static hssize_t
-H5S__all_serial_size(const H5S_t H5_ATTR_UNUSED *space)
+H5S__all_serial_size(H5S_t H5_ATTR_UNUSED *space)
{
FUNC_ENTER_STATIC_NOERR
@@ -577,7 +577,7 @@ H5S__all_serial_size(const H5S_t H5_ATTR_UNUSED *space)
Serialize the current selection into a user-provided buffer.
USAGE
herr_t H5S__all_serialize(space, p)
- const H5S_t *space; IN: Dataspace with selection to serialize
+ H5S_t *space; IN: Dataspace with selection to serialize
uint8_t **p; OUT: Pointer to buffer to put serialized
selection. Will be advanced to end of
serialized selection.
@@ -592,7 +592,7 @@ H5S__all_serial_size(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S__all_serialize(const H5S_t *space, uint8_t **p)
+H5S__all_serialize(H5S_t *space, uint8_t **p)
{
uint8_t *pp = (*p); /* Local pointer for decoding */
@@ -864,7 +864,7 @@ H5S__all_is_single(const H5S_t H5_ATTR_UNUSED *space)
Check if a "all" selection is "regular"
USAGE
htri_t H5S__all_is_regular(space)
- const H5S_t *space; IN: Dataspace pointer to check
+ H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
DESCRIPTION
@@ -877,7 +877,7 @@ H5S__all_is_single(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__all_is_regular(const H5S_t H5_ATTR_UNUSED *space)
+H5S__all_is_regular(H5S_t H5_ATTR_UNUSED *space)
{
FUNC_ENTER_STATIC_NOERR
@@ -894,8 +894,8 @@ H5S__all_is_regular(const H5S_t H5_ATTR_UNUSED *space)
Check if a two "all" selections are the same shape
USAGE
htri_t H5S__all_shape_same(space1, space2)
- const H5S_t *space1; IN: First dataspace to check
- const H5S_t *space2; IN: Second dataspace to check
+ H5S_t *space1; IN: First dataspace to check
+ H5S_t *space2; IN: Second dataspace to check
RETURNS
TRUE / FALSE / FAIL
DESCRIPTION
@@ -907,7 +907,7 @@ H5S__all_is_regular(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__all_shape_same(const H5S_t *space1, const H5S_t *space2)
+H5S__all_shape_same(H5S_t *space1, H5S_t *space2)
{
int space1_dim; /* Current dimension in first dataspace */
int space2_dim; /* Current dimension in second dataspace */
@@ -957,7 +957,7 @@ done:
Detect intersections of selection with block
USAGE
htri_t H5S__all_intersect_block(space, start, end)
- const H5S_t *space; IN: Dataspace with selection to use
+ H5S_t *space; IN: Dataspace with selection to use
const hsize_t *start; IN: Starting coordinate for block
const hsize_t *end; IN: Ending coordinate for block
RETURNS
@@ -970,7 +970,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S__all_intersect_block(const H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *start,
+H5S__all_intersect_block(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *start,
const hsize_t H5_ATTR_UNUSED *end)
{
FUNC_ENTER_STATIC_NOERR
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index a5b9b6c..7284846 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -173,8 +173,8 @@ static herr_t H5S__hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_sele
static herr_t H5S__hyper_release(H5S_t *space);
static htri_t H5S__hyper_is_valid(const H5S_t *space);
static hsize_t H5S__hyper_span_nblocks(H5S_hyper_span_info_t *spans);
-static hssize_t H5S__hyper_serial_size(const H5S_t *space);
-static herr_t H5S__hyper_serialize(const H5S_t *space, uint8_t **p);
+static hssize_t H5S__hyper_serial_size(H5S_t *space);
+static herr_t H5S__hyper_serialize(H5S_t *space, uint8_t **p);
static herr_t H5S__hyper_deserialize(H5S_t **space, const uint8_t **p);
static herr_t H5S__hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S__hyper_offset(const H5S_t *space, hsize_t *offset);
@@ -182,14 +182,14 @@ static int H5S__hyper_unlim_dim(const H5S_t *space);
static herr_t H5S__hyper_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim);
static htri_t H5S__hyper_is_contiguous(const H5S_t *space);
static htri_t H5S__hyper_is_single(const H5S_t *space);
-static htri_t H5S__hyper_is_regular(const H5S_t *space);
-static htri_t H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2);
-static htri_t H5S__hyper_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end);
+static htri_t H5S__hyper_is_regular(H5S_t *space);
+static htri_t H5S__hyper_shape_same(H5S_t *space1, H5S_t *space2);
+static htri_t H5S__hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end);
static herr_t H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset);
static herr_t H5S__hyper_adjust_s(H5S_t *space, const hssize_t *offset);
static herr_t H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__hyper_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
-static herr_t H5S__hyper_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
+static herr_t H5S__hyper_iter_init(H5S_t *space, H5S_sel_iter_t *iter);
/* Selection iteration callbacks */
static herr_t H5S__hyper_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords);
@@ -296,12 +296,12 @@ H5S__hyper_print_spans_helper(FILE *f, const H5S_hyper_span_t *span, unsigned de
FUNC_ENTER_STATIC_NOERR
while (span) {
- HDfprintf(f, "%s: %*sdepth=%u, span=%p, (%Hu, %Hu), next=%p\n", __func__, depth * 2, "", depth, span,
- span->low, span->high, span->next);
+ HDfprintf(f, "%s: %*sdepth=%u, span=%p, (%" PRIuHSIZE ", %" PRIuHSIZE "), next=%p\n", __func__,
+ depth * 2, "", depth, (void *)span, span->low, span->high, (void *)span->next);
if (span->down) {
- HDfprintf(f, "%s: %*sspans=%p, count=%u, bounds[0]={%Hu, %Hu}, head=%p\n", __func__,
- (depth + 1) * 2, "", span->down, span->down->count, span->down->low_bounds[0],
- span->down->high_bounds[0], span->down->head);
+ HDfprintf(f, "%s: %*sspans=%p, count=%u, bounds[0]={%" PRIuHSIZE ", %" PRIuHSIZE "}, head=%p\n",
+ __func__, (depth + 1) * 2, "", (void *)span->down, span->down->count,
+ span->down->low_bounds[0], span->down->high_bounds[0], (void *)span->down->head);
H5S__hyper_print_spans_helper(f, span->down->head, depth + 1);
} /* end if */
span = span->next;
@@ -316,8 +316,9 @@ H5S__hyper_print_spans(FILE *f, const H5S_hyper_span_info_t *span_lst)
FUNC_ENTER_STATIC_NOERR
if (span_lst != NULL) {
- HDfprintf(f, "%s: spans=%p, count=%u, bounds[0]={%Hu, %Hu}, head=%p\n", __func__, span_lst,
- span_lst->count, span_lst->low_bounds[0], span_lst->high_bounds[0], span_lst->head);
+ HDfprintf(f, "%s: spans=%p, count=%u, bounds[0]={%" PRIuHSIZE ", %" PRIuHSIZE "}, head=%p\n",
+ __func__, (void *)span_lst, span_lst->count, span_lst->low_bounds[0],
+ span_lst->high_bounds[0], (void *)span_lst->head);
H5S__hyper_print_spans_helper(f, span_lst->head, 0);
} /* end if */
@@ -344,16 +345,16 @@ H5S__hyper_print_diminfo_helper(FILE *f, const char *field, unsigned ndims, cons
if (dinfo != NULL) {
HDfprintf(f, "%s: %s: start=[", __func__, field);
for (u = 0; u < ndims; u++)
- HDfprintf(f, "%Hd%s", dinfo[u].start, (u < (ndims - 1) ? ", " : "]\n"));
+ HDfprintf(f, "%" PRIuHSIZE "%s", dinfo[u].start, (u < (ndims - 1) ? ", " : "]\n"));
HDfprintf(f, "%s: %s: stride=[", __func__, field);
for (u = 0; u < ndims; u++)
- HDfprintf(f, "%Hu%s", dinfo[u].stride, (u < (ndims - 1) ? ", " : "]\n"));
+ HDfprintf(f, "%" PRIuHSIZE "%s", dinfo[u].stride, (u < (ndims - 1) ? ", " : "]\n"));
HDfprintf(f, "%s: %s: count=[", __func__, field);
for (u = 0; u < ndims; u++)
- HDfprintf(f, "%Hu%s", dinfo[u].count, (u < (ndims - 1) ? ", " : "]\n"));
+ HDfprintf(f, "%" PRIuHSIZE "%s", dinfo[u].count, (u < (ndims - 1) ? ", " : "]\n"));
HDfprintf(f, "%s: %s: block=[", __func__, field);
for (u = 0; u < ndims; u++)
- HDfprintf(f, "%Hu%s", dinfo[u].block, (u < (ndims - 1) ? ", " : "]\n"));
+ HDfprintf(f, "%" PRIuHSIZE "%s", dinfo[u].block, (u < (ndims - 1) ? ", " : "]\n"));
} /* end if */
else
HDfprintf(f, "%s: %s==NULL\n", __func__, field);
@@ -412,31 +413,31 @@ H5S__hyper_print_spans_dfs(FILE *f, const H5S_hyper_span_info_t *span_lst, unsig
for (u = 0; u < depth; u++)
HDfprintf(f, "\t");
- HDfprintf(f, "DIM[%u]: ref_count=%u, #elems=%u, head=%p, tail=%p, actual_tail=%p, matched=%t\n", depth,
- span_lst->count, num_elems, span_lst->head, span_lst->tail, actual_tail,
+ HDfprintf(f, "DIM[%u]: ref_count=%u, #elems=%u, head=%p, tail=%p, actual_tail=%p, matched=%d\n", depth,
+ span_lst->count, num_elems, (void *)span_lst->head, (void *)span_lst->tail, (void *)actual_tail,
(span_lst->tail == actual_tail));
for (u = 0; u < depth; u++)
HDfprintf(f, "\t");
HDfprintf(f, "low_bounds=[");
for (u = 0; u < dims - 1; u++)
- HDfprintf(f, "%llu,", span_lst->low_bounds[u]);
- HDfprintf(f, "%llu]\n", span_lst->low_bounds[dims - 1]);
+ HDfprintf(f, "%" PRIuHSIZE ",", span_lst->low_bounds[u]);
+ HDfprintf(f, "%" PRIuHSIZE "]\n", span_lst->low_bounds[dims - 1]);
for (u = 0; u < depth; u++)
HDfprintf(f, "\t");
HDfprintf(f, "high_bounds=[");
for (u = 0; u < dims - 1; u++)
- HDfprintf(f, "%llu,", span_lst->high_bounds[u]);
- HDfprintf(f, "%llu]\n", span_lst->high_bounds[dims - 1]);
+ HDfprintf(f, "%" PRIuHSIZE ",", span_lst->high_bounds[u]);
+ HDfprintf(f, "%" PRIuHSIZE "]\n", span_lst->high_bounds[dims - 1]);
cur_elem = span_lst->head;
elem_idx = 0;
while (cur_elem) {
for (u = 0; u < depth; u++)
HDfprintf(f, "\t");
- HDfprintf(f, "ELEM[%u]: ptr=%p, low=%Hu, high=%Hu, down=%p\n", elem_idx++, cur_elem, cur_elem->low,
- cur_elem->high, cur_elem->down);
+ HDfprintf(f, "ELEM[%u]: ptr=%p, low=%" PRIuHSIZE ", high=%" PRIuHSIZE ", down=%p\n", elem_idx++,
+ (void *)cur_elem, cur_elem->low, cur_elem->high, (void *)cur_elem->down);
if (cur_elem->down)
H5S__hyper_print_spans_dfs(f, cur_elem->down, depth + 1, dims);
cur_elem = cur_elem->next;
@@ -473,7 +474,7 @@ H5S__hyper_print_space_dfs(FILE *f, const H5S_t *space)
HDassert(hslab);
HDfprintf(f, "=======================\n");
- HDfprintf(f, "SPACE: span_lst=%p, #dims=%u, offset_changed=%d\n", hslab->span_lst, dims,
+ HDfprintf(f, "SPACE: span_lst=%p, #dims=%u, offset_changed=%d\n", (void *)hslab->span_lst, dims,
space->select.offset_changed);
HDfprintf(f, " offset=[");
@@ -484,25 +485,25 @@ H5S__hyper_print_space_dfs(FILE *f, const H5S_t *space)
HDfprintf(f, " low_bounds=[");
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
for (u = 0; u < dims - 1; u++)
- HDfprintf(f, "%llu,", space->select.sel_info.hslab->diminfo.low_bounds[u]);
- HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->diminfo.low_bounds[dims - 1]);
+ HDfprintf(f, "%" PRIuHSIZE ",", space->select.sel_info.hslab->diminfo.low_bounds[u]);
+ HDfprintf(f, "%" PRIuHSIZE "]\n", space->select.sel_info.hslab->diminfo.low_bounds[dims - 1]);
} /* end if */
else {
for (u = 0; u < dims - 1; u++)
- HDfprintf(f, "%llu,", space->select.sel_info.hslab->span_lst->low_bounds[u]);
- HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->span_lst->low_bounds[dims - 1]);
+ HDfprintf(f, "%" PRIuHSIZE ",", space->select.sel_info.hslab->span_lst->low_bounds[u]);
+ HDfprintf(f, "%" PRIuHSIZE "]\n", space->select.sel_info.hslab->span_lst->low_bounds[dims - 1]);
} /* end else */
HDfprintf(f, " high_bounds=[");
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
for (u = 0; u < dims - 1; u++)
- HDfprintf(f, "%llu,", space->select.sel_info.hslab->diminfo.high_bounds[u]);
- HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->diminfo.high_bounds[dims - 1]);
+ HDfprintf(f, "%" PRIuHSIZE ",", space->select.sel_info.hslab->diminfo.high_bounds[u]);
+ HDfprintf(f, "%" PRIuHSIZE "]\n", space->select.sel_info.hslab->diminfo.high_bounds[dims - 1]);
} /* end if */
else {
for (u = 0; u < dims - 1; u++)
- HDfprintf(f, "%llu,", space->select.sel_info.hslab->span_lst->high_bounds[u]);
- HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->span_lst->high_bounds[dims - 1]);
+ HDfprintf(f, "%" PRIuHSIZE ",", space->select.sel_info.hslab->span_lst->high_bounds[u]);
+ HDfprintf(f, "%" PRIuHSIZE "]\n", space->select.sel_info.hslab->span_lst->high_bounds[dims - 1]);
} /* end else */
/* Print out diminfo, if it's valid */
@@ -559,7 +560,7 @@ H5S__hyper_get_op_gen(void)
*-------------------------------------------------------------------------
*/
static herr_t
-H5S__hyper_iter_init(const H5S_t *space, H5S_sel_iter_t *iter)
+H5S__hyper_iter_init(H5S_t *space, H5S_sel_iter_t *iter)
{
hsize_t *slab_size; /* Pointer to the dataspace dimensions to use for calc. slab */
hsize_t acc; /* Accumulator for computing cumulative sizes */
@@ -586,7 +587,7 @@ H5S__hyper_iter_init(const H5S_t *space, H5S_sel_iter_t *iter)
* to be impossible.
*/
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- H5S__hyper_rebuild((H5S_t *)space); /* Casting away const OK -NAF */
+ H5S__hyper_rebuild(space);
/* Check for the special case of just one H5Sselect_hyperslab call made */
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
@@ -2060,7 +2061,7 @@ H5S__hyper_iter_get_seq_list_opt(H5S_sel_iter_t *iter, size_t maxseq, size_t max
/* Increment the offset and count for the other dimensions */
temp_dim = (int)fast_dim - 1;
while (temp_dim >= 0) {
- /* Move to the next row in the curent dimension */
+ /* Move to the next row in the current dimension */
offset[temp_dim]++;
tmp_block[temp_dim]++;
@@ -2178,7 +2179,7 @@ H5S__hyper_iter_get_seq_list_opt(H5S_sel_iter_t *iter, size_t maxseq, size_t max
/* Increment the offset and count for the other dimensions */
temp_dim = (int)fast_dim - 1;
while (temp_dim >= 0) {
- /* Move to the next row in the curent dimension */
+ /* Move to the next row in the current dimension */
offset[temp_dim]++;
tmp_block[temp_dim]++;
@@ -2492,7 +2493,7 @@ H5S__hyper_iter_get_seq_list_single(H5S_sel_iter_t *iter, size_t maxseq, size_t
/* Increment the offset and count for the other dimensions */
while (temp_dim >= 0) {
- /* Move to the next row in the curent dimension */
+ /* Move to the next row in the current dimension */
offset[temp_dim]++;
tmp_block[temp_dim]++;
@@ -3575,7 +3576,7 @@ H5S__hyper_get_enc_size_real(hsize_t max_size)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S__hyper_get_version_enc_size(const H5S_t *space, hsize_t block_count, uint32_t *version, uint8_t *enc_size)
+H5S__hyper_get_version_enc_size(H5S_t *space, hsize_t block_count, uint32_t *version, uint8_t *enc_size)
{
hsize_t bounds_start[H5S_MAX_RANK]; /* Starting coordinate of bounding box */
hsize_t bounds_end[H5S_MAX_RANK]; /* Opposite coordinate of bounding box */
@@ -3584,7 +3585,7 @@ H5S__hyper_get_version_enc_size(const H5S_t *space, hsize_t block_count, uint32_
H5F_libver_t low_bound; /* The 'low' bound of library format versions */
H5F_libver_t high_bound; /* The 'high' bound of library format versions */
htri_t is_regular; /* A regular hyperslab or not */
- uint32_t tmp_version; /* Local temporay version */
+ uint32_t tmp_version; /* Local temporary version */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3728,7 +3729,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static hssize_t
-H5S__hyper_serial_size(const H5S_t *space)
+H5S__hyper_serial_size(H5S_t *space)
{
hsize_t block_count = 0; /* block counter for regular hyperslabs */
uint32_t version; /* Version number */
@@ -3928,7 +3929,7 @@ H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans, hsize_t *start,
Serialize the current selection into a user-provided buffer.
USAGE
herr_t H5S__hyper_serialize(space, p)
- const H5S_t *space; IN: Dataspace with selection to serialize
+ H5S_t *space; IN: Dataspace with selection to serialize
uint8_t **p; OUT: Pointer to buffer to put serialized
selection. Will be advanced to end of
serialized selection.
@@ -3943,7 +3944,7 @@ H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans, hsize_t *start,
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S__hyper_serialize(const H5S_t *space, uint8_t **p)
+H5S__hyper_serialize(H5S_t *space, uint8_t **p)
{
const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */
@@ -3972,7 +3973,7 @@ H5S__hyper_serialize(const H5S_t *space, uint8_t **p)
pp = (*p);
HDassert(pp);
- /* Set some convienence values */
+ /* Set some convenience values */
ndims = space->extent.rank;
diminfo = space->select.sel_info.hslab->diminfo.opt;
@@ -4075,7 +4076,7 @@ H5S__hyper_serialize(const H5S_t *space, uint8_t **p)
else {
HDassert(version == H5S_HYPER_VERSION_1);
- /* Set some convienence values */
+ /* Set some convenience values */
fast_dim = ndims - 1;
/* Encode number of hyperslabs */
@@ -4225,7 +4226,7 @@ H5S__hyper_deserialize(H5S_t **space, const uint8_t **p)
{
H5S_t *tmp_space = NULL; /* Pointer to actual dataspace to use,
either *space or a newly allocated one */
- hsize_t dims[H5S_MAX_RANK]; /* Dimenion sizes */
+ hsize_t dims[H5S_MAX_RANK]; /* Dimension sizes */
hsize_t start[H5S_MAX_RANK]; /* hyperslab start information */
hsize_t block[H5S_MAX_RANK]; /* hyperslab block information */
uint32_t version; /* Version number */
@@ -4618,7 +4619,7 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numblo
hbool_t done; /* Whether we are done with the iteration */
unsigned u; /* Counter */
- /* Set some convienence values */
+ /* Set some convenience values */
ndims = space->extent.rank;
fast_dim = ndims - 1;
@@ -5112,7 +5113,7 @@ H5S__hyper_is_contiguous(const H5S_t *space)
large_contiguous = TRUE; /* assume true and reset if the dimensions don't match */
small_contiguous = FALSE; /* assume false initially */
- /* Check for a "large contigous" block */
+ /* Check for a "large contiguous" block */
for (u = 0; u < space->extent.rank; u++) {
if (diminfo[u].count > 1) {
large_contiguous = FALSE;
@@ -5326,7 +5327,7 @@ done:
Check if a hyperslab selection is "regular"
USAGE
htri_t H5S__hyper_is_regular(space)
- const H5S_t *space; IN: Dataspace pointer to check
+ H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
DESCRIPTION
@@ -5339,7 +5340,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__hyper_is_regular(const H5S_t *space)
+H5S__hyper_is_regular(H5S_t *space)
{
htri_t ret_value = FAIL; /* return value */
@@ -5352,7 +5353,7 @@ H5S__hyper_is_regular(const H5S_t *space)
* to be impossible.
*/
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- H5S__hyper_rebuild((H5S_t *)space); /* Casting away const OK -NAF */
+ H5S__hyper_rebuild(space);
/* Only simple check for regular hyperslabs for now... */
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES)
@@ -5576,8 +5577,8 @@ H5S__hyper_spans_shape_same(const H5S_hyper_span_info_t *span_info1, const H5S_h
Check if a two hyperslab selections are the same shape
USAGE
htri_t H5S__hyper_shape_same(space1, space2)
- const H5S_t *space1; IN: First dataspace to check
- const H5S_t *space2; IN: Second dataspace to check
+ H5S_t *space1; IN: First dataspace to check
+ H5S_t *space2; IN: Second dataspace to check
RETURNS
TRUE / FALSE / FAIL
DESCRIPTION
@@ -5594,7 +5595,7 @@ H5S__hyper_spans_shape_same(const H5S_hyper_span_info_t *span_info1, const H5S_h
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2)
+H5S__hyper_shape_same(H5S_t *space1, H5S_t *space2)
{
unsigned space1_rank; /* Number of dimensions of first dataspace */
unsigned space2_rank; /* Number of dimensions of second dataspace */
@@ -5617,9 +5618,9 @@ H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2)
/* Rebuild diminfo if it is invalid and has not been confirmed to be
* impossible */
if (space1->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- H5S__hyper_rebuild((H5S_t *)space1); /* Casting away const OK -QAK */
+ H5S__hyper_rebuild(space1);
if (space2->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- H5S__hyper_rebuild((H5S_t *)space2); /* Casting away const OK -QAK */
+ H5S__hyper_rebuild(space2);
/* If both are regular hyperslabs, compare their diminfo values */
if (space1->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES &&
@@ -5664,11 +5665,11 @@ H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2)
/* Make certain that both selections have span trees */
if (NULL == space1->select.sel_info.hslab->span_lst)
- if (H5S__hyper_generate_spans((H5S_t *)space1) < 0) /* Casting away const OK -QAK */
+ if (H5S__hyper_generate_spans(space1) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL,
"can't construct span tree for hyperslab selection")
if (NULL == space2->select.sel_info.hslab->span_lst)
- if (H5S__hyper_generate_spans((H5S_t *)space2) < 0) /* Casting away const OK -QAK */
+ if (H5S__hyper_generate_spans(space2) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL,
"can't construct span tree for hyperslab selection")
@@ -6255,7 +6256,7 @@ done:
Detect intersections of selection with block
USAGE
htri_t H5S__hyper_intersect_block(space, start, end)
- const H5S_t *space; IN: Dataspace with selection to use
+ H5S_t *space; IN: Dataspace with selection to use
const hsize_t *start; IN: Starting coordinate for block
const hsize_t *end; IN: Ending coordinate for block
RETURNS
@@ -6270,7 +6271,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__hyper_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end)
+H5S__hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end)
{
htri_t ret_value = FAIL; /* Return value */
@@ -6286,7 +6287,7 @@ H5S__hyper_intersect_block(const H5S_t *space, const hsize_t *start, const hsize
* to be impossible.
*/
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- H5S__hyper_rebuild((H5S_t *)space); /* Casting away const OK -QAK */
+ H5S__hyper_rebuild(space);
/* Check for regular hyperslab intersection */
if (space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
@@ -11516,7 +11517,7 @@ H5S__hyper_proj_int_iterate(const H5S_hyper_span_info_t *ss_span_info,
udata->skip += (count - 1) * (udata->skip - old_skip);
} /* end if */
else {
- /* Third case: agorithm added skip and nelem (in that
+ /* Third case: algorithm added skip and nelem (in that
* order). Add the same skip and nelem once for each item
* remaining in count. */
hsize_t skip_add;
@@ -11592,8 +11593,8 @@ also that proj_space can share some span trees with dst_space, so proj_space mus
if dst_space must be preserved. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
- const H5S_t *src_intersect_space, H5S_t *proj_space, hbool_t share_selection)
+H5S__hyper_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_intersect_space,
+ H5S_t *proj_space, hbool_t share_selection)
{
H5S_hyper_project_intersect_ud_t udata; /* User data for subroutines */
const H5S_hyper_span_info_t * ss_span_info;
@@ -11622,7 +11623,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
if (H5S_GET_SELECT_TYPE(src_space) == H5S_SEL_HYPERSLABS) {
/* Make certain the selection has a span tree */
if (NULL == src_space->select.sel_info.hslab->span_lst)
- if (H5S__hyper_generate_spans((H5S_t *)src_space) < 0) /* Casting away const OK -NAF */
+ if (H5S__hyper_generate_spans(src_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL,
"can't construct span tree for source hyperslab selection")
@@ -11644,7 +11645,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
if (H5S_GET_SELECT_TYPE(dst_space) == H5S_SEL_HYPERSLABS) {
/* Make certain the selection has a span tree */
if (NULL == dst_space->select.sel_info.hslab->span_lst)
- if (H5S__hyper_generate_spans((H5S_t *)dst_space) < 0) /* Casting away const OK -NAF */
+ if (H5S__hyper_generate_spans(dst_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL,
"can't construct span tree for dsetination hyperslab selection")
@@ -11664,7 +11665,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
/* Make certain the source intersect selection has a span tree */
if (NULL == src_intersect_space->select.sel_info.hslab->span_lst)
- if (H5S__hyper_generate_spans((H5S_t *)src_intersect_space) < 0) /* Casting away const OK -NAF */
+ if (H5S__hyper_generate_spans(src_intersect_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL,
"can't construct span tree for source intersect hyperslab selection")
@@ -12036,7 +12037,7 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, hbo
hsize_t num_slices; /* Number of slices in unlimited dimension */
hsize_t ret_value = 0; /* Return value */
- FUNC_ENTER_NOAPI(0)
+ FUNC_ENTER_NOAPI_NOERR
/* Check parameters */
HDassert(clip_space);
@@ -12058,7 +12059,6 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, hbo
/* Call "real" get_clip_extent function */
ret_value = H5S__hyper_get_clip_extent_real(clip_space, num_slices, incl_trail);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_hyper_get_clip_extent() */
@@ -12094,7 +12094,7 @@ H5S_hyper_get_clip_extent_match(const H5S_t *clip_space, const H5S_t *match_spac
hsize_t num_slices; /* Number of slices in unlimited dimension */
hsize_t ret_value = 0; /* Return value */
- FUNC_ENTER_NOAPI(0)
+ FUNC_ENTER_NOAPI_NOERR
/* Check parameters */
HDassert(clip_space);
@@ -12140,7 +12140,6 @@ H5S_hyper_get_clip_extent_match(const H5S_t *clip_space, const H5S_t *match_spac
/* Call "real" get_clip_extent function */
ret_value = H5S__hyper_get_clip_extent_real(clip_space, num_slices, incl_trail);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_hyper_get_clip_extent_match() */
@@ -12256,7 +12255,7 @@ H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, hbool_t *pa
H5S_hyper_dim_t *diminfo; /* Convenience pointer to diminfo in unlimited dimension */
hsize_t ret_value = 0;
- FUNC_ENTER_NOAPI(0)
+ FUNC_ENTER_NOAPI_NOERR
/* Check parameters */
HDassert(space);
@@ -12286,7 +12285,6 @@ H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, hbool_t *pa
} /* end if */
} /* end else */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_hyper_get_first_inc_block */
diff --git a/src/H5Smpio.c b/src/H5Smpio.c
index b626b77..aec5560 100644
--- a/src/H5Smpio.c
+++ b/src/H5Smpio.c
@@ -1145,7 +1145,7 @@ H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, size_t e
/* If this is the fastest changing dimension, it is the base case for derived datatype. */
span = spans->head;
if (NULL == span->down) {
- hbool_t large_block = FALSE; /* Wether the block length is larger than 32 bit integer */
+ hbool_t large_block = FALSE; /* Whether the block length is larger than 32 bit integer */
outercount = 0;
while (span) {
diff --git a/src/H5Snone.c b/src/H5Snone.c
index 82e513e..9292cd4 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -49,22 +49,22 @@
static herr_t H5S__none_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
static herr_t H5S__none_release(H5S_t *space);
static htri_t H5S__none_is_valid(const H5S_t *space);
-static hssize_t H5S__none_serial_size(const H5S_t *space);
-static herr_t H5S__none_serialize(const H5S_t *space, uint8_t **p);
+static hssize_t H5S__none_serial_size(H5S_t *space);
+static herr_t H5S__none_serialize(H5S_t *space, uint8_t **p);
static herr_t H5S__none_deserialize(H5S_t **space, const uint8_t **p);
static herr_t H5S__none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S__none_offset(const H5S_t *space, hsize_t *off);
static int H5S__none_unlim_dim(const H5S_t *space);
static htri_t H5S__none_is_contiguous(const H5S_t *space);
static htri_t H5S__none_is_single(const H5S_t *space);
-static htri_t H5S__none_is_regular(const H5S_t *space);
-static htri_t H5S__none_shape_same(const H5S_t *space1, const H5S_t *space2);
-static htri_t H5S__none_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end);
+static htri_t H5S__none_is_regular(H5S_t *space);
+static htri_t H5S__none_shape_same(H5S_t *space1, H5S_t *space2);
+static htri_t H5S__none_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end);
static herr_t H5S__none_adjust_u(H5S_t *space, const hsize_t *offset);
static herr_t H5S__none_adjust_s(H5S_t *space, const hssize_t *offset);
static herr_t H5S__none_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__none_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
-static herr_t H5S__none_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
+static herr_t H5S__none_iter_init(H5S_t *space, H5S_sel_iter_t *iter);
/* Selection iteration callbacks */
static herr_t H5S__none_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords);
@@ -144,7 +144,7 @@ static const H5S_sel_iter_class_t H5S_sel_iter_none[1] = {{
*-------------------------------------------------------------------------
*/
static herr_t
-H5S__none_iter_init(const H5S_t H5_ATTR_UNUSED *space, H5S_sel_iter_t *iter)
+H5S__none_iter_init(H5S_t H5_ATTR_UNUSED *space, H5S_sel_iter_t *iter)
{
FUNC_ENTER_STATIC_NOERR
@@ -513,7 +513,7 @@ H5S__none_is_valid(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static hssize_t
-H5S__none_serial_size(const H5S_t H5_ATTR_UNUSED *space)
+H5S__none_serial_size(H5S_t H5_ATTR_UNUSED *space)
{
FUNC_ENTER_STATIC_NOERR
@@ -533,7 +533,7 @@ H5S__none_serial_size(const H5S_t H5_ATTR_UNUSED *space)
Serialize the current selection into a user-provided buffer.
USAGE
herr_t H5S__none_serialize(space, p)
- const H5S_t *space; IN: Dataspace with selection to serialize
+ H5S_t *space; IN: Dataspace with selection to serialize
uint8_t **p; OUT: Pointer to buffer to put serialized
selection. Will be advanced to end of
serialized selection.
@@ -548,7 +548,7 @@ H5S__none_serial_size(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S__none_serialize(const H5S_t *space, uint8_t **p)
+H5S__none_serialize(H5S_t *space, uint8_t **p)
{
uint8_t *pp = (*p); /* Local pointer for decoding */
@@ -803,7 +803,7 @@ H5S__none_is_single(const H5S_t H5_ATTR_UNUSED *space)
Check if a "none" selection is "regular"
USAGE
htri_t H5S__none_is_regular(space)
- const H5S_t *space; IN: Dataspace pointer to check
+ H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
DESCRIPTION
@@ -816,7 +816,7 @@ H5S__none_is_single(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__none_is_regular(const H5S_t H5_ATTR_UNUSED *space)
+H5S__none_is_regular(H5S_t H5_ATTR_UNUSED *space)
{
FUNC_ENTER_STATIC_NOERR
@@ -833,8 +833,8 @@ H5S__none_is_regular(const H5S_t H5_ATTR_UNUSED *space)
Check if a two "none" selections are the same shape
USAGE
htri_t H5S__none_shape_same(space1, space2)
- const H5S_t *space1; IN: First dataspace to check
- const H5S_t *space2; IN: Second dataspace to check
+ H5S_t *space1; IN: First dataspace to check
+ H5S_t *space2; IN: Second dataspace to check
RETURNS
TRUE / FALSE / FAIL
DESCRIPTION
@@ -846,7 +846,7 @@ H5S__none_is_regular(const H5S_t H5_ATTR_UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__none_shape_same(const H5S_t H5_ATTR_UNUSED *space1, const H5S_t H5_ATTR_UNUSED *space2)
+H5S__none_shape_same(H5S_t H5_ATTR_UNUSED *space1, H5S_t H5_ATTR_UNUSED *space2)
{
FUNC_ENTER_STATIC_NOERR
@@ -864,7 +864,7 @@ H5S__none_shape_same(const H5S_t H5_ATTR_UNUSED *space1, const H5S_t H5_ATTR_UNU
Detect intersections of selection with block
USAGE
htri_t H5S__none_intersect_block(space, start, end)
- const H5S_t *space; IN: Dataspace with selection to use
+ H5S_t *space; IN: Dataspace with selection to use
const hsize_t *start; IN: Starting coordinate for block
const hsize_t *end; IN: Ending coordinate for block
RETURNS
@@ -877,7 +877,7 @@ H5S__none_shape_same(const H5S_t H5_ATTR_UNUSED *space1, const H5S_t H5_ATTR_UNU
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S__none_intersect_block(const H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *start,
+H5S__none_intersect_block(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *start,
const hsize_t H5_ATTR_UNUSED *end)
{
FUNC_ENTER_STATIC_NOERR
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index c89b616..afabf25 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -201,7 +201,7 @@ struct H5S_hyper_span_info_t {
typedef enum {
H5S_DIMINFO_VALID_IMPOSSIBLE, /* 0: diminfo is not valid and can never be valid with the current selection
*/
- H5S_DIMINFO_VALID_NO, /* 1: diminfo is not valid but may or may not be possible to constuct */
+ H5S_DIMINFO_VALID_NO, /* 1: diminfo is not valid but may or may not be possible to construct */
H5S_DIMINFO_VALID_YES /* 2: diminfo is valid */
} H5S_diminfo_valid_t;
@@ -242,9 +242,9 @@ typedef herr_t (*H5S_sel_release_func_t)(H5S_t *space);
/* Method to determine if current selection is valid for dataspace */
typedef htri_t (*H5S_sel_is_valid_func_t)(const H5S_t *space);
/* Method to determine number of bytes required to store current selection */
-typedef hssize_t (*H5S_sel_serial_size_func_t)(const H5S_t *space);
+typedef hssize_t (*H5S_sel_serial_size_func_t)(H5S_t *space);
/* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */
-typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t **p);
+typedef herr_t (*H5S_sel_serialize_func_t)(H5S_t *space, uint8_t **p);
/* Method to create selection from "serialized" form (a byte sequence suitable for storing on disk) */
typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t **space, const uint8_t **p);
/* Method to determine smallest n-D bounding box containing the current selection */
@@ -260,12 +260,11 @@ typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space);
/* Method to determine if current selection is a single block */
typedef htri_t (*H5S_sel_is_single_func_t)(const H5S_t *space);
/* Method to determine if current selection is "regular" */
-typedef htri_t (*H5S_sel_is_regular_func_t)(const H5S_t *space);
+typedef htri_t (*H5S_sel_is_regular_func_t)(H5S_t *space);
/* Method to determine if two dataspaces' selections are the same shape */
-typedef htri_t (*H5S_sel_shape_same_func_t)(const H5S_t *space1, const H5S_t *space2);
+typedef htri_t (*H5S_sel_shape_same_func_t)(H5S_t *space1, H5S_t *space2);
/* Method to determine if selection intersects a block */
-typedef htri_t (*H5S_sel_intersect_block_func_t)(const H5S_t *space, const hsize_t *start,
- const hsize_t *end);
+typedef htri_t (*H5S_sel_intersect_block_func_t)(H5S_t *space, const hsize_t *start, const hsize_t *end);
/* Method to adjust a selection by an offset */
typedef herr_t (*H5S_sel_adjust_u_func_t)(H5S_t *space, const hsize_t *offset);
/* Method to adjust a selection by an offset (signed) */
@@ -275,7 +274,7 @@ typedef herr_t (*H5S_sel_project_scalar)(const H5S_t *space, hsize_t *offset);
/* Method to construct selection projection onto/into simple dataspace */
typedef herr_t (*H5S_sel_project_simple)(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
/* Method to initialize iterator for current selection */
-typedef herr_t (*H5S_sel_iter_init_func_t)(const H5S_t *space, H5S_sel_iter_t *sel_iter);
+typedef herr_t (*H5S_sel_iter_init_func_t)(H5S_t *space, H5S_sel_iter_t *sel_iter);
/* Selection class information */
typedef struct {
@@ -405,9 +404,8 @@ H5_DLL herr_t H5S__extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src,
H5_DLL uint64_t H5S__hyper_get_op_gen(void);
H5_DLL void H5S__hyper_rebuild(H5S_t *space);
H5_DLL herr_t H5S__modify_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2);
-H5_DLL herr_t H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
- const H5S_t *src_intersect_space, H5S_t *proj_space,
- hbool_t share_space);
+H5_DLL herr_t H5S__hyper_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_intersect_space,
+ H5S_t *proj_space, hbool_t share_space);
/* Operations on selection iterators */
H5_DLL herr_t H5S__sel_iter_close_cb(H5S_sel_iter_t *_sel_iter, void **request);
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 5991116..240b722 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -59,22 +59,22 @@ static void H5S__free_pnt_list(H5S_pnt_list_t *pnt_lst);
static herr_t H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
static herr_t H5S__point_release(H5S_t *space);
static htri_t H5S__point_is_valid(const H5S_t *space);
-static hssize_t H5S__point_serial_size(const H5S_t *space);
-static herr_t H5S__point_serialize(const H5S_t *space, uint8_t **p);
+static hssize_t H5S__point_serial_size(H5S_t *space);
+static herr_t H5S__point_serialize(H5S_t *space, uint8_t **p);
static herr_t H5S__point_deserialize(H5S_t **space, const uint8_t **p);
static herr_t H5S__point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S__point_offset(const H5S_t *space, hsize_t *off);
static int H5S__point_unlim_dim(const H5S_t *space);
static htri_t H5S__point_is_contiguous(const H5S_t *space);
static htri_t H5S__point_is_single(const H5S_t *space);
-static htri_t H5S__point_is_regular(const H5S_t *space);
-static htri_t H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2);
-static htri_t H5S__point_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end);
+static htri_t H5S__point_is_regular(H5S_t *space);
+static htri_t H5S__point_shape_same(H5S_t *space1, H5S_t *space2);
+static htri_t H5S__point_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end);
static herr_t H5S__point_adjust_u(H5S_t *space, const hsize_t *offset);
static herr_t H5S__point_adjust_s(H5S_t *space, const hssize_t *offset);
static herr_t H5S__point_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__point_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
-static herr_t H5S__point_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
+static herr_t H5S__point_iter_init(H5S_t *space, H5S_sel_iter_t *iter);
static herr_t H5S__point_get_version_enc_size(const H5S_t *space, uint32_t *version, uint8_t *enc_size);
/* Selection iteration callbacks */
@@ -170,7 +170,7 @@ H5FL_DEFINE_STATIC(H5S_pnt_list_t);
*-------------------------------------------------------------------------
*/
static herr_t
-H5S__point_iter_init(const H5S_t *space, H5S_sel_iter_t *iter)
+H5S__point_iter_init(H5S_t *space, H5S_sel_iter_t *iter)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -1159,7 +1159,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static hssize_t
-H5S__point_serial_size(const H5S_t *space)
+H5S__point_serial_size(H5S_t *space)
{
uint32_t version; /* Version number */
uint8_t enc_size; /* Encoded size of point selection info */
@@ -1204,7 +1204,7 @@ done:
Serialize the current selection into a user-provided buffer.
USAGE
herr_t H5S__point_serialize(space, p)
- const H5S_t *space; IN: Dataspace with selection to serialize
+ H5S_t *space; IN: Dataspace with selection to serialize
uint8_t **p; OUT: Pointer to buffer to put serialized
selection. Will be advanced to end of
serialized selection.
@@ -1219,7 +1219,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S__point_serialize(const H5S_t *space, uint8_t **p)
+H5S__point_serialize(H5S_t *space, uint8_t **p)
{
H5S_pnt_node_t *curr; /* Point information nodes */
uint8_t * pp; /* Local pointer for encoding */
@@ -1505,7 +1505,7 @@ done:
dataspace they are located within. The list of points is formatted as
follows: <coordinate> followed by the next coordinate, etc. until all the
point information in the selection have been put into the user's buffer.
- The points are returned in the order they will be interated through
+ The points are returned in the order they will be iterated through
when a selection is read/written from/to disk.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
@@ -1579,7 +1579,7 @@ H5S__get_select_elem_pointlist(const H5S_t *space, hsize_t startpoint, hsize_t n
dataspace they are located within. The list of points is formatted as
follows: <coordinate> followed by the next coordinate, etc. until all the
point information in the selection have been put into the user's buffer.
- The points are returned in the order they will be interated through
+ The points are returned in the order they will be iterated through
when a selection is read/written from/to disk.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
@@ -1844,7 +1844,7 @@ H5S__point_is_single(const H5S_t *space)
Check if a point selection is "regular"
USAGE
htri_t H5S__point_is_regular(space)
- const H5S_t *space; IN: Dataspace pointer to check
+ H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
DESCRIPTION
@@ -1859,7 +1859,7 @@ H5S__point_is_single(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__point_is_regular(const H5S_t *space)
+H5S__point_is_regular(H5S_t *space)
{
htri_t ret_value = FAIL; /* Return value */
@@ -1884,8 +1884,8 @@ H5S__point_is_regular(const H5S_t *space)
Check if a two "point" selections are the same shape
USAGE
htri_t H5S__point_shape_same(space1, space2)
- const H5S_t *space1; IN: First dataspace to check
- const H5S_t *space2; IN: Second dataspace to check
+ H5S_t *space1; IN: First dataspace to check
+ H5S_t *space2; IN: Second dataspace to check
RETURNS
TRUE / FALSE / FAIL
DESCRIPTION
@@ -1897,7 +1897,7 @@ H5S__point_is_regular(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2)
+H5S__point_shape_same(H5S_t *space1, H5S_t *space2)
{
H5S_pnt_node_t *pnt1, *pnt2; /* Point information nodes */
hssize_t offset[H5S_MAX_RANK]; /* Offset between the selections */
@@ -1990,7 +1990,7 @@ done:
Detect intersections of selection with block
USAGE
htri_t H5S__point_intersect_block(space, start, end)
- const H5S_t *space; IN: Dataspace with selection to use
+ H5S_t *space; IN: Dataspace with selection to use
const hsize_t *start; IN: Starting coordinate for block
const hsize_t *end; IN: Ending coordinate for block
RETURNS
@@ -2003,7 +2003,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S__point_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end)
+H5S__point_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end)
{
H5S_pnt_node_t *pnt; /* Point information node */
htri_t ret_value = FALSE; /* Return value */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 51a98a6..8a14563 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -232,36 +232,35 @@ H5_DLL herr_t H5S_extent_copy(H5S_t *dst, const H5S_t *src);
/* Operations on selections */
H5_DLL herr_t H5S_select_deserialize(H5S_t **space, const uint8_t **p);
H5_DLL H5S_sel_type H5S_get_select_type(const H5S_t *space);
-H5_DLL herr_t H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space,
- const H5S_sel_iter_op_t *op, void *op_data);
-H5_DLL herr_t H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *buf);
-H5_DLL htri_t H5S_select_valid(const H5S_t *space);
-H5_DLL hsize_t H5S_get_select_npoints(const H5S_t *space);
-H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
-H5_DLL herr_t H5S_get_select_offset(const H5S_t *space, hsize_t *offset);
-H5_DLL int H5S_get_select_unlim_dim(const H5S_t *space);
-H5_DLL herr_t H5S_get_select_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim);
-H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset);
-H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
-H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2);
-H5_DLL htri_t H5S_select_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end);
-H5_DLL herr_t H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
- unsigned new_space_rank, const void *buf,
- void const **adj_buf_ptr, hsize_t element_size);
-H5_DLL herr_t H5S_select_release(H5S_t *ds);
-H5_DLL hssize_t H5S_select_serial_size(const H5S_t *space);
-H5_DLL herr_t H5S_select_serialize(const H5S_t *space, uint8_t **p);
-H5_DLL htri_t H5S_select_is_contiguous(const H5S_t *space);
-H5_DLL htri_t H5S_select_is_single(const H5S_t *space);
-H5_DLL htri_t H5S_select_is_regular(const H5S_t *space);
-H5_DLL herr_t H5S_select_adjust_u(H5S_t *space, const hsize_t *offset);
-H5_DLL herr_t H5S_select_adjust_s(H5S_t *space, const hssize_t *offset);
-H5_DLL herr_t H5S_select_project_scalar(const H5S_t *space, hsize_t *offset);
-H5_DLL herr_t H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
-H5_DLL herr_t H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
- const H5S_t *src_intersect_space, H5S_t **new_space_ptr,
- hbool_t share_space);
-H5_DLL herr_t H5S_select_subtract(H5S_t *space, H5S_t *subtract_space);
+H5_DLL herr_t H5S_select_iterate(void *buf, const H5T_t *type, H5S_t *space, const H5S_sel_iter_op_t *op,
+ void *op_data);
+H5_DLL herr_t H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *buf);
+H5_DLL htri_t H5S_select_valid(const H5S_t *space);
+H5_DLL hsize_t H5S_get_select_npoints(const H5S_t *space);
+H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+H5_DLL herr_t H5S_get_select_offset(const H5S_t *space, hsize_t *offset);
+H5_DLL int H5S_get_select_unlim_dim(const H5S_t *space);
+H5_DLL herr_t H5S_get_select_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim);
+H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset);
+H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
+H5_DLL htri_t H5S_select_shape_same(H5S_t *space1, H5S_t *space2);
+H5_DLL htri_t H5S_select_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end);
+H5_DLL herr_t H5S_select_construct_projection(H5S_t *base_space, H5S_t **new_space_ptr,
+ unsigned new_space_rank, const void *buf,
+ void const **adj_buf_ptr, hsize_t element_size);
+H5_DLL herr_t H5S_select_release(H5S_t *ds);
+H5_DLL hssize_t H5S_select_serial_size(H5S_t *space);
+H5_DLL herr_t H5S_select_serialize(H5S_t *space, uint8_t **p);
+H5_DLL htri_t H5S_select_is_contiguous(const H5S_t *space);
+H5_DLL htri_t H5S_select_is_single(const H5S_t *space);
+H5_DLL htri_t H5S_select_is_regular(H5S_t *space);
+H5_DLL herr_t H5S_select_adjust_u(H5S_t *space, const hsize_t *offset);
+H5_DLL herr_t H5S_select_adjust_s(H5S_t *space, const hssize_t *offset);
+H5_DLL herr_t H5S_select_project_scalar(const H5S_t *space, hsize_t *offset);
+H5_DLL herr_t H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
+H5_DLL herr_t H5S_select_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_intersect_space,
+ H5S_t **new_space_ptr, hbool_t share_space);
+H5_DLL herr_t H5S_select_subtract(H5S_t *space, H5S_t *subtract_space);
/* Operations on all selections */
H5_DLL herr_t H5S_select_all(H5S_t *space, hbool_t rel_prev);
@@ -290,8 +289,7 @@ H5_DLL H5S_t * H5S_hyper_get_unlim_block(const H5S_t *space, hsize_t block_index
H5_DLL hsize_t H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, hbool_t *partial);
/* Operations on selection iterators */
-H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size,
- unsigned flags);
+H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, H5S_t *space, size_t elmt_size, unsigned flags);
H5_DLL herr_t H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords);
H5_DLL hsize_t H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter);
H5_DLL herr_t H5S_select_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index 30ca813..536f290 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -171,7 +171,7 @@ H5_DLL herr_t H5Sclose(hid_t space_id);
* composing the entire current extent). If either \p stride or
* \p block is NULL, then it will be set to \p 1.
*
- * \since 1.12.0
+ * \since 1.10.6
*
*/
H5_DLL hid_t H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
@@ -194,7 +194,7 @@ H5_DLL hid_t H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_
* from \p space1_id is copied for the dataspace extent of the
* newly created dataspace.
*
- * \since 1.12.0
+ * \since 1.10.6
*
*/
H5_DLL hid_t H5Scombine_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id);
@@ -795,7 +795,7 @@ H5_DLL htri_t H5Sis_simple(hid_t space_id);
* \p space2_id. The first selection is modified to contain the
* result of \p space1_id operated on by \p space2_id.
*
- * \since 1.12.0
+ * \since 1.10.6
*
*/
H5_DLL herr_t H5Smodify_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id);
@@ -940,7 +940,7 @@ H5_DLL herr_t H5Ssel_iter_reset(hid_t sel_iter_id, hid_t space_id);
*
* \note This can be useful for VOL developers to implement chunked datasets.
*
- * \since 1.12.0
+ * \since 1.10.6
*/
H5_DLL herr_t H5Sselect_adjust(hid_t spaceid, const hssize_t *offset);
/**
@@ -977,7 +977,7 @@ H5_DLL herr_t H5Sselect_all(hid_t spaceid);
* offset) from the source dataspace \p src_id to the destination
* dataspace \p dst_id.
*
- * \since 1.12.0
+ * \since 1.10.6
*
*/
H5_DLL herr_t H5Sselect_copy(hid_t dst_id, hid_t src_id);
@@ -1205,7 +1205,7 @@ H5_DLL herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_
* \note Assumes that \p start & \p end block bounds are inclusive, so
* \p start == \p end value is OK.
*
- * \since 1.12.0
+ * \since 1.10.6
*
*/
H5_DLL htri_t H5Sselect_intersect_block(hid_t space_id, const hsize_t *start, const hsize_t *end);
@@ -1244,7 +1244,7 @@ H5_DLL herr_t H5Sselect_none(hid_t spaceid);
* into a third selection.This can be useful for VOL developers to
* implement chunked or virtual datasets.
*
- * \since 1.12.0
+ * \since 1.10.6
*
*/
H5_DLL hid_t H5Sselect_project_intersection(hid_t src_space_id, hid_t dst_space_id,
@@ -1265,7 +1265,7 @@ H5_DLL hid_t H5Sselect_project_intersection(hid_t src_space_id, hid_t dst_space_
* This is primarily used for reading the entire selection in
* one swoop.
*
- * \since 1.12.0
+ * \since 1.10.6
*
*/
H5_DLL htri_t H5Sselect_shape_same(hid_t space1_id, hid_t space2_id);
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 7a0ea3c..bcf12a0 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -304,7 +304,7 @@ done:
*-------------------------------------------------------------------------
*/
hssize_t
-H5S_select_serial_size(const H5S_t *space)
+H5S_select_serial_size(H5S_t *space)
{
hssize_t ret_value = -1; /* Return value */
@@ -343,7 +343,7 @@ H5S_select_serial_size(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_serialize(const H5S_t *space, uint8_t **p)
+H5S_select_serialize(H5S_t *space, uint8_t **p)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -880,7 +880,7 @@ H5S_select_is_single(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_select_is_regular(const H5S_t *space)
+H5S_select_is_regular(H5S_t *space)
{
herr_t ret_value = FAIL; /* Return value */
@@ -1116,7 +1116,7 @@ H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
in the dataspace's selection.
--------------------------------------------------------------------------*/
herr_t
-H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_size, unsigned flags)
+H5S_select_iter_init(H5S_sel_iter_t *sel_iter, H5S_t *space, size_t elmt_size, unsigned flags)
{
herr_t ret_value = FAIL; /* Return value */
@@ -1497,8 +1497,7 @@ H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
the selection is not modified.
--------------------------------------------------------------------------*/
herr_t
-H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space, const H5S_sel_iter_op_t *op,
- void *op_data)
+H5S_select_iterate(void *buf, const H5T_t *type, H5S_t *space, const H5S_sel_iter_op_t *op, void *op_data)
{
H5S_sel_iter_t *iter = NULL; /* Selection iteration info */
hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
@@ -1739,7 +1738,7 @@ H5S_get_select_type(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
+H5S_select_shape_same(H5S_t *space1, H5S_t *space2)
{
H5S_sel_iter_t *iter_a = NULL; /* Selection a iteration info */
H5S_sel_iter_t *iter_b = NULL; /* Selection b iteration info */
@@ -1760,8 +1759,8 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
/* Check special cases if both dataspaces aren't scalar */
/* (If only one is, the number of selected points check is sufficient) */
if (space1->extent.rank > 0 && space2->extent.rank > 0) {
- const H5S_t *space_a; /* Dataspace with larger rank */
- const H5S_t *space_b; /* Dataspace with smaller rank */
+ H5S_t * space_a; /* Dataspace with larger rank */
+ H5S_t * space_b; /* Dataspace with smaller rank */
unsigned space_a_rank; /* Number of dimensions of dataspace A */
unsigned space_b_rank; /* Number of dimensions of dataspace B */
int space_a_dim; /* Current dimension in dataspace A */
@@ -2063,7 +2062,7 @@ done:
don't call it directly, use the appropriate macro defined in H5Sprivate.h.
--------------------------------------------------------------------------*/
htri_t
-H5S_select_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end)
+H5S_select_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end)
{
htri_t ret_value = TRUE; /* Return value */
@@ -2214,7 +2213,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, unsigned new_space_rank,
+H5S_select_construct_projection(H5S_t *base_space, H5S_t **new_space_ptr, unsigned new_space_rank,
const void *buf, void const **adj_buf_ptr, hsize_t element_size)
{
H5S_t * new_space = NULL; /* New dataspace constructed */
@@ -2247,7 +2246,7 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
if (new_space_rank == 0) {
hssize_t npoints; /* Number of points selected */
- /* Retreve the number of elements selected */
+ /* Retrieve the number of elements selected */
if ((npoints = (hssize_t)H5S_GET_SELECT_NPOINTS(base_space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get number of points selected")
HDassert(npoints <= 1);
@@ -2316,12 +2315,12 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
* true on selections of different rank iff:
*
* 1) the selection in the lower rank dataspace matches that
- * in the dimensions with the fastest changing indicies in
+ * in the dimensions with the fastest changing indices in
* the larger rank dataspace, and
*
* 2) the selection has thickness 1 in all ranks that appear
* only in the higher rank dataspace (i.e. those with
- * more slowly changing indicies).
+ * more slowly changing indices).
*/
if (new_space_rank > base_space_rank) {
hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */
@@ -2452,7 +2451,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf)
+H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *_buf)
{
H5S_sel_iter_t *iter = NULL; /* Selection iteration info */
hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
@@ -2568,9 +2567,8 @@ to share structures inside dst_space with proj_space
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
- const H5S_t *src_intersect_space, H5S_t **new_space_ptr,
- hbool_t share_selection)
+H5S_select_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_intersect_space,
+ H5S_t **new_space_ptr, hbool_t share_selection)
{
H5S_t * new_space = NULL; /* New dataspace constructed */
H5S_t * tmp_src_intersect_space = NULL; /* Temporary SIS converted from points->hyperslabs */
diff --git a/src/H5Stest.c b/src/H5Stest.c
index a851549..6a31f3c 100644
--- a/src/H5Stest.c
+++ b/src/H5Stest.c
@@ -185,12 +185,13 @@ H5S__check_spans_tail_ptr(const H5S_hyper_span_info_t *span_lst)
if (NULL != cur_elem->down)
if ((ret_value = H5S__check_spans_tail_ptr(cur_elem->down)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL,
- "the seletion has inconsistent tail pointers")
+ "the selection has inconsistent tail pointers")
cur_elem = cur_elem->next;
} /* end while */
if (actual_tail != span_lst->tail)
- HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the seletion has inconsistent tail pointers")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL,
+ "the selection has inconsistent tail pointers")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -231,7 +232,8 @@ H5S__check_points_tail_ptr(const H5S_pnt_list_t *pnt_lst)
cur_elem = cur_elem->next;
} /* end while */
if (actual_tail != pnt_lst->tail)
- HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the seletion has inconsistent tail pointers")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL,
+ "the selection has inconsistent tail pointers")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -314,7 +316,7 @@ H5S__check_internal_consistency(const H5S_t *space)
if ((NULL != hslab) && (NULL != hslab->span_lst))
if (H5S__check_spans_tail_ptr(hslab->span_lst) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL,
- "the seletion has inconsistent tail pointers")
+ "the selection has inconsistent tail pointers")
} /* end if */
else if (space->select.type->type == H5S_SEL_POINTS) {
H5S_pnt_list_t *pnt_lst = space->select.sel_info.pnt_lst;
@@ -322,7 +324,7 @@ H5S__check_internal_consistency(const H5S_t *space)
if (NULL != pnt_lst)
if (H5S__check_points_tail_ptr(pnt_lst) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL,
- "the seletion has inconsistent tail pointers")
+ "the selection has inconsistent tail pointers")
} /* end else-if */
done:
diff --git a/src/H5T.c b/src/H5T.c
index 461e6b9..bbe6ce7 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -368,12 +368,9 @@ H5T_order_t H5T_native_order_g = H5T_ORDER_ERROR;
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*
* Predefined data types. These are initialized at runtime in H5Tinit.c and
- * by H5T__init_package() in this source file.
+ * by H5T_init() in this source file.
*
* If more of these are added, the new ones must be added to the list of
* types to reset in H5T_term_package().
@@ -600,34 +597,6 @@ static const H5I_class_t H5I_DATATYPE_CLS[1] = {{
(H5I_free_t)H5T__close_cb /* Callback routine for closing objects of this class */
}};
-/* Flag indicating "top" of interface has been initialized */
-static hbool_t H5T_top_package_initialize_s = FALSE;
-
-/*-------------------------------------------------------------------------
- * Function: H5T_init
- *
- * Purpose: Initialize the interface from some other package.
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Robb Matzke
- * Wednesday, December 16, 1998
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5T_init(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T_init() */
-
/*-------------------------------------------------------------------------
* Function: H5T__init_inf
*
@@ -740,19 +709,17 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__init_inf() */
-/*--------------------------------------------------------------------------
-NAME
- H5T__init_package -- Initialize interface-specific information
-USAGE
- herr__t H5T_init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
-
---------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------
+ * Function: H5T_init
+ *
+ * Purpose: Initialize the interface from some other layer.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5T__init_package(void)
+H5T_init(void)
{
H5T_t * native_schar = NULL; /* Datatype structure for native signed char */
H5T_t * native_uchar = NULL; /* Datatype structure for native unsigned char */
@@ -793,7 +760,7 @@ H5T__init_package(void)
TRUE; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_NOAPI(FAIL)
/* Initialize the ID group for the file IDs */
if (H5I_register_type(H5I_DATATYPE_CLS) < 0)
@@ -1433,7 +1400,7 @@ H5T__init_package(void)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function(s)")
/* Register datatype creation property class properties here. See similar
- * code in H5D__init_package(), etc. for example.
+ * code in H5D_init(), etc. for example.
*/
/* Only register the default property list if it hasn't been created yet */
@@ -1446,9 +1413,6 @@ H5T__init_package(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
} /* end if */
- /* Mark "top" of interface as initialized, too */
- H5T_top_package_initialize_s = TRUE;
-
done:
/* General cleanup */
if (compound != NULL)
@@ -1476,7 +1440,7 @@ done:
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T__init_package() */
+} /* end H5T_init() */
/*-------------------------------------------------------------------------
* Function: H5T__unlock_cb
@@ -1532,183 +1496,177 @@ H5T_top_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5T_top_package_initialize_s) {
- /* Unregister all conversion functions */
- if (H5T_g.path) {
- int i, nprint = 0;
-
- for (i = 0; i < H5T_g.npaths; i++) {
- H5T_path_t *path;
-
- path = H5T_g.path[i];
- HDassert(path);
- if (path->conv.u.app_func) {
- H5T__print_stats(path, &nprint /*in,out*/);
- path->cdata.command = H5T_CONV_FREE;
- if (path->conv.is_app) {
- if ((path->conv.u.app_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0,
- (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
+ /* Unregister all conversion functions */
+ if (H5T_g.path) {
+ int i, nprint = 0;
+
+ for (i = 0; i < H5T_g.npaths; i++) {
+ H5T_path_t *path;
+
+ path = H5T_g.path[i];
+ HDassert(path);
+ if (path->conv.u.app_func) {
+ H5T__print_stats(path, &nprint /*in,out*/);
+ path->cdata.command = H5T_CONV_FREE;
+ if (path->conv.is_app) {
+ if ((path->conv.u.app_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0,
+ (size_t)0, (size_t)0, NULL, NULL, H5CX_get_dxpl()) < 0) {
#ifdef H5T_DEBUG
- if (H5DEBUG(T)) {
- HDfprintf(H5DEBUG(T),
- "H5T: conversion function "
- "0x%08lx failed to free private data for "
- "%s (ignored)\n",
- (unsigned long)(path->conv.u.app_func), path->name);
- } /* end if */
+ if (H5DEBUG(T)) {
+ HDfprintf(H5DEBUG(T),
+ "H5T: conversion function "
+ "0x%08lx failed to free private data for "
+ "%s (ignored)\n",
+ (unsigned long)(path->conv.u.app_func), path->name);
+ } /* end if */
#endif
- H5E_clear_stack(NULL); /*ignore the error*/
- } /* end if */
- } /* end if */
- else {
- if ((path->conv.u.lib_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0,
- (size_t)0, (size_t)0, NULL, NULL) < 0) {
+ H5E_clear_stack(NULL); /*ignore the error*/
+ } /* end if */
+ } /* end if */
+ else {
+ if ((path->conv.u.lib_func)((hid_t)FAIL, (hid_t)FAIL, &(path->cdata), (size_t)0,
+ (size_t)0, (size_t)0, NULL, NULL) < 0) {
#ifdef H5T_DEBUG
- if (H5DEBUG(T)) {
- HDfprintf(H5DEBUG(T),
- "H5T: conversion function "
- "0x%08lx failed to free private data for "
- "%s (ignored)\n",
- (unsigned long)(path->conv.u.lib_func), path->name);
- } /* end if */
+ if (H5DEBUG(T)) {
+ HDfprintf(H5DEBUG(T),
+ "H5T: conversion function "
+ "0x%08lx failed to free private data for "
+ "%s (ignored)\n",
+ (unsigned long)(path->conv.u.lib_func), path->name);
+ } /* end if */
#endif
- H5E_clear_stack(NULL); /*ignore the error*/
- } /* end if */
- } /* end else */
- } /* end if */
-
- if (path->src)
- (void)H5T_close_real(path->src);
- if (path->dst)
- (void)H5T_close_real(path->dst);
- path = H5FL_FREE(H5T_path_t, path);
- H5T_g.path[i] = NULL;
- } /* end for */
-
- /* Clear conversion tables */
- H5T_g.path = (H5T_path_t **)H5MM_xfree(H5T_g.path);
- H5T_g.npaths = 0;
- H5T_g.apaths = 0;
- H5T_g.soft = (H5T_soft_t *)H5MM_xfree(H5T_g.soft);
- H5T_g.nsoft = 0;
- H5T_g.asoft = 0;
+ H5E_clear_stack(NULL); /*ignore the error*/
+ } /* end if */
+ } /* end else */
+ } /* end if */
+
+ if (path->src)
+ (void)H5T_close_real(path->src);
+ if (path->dst)
+ (void)H5T_close_real(path->dst);
+ path = H5FL_FREE(H5T_path_t, path);
+ H5T_g.path[i] = NULL;
+ } /* end for */
- n++;
- } /* end if */
+ /* Clear conversion tables */
+ H5T_g.path = (H5T_path_t **)H5MM_xfree(H5T_g.path);
+ H5T_g.npaths = 0;
+ H5T_g.apaths = 0;
+ H5T_g.soft = (H5T_soft_t *)H5MM_xfree(H5T_g.soft);
+ H5T_g.nsoft = 0;
+ H5T_g.asoft = 0;
- /* Unlock all datatypes, then free them */
- /* note that we are ignoring the return value from H5I_iterate() */
- /* Also note that we are incrementing 'n' in the callback */
- H5I_iterate(H5I_DATATYPE, H5T__unlock_cb, &n, FALSE);
-
- /* Release all datatype IDs */
- if (H5I_nmembers(H5I_DATATYPE) > 0) {
- (void)H5I_clear_type(H5I_DATATYPE, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
-
- /* Reset all the datatype IDs */
- if (H5T_IEEE_F32BE_g > 0) {
- H5T_IEEE_F32BE_g = FAIL;
- H5T_IEEE_F32LE_g = FAIL;
- H5T_IEEE_F64BE_g = FAIL;
- H5T_IEEE_F64LE_g = FAIL;
-
- H5T_STD_I8BE_g = FAIL;
- H5T_STD_I8LE_g = FAIL;
- H5T_STD_I16BE_g = FAIL;
- H5T_STD_I16LE_g = FAIL;
- H5T_STD_I32BE_g = FAIL;
- H5T_STD_I32LE_g = FAIL;
- H5T_STD_I64BE_g = FAIL;
- H5T_STD_I64LE_g = FAIL;
- H5T_STD_U8BE_g = FAIL;
- H5T_STD_U8LE_g = FAIL;
- H5T_STD_U16BE_g = FAIL;
- H5T_STD_U16LE_g = FAIL;
- H5T_STD_U32BE_g = FAIL;
- H5T_STD_U32LE_g = FAIL;
- H5T_STD_U64BE_g = FAIL;
- H5T_STD_U64LE_g = FAIL;
- H5T_STD_B8BE_g = FAIL;
- H5T_STD_B8LE_g = FAIL;
- H5T_STD_B16BE_g = FAIL;
- H5T_STD_B16LE_g = FAIL;
- H5T_STD_B32BE_g = FAIL;
- H5T_STD_B32LE_g = FAIL;
- H5T_STD_B64BE_g = FAIL;
- H5T_STD_B64LE_g = FAIL;
- H5T_STD_REF_OBJ_g = FAIL;
- H5T_STD_REF_DSETREG_g = FAIL;
- H5T_STD_REF_g = FAIL;
-
- H5T_UNIX_D32BE_g = FAIL;
- H5T_UNIX_D32LE_g = FAIL;
- H5T_UNIX_D64BE_g = FAIL;
- H5T_UNIX_D64LE_g = FAIL;
-
- H5T_C_S1_g = FAIL;
-
- H5T_FORTRAN_S1_g = FAIL;
-
- H5T_NATIVE_SCHAR_g = FAIL;
- H5T_NATIVE_UCHAR_g = FAIL;
- H5T_NATIVE_SHORT_g = FAIL;
- H5T_NATIVE_USHORT_g = FAIL;
- H5T_NATIVE_INT_g = FAIL;
- H5T_NATIVE_UINT_g = FAIL;
- H5T_NATIVE_LONG_g = FAIL;
- H5T_NATIVE_ULONG_g = FAIL;
- H5T_NATIVE_LLONG_g = FAIL;
- H5T_NATIVE_ULLONG_g = FAIL;
- H5T_NATIVE_FLOAT_g = FAIL;
- H5T_NATIVE_DOUBLE_g = FAIL;
- H5T_NATIVE_LDOUBLE_g = FAIL;
- H5T_NATIVE_B8_g = FAIL;
- H5T_NATIVE_B16_g = FAIL;
- H5T_NATIVE_B32_g = FAIL;
- H5T_NATIVE_B64_g = FAIL;
- H5T_NATIVE_OPAQUE_g = FAIL;
- H5T_NATIVE_HADDR_g = FAIL;
- H5T_NATIVE_HSIZE_g = FAIL;
- H5T_NATIVE_HSSIZE_g = FAIL;
- H5T_NATIVE_HERR_g = FAIL;
- H5T_NATIVE_HBOOL_g = FAIL;
-
- H5T_NATIVE_INT8_g = FAIL;
- H5T_NATIVE_UINT8_g = FAIL;
- H5T_NATIVE_INT_LEAST8_g = FAIL;
- H5T_NATIVE_UINT_LEAST8_g = FAIL;
- H5T_NATIVE_INT_FAST8_g = FAIL;
- H5T_NATIVE_UINT_FAST8_g = FAIL;
-
- H5T_NATIVE_INT16_g = FAIL;
- H5T_NATIVE_UINT16_g = FAIL;
- H5T_NATIVE_INT_LEAST16_g = FAIL;
- H5T_NATIVE_UINT_LEAST16_g = FAIL;
- H5T_NATIVE_INT_FAST16_g = FAIL;
- H5T_NATIVE_UINT_FAST16_g = FAIL;
-
- H5T_NATIVE_INT32_g = FAIL;
- H5T_NATIVE_UINT32_g = FAIL;
- H5T_NATIVE_INT_LEAST32_g = FAIL;
- H5T_NATIVE_UINT_LEAST32_g = FAIL;
- H5T_NATIVE_INT_FAST32_g = FAIL;
- H5T_NATIVE_UINT_FAST32_g = FAIL;
-
- H5T_NATIVE_INT64_g = FAIL;
- H5T_NATIVE_UINT64_g = FAIL;
- H5T_NATIVE_INT_LEAST64_g = FAIL;
- H5T_NATIVE_UINT_LEAST64_g = FAIL;
- H5T_NATIVE_INT_FAST64_g = FAIL;
- H5T_NATIVE_UINT_FAST64_g = FAIL;
-
- n++;
- } /* end if */
+ n++;
+ } /* end if */
- /* Mark "top" of interface as closed */
- if (0 == n)
- H5T_top_package_initialize_s = FALSE;
+ /* Unlock all datatypes, then free them */
+ /* note that we are ignoring the return value from H5I_iterate() */
+ /* Also note that we are incrementing 'n' in the callback */
+ H5I_iterate(H5I_DATATYPE, H5T__unlock_cb, &n, FALSE);
+
+ /* Release all datatype IDs */
+ if (H5I_nmembers(H5I_DATATYPE) > 0) {
+ (void)H5I_clear_type(H5I_DATATYPE, FALSE, FALSE);
+ n++; /*H5I*/
+ } /* end if */
+
+ /* Reset all the datatype IDs */
+ if (H5T_IEEE_F32BE_g > 0) {
+ H5T_IEEE_F32BE_g = FAIL;
+ H5T_IEEE_F32LE_g = FAIL;
+ H5T_IEEE_F64BE_g = FAIL;
+ H5T_IEEE_F64LE_g = FAIL;
+
+ H5T_STD_I8BE_g = FAIL;
+ H5T_STD_I8LE_g = FAIL;
+ H5T_STD_I16BE_g = FAIL;
+ H5T_STD_I16LE_g = FAIL;
+ H5T_STD_I32BE_g = FAIL;
+ H5T_STD_I32LE_g = FAIL;
+ H5T_STD_I64BE_g = FAIL;
+ H5T_STD_I64LE_g = FAIL;
+ H5T_STD_U8BE_g = FAIL;
+ H5T_STD_U8LE_g = FAIL;
+ H5T_STD_U16BE_g = FAIL;
+ H5T_STD_U16LE_g = FAIL;
+ H5T_STD_U32BE_g = FAIL;
+ H5T_STD_U32LE_g = FAIL;
+ H5T_STD_U64BE_g = FAIL;
+ H5T_STD_U64LE_g = FAIL;
+ H5T_STD_B8BE_g = FAIL;
+ H5T_STD_B8LE_g = FAIL;
+ H5T_STD_B16BE_g = FAIL;
+ H5T_STD_B16LE_g = FAIL;
+ H5T_STD_B32BE_g = FAIL;
+ H5T_STD_B32LE_g = FAIL;
+ H5T_STD_B64BE_g = FAIL;
+ H5T_STD_B64LE_g = FAIL;
+ H5T_STD_REF_OBJ_g = FAIL;
+ H5T_STD_REF_DSETREG_g = FAIL;
+ H5T_STD_REF_g = FAIL;
+
+ H5T_UNIX_D32BE_g = FAIL;
+ H5T_UNIX_D32LE_g = FAIL;
+ H5T_UNIX_D64BE_g = FAIL;
+ H5T_UNIX_D64LE_g = FAIL;
+
+ H5T_C_S1_g = FAIL;
+
+ H5T_FORTRAN_S1_g = FAIL;
+
+ H5T_NATIVE_SCHAR_g = FAIL;
+ H5T_NATIVE_UCHAR_g = FAIL;
+ H5T_NATIVE_SHORT_g = FAIL;
+ H5T_NATIVE_USHORT_g = FAIL;
+ H5T_NATIVE_INT_g = FAIL;
+ H5T_NATIVE_UINT_g = FAIL;
+ H5T_NATIVE_LONG_g = FAIL;
+ H5T_NATIVE_ULONG_g = FAIL;
+ H5T_NATIVE_LLONG_g = FAIL;
+ H5T_NATIVE_ULLONG_g = FAIL;
+ H5T_NATIVE_FLOAT_g = FAIL;
+ H5T_NATIVE_DOUBLE_g = FAIL;
+ H5T_NATIVE_LDOUBLE_g = FAIL;
+ H5T_NATIVE_B8_g = FAIL;
+ H5T_NATIVE_B16_g = FAIL;
+ H5T_NATIVE_B32_g = FAIL;
+ H5T_NATIVE_B64_g = FAIL;
+ H5T_NATIVE_OPAQUE_g = FAIL;
+ H5T_NATIVE_HADDR_g = FAIL;
+ H5T_NATIVE_HSIZE_g = FAIL;
+ H5T_NATIVE_HSSIZE_g = FAIL;
+ H5T_NATIVE_HERR_g = FAIL;
+ H5T_NATIVE_HBOOL_g = FAIL;
+
+ H5T_NATIVE_INT8_g = FAIL;
+ H5T_NATIVE_UINT8_g = FAIL;
+ H5T_NATIVE_INT_LEAST8_g = FAIL;
+ H5T_NATIVE_UINT_LEAST8_g = FAIL;
+ H5T_NATIVE_INT_FAST8_g = FAIL;
+ H5T_NATIVE_UINT_FAST8_g = FAIL;
+
+ H5T_NATIVE_INT16_g = FAIL;
+ H5T_NATIVE_UINT16_g = FAIL;
+ H5T_NATIVE_INT_LEAST16_g = FAIL;
+ H5T_NATIVE_UINT_LEAST16_g = FAIL;
+ H5T_NATIVE_INT_FAST16_g = FAIL;
+ H5T_NATIVE_UINT_FAST16_g = FAIL;
+
+ H5T_NATIVE_INT32_g = FAIL;
+ H5T_NATIVE_UINT32_g = FAIL;
+ H5T_NATIVE_INT_LEAST32_g = FAIL;
+ H5T_NATIVE_UINT_LEAST32_g = FAIL;
+ H5T_NATIVE_INT_FAST32_g = FAIL;
+ H5T_NATIVE_UINT_FAST32_g = FAIL;
+
+ H5T_NATIVE_INT64_g = FAIL;
+ H5T_NATIVE_UINT64_g = FAIL;
+ H5T_NATIVE_INT_LEAST64_g = FAIL;
+ H5T_NATIVE_UINT_LEAST64_g = FAIL;
+ H5T_NATIVE_INT_FAST64_g = FAIL;
+ H5T_NATIVE_UINT_FAST64_g = FAIL;
+
+ n++;
} /* end if */
FUNC_LEAVE_NOAPI(n)
@@ -1739,18 +1697,11 @@ H5T_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- /* Sanity check */
- HDassert(0 == H5I_nmembers(H5I_DATATYPE));
- HDassert(FALSE == H5T_top_package_initialize_s);
-
- /* Destroy the datatype object id group */
- n += (H5I_dec_type_ref(H5I_DATATYPE) > 0);
+ /* Sanity check */
+ HDassert(0 == H5I_nmembers(H5I_DATATYPE));
- /* Mark interface as closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
+ /* Destroy the datatype object id group */
+ n += (H5I_dec_type_ref(H5I_DATATYPE) > 0);
FUNC_LEAVE_NOAPI(n)
} /* end H5T_term_package() */
@@ -2170,7 +2121,7 @@ H5T_get_class(const H5T_t *dt, htri_t internal)
{
H5T_class_t ret_value = H5T_NO_CLASS; /* Return value */
- FUNC_ENTER_NOAPI(H5T_NO_CLASS)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(dt);
@@ -2185,7 +2136,6 @@ H5T_get_class(const H5T_t *dt, htri_t internal)
ret_value = dt->shared->type;
}
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_get_class() */
@@ -2243,7 +2193,7 @@ H5T_detect_class(const H5T_t *dt, H5T_class_t cls, hbool_t from_api)
unsigned i;
htri_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(dt);
HDassert(cls > H5T_NO_CLASS && cls < H5T_NCLASSES);
@@ -4276,7 +4226,7 @@ done:
*
* Return: Success: non-negative
*
- * Failure: nagative
+ * Failure: negative
*
* Programmer: Robb Matzke
* Tuesday, December 22, 1998
@@ -5626,14 +5576,13 @@ H5T_is_immutable(const H5T_t *dt)
{
htri_t ret_value = FALSE;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(dt);
if (dt->shared->state == H5T_STATE_IMMUTABLE)
ret_value = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5651,7 +5600,7 @@ H5T_is_named(const H5T_t *dt)
{
htri_t ret_value = FALSE;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(dt);
@@ -5660,7 +5609,6 @@ H5T_is_named(const H5T_t *dt)
else
ret_value = (H5T_STATE_OPEN == dt->shared->state || H5T_STATE_NAMED == dt->shared->state);
-done:
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5738,14 +5686,13 @@ H5T_get_ref_type(const H5T_t *dt)
{
H5R_type_t ret_value = H5R_BADTYPE;
- FUNC_ENTER_NOAPI(H5R_BADTYPE)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(dt);
if (dt->shared->type == H5T_REFERENCE)
ret_value = dt->shared->u.atomic.u.r.rtype;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_get_ref_type() */
@@ -5768,7 +5715,7 @@ H5T_is_sensible(const H5T_t *dt)
{
htri_t ret_value = FAIL; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(dt);
@@ -5806,7 +5753,6 @@ H5T_is_sensible(const H5T_t *dt)
break;
} /* end switch */
-done:
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -5999,7 +5945,7 @@ H5T_is_relocatable(const H5T_t *dt)
{
htri_t ret_value = FALSE;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
HDassert(dt);
@@ -6008,7 +5954,6 @@ H5T_is_relocatable(const H5T_t *dt)
if (H5T_detect_class(dt, H5T_VLEN, FALSE) || H5T_detect_class(dt, H5T_REFERENCE, FALSE))
ret_value = TRUE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_is_relocatable() */
@@ -6099,7 +6044,7 @@ H5T_is_vl_storage(const H5T_t *dt)
{
htri_t ret_value = FALSE;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
HDassert(dt);
@@ -6112,7 +6057,6 @@ H5T_is_vl_storage(const H5T_t *dt)
else
ret_value = FALSE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_is_vl_storage() */
@@ -6266,7 +6210,7 @@ H5T_patch_file(H5T_t *dt, H5F_t *f)
{
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity check */
HDassert(dt);
@@ -6277,7 +6221,6 @@ H5T_patch_file(H5T_t *dt, H5F_t *f)
dt->sh_loc.file = f;
} /* end if */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_patch_file() */
diff --git a/src/H5TS.c b/src/H5TS.c
index 258c9df..37fd66a 100644
--- a/src/H5TS.c
+++ b/src/H5TS.c
@@ -43,7 +43,7 @@
/* Local Typedefs */
/******************/
-/* Cancelability structure */
+/* Cancellability structure */
typedef struct H5TS_cancel_struct {
int previous_state;
unsigned int cancel_count;
@@ -192,10 +192,10 @@ H5TS_tid_destructor(void *_v)
return;
/* TBD use an atomic CAS */
- HDpthread_mutex_lock(&H5TS_tid_mtx);
+ pthread_mutex_lock(&H5TS_tid_mtx);
tid->next = H5TS_tid_next_free;
H5TS_tid_next_free = tid;
- HDpthread_mutex_unlock(&H5TS_tid_mtx);
+ pthread_mutex_unlock(&H5TS_tid_mtx);
}
/*--------------------------------------------------------------------------
@@ -215,8 +215,8 @@ H5TS_tid_destructor(void *_v)
static void
H5TS_tid_init(void)
{
- HDpthread_mutex_init(&H5TS_tid_mtx, NULL);
- HDpthread_key_create(&H5TS_tid_key, H5TS_tid_destructor);
+ pthread_mutex_init(&H5TS_tid_mtx, NULL);
+ pthread_key_create(&H5TS_tid_key, H5TS_tid_destructor);
}
/*--------------------------------------------------------------------------
@@ -246,7 +246,7 @@ H5TS_tid_init(void)
uint64_t
H5TS_thread_id(void)
{
- H5TS_tid_t *tid = HDpthread_getspecific(H5TS_tid_key);
+ H5TS_tid_t *tid = pthread_getspecific(H5TS_tid_key);
H5TS_tid_t proto_tid;
/* An ID is already assigned. */
@@ -260,14 +260,14 @@ H5TS_thread_id(void)
* point `tid` at `proto_tid` if we need to allocate some
* memory.
*/
- HDpthread_mutex_lock(&H5TS_tid_mtx);
+ pthread_mutex_lock(&H5TS_tid_mtx);
if ((tid = H5TS_tid_next_free) != NULL)
H5TS_tid_next_free = tid->next;
else if (H5TS_tid_next_id != UINT64_MAX) {
tid = &proto_tid;
tid->id = ++H5TS_tid_next_id;
}
- HDpthread_mutex_unlock(&H5TS_tid_mtx);
+ pthread_mutex_unlock(&H5TS_tid_mtx);
/* If a prototype ID record was established, copy it to the heap. */
if (tid == &proto_tid)
@@ -281,7 +281,7 @@ H5TS_thread_id(void)
* to it.
*/
tid->next = NULL;
- if (HDpthread_setspecific(H5TS_tid_key, tid) != 0) {
+ if (pthread_setspecific(H5TS_tid_key, tid) != 0) {
H5TS_tid_destructor(tid);
return 0;
}
@@ -323,29 +323,29 @@ H5TS_pthread_first_thread_init(void)
#endif
/* initialize global API mutex lock */
- HDpthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL);
- HDpthread_cond_init(&H5_g.init_lock.cond_var, NULL);
+ pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL);
+ pthread_cond_init(&H5_g.init_lock.cond_var, NULL);
H5_g.init_lock.lock_count = 0;
- HDpthread_mutex_init(&H5_g.init_lock.atomic_lock2, NULL);
+ pthread_mutex_init(&H5_g.init_lock.atomic_lock2, NULL);
H5_g.init_lock.attempt_lock_count = 0;
/* Initialize integer thread identifiers. */
H5TS_tid_init();
/* initialize key for thread-specific error stacks */
- HDpthread_key_create(&H5TS_errstk_key_g, H5TS__key_destructor);
+ pthread_key_create(&H5TS_errstk_key_g, H5TS__key_destructor);
#ifdef H5_HAVE_CODESTACK
/* initialize key for thread-specific function stacks */
- HDpthread_key_create(&H5TS_funcstk_key_g, H5TS__key_destructor);
+ pthread_key_create(&H5TS_funcstk_key_g, H5TS__key_destructor);
#endif /* H5_HAVE_CODESTACK */
/* initialize key for thread-specific API contexts */
- HDpthread_key_create(&H5TS_apictx_key_g, H5TS__key_destructor);
+ pthread_key_create(&H5TS_apictx_key_g, H5TS__key_destructor);
/* initialize key for thread cancellability mechanism */
- HDpthread_key_create(&H5TS_cancel_key_s, H5TS__key_destructor);
+ pthread_key_create(&H5TS_cancel_key_s, H5TS__key_destructor);
FUNC_LEAVE_NOAPI_VOID_NAMECHECK_ONLY
} /* end H5TS_pthread_first_thread_init() */
@@ -380,13 +380,13 @@ H5TS__mutex_acquire(H5TS_mutex_t *mutex, unsigned int lock_count, hbool_t *acqui
*acquired = TRUE;
#else /* H5_HAVE_WIN_THREADS */
/* Attempt to acquire the mutex lock */
- if (0 == HDpthread_mutex_lock(&mutex->atomic_lock)) {
- pthread_t my_thread_id = HDpthread_self();
+ if (0 == pthread_mutex_lock(&mutex->atomic_lock)) {
+ pthread_t my_thread_id = pthread_self();
/* Check if locked already */
if (mutex->lock_count) {
/* Check for this thread already owning the lock */
- if (HDpthread_equal(my_thread_id, mutex->owner_thread)) {
+ if (pthread_equal(my_thread_id, mutex->owner_thread)) {
/* Already owned by self - increment count */
mutex->lock_count += lock_count;
*acquired = TRUE;
@@ -401,7 +401,7 @@ H5TS__mutex_acquire(H5TS_mutex_t *mutex, unsigned int lock_count, hbool_t *acqui
*acquired = TRUE;
} /* end else */
- if (0 != HDpthread_mutex_unlock(&mutex->atomic_lock))
+ if (0 != pthread_mutex_unlock(&mutex->atomic_lock))
ret_value = -1;
} /* end if */
else
@@ -463,35 +463,35 @@ herr_t H5TS_mutex_lock(H5TS_mutex_t *mutex)
EnterCriticalSection(&mutex->CriticalSection);
#else /* H5_HAVE_WIN_THREADS */
/* Acquire the "attempt" lock, increment the attempt lock count, release the lock */
- ret_value = HDpthread_mutex_lock(&mutex->atomic_lock2);
+ ret_value = pthread_mutex_lock(&mutex->atomic_lock2);
if (ret_value)
HGOTO_DONE(ret_value);
mutex->attempt_lock_count++;
- ret_value = HDpthread_mutex_unlock(&mutex->atomic_lock2);
+ ret_value = pthread_mutex_unlock(&mutex->atomic_lock2);
if (ret_value)
HGOTO_DONE(ret_value);
/* Acquire the library lock */
- ret_value = HDpthread_mutex_lock(&mutex->atomic_lock);
+ ret_value = pthread_mutex_lock(&mutex->atomic_lock);
if (ret_value)
HGOTO_DONE(ret_value);
/* Check if this thread already owns the lock */
- if (mutex->lock_count && HDpthread_equal(HDpthread_self(), mutex->owner_thread))
+ if (mutex->lock_count && pthread_equal(pthread_self(), mutex->owner_thread))
/* already owned by self - increment count */
mutex->lock_count++;
else {
/* Wait until the lock is released by current owner thread */
while (mutex->lock_count)
- HDpthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock);
+ pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock);
/* After we've received the signal, take ownership of the mutex */
- mutex->owner_thread = HDpthread_self();
+ mutex->owner_thread = pthread_self();
mutex->lock_count = 1;
} /* end else */
/* Release the library lock */
- ret_value = HDpthread_mutex_unlock(&mutex->atomic_lock);
+ ret_value = pthread_mutex_unlock(&mutex->atomic_lock);
done:
#endif /* H5_HAVE_WIN_THREADS */
@@ -530,12 +530,12 @@ H5TS__mutex_unlock(H5TS_mutex_t *mutex, unsigned int *lock_count)
#else /* H5_HAVE_WIN_THREADS */
/* Reset the lock count for this thread */
- ret_value = HDpthread_mutex_lock(&mutex->atomic_lock);
+ ret_value = pthread_mutex_lock(&mutex->atomic_lock);
if (ret_value)
HGOTO_DONE(ret_value);
*lock_count = mutex->lock_count;
mutex->lock_count = 0;
- ret_value = HDpthread_mutex_unlock(&mutex->atomic_lock);
+ ret_value = pthread_mutex_unlock(&mutex->atomic_lock);
/* If the lock count drops to zero, signal the condition variable, to
* wake another thread.
@@ -543,7 +543,7 @@ H5TS__mutex_unlock(H5TS_mutex_t *mutex, unsigned int *lock_count)
if (mutex->lock_count == 0) {
int err;
- err = HDpthread_cond_signal(&mutex->cond_var);
+ err = pthread_cond_signal(&mutex->cond_var);
if (err != 0)
ret_value = err;
} /* end if */
@@ -586,11 +586,11 @@ H5TS_mutex_unlock(H5TS_mutex_t *mutex)
#else /* H5_HAVE_WIN_THREADS */
/* Decrement the lock count for this thread */
- ret_value = HDpthread_mutex_lock(&mutex->atomic_lock);
+ ret_value = pthread_mutex_lock(&mutex->atomic_lock);
if (ret_value)
HGOTO_DONE(ret_value);
mutex->lock_count--;
- ret_value = HDpthread_mutex_unlock(&mutex->atomic_lock);
+ ret_value = pthread_mutex_unlock(&mutex->atomic_lock);
/* If the lock count drops to zero, signal the condition variable, to
* wake another thread.
@@ -598,7 +598,7 @@ H5TS_mutex_unlock(H5TS_mutex_t *mutex)
if (mutex->lock_count == 0) {
int err;
- err = HDpthread_cond_signal(&mutex->cond_var);
+ err = pthread_cond_signal(&mutex->cond_var);
if (err != 0)
ret_value = err;
} /* end if */
@@ -630,13 +630,13 @@ H5TSmutex_get_attempt_count(unsigned int *count)
#ifdef H5_HAVE_WIN_THREADS
/* Add Win32 equivalent here when async is supported */
#else /* H5_HAVE_WIN_THREADS */
- ret_value = HDpthread_mutex_lock(&H5_g.init_lock.atomic_lock2);
+ ret_value = pthread_mutex_lock(&H5_g.init_lock.atomic_lock2);
if (ret_value)
HGOTO_DONE(ret_value);
*count = H5_g.init_lock.attempt_lock_count;
- ret_value = HDpthread_mutex_unlock(&H5_g.init_lock.atomic_lock2);
+ ret_value = pthread_mutex_unlock(&H5_g.init_lock.atomic_lock2);
if (ret_value)
HGOTO_DONE(ret_value);
@@ -685,9 +685,9 @@ H5TSmutex_release(unsigned int *lock_count)
* Creates a cancellation counter for a thread if it is the first time
* the thread is entering the library.
*
- * if counter value is zero, then set cancelability type of the thread
+ * if counter value is zero, then set cancellability type of the thread
* to PTHREAD_CANCEL_DISABLE as thread is entering the library and store
- * the previous cancelability type into cancellation counter.
+ * the previous cancellability type into cancellation counter.
* Increase the counter value by 1.
*
* PROGRAMMER: Chee Wai LEE
@@ -725,7 +725,7 @@ H5TS_cancel_count_inc(void)
HGOTO_DONE(FAIL);
/* Set the thread's cancellation counter with the new object */
- ret_value = HDpthread_setspecific(H5TS_cancel_key_s, (void *)cancel_counter);
+ ret_value = pthread_setspecific(H5TS_cancel_key_s, (void *)cancel_counter);
if (ret_value) {
HDfree(cancel_counter);
HGOTO_DONE(FAIL);
@@ -735,7 +735,7 @@ H5TS_cancel_count_inc(void)
/* Check if thread entering library */
if (cancel_counter->cancel_count == 0)
/* Set cancellation state to 'disable', and remember previous state */
- ret_value = HDpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_counter->previous_state);
+ ret_value = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_counter->previous_state);
/* Increment # of times the library API was re-entered, to avoid resetting
* previous cancellation state until the final API routine is returning.
@@ -758,8 +758,8 @@ done:
* 0 on success and a non-zero error code on error.
*
* DESCRIPTION
- * If counter value is one, then set cancelability type of the thread
- * to the previous cancelability type stored in the cancellation counter.
+ * If counter value is one, then set cancellability type of the thread
+ * to the previous cancellability type stored in the cancellation counter.
* (the thread is leaving the library).
*
* Decrement the counter value by 1.
@@ -788,7 +788,7 @@ H5TS_cancel_count_dec(void)
/* Check for leaving last API routine */
if (cancel_counter->cancel_count == 1)
/* Reset to previous thread cancellation state, if last API */
- ret_value = HDpthread_setcancelstate(cancel_counter->previous_state, NULL);
+ ret_value = pthread_setcancelstate(cancel_counter->previous_state, NULL);
/* Decrement cancellation counter */
--cancel_counter->cancel_count;
@@ -995,7 +995,7 @@ H5TS_create_thread(H5TS_thread_cb_t func, H5TS_attr_t *attr, void *udata)
#else /* H5_HAVE_WIN_THREADS */
- HDpthread_create(&ret_value, attr, (void *(*)(void *))func, udata);
+ pthread_create(&ret_value, attr, (void *(*)(void *))func, udata);
#endif /* H5_HAVE_WIN_THREADS */
diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h
index 3150f59..5d69854 100644
--- a/src/H5TSprivate.h
+++ b/src/H5TSprivate.h
@@ -13,11 +13,9 @@
/*-------------------------------------------------------------------------
*
- * Created: H5TSprivate.h
- * May 2 2000
- * Chee Wai LEE
+ * Created: H5TSprivate.h
*
- * Purpose: Private non-prototype header.
+ * Purpose: Thread-safety abstractions used by the library
*
*-------------------------------------------------------------------------
*/
diff --git a/src/H5Tbit.c b/src/H5Tbit.c
index 04e2a97..20f3855 100644
--- a/src/H5Tbit.c
+++ b/src/H5Tbit.c
@@ -228,7 +228,7 @@ done:
* Purpose: Return a small bit sequence as a number. Bit vector starts
* at OFFSET and is SIZE bits long.
*
- * Return: The bit sequence interpretted as an unsigned integer
+ * Return: The bit sequence interpreted as an unsigned integer
*
*-------------------------------------------------------------------------
*/
@@ -538,7 +538,7 @@ H5T__bit_inc(uint8_t *buf, size_t start, size_t size)
/*-------------------------------------------------------------------------
* Function: H5T__bit_dec
*
- * Purpose: Decrement part of a bit field by substracting 1. The bit
+ * Purpose: Decrement part of a bit field by subtracting 1. The bit
* field starts with bit position START and is SIZE bits long.
*
* Return: The "borrow-in" value. It's TRUE if underflows, FALSE
@@ -564,9 +564,9 @@ H5T__bit_dec(uint8_t *buf, size_t start, size_t size)
if ((size + start - 1) / 8 > idx) {
/* The bit sequence doesn't end in the same byte as starts */
- /* Example: a sequence like 11000100 and start = 3. We substract 00001000 from
+ /* Example: a sequence like 11000100 and start = 3. We subtract 00001000 from
* it and get 10111100. If a sequence is 00000111, we do right shift for START
- * bits and get 00000000. So we need to borrow from higher byte when we substract
+ * bits and get 00000000. So we need to borrow from higher byte when we subtract
* 00001000.
*/
if (!(buf[idx] >> pos))
@@ -597,7 +597,7 @@ H5T__bit_dec(uint8_t *buf, size_t start, size_t size)
else {
/* The bit sequence ends in the same byte as starts */
- /* Example: a sequence like 11000100 and pos=3, size=3. We substract 00001000
+ /* Example: a sequence like 11000100 and pos=3, size=3. We subtract 00001000
* and get 10111100. A bit is borrowed from 6th bit(buf[idx]>>6=00000010, tmp>>6=00000011,
* not equal). We need to put this bit back by increment 1000000.
*/
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index d079e71..a3a1aa0 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -1127,7 +1127,7 @@ H5T_open(const H5G_loc_t *loc)
done:
if (ret_value == NULL) {
if (dt) {
- if (shared_fo == NULL) { /* Need to free shared fo */
+ if (shared_fo == NULL) { /* Need to free shared file object */
if (dt->shared->owned_vol_obj && H5VL_free_object(dt->shared->owned_vol_obj) < 0)
HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object")
dt->shared = H5FL_FREE(H5T_shared_t, dt->shared);
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index c06c895..5efff10 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -2753,7 +2753,7 @@ H5T__conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
HDassert(domain[1] >= domain[0]);
length = (unsigned)(domain[1] - domain[0]) + 1;
if (src->shared->u.enumer.nmembs < 2 ||
- (double)length / src->shared->u.enumer.nmembs < (double)(1.2f)) {
+ (double)length / src->shared->u.enumer.nmembs < (double)(1.2F)) {
priv->base = domain[0];
priv->length = length;
if (NULL == (map = (int *)H5MM_malloc(length * sizeof(int))))
@@ -3205,14 +3205,14 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, si
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy src type for conversion")
/* References need to know about the src file */
if (tsrc_cpy->shared->type == H5T_REFERENCE)
- if (H5T_set_loc(tsrc_cpy, src->shared->u.vlen.file, H5T_LOC_MEMORY) < 0)
+ if (H5T_set_loc(tsrc_cpy, src->shared->u.vlen.file, src->shared->u.vlen.loc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location");
if (NULL == (tdst_cpy = H5T_copy(dst->shared->parent, H5T_COPY_ALL)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy dst type for conversion")
/* References need to know about the dst file */
if (tdst_cpy->shared->type == H5T_REFERENCE)
- if (H5T_set_loc(tdst_cpy, dst->shared->u.vlen.file, H5T_LOC_MEMORY) < 0)
+ if (H5T_set_loc(tdst_cpy, dst->shared->u.vlen.file, dst->shared->u.vlen.loc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set datatype location");
if (((tsrc_id = H5I_register(H5I_DATATYPE, tsrc_cpy, FALSE)) < 0) ||
@@ -4867,7 +4867,7 @@ H5T__conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
size_t olap; /*num overlapping elements */
size_t nchars = 0; /*number of characters copied */
uint8_t *s, *sp, *d, *dp; /*src and dst traversal pointers*/
- uint8_t *dbuf = NULL; /*temp buf for overlap convers. */
+ uint8_t *dbuf = NULL; /*temp buf for overlap converts. */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -7145,7 +7145,7 @@ H5T__conv_schar_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7205,7 +7205,7 @@ H5T__conv_uchar_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7265,7 +7265,7 @@ H5T__conv_short_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7325,7 +7325,7 @@ H5T__conv_ushort_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7385,7 +7385,7 @@ H5T__conv_int_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7445,7 +7445,7 @@ H5T__conv_uint_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7505,7 +7505,7 @@ H5T__conv_long_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7565,7 +7565,7 @@ H5T__conv_ulong_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7625,7 +7625,7 @@ H5T__conv_llong_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7687,7 +7687,7 @@ H5T__conv_ullong_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7797,7 +7797,7 @@ H5T__conv_double_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7819,7 +7819,7 @@ H5T__conv_ldouble_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7929,7 +7929,7 @@ H5T__conv_double_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -7951,7 +7951,7 @@ H5T__conv_ldouble_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -8061,7 +8061,7 @@ H5T__conv_double_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -8083,7 +8083,7 @@ H5T__conv_ldouble_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -8193,7 +8193,7 @@ H5T__conv_double_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -8215,7 +8215,7 @@ H5T__conv_ldouble_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -8325,7 +8325,7 @@ H5T__conv_double_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
@@ -8349,7 +8349,7 @@ H5T__conv_ldouble_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n
* Return: Non-negative on success/Negative on failure
*
* Programmer: Raymond Lu
- * Tuesday, Febuary 1, 2005
+ * Tuesday, February 1, 2005
*
*-------------------------------------------------------------------------
*/
diff --git a/src/H5Tfields.c b/src/H5Tfields.c
index baeae6d..68bc0a3 100644
--- a/src/H5Tfields.c
+++ b/src/H5Tfields.c
@@ -12,7 +12,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Module Info: This module contains commond functionality for fields in
+ * Module Info: This module contains command functionality for fields in
* enumerated & compound datatypes in the H5T interface.
*/
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index c9a2907..e6fab51 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -43,7 +43,7 @@ static herr_t H5T__cmp_offset(size_t *comp_size, size_t *offset, size_t elem_siz
*
* Purpose: High-level API to return the native type of a datatype.
* The native type is chosen by matching the size and class of
- * querried datatype from the following native premitive
+ * queried datatype from the following native primitive
* datatypes:
* H5T_NATIVE_CHAR H5T_NATIVE_UCHAR
* H5T_NATIVE_SHORT H5T_NATIVE_USHORT
@@ -56,7 +56,7 @@ static herr_t H5T__cmp_offset(size_t *comp_size, size_t *offset, size_t elem_siz
* H5T_NATIVE_LDOUBLE
*
* Compound, array, enum, and VL types all choose among these
- * types for theire members. Time, Bifield, Opaque, Reference
+ * types for their members. Time, Bitfield, Opaque, Reference
* types are only copy out.
*
* Return: Success: Returns the native data type if successful.
@@ -696,7 +696,7 @@ H5_GCC_DIAG_OFF("duplicated-branches")
/*-------------------------------------------------------------------------
* Function: H5T__get_native_float
*
- * Purpose: Returns the native floatt type of a datatype.
+ * Purpose: Returns the native float type of a datatype.
*
* Return: Success: Returns the native data type if successful.
*
diff --git a/src/H5Topaque.c b/src/H5Topaque.c
index f097fca..c5c2788 100644
--- a/src/H5Topaque.c
+++ b/src/H5Topaque.c
@@ -70,7 +70,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Tget_tag
*
- * Purpose: Get tha tag associated with an opaque datatype.
+ * Purpose: Get the tag associated with an opaque datatype.
*
* Return: A pointer to an allocated string. The caller should free
* the string. NULL is returned for errors.
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 19593dd..4062cbe 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -123,7 +123,7 @@
#endif
/* Define an internal macro for converting unsigned long long to long double. SGI compilers give
- * some incorect conversion. 64-bit Solaris does different rounding. Windows Visual Studio 6 does
+ * some incorrect conversion. 64-bit Solaris does different rounding. Windows Visual Studio 6 does
* not support unsigned long long. For FreeBSD(sleipnir), the last 2 bytes of mantissa are lost when
* compiler tries to do the conversion. For Cygwin, compiler doesn't do rounding correctly.
* Mac OS 10.4 gives some incorrect result. */
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 911efdf..3df7ca2 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -148,7 +148,7 @@ typedef enum H5T_pad_t {
H5T_PAD_ONE = 1, /**< always set to one */
H5T_PAD_BACKGROUND = 2, /**< set to background value */
- H5T_NPAD = 3 /**< sentinal: THIS MUST BE LAST */
+ H5T_NPAD = 3 /**< sentinel: THIS MUST BE LAST */
} H5T_pad_t;
//! <!-- [H5T_pad_t_snip] -->
@@ -1161,7 +1161,7 @@ H5_DLL herr_t H5Tlock(hid_t type_id);
* the link(s) by which the new committed datatype is accessed and
* the creation of any intermediate groups that may be missing.
*
- * Once commited, this datatype may be used to define the datatype
+ * Once committed, this datatype may be used to define the datatype
* of any other dataset or attribute in the file.
*
* This function will not accept a datatype that cannot actually hold
@@ -1171,7 +1171,7 @@ H5_DLL herr_t H5Tlock(hid_t type_id);
* Committed datatypes are sometimes referred to as named datatypes.
*
* \version 1.8.7 Function modified in this release to reject datatypes that
- * will not accomodate actual data, such as a compound datatype
+ * will not accommodate actual data, such as a compound datatype
* with no fields or an enumerated datatype with no members.
*
* \since 1.8.0
@@ -1266,7 +1266,7 @@ H5_DLL hid_t H5Topen_async(const char *app_file, const char *app_func, unsigned
* fields and enumerated datatypes with no members.
*
* \version 1.8.7 Function modified in this release to reject datatypes that
- * will not accomodate actual data, such as a compound datatype
+ * will not accommodate actual data, such as a compound datatype
* with no fields or an enumerated datatype with no members.
*
* \since 1.2.0
diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c
index fcab19f..0c5c73d 100644
--- a/src/H5VLcallback.c
+++ b/src/H5VLcallback.c
@@ -4967,7 +4967,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5VL__link_copy
*
- * Purpose: Copys a link from src to dst.
+ * Purpose: Copies a link from src to dst.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -4998,7 +4998,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5VL_link_copy
*
- * Purpose: Copys a link from src to dst.
+ * Purpose: Copies a link from src to dst.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -6408,7 +6408,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5VL__request_wait
*
- * Purpose: Waits on an asychronous request through the VOL
+ * Purpose: Waits on an asynchronous request through the VOL
*
* Return: Success: Non-negative
* Failure: Negative
@@ -6442,7 +6442,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5VL_request_wait
*
- * Purpose: Waits on an asychronous request through the VOL
+ * Purpose: Waits on an asynchronous request through the VOL
*
* Return: Success: Non-negative
* Failure: Negative
@@ -6452,18 +6452,28 @@ done:
herr_t
H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t vol_wrapper_set = FALSE;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity checks */
HDassert(vol_obj);
+ /* Set wrapper info in API context */
+ if (H5VL_set_vol_wrapper(vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
/* Call the corresponding internal VOL routine */
if (H5VL__request_wait(vol_obj->data, vol_obj->connector->cls, timeout, status) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request wait failed")
done:
+ /* Reset object wrapping info in API context */
+ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_request_wait() */
@@ -6546,18 +6556,28 @@ done:
herr_t
H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t vol_wrapper_set = FALSE;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
HDassert(vol_obj);
+ /* Set wrapper info in API context */
+ if (H5VL_set_vol_wrapper(vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
/* Call the corresponding internal VOL routine */
if (H5VL__request_notify(vol_obj->data, vol_obj->connector->cls, cb, ctx) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "request notify failed")
done:
+ /* Reset object wrapping info in API context */
+ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_request_notify() */
@@ -6639,18 +6659,28 @@ done:
herr_t
H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t vol_wrapper_set = FALSE;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
HDassert(vol_obj);
+ /* Set wrapper info in API context */
+ if (H5VL_set_vol_wrapper(vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
/* Call the corresponding internal VOL routine */
if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls, status) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed")
done:
+ /* Reset object wrapping info in API context */
+ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_request_cancel() */
@@ -6732,19 +6762,29 @@ done:
herr_t
H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_args_t *args)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t vol_wrapper_set = FALSE;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
HDassert(vol_obj);
+ /* Set wrapper info in API context */
+ if (H5VL_set_vol_wrapper(vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
/* Call the corresponding internal VOL routine */
if (H5VL__request_specific(vol_obj->data, vol_obj->connector->cls, args) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
"unable to execute asynchronous request specific callback")
done:
+ /* Reset object wrapping info in API context */
+ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_request_specific() */
@@ -6827,19 +6867,29 @@ done:
herr_t
H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t vol_wrapper_set = FALSE;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
HDassert(vol_obj);
+ /* Set wrapper info in API context */
+ if (H5VL_set_vol_wrapper(vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
/* Call the corresponding internal VOL routine */
if (H5VL__request_optional(vol_obj->data, vol_obj->connector->cls, args) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
"unable to execute asynchronous request optional callback")
done:
+ /* Reset object wrapping info in API context */
+ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_request_optional() */
@@ -6958,18 +7008,28 @@ done:
herr_t
H5VL_request_free(const H5VL_object_t *vol_obj)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t vol_wrapper_set = FALSE;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
HDassert(vol_obj);
+ /* Set wrapper info in API context */
+ if (H5VL_set_vol_wrapper(vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
/* Call the corresponding VOL callback */
if (H5VL__request_free(vol_obj->data, vol_obj->connector->cls) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request free failed")
done:
+ /* Reset object wrapping info in API context */
+ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_request_free() */
diff --git a/src/H5VLint.c b/src/H5VLint.c
index 70c8112..391bd91 100644
--- a/src/H5VLint.c
+++ b/src/H5VLint.c
@@ -32,6 +32,7 @@
#include "H5CXprivate.h" /* API Contexts */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event sets */
#include "H5Fprivate.h" /* Files */
#include "H5FLprivate.h" /* Free lists */
#include "H5Gprivate.h" /* Groups */
@@ -69,11 +70,7 @@ typedef struct H5VL_wrap_ctx_t {
*/
typedef struct {
/* IN */
- H5VL_get_connector_kind_t kind; /* Which kind of connector search to make */
- union {
- const char * name; /* The name of the VOL connector to check */
- H5VL_class_value_t value; /* The value of the VOL connector to check */
- } u;
+ H5PL_vol_key_t key;
/* OUT */
hid_t found_id; /* The connector ID, if we found a match */
@@ -98,9 +95,6 @@ static herr_t H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -153,7 +147,9 @@ H5VL_init_phase1(void)
FUNC_ENTER_NOAPI(FAIL)
- /* FUNC_ENTER() does all the work */
+ /* Initialize the ID group for the VL IDs */
+ if (H5I_register_type(H5I_VOL_CLS) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize H5VL interface")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -175,23 +171,38 @@ done:
herr_t
H5VL_init_phase2(void)
{
+ size_t i;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
+ /* clang-format off */
+ struct {
+ herr_t (*func)(void);
+ const char *descr;
+ } initializer[] = {
+ {H5T_init, "datatype"}
+ , {H5O_init, "object header"}
+ , {H5D_init, "dataset"}
+ , {H5F_init, "file"}
+ , {H5G_init, "group"}
+ , {H5A_init, "attribute"}
+ , {H5M_init, "map"}
+ , {H5CX_init, "context"}
+ , {H5ES_init, "event set"}
+ , {H5Z_init, "transform"}
+ , {H5R_init, "reference"}
+ };
+
/* Initialize all packages for VOL-managed objects */
- if (H5T_init() < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize datatype interface")
- if (H5D_init() < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize dataset interface")
- if (H5F_init() < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize file interface")
- if (H5G_init() < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize group interface")
- if (H5A_init() < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize attribute interface")
- if (H5M_init() < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize map interface")
+ for (i = 0; i < NELMTS(initializer); i++) {
+ if (initializer[i].func() < 0) {
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL,
+ "unable to initialize %s interface", initializer[i].descr)
+ }
+ }
+
+ /* clang-format on */
/* Sanity check default VOL connector */
HDassert(H5VL_def_conn_s.connector_id == (-1));
@@ -206,32 +217,6 @@ done:
} /* end H5VL_init_phase2() */
/*-------------------------------------------------------------------------
- * Function: H5VL__init_package
- *
- * Purpose: Initialize interface-specific information
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5VL__init_package(void)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
-
- /* Initialize the ID group for the VL IDs */
- if (H5I_register_type(H5I_VOL_CLS) < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize H5VL interface")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5VL__init_package() */
-
-/*-------------------------------------------------------------------------
* Function: H5VL_term_package
*
* Purpose: Terminate various H5VL objects
@@ -249,37 +234,31 @@ H5VL_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- if (H5VL_def_conn_s.connector_id > 0) {
- /* Release the default VOL connector */
- (void)H5VL_conn_free(&H5VL_def_conn_s);
- H5VL_def_conn_s.connector_id = -1;
- H5VL_def_conn_s.connector_info = NULL;
+ if (H5VL_def_conn_s.connector_id > 0) {
+ /* Release the default VOL connector */
+ (void)H5VL_conn_free(&H5VL_def_conn_s);
+ H5VL_def_conn_s.connector_id = -1;
+ H5VL_def_conn_s.connector_info = NULL;
+ n++;
+ } /* end if */
+ else {
+ if (H5I_nmembers(H5I_VOL) > 0) {
+ /* Unregister all VOL connectors */
+ (void)H5I_clear_type(H5I_VOL, TRUE, FALSE);
n++;
} /* end if */
else {
- if (H5I_nmembers(H5I_VOL) > 0) {
- /* Unregister all VOL connectors */
- (void)H5I_clear_type(H5I_VOL, TRUE, FALSE);
+ if (H5VL__num_opt_operation() > 0) {
+ /* Unregister all dynamically registered optional operations */
+ (void)H5VL__term_opt_operation();
n++;
} /* end if */
else {
- if (H5VL__num_opt_operation() > 0) {
- /* Unregister all dynamically registered optional operations */
- (void)H5VL__term_opt_operation();
- n++;
- } /* end if */
- else {
- /* Destroy the VOL connector ID group */
- n += (H5I_dec_type_ref(H5I_VOL) > 0);
-
- /* Mark interface as closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end else */
- } /* end else */
- } /* end else */
- } /* end if */
+ /* Destroy the VOL connector ID group */
+ n += (H5I_dec_type_ref(H5I_VOL) > 0);
+ } /* end else */
+ } /* end else */
+ } /* end else */
FUNC_LEAVE_NOAPI(n)
} /* end H5VL_term_package() */
@@ -341,15 +320,15 @@ H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data)
FUNC_ENTER_STATIC_NOERR
- if (H5VL_GET_CONNECTOR_BY_NAME == op_data->kind) {
- if (0 == HDstrcmp(cls->name, op_data->u.name)) {
+ if (H5VL_GET_CONNECTOR_BY_NAME == op_data->key.kind) {
+ if (0 == HDstrcmp(cls->name, op_data->key.u.name)) {
op_data->found_id = id;
ret_value = H5_ITER_STOP;
} /* end if */
} /* end if */
else {
- HDassert(H5VL_GET_CONNECTOR_BY_VALUE == op_data->kind);
- if (cls->value == op_data->u.value) {
+ HDassert(H5VL_GET_CONNECTOR_BY_VALUE == op_data->key.kind);
+ if (cls->value == op_data->key.u.value) {
op_data->found_id = id;
ret_value = H5_ITER_STOP;
} /* end if */
@@ -398,7 +377,7 @@ H5VL__set_def_conn(void)
} /* end if */
/* Check for environment variable set */
- env_var = HDgetenv("HDF5_VOL_CONNECTOR");
+ env_var = HDgetenv(HDF5_VOL_CONNECTOR);
/* Only parse the string if it's set */
if (env_var && *env_var) {
@@ -976,7 +955,7 @@ H5VL_conn_inc_rc(H5VL_t *connector)
{
int64_t ret_value = -1;
- FUNC_ENTER_NOAPI(-1)
+ FUNC_ENTER_NOAPI_NOERR
/* Check arguments */
HDassert(connector);
@@ -986,7 +965,6 @@ H5VL_conn_inc_rc(H5VL_t *connector)
ret_value = connector->nrefs;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_conn_inc_rc() */
@@ -1299,9 +1277,9 @@ H5VL__register_connector_by_class(const H5VL_class_t *cls, hbool_t app_ref, hid_
"callback is provided")
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = cls->name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = cls->name;
+ op_data.found_id = H5I_INVALID_HID;
/* Check if connector is already registered */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1350,15 +1328,15 @@ H5VL__register_connector_by_name(const char *name, hbool_t app_ref, hid_t vipl_i
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
/* Check if connector is already registered */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, app_ref) < 0)
HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL ids")
- /* If connector alread registered, increment ref count on ID and return ID */
+ /* If connector already registered, increment ref count on ID and return ID */
if (op_data.found_id != H5I_INVALID_HID) {
if (H5I_inc_ref(op_data.found_id, app_ref) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID,
@@ -1410,15 +1388,15 @@ H5VL__register_connector_by_value(H5VL_class_value_t value, hbool_t app_ref, hid
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE;
- op_data.u.value = value;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
/* Check if connector is already registered */
- if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
+ if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, app_ref) < 0)
HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL ids")
- /* If connector alread registered, increment ref count on ID and return ID */
+ /* If connector already registered, increment ref count on ID and return ID */
if (op_data.found_id != H5I_INVALID_HID) {
if (H5I_inc_ref(op_data.found_id, app_ref) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID,
@@ -1449,8 +1427,9 @@ done:
*
* Purpose: Checks if a connector with a particular name is registered.
*
- * Return: Success: 0
- * Failure: -1
+ * Return: >0 if a VOL connector with that name has been registered
+ * 0 if a VOL connector with that name has NOT been registered
+ * <0 on errors
*
* Programmer: Dana Robinson
* June 17, 2017
@@ -1466,9 +1445,9 @@ H5VL__is_connector_registered_by_name(const char *name)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with name */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1488,8 +1467,9 @@ done:
* Purpose: Checks if a connector with a particular value (ID) is
* registered.
*
- * Return: Success: 0
- * Failure: -1
+ * Return: >0 if a VOL connector with that value has been registered
+ * 0 if a VOL connector with that value hasn't been registered
+ * <0 on errors
*
*-------------------------------------------------------------------------
*/
@@ -1502,9 +1482,9 @@ H5VL__is_connector_registered_by_value(H5VL_class_value_t value)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE;
- op_data.u.value = value;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with value */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1635,9 +1615,9 @@ H5VL__peek_connector_id_by_name(const char *name)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_NAME;
- op_data.u.name = name;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_NAME;
+ op_data.key.u.name = name;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with name */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1671,9 +1651,9 @@ H5VL__peek_connector_id_by_value(H5VL_class_value_t value)
FUNC_ENTER_PACKAGE
/* Set up op data for iteration */
- op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE;
- op_data.u.value = value;
- op_data.found_id = H5I_INVALID_HID;
+ op_data.key.kind = H5VL_GET_CONNECTOR_BY_VALUE;
+ op_data.key.u.value = value;
+ op_data.found_id = H5I_INVALID_HID;
/* Find connector with value */
if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0)
@@ -1757,7 +1737,7 @@ H5VL__get_connector_name(hid_t id, char *name /*out*/, size_t size)
len = HDstrlen(cls->name);
if (name) {
- HDstrncpy(name, cls->name, MIN(len + 1, size));
+ HDstrncpy(name, cls->name, size);
if (len >= size)
name[size - 1] = '\0';
} /* end if */
@@ -2006,7 +1986,7 @@ H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_clas
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(cls1);
@@ -2534,7 +2514,7 @@ H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, hbool_t *
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(cls);
@@ -2560,7 +2540,6 @@ H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, hbool_t *
if (*success && cls->version != H5VL_VERSION)
*success = FALSE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_check_plugin_load() */
diff --git a/src/H5VLnative.c b/src/H5VLnative.c
index 18b5b9c..2a86c26 100644
--- a/src/H5VLnative.c
+++ b/src/H5VLnative.c
@@ -224,7 +224,7 @@ H5VL__native_term(void)
* Purpose: Query the connector class.
*
* Note: This routine is in this file so that it can return the address
- * of the staticly declared class struct.
+ * of the statically declared class struct.
*
* Returns: SUCCEED (Can't fail)
*
@@ -251,7 +251,7 @@ H5VL__native_introspect_get_conn_cls(void H5_ATTR_UNUSED *obj, H5VL_get_conn_lvl
* Purpose: Query the capability flags for this connector.
*
* Note: This routine is in this file so that it can return the field
- * from the staticly declared class struct.
+ * from the statically declared class struct.
*
* Returns: SUCCEED (Can't fail)
*
@@ -324,7 +324,7 @@ done:
herr_t
H5VL__native_get_file_addr_len(void *obj, H5I_type_t obj_type, size_t *addr_len)
{
- H5F_t *file = NULL; /* File stuct pointer */
+ H5F_t *file = NULL; /* File struct pointer */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
diff --git a/src/H5VLnative_introspect.c b/src/H5VLnative_introspect.c
index fa11bea..0cc6ee4 100644
--- a/src/H5VLnative_introspect.c
+++ b/src/H5VLnative_introspect.c
@@ -53,7 +53,7 @@
/*******************/
/* Note: H5VL__native_introspect_get_conn_cls and H5VL__native_introspect_get_cap_flags
- * are in src/H5VLnative.c so that they can work with the staticly declared
+ * are in src/H5VLnative.c so that they can work with the statically declared
* class struct.
*/
diff --git a/src/H5VLnative_token.c b/src/H5VLnative_token.c
index bed0164..b5bd7b8 100644
--- a/src/H5VLnative_token.c
+++ b/src/H5VLnative_token.c
@@ -112,7 +112,7 @@ H5VL__native_token_to_str(void *obj, H5I_type_t obj_type, const H5O_token_t *tok
if (NULL == (*token_str = H5MM_malloc(addr_ndigits + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for token string")
- HDsnprintf(*token_str, addr_ndigits + 1, H5_PRINTF_HADDR_FMT, addr);
+ HDsnprintf(*token_str, addr_ndigits + 1, "%" PRIuHADDR, addr);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -139,7 +139,7 @@ H5VL__native_str_to_token(void *obj, H5I_type_t obj_type, const char *token_str,
/* Check parameters */
HDassert(token_str);
- HDsscanf(token_str, H5_PRINTF_HADDR_FMT, &addr);
+ HDsscanf(token_str, "%" PRIuHADDR, &addr);
if (H5VL_native_addr_to_token(obj, obj_type, addr, token) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "can't convert address to object token")
diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c
index 681531e..6eda875 100644
--- a/src/H5VLpassthru.c
+++ b/src/H5VLpassthru.c
@@ -45,7 +45,7 @@
/* Macros */
/**********/
-/* Whether to display log messge when callback is invoked */
+/* Whether to display log message when callback is invoked */
/* (Uncomment to enable) */
/* #define ENABLE_PASSTHRU_LOGGING */
@@ -641,16 +641,13 @@ H5VL_pass_through_info_to_str(const void *_info, char **str)
under_vol_str_len = strlen(under_vol_string);
/* Allocate space for our info */
- *str = (char *)H5allocate_memory(32 + under_vol_str_len, (hbool_t)0);
+ size_t strSize = 32 + under_vol_str_len;
+ *str = (char *)H5allocate_memory(strSize, (hbool_t)0);
assert(*str);
- /* Encode our info
- * Normally we'd use snprintf() here for a little extra safety, but that
- * call had problems on Windows until recently. So, to be as platform-independent
- * as we can, we're using sprintf() instead.
- */
- sprintf(*str, "under_vol=%u;under_info={%s}", (unsigned)under_value,
- (under_vol_string ? under_vol_string : ""));
+ /* Encode our info */
+ snprintf(*str, strSize, "under_vol=%u;under_info={%s}", (unsigned)under_value,
+ (under_vol_string ? under_vol_string : ""));
return 0;
} /* end H5VL_pass_through_info_to_str() */
diff --git a/src/H5VM.c b/src/H5VM.c
index 4d65d75..209ac25 100644
--- a/src/H5VM.c
+++ b/src/H5VM.c
@@ -1244,7 +1244,7 @@ H5VM_chunk_index_scaled(unsigned ndims, const hsize_t *coord, const uint32_t *ch
* Function: H5VM_opvv
*
* Purpose: Perform an operation on a source & destination sequences
- * of offset/length pairs. Each set of sequnces has an array
+ * of offset/length pairs. Each set of sequences has an array
* of lengths, an array of offsets, the maximum number of
* sequences and the current sequence to start at in the sequence.
*
diff --git a/src/H5VMprivate.h b/src/H5VMprivate.h
index 0d3bd0f..e773bae 100644
--- a/src/H5VMprivate.h
+++ b/src/H5VMprivate.h
@@ -393,8 +393,8 @@ static const unsigned char LogTable256[] = {
static inline unsigned H5_ATTR_UNUSED
H5VM_log2_gen(uint64_t n)
{
- unsigned r; /* r will be log2(n) */
- register unsigned int t, tt, ttt; /* temporaries */
+ unsigned r; /* r will be log2(n) */
+ unsigned int t, tt, ttt; /* temporaries */
if ((ttt = (unsigned)(n >> 32)))
if ((tt = (unsigned)(n >> 48)))
diff --git a/src/H5WB.c b/src/H5WB.c
index df7627f..84592bd 100644
--- a/src/H5WB.c
+++ b/src/H5WB.c
@@ -18,7 +18,7 @@
* Quincey Koziol
*
* Purpose: Implements the "wrapped buffer" code for wrapping
- * an existing [staticly sized] buffer, in order to
+ * an existing [statically sized] buffer, in order to
* avoid lots of memory allocation calls.
*
*-------------------------------------------------------------------------
diff --git a/src/H5Z.c b/src/H5Z.c
index ea92a01..763eac2 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -56,9 +56,6 @@ typedef enum {
H5Z_PRELUDE_SET_LOCAL /* Call "set local" callback */
} H5Z_prelude_type_t;
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/* Local variables */
static size_t H5Z_table_alloc_g = 0;
static size_t H5Z_table_used_g = 0;
@@ -74,19 +71,23 @@ static int H5Z__check_unregister_group_cb(void *obj_ptr, hid_t obj_id, void *key
static int H5Z__flush_file_cb(void *obj_ptr, hid_t obj_id, void *key);
/*-------------------------------------------------------------------------
- * Function: H5Z__init_package
+ * Function: H5Z_init
*
- * Purpose: Initializes the data filter layer.
+ * Purpose: Initialize the interface from some other layer.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Success: non-negative
+ * Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
-H5Z__init_package(void)
+H5Z_init(void)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI(FAIL)
+
+ if (H5_TERM_GLOBAL)
+ HGOTO_DONE(SUCCEED)
/* Internal filters */
if (H5Z_register(H5Z_SHUFFLE) < 0)
@@ -111,7 +112,7 @@ H5Z__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5Z__init_package() */
+}
/*-------------------------------------------------------------------------
* Function: H5Z_term_package
@@ -128,76 +129,70 @@ H5Z_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
#ifdef H5Z_DEBUG
- char comment[16], bandwidth[32];
- int dir, nprint = 0;
- size_t i;
-
- if (H5DEBUG(Z)) {
- for (i = 0; i < H5Z_table_used_g; i++) {
- for (dir = 0; dir < 2; dir++) {
- struct {
- char *user;
- char *system;
- char *elapsed;
- } timestrs = {H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.user),
- H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.system),
- H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.elapsed)};
- if (0 == H5Z_stat_table_g[i].stats[dir].total)
- goto next;
-
- if (0 == nprint++) {
- /* Print column headers */
- HDfprintf(H5DEBUG(Z), "H5Z: filter statistics "
- "accumulated over life of library:\n");
- HDfprintf(H5DEBUG(Z), " %-16s %10s %10s %8s %8s %8s %10s\n", "Filter", "Total",
- "Errors", "User", "System", "Elapsed", "Bandwidth");
- HDfprintf(H5DEBUG(Z), " %-16s %10s %10s %8s %8s %8s %10s\n", "------", "-----",
- "------", "----", "------", "-------", "---------");
- } /* end if */
+ char comment[16], bandwidth[32];
+ int dir, nprint = 0;
+ size_t i;
- /* Truncate the comment to fit in the field */
- HDstrncpy(comment, H5Z_table_g[i].name, sizeof comment);
- comment[sizeof(comment) - 1] = '\0';
-
- /*
- * Format bandwidth to have four significant digits and
- * units of `B/s', `kB/s', `MB/s', `GB/s', or `TB/s' or
- * the word `Inf' if the elapsed time is zero.
- */
- H5_bandwidth(bandwidth, (double)(H5Z_stat_table_g[i].stats[dir].total),
- H5Z_stat_table_g[i].stats[dir].times.elapsed);
-
- /* Print the statistics */
- HDfprintf(H5DEBUG(Z), " %s%-15s %10" PRIdHSIZE " %10" PRIdHSIZE " %8s %8s %8s %10s\n",
- (dir ? "<" : ">"), comment, H5Z_stat_table_g[i].stats[dir].total,
- H5Z_stat_table_g[i].stats[dir].errors, timestrs.user, timestrs.system,
- timestrs.elapsed, bandwidth);
+ if (H5DEBUG(Z)) {
+ for (i = 0; i < H5Z_table_used_g; i++) {
+ for (dir = 0; dir < 2; dir++) {
+ struct {
+ char *user;
+ char *system;
+ char *elapsed;
+ } timestrs = {H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.user),
+ H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.system),
+ H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.elapsed)};
+ if (0 == H5Z_stat_table_g[i].stats[dir].total)
+ goto next;
+
+ if (0 == nprint++) {
+ /* Print column headers */
+ HDfprintf(H5DEBUG(Z), "H5Z: filter statistics "
+ "accumulated over life of library:\n");
+ HDfprintf(H5DEBUG(Z), " %-16s %10s %10s %8s %8s %8s %10s\n", "Filter", "Total",
+ "Errors", "User", "System", "Elapsed", "Bandwidth");
+ HDfprintf(H5DEBUG(Z), " %-16s %10s %10s %8s %8s %8s %10s\n", "------", "-----",
+ "------", "----", "------", "-------", "---------");
+ } /* end if */
+
+ /* Truncate the comment to fit in the field */
+ HDstrncpy(comment, H5Z_table_g[i].name, sizeof comment);
+ comment[sizeof(comment) - 1] = '\0';
+
+ /*
+ * Format bandwidth to have four significant digits and
+ * units of `B/s', `kB/s', `MB/s', `GB/s', or `TB/s' or
+ * the word `Inf' if the elapsed time is zero.
+ */
+ H5_bandwidth(bandwidth, (double)(H5Z_stat_table_g[i].stats[dir].total),
+ H5Z_stat_table_g[i].stats[dir].times.elapsed);
+
+ /* Print the statistics */
+ HDfprintf(H5DEBUG(Z), " %s%-15s %10" PRIdHSIZE " %10" PRIdHSIZE " %8s %8s %8s %10s\n",
+ (dir ? "<" : ">"), comment, H5Z_stat_table_g[i].stats[dir].total,
+ H5Z_stat_table_g[i].stats[dir].errors, timestrs.user, timestrs.system,
+ timestrs.elapsed, bandwidth);
next:
- HDfree(timestrs.user);
- HDfree(timestrs.system);
- HDfree(timestrs.elapsed);
- } /* end for */
- } /* end for */
- } /* end if */
-#endif /* H5Z_DEBUG */
-
- /* Free the table of filters */
- if (H5Z_table_g) {
- H5Z_table_g = (H5Z_class2_t *)H5MM_xfree(H5Z_table_g);
+ HDfree(timestrs.user);
+ HDfree(timestrs.system);
+ HDfree(timestrs.elapsed);
+ } /* end for */
+ } /* end for */
+ } /* end if */
+#endif /* H5Z_DEBUG */
+
+ /* Free the table of filters */
+ if (H5Z_table_g) {
+ H5Z_table_g = (H5Z_class2_t *)H5MM_xfree(H5Z_table_g);
#ifdef H5Z_DEBUG
- H5Z_stat_table_g = (H5Z_stats_t *)H5MM_xfree(H5Z_stat_table_g);
+ H5Z_stat_table_g = (H5Z_stats_t *)H5MM_xfree(H5Z_stat_table_g);
#endif /* H5Z_DEBUG */
- H5Z_table_used_g = H5Z_table_alloc_g = 0;
+ H5Z_table_used_g = H5Z_table_alloc_g = 0;
- n++;
- } /* end if */
-
- /* Mark interface as closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
+ n++;
} /* end if */
FUNC_LEAVE_NOAPI(n)
@@ -599,14 +594,9 @@ H5Z__flush_file_cb(void *obj_ptr, hid_t H5_ATTR_UNUSED obj_id, void H5_ATTR_PARA
/* Do a global flush if the file is opened for write */
if (H5F_ACC_RDWR & H5F_INTENT(f)) {
-/* When parallel HDF5 is defined, check for collective metadata reads on this
- * file and set the flag for metadata I/O in the API context. -QAK, 2018/02/14
- */
#ifdef H5_HAVE_PARALLEL
/* Check if MPIO driver is used */
if (H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) {
- H5P_coll_md_read_flag_t coll_md_read; /* Do all metadata reads collectively */
-
/* Sanity check for collectively calling H5Zunregister, if requested */
/* (Sanity check assumes that a barrier on one file's comm
* is sufficient (i.e. that there aren't different comms for
@@ -626,13 +616,8 @@ H5Z__flush_file_cb(void *obj_ptr, hid_t H5_ATTR_UNUSED obj_id, void H5_ATTR_PARA
/* Set the "sanity checked" flag */
object->sanity_checked = TRUE;
} /* end if */
-
- /* Check whether to use the collective metadata read DXPL */
- coll_md_read = H5F_COLL_MD_READ(f);
- if (H5P_USER_TRUE == coll_md_read)
- H5CX_set_coll_metadata_read(TRUE);
- } /* end if */
-#endif /* H5_HAVE_PARALLEL */
+ } /* end if */
+#endif /* H5_HAVE_PARALLEL */
/* Call the flush routine for mounted file hierarchies */
if (H5F_flush_mounts((H5F_t *)obj_ptr) < 0)
@@ -1506,7 +1491,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Z_filter_in_pline
*
- * Purpose: Check wheter a filter is in the filter pipeline using the
+ * Purpose: Check whether a filter is in the filter pipeline using the
* filter ID. This function is very similar to H5Z_filter_info
*
* Return: TRUE - found filter
@@ -1520,7 +1505,7 @@ H5Z_filter_in_pline(const H5O_pline_t *pline, H5Z_filter_t filter)
size_t idx; /* Index of filter in pipeline */
htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
HDassert(pline);
HDassert(filter >= 0 && filter <= H5Z_FILTER_MAX);
@@ -1534,7 +1519,6 @@ H5Z_filter_in_pline(const H5O_pline_t *pline, H5Z_filter_t filter)
if (idx >= pline->nused)
ret_value = FALSE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5Z_filter_in_pline() */
@@ -1554,7 +1538,7 @@ H5Z_all_filters_avail(const H5O_pline_t *pline)
size_t i, j; /* Local index variable */
htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOERR
/* Check args */
HDassert(pline);
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index b696085..905d417 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -975,7 +975,7 @@ H5Z__filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[], s
/* input; decompress */
if (flags & H5Z_FLAG_REVERSE) {
- size_out = d_nelmts * cd_values[4]; /* cd_values[4] stores datatype size */
+ size_out = d_nelmts * (size_t)cd_values[4]; /* cd_values[4] stores datatype size */
/* allocate memory space for decompressed buffer */
if (NULL == (outbuf = (unsigned char *)H5MM_malloc(size_out)))
@@ -1015,7 +1015,7 @@ done:
* assume one byte has 8 bit
* assume padding bit is 0
* assume size of unsigned char is one byte
- * assume one data item of certain datatype is stored continously in bytes
+ * assume one data item of certain datatype is stored continuously in bytes
* atomic datatype is treated on byte basis
*/
@@ -1170,7 +1170,8 @@ H5Z__nbit_decompress_one_array(unsigned char *data, size_t data_offset, unsigned
n = total_size / p.size;
for (i = 0; i < n; i++)
- H5Z__nbit_decompress_one_atomic(data, data_offset + i * p.size, buffer, j, buf_len, &p);
+ H5Z__nbit_decompress_one_atomic(data, data_offset + i * (size_t)p.size, buffer, j, buf_len,
+ &p);
break;
case H5Z_NBIT_ARRAY:
@@ -1178,8 +1179,8 @@ H5Z__nbit_decompress_one_array(unsigned char *data, size_t data_offset, unsigned
n = total_size / base_size; /* number of base_type elements inside the array datatype */
begin_index = *parms_index;
for (i = 0; i < n; i++) {
- if (H5Z__nbit_decompress_one_array(data, data_offset + i * base_size, buffer, j, buf_len,
- parms, parms_index) < 0)
+ if (H5Z__nbit_decompress_one_array(data, data_offset + i * (size_t)base_size, buffer, j,
+ buf_len, parms, parms_index) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress array")
*parms_index = begin_index;
}
@@ -1190,8 +1191,8 @@ H5Z__nbit_decompress_one_array(unsigned char *data, size_t data_offset, unsigned
n = total_size / base_size; /* number of base_type elements inside the array datatype */
begin_index = *parms_index;
for (i = 0; i < n; i++) {
- if (H5Z__nbit_decompress_one_compound(data, data_offset + i * base_size, buffer, j, buf_len,
- parms, parms_index) < 0)
+ if (H5Z__nbit_decompress_one_compound(data, data_offset + i * (size_t)base_size, buffer, j,
+ buf_len, parms, parms_index) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress compound")
*parms_index = begin_index;
}
@@ -1291,7 +1292,7 @@ H5Z__nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buff
FUNC_ENTER_STATIC
/* may not have to initialize to zeros */
- HDmemset(data, 0, d_nelmts * parms[4]);
+ HDmemset(data, 0, d_nelmts * (size_t)parms[4]);
/* initialization before the loop */
j = 0;
@@ -1309,7 +1310,7 @@ H5Z__nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buff
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "invalid datatype precision/offset")
for (i = 0; i < d_nelmts; i++)
- H5Z__nbit_decompress_one_atomic(data, i * p.size, buffer, &j, &buf_len, &p);
+ H5Z__nbit_decompress_one_atomic(data, i * (size_t)p.size, buffer, &j, &buf_len, &p);
break;
case H5Z_NBIT_ARRAY:
@@ -1468,7 +1469,7 @@ H5Z__nbit_compress_one_array(unsigned char *data, size_t data_offset, unsigned c
p.offset = parms[(*parms_index)++];
n = total_size / p.size;
for (i = 0; i < n; i++)
- H5Z__nbit_compress_one_atomic(data, data_offset + i * p.size, buffer, j, buf_len, &p);
+ H5Z__nbit_compress_one_atomic(data, data_offset + i * (size_t)p.size, buffer, j, buf_len, &p);
break;
case H5Z_NBIT_ARRAY:
@@ -1476,8 +1477,8 @@ H5Z__nbit_compress_one_array(unsigned char *data, size_t data_offset, unsigned c
n = total_size / base_size; /* number of base_type elements inside the array datatype */
begin_index = *parms_index;
for (i = 0; i < n; i++) {
- H5Z__nbit_compress_one_array(data, data_offset + i * base_size, buffer, j, buf_len, parms,
- parms_index);
+ H5Z__nbit_compress_one_array(data, data_offset + i * (size_t)base_size, buffer, j, buf_len,
+ parms, parms_index);
*parms_index = begin_index;
}
break;
@@ -1487,8 +1488,8 @@ H5Z__nbit_compress_one_array(unsigned char *data, size_t data_offset, unsigned c
n = total_size / base_size; /* number of base_type elements inside the array datatype */
begin_index = *parms_index;
for (i = 0; i < n; i++) {
- H5Z__nbit_compress_one_compound(data, data_offset + i * base_size, buffer, j, buf_len, parms,
- parms_index);
+ H5Z__nbit_compress_one_compound(data, data_offset + i * (size_t)base_size, buffer, j, buf_len,
+ parms, parms_index);
*parms_index = begin_index;
}
break;
@@ -1574,7 +1575,7 @@ H5Z__nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer
p.offset = parms[7];
for (i = 0; i < d_nelmts; i++)
- H5Z__nbit_compress_one_atomic(data, i * p.size, buffer, &new_size, &buf_len, &p);
+ H5Z__nbit_compress_one_atomic(data, i * (size_t)p.size, buffer, &new_size, &buf_len, &p);
break;
case H5Z_NBIT_ARRAY:
diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
index 48a29cd..46c1a10 100644
--- a/src/H5Zscaleoffset.c
+++ b/src/H5Zscaleoffset.c
@@ -659,7 +659,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{
buf[i] = (type)(buf[i] + (type)(minval)); \
} while (0)
-/* Retrive minimum value of floating-point type */
+/* Retrieve minimum value of floating-point type */
#define H5Z_scaleoffset_get_min(type, minval, min) \
{ \
if (sizeof(type) <= sizeof(long long)) \
@@ -1205,7 +1205,7 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu
/* prepare parameters to pass to compress/decompress functions */
p.size = cd_values[H5Z_SCALEOFFSET_PARM_SIZE];
- p.mem_order = H5T_native_order_g;
+ p.mem_order = (unsigned)H5T_native_order_g;
/* input; decompress */
if (flags & H5Z_FLAG_REVERSE) {
@@ -1240,7 +1240,7 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu
p.minbits = minbits;
/* calculate size of output buffer after decompression */
- size_out = d_nelmts * p.size;
+ size_out = d_nelmts * (size_t)p.size;
/* allocate memory space for decompressed buffer */
if (NULL == (outbuf = (unsigned char *)H5MM_malloc(size_out)))
@@ -1388,7 +1388,7 @@ done:
* assume one byte has 8 bit
* assume padding bit is 0
* assume size of unsigned char is one byte
- * assume one data item of certain datatype is stored continously in bytes
+ * assume one data item of certain datatype is stored continuously in bytes
* atomic datatype is treated on byte basis
*/
@@ -1403,7 +1403,7 @@ H5Z__scaleoffset_convert(void *buf, unsigned d_nelmts, unsigned dtype_size)
unsigned char *buffer, temp;
buffer = (unsigned char *)buf;
- for (i = 0; i < d_nelmts * dtype_size; i += dtype_size)
+ for (i = 0; i < d_nelmts * (size_t)dtype_size; i += dtype_size)
for (j = 0; j < dtype_size / 2; j++) {
/* swap pair of bytes */
temp = buffer[i + j];
@@ -1681,7 +1681,7 @@ H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned cha
unsigned buf_len;
/* must initialize to zeros */
- for (i = 0; i < d_nelmts * p.size; i++)
+ for (i = 0; i < d_nelmts * (size_t)p.size; i++)
data[i] = 0;
/* initialization before the loop */
diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c
index ea532cf..092b289 100644
--- a/src/H5Ztrans.c
+++ b/src/H5Ztrans.c
@@ -1352,7 +1352,7 @@ H5Z__op_is_numbs2(H5Z_node *_tree)
* Function: H5Z__xform_reduce_tree
*
* Purpose: Simplifies parse tree passed in by performing any obvious
- * and trivial arithemtic calculations.
+ * and trivial arithmetic calculations.
*
* Return: None.
*
@@ -1692,7 +1692,7 @@ H5Z_xform_noop(const H5Z_data_xform_t *data_xform_prop)
if (data_xform_prop) {
ret_value = FALSE;
- /* Check for trivial data tranformation: expression = "x" */
+ /* Check for trivial data transformation: expression = "x" */
if ((HDstrlen(data_xform_prop->xform_exp) == 1) && data_xform_prop->dat_val_pointers &&
(data_xform_prop->dat_val_pointers->num_ptrs == 1)) {
ret_value = TRUE;
@@ -1723,7 +1723,7 @@ H5Z_xform_extract_xform_str(const H5Z_data_xform_t *data_xform_prop)
/* There should be no way that this can be NULL since the function
* that calls this one checks to make sure it isn't before
- * pasing them */
+ * passing them */
HDassert(data_xform_prop);
FUNC_LEAVE_NOAPI(data_xform_prop->xform_exp)
diff --git a/src/H5detect.c b/src/H5detect.c
index 022cb55..e72d7a0 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -772,7 +772,7 @@ done:\n\
fprintf(rawoutstream, "/* sigprocmask() support: no */\n");
#endif
- /* Print the statics of signal handlers called for debugging */
+ /* Print the statistics of signal handlers called for debugging */
fprintf(rawoutstream, "\n"
"/******************************/\n"
"/* signal handlers statistics */\n"
@@ -1475,7 +1475,7 @@ verify_signal_handlers(int signum, void (*handler)(int))
}
else {
if (val == signum) {
- /* return from signum handler. Record a sucess. */
+ /* return from signum handler. Record a success. */
nsuccesses++;
}
else {
diff --git a/src/H5module.h b/src/H5module.h
index 6d3cba8..f7d3cd6 100644
--- a/src/H5module.h
+++ b/src/H5module.h
@@ -11,9 +11,9 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * 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.
+ * 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
diff --git a/src/H5mpi.c b/src/H5mpi.c
index 4a8aa44..15fb785 100644
--- a/src/H5mpi.c
+++ b/src/H5mpi.c
@@ -38,7 +38,7 @@ static hsize_t bigio_count_g = H5_MAX_MPI_COUNT;
/*-------------------------------------------------------------------------
* Function: H5_mpi_set_bigio_count
*
- * Purpose: Allow us to programatically change the switch point
+ * Purpose: Allow us to programmatically change the switch point
* when we utilize derived datatypes. This is of
* particular interest for allowing nightly testing
*
@@ -549,4 +549,237 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5_mpio_create_large_type() */
+/*-------------------------------------------------------------------------
+ * Function: H5_mpio_gatherv_alloc
+ *
+ * Purpose: A wrapper around MPI_(All)gatherv that performs allocation
+ * of the receive buffer on the caller's behalf. This
+ * routine's parameters are as follows:
+ *
+ * `send_buf` - The buffer that data will be sent from for
+ * the calling MPI rank. Analogous to
+ * MPI_(All)gatherv's `sendbuf` parameter.
+ *
+ * `send_count` - The number of `send_type` elements in the
+ * send buffer. Analogous to MPI_(All)gatherv's
+ * `sendcount` parameter.
+ *
+ * `send_type` - The MPI Datatype of the elements in the send
+ * buffer. Analogous to MPI_(All)gatherv's
+ * `sendtype` parameter.
+ *
+ * `recv_counts` - An array containing the number of elements
+ * to be received from each MPI rank.
+ * Analogous to MPI_(All)gatherv's `recvcount`
+ * parameter.
+ *
+ * `displacements` - An array containing the displacements
+ * in the receive buffer where data from
+ * each MPI rank should be placed. Analogous
+ * to MPI_(All)gatherv's `displs` parameter.
+ *
+ * `recv_type` - The MPI Datatype of the elements in the
+ * receive buffer. Analogous to
+ * MPI_(All)gatherv's `recvtype` parameter.
+ *
+ * `allgather` - Specifies whether the gather operation to be
+ * performed should be MPI_Allgatherv (TRUE) or
+ * MPI_Gatherv (FALSE).
+ *
+ * `root` - For MPI_Gatherv operations, specifies the rank
+ * that will receive the data sent by other ranks.
+ * Analogous to MPI_Gatherv's `root` parameter. For
+ * MPI_Allgatherv operations, this parameter is
+ * ignored.
+ *
+ * `comm` - Specifies the MPI Communicator for the operation.
+ * Analogous to MPI_(All)gatherv's `comm` parameter.
+ *
+ * `mpi_rank` - Specifies the calling rank's rank value, as
+ * obtained by calling MPI_Comm_rank on the
+ * MPI Communicator `comm`.
+ *
+ * `mpi_size` - Specifies the MPI Communicator size, as
+ * obtained by calling MPI_Comm_size on the
+ * MPI Communicator `comm`.
+ *
+ * `out_buf` - Resulting buffer that is allocated and
+ * returned to the caller after data has been
+ * gathered into it. Returned only to the rank
+ * specified by `root` for MPI_Gatherv
+ * operations, or to all ranks for
+ * MPI_Allgatherv operations.
+ *
+ * `out_buf_num_entries` - The number of elements in the
+ * resulting buffer, in terms of
+ * the MPI Datatype provided for
+ * `recv_type`.
+ *
+ * Notes: This routine is collective across `comm`.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5_mpio_gatherv_alloc(void *send_buf, int send_count, MPI_Datatype send_type, const int recv_counts[],
+ const int displacements[], MPI_Datatype recv_type, hbool_t allgather, int root,
+ MPI_Comm comm, int mpi_rank, int mpi_size, void **out_buf, size_t *out_buf_num_entries)
+{
+ size_t recv_buf_num_entries = 0;
+ void * recv_buf = NULL;
+#if MPI_VERSION >= 3
+ MPI_Count type_lb;
+ MPI_Count type_extent;
+#else
+ MPI_Aint type_lb;
+ MPI_Aint type_extent;
+#endif
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(send_buf || send_count == 0);
+ if (allgather || (mpi_rank == root))
+ HDassert(out_buf && out_buf_num_entries);
+
+ /* Retrieve the extent of the MPI Datatype being used */
+#if MPI_VERSION >= 3
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_get_extent_x(recv_type, &type_lb, &type_extent)))
+#else
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_get_extent(recv_type, &type_lb, &type_extent)))
+#endif
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_get_extent(_x) failed", mpi_code)
+
+ if (type_extent < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "MPI recv_type had a negative extent")
+
+ /*
+ * Calculate the total size of the buffer being
+ * returned and allocate it
+ */
+ if (allgather || (mpi_rank == root)) {
+ size_t i;
+ size_t buf_size;
+
+ for (i = 0, recv_buf_num_entries = 0; i < (size_t)mpi_size; i++)
+ recv_buf_num_entries += (size_t)recv_counts[i];
+ buf_size = recv_buf_num_entries * (size_t)type_extent;
+
+ /* If our buffer size is 0, there's nothing to do */
+ if (buf_size == 0)
+ HGOTO_DONE(SUCCEED)
+
+ if (NULL == (recv_buf = H5MM_malloc(buf_size)))
+ /* Push an error, but still participate in collective gather operation */
+ HDONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate receive buffer")
+ }
+
+ /* Perform gather operation */
+ if (allgather) {
+ if (MPI_SUCCESS != (mpi_code = MPI_Allgatherv(send_buf, send_count, send_type, recv_buf, recv_counts,
+ displacements, recv_type, comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Allgatherv failed", mpi_code)
+ }
+ else {
+ if (MPI_SUCCESS != (mpi_code = MPI_Gatherv(send_buf, send_count, send_type, recv_buf, recv_counts,
+ displacements, recv_type, root, comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Gatherv failed", mpi_code)
+ }
+
+ if (allgather || (mpi_rank == root)) {
+ *out_buf = recv_buf;
+ *out_buf_num_entries = recv_buf_num_entries;
+ }
+
+done:
+ if (ret_value < 0) {
+ if (recv_buf)
+ H5MM_free(recv_buf);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5_mpio_gatherv_alloc() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5_mpio_gatherv_alloc_simple
+ *
+ * Purpose: A slightly simplified interface to H5_mpio_gatherv_alloc
+ * which calculates the receive counts and receive buffer
+ * displacements for the caller.
+ *
+ * Notes: This routine is collective across `comm`.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5_mpio_gatherv_alloc_simple(void *send_buf, int send_count, MPI_Datatype send_type, MPI_Datatype recv_type,
+ hbool_t allgather, int root, MPI_Comm comm, int mpi_rank, int mpi_size,
+ void **out_buf, size_t *out_buf_num_entries)
+{
+ int * recv_counts_disps_array = NULL;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(send_buf || send_count == 0);
+ if (allgather || (mpi_rank == root))
+ HDassert(out_buf && out_buf_num_entries);
+
+ /*
+ * Allocate array to store the receive counts of each rank, as well as
+ * the displacements into the final array where each rank will place
+ * their data. The first half of the array contains the receive counts
+ * (in rank order), while the latter half contains the displacements
+ * (also in rank order).
+ */
+ if (allgather || (mpi_rank == root)) {
+ if (NULL ==
+ (recv_counts_disps_array = H5MM_malloc(2 * (size_t)mpi_size * sizeof(*recv_counts_disps_array))))
+ /* Push an error, but still participate in collective gather operation */
+ HDONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "couldn't allocate receive counts and displacements array")
+ }
+
+ /* Collect each rank's send count to interested ranks */
+ if (allgather) {
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Allgather(&send_count, 1, MPI_INT, recv_counts_disps_array, 1, MPI_INT, comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code)
+ }
+ else {
+ if (MPI_SUCCESS !=
+ (mpi_code = MPI_Gather(&send_count, 1, MPI_INT, recv_counts_disps_array, 1, MPI_INT, root, comm)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code)
+ }
+
+ /* Set the displacements into the receive buffer for the gather operation */
+ if (allgather || (mpi_rank == root)) {
+ size_t i;
+ int * displacements_ptr;
+
+ displacements_ptr = &recv_counts_disps_array[mpi_size];
+
+ *displacements_ptr = 0;
+ for (i = 1; i < (size_t)mpi_size; i++)
+ displacements_ptr[i] = displacements_ptr[i - 1] + recv_counts_disps_array[i - 1];
+ }
+
+ /* Perform gather operation */
+ if (H5_mpio_gatherv_alloc(send_buf, send_count, send_type, recv_counts_disps_array,
+ &recv_counts_disps_array[mpi_size], recv_type, allgather, root, comm, mpi_rank,
+ mpi_size, out_buf, out_buf_num_entries) < 0)
+ HGOTO_ERROR(H5E_LIB, H5E_CANTGATHER, FAIL, "can't gather data")
+
+done:
+ if (recv_counts_disps_array)
+ H5MM_free(recv_counts_disps_array);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5_mpio_gatherv_alloc_simple() */
+
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5private.h b/src/H5private.h
index 58a4100..b9bbe3b 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -44,10 +44,12 @@
#include <sys/time.h>
#endif
#ifdef H5_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#ifdef H5_HAVE_PWD_H
#include <pwd.h>
#endif
-#include <unistd.h>
+#ifdef H5_HAVE_WAITPID
#include <sys/wait.h>
#endif
@@ -106,8 +108,14 @@
*/
#include "H5queue.h"
-/* Define the default VFD for this platform.
- * Since the removal of the Windows VFD, this is sec2 for all platforms.
+/* Define the default VFD for this platform. Since the removal of the
+ * Windows VFD, this is sec2 for all platforms.
+ *
+ * Note well: if you change the default, then be sure to change
+ * H5_default_vfd_init() to call that default's initializer. Also,
+ * make sure that the initializer for each *non*-default VFD calls
+ * H5_init_library(); also, make sure that the initializer for default
+ * VFD does *not* call H5_init_library().
*/
#define H5_DEFAULT_VFD H5FD_SEC2
@@ -171,7 +179,7 @@
*/
#define BEGIN_MPE_LOG \
if (H5_MPEinit_g) { \
- sprintf(p_event_start, "start %s", __func__); \
+ snprintf(p_event_start, sizeof(p_event_start), "start %s", __func__); \
if (eventa(__func__) == -1 && eventb(__func__) == -1) { \
const char *p_color = "red"; \
eventa(__func__) = MPE_Log_get_event_number(); \
@@ -386,6 +394,25 @@
#define HSSIZET_MAX ((hssize_t)LLONG_MAX)
#define HSSIZET_MIN (~(HSSIZET_MAX))
+#ifdef H5_HAVE_PARALLEL
+
+/* Define a type for safely sending size_t values with MPI */
+#if SIZE_MAX == UCHAR_MAX
+#define H5_SIZE_T_AS_MPI_TYPE MPI_UNSIGNED_CHAR
+#elif SIZE_MAX == USHRT_MAX
+#define H5_SIZE_T_AS_MPI_TYPE MPI_UNSIGNED_SHORT
+#elif SIZE_MAX == UINT_MAX
+#define H5_SIZE_T_AS_MPI_TYPE MPI_UNSIGNED
+#elif SIZE_MAX == ULONG_MAX
+#define H5_SIZE_T_AS_MPI_TYPE MPI_UNSIGNED_LONG
+#elif SIZE_MAX == ULLONG_MAX
+#define H5_SIZE_T_AS_MPI_TYPE MPI_UNSIGNED_LONG_LONG
+#else
+#error "no suitable MPI type for size_t"
+#endif
+
+#endif /* H5_HAVE_PARALLEL */
+
/*
* Types and max sizes for POSIX I/O.
* OS X (Darwin) is odd since the max I/O size does not match the types.
@@ -507,6 +534,9 @@
#define H5_GCC_CLANG_DIAG_ON(x)
#endif
+/* Function pointer typedef for qsort */
+typedef int (*H5_sort_func_cb_t)(const void *, const void *);
+
/* Typedefs and functions for timing certain parts of the library. */
/* A set of elapsed/user/system times emitted as a time point by the
@@ -575,7 +605,7 @@ typedef off_t h5_stat_size_t;
#define HDoff_t off_t
#endif
-#/* Redefine all the POSIX and C functions. We should never see an
+/* Redefine all the POSIX and C functions. We should never see an
* undecorated POSIX or C function (or any other non-HDF5 function)
* in the source.
*/
@@ -1134,57 +1164,6 @@ H5_DLL H5_ATTR_CONST int Nflock(int fd, int operation);
#ifndef HDprintf
#define HDprintf printf /*varargs*/
#endif
-#ifndef HDpthread_attr_destroy
-#define HDpthread_attr_destroy(A) pthread_attr_destroy(A)
-#endif
-#ifndef HDpthread_attr_init
-#define HDpthread_attr_init(A) pthread_attr_init(A)
-#endif
-#ifndef HDpthread_attr_setscope
-#define HDpthread_attr_setscope(A, S) pthread_attr_setscope(A, S)
-#endif
-#ifndef HDpthread_cond_init
-#define HDpthread_cond_init(C, A) pthread_cond_init(C, A)
-#endif
-#ifndef HDpthread_cond_signal
-#define HDpthread_cond_signal(C) pthread_cond_signal(C)
-#endif
-#ifndef HDpthread_cond_wait
-#define HDpthread_cond_wait(C, M) pthread_cond_wait(C, M)
-#endif
-#ifndef HDpthread_create
-#define HDpthread_create(R, A, F, U) pthread_create(R, A, F, U)
-#endif
-#ifndef HDpthread_equal
-#define HDpthread_equal(T1, T2) pthread_equal(T1, T2)
-#endif
-#ifndef HDpthread_getspecific
-#define HDpthread_getspecific(K) pthread_getspecific(K)
-#endif
-#ifndef HDpthread_join
-#define HDpthread_join(T, V) pthread_join(T, V)
-#endif
-#ifndef HDpthread_key_create
-#define HDpthread_key_create(K, D) pthread_key_create(K, D)
-#endif
-#ifndef HDpthread_mutex_init
-#define HDpthread_mutex_init(M, A) pthread_mutex_init(M, A)
-#endif
-#ifndef HDpthread_mutex_lock
-#define HDpthread_mutex_lock(M) pthread_mutex_lock(M)
-#endif
-#ifndef HDpthread_mutex_unlock
-#define HDpthread_mutex_unlock(M) pthread_mutex_unlock(M)
-#endif
-#ifndef HDpthread_self
-#define HDpthread_self() pthread_self()
-#endif
-#ifndef HDpthread_setcancelstate
-#define HDpthread_setcancelstate(N, O) pthread_setcancelstate(N, O)
-#endif
-#ifndef HDpthread_setspecific
-#define HDpthread_setspecific(K, V) pthread_setspecific(K, V)
-#endif
#ifndef HDputc
#define HDputc(C, F) putc(C, F)
#endif
@@ -1351,6 +1330,9 @@ H5_DLL H5_ATTR_CONST int Nflock(int fd, int operation);
#ifndef HDsigsetjmp
#define HDsigsetjmp(J, N) sigsetjmp(J, N)
#endif
+#ifndef HDsigtimedwait
+#define HDsigtimedwait(S, I, T) sigtimedwait(S, I, T)
+#endif
#ifndef HDsigsuspend
#define HDsigsuspend(S) sigsuspend(S)
#endif
@@ -1429,6 +1411,9 @@ H5_DLL H5_ATTR_CONST int Nflock(int fd, int operation);
#ifndef HDstrrchr
#define HDstrrchr(S, C) strrchr(S, C)
#endif
+#ifndef HDstrsignal
+#define HDstrsignal(S) strsignal(S)
+#endif
#ifndef HDstrspn
#define HDstrspn(X, Y) strspn(X, Y)
#endif
@@ -1507,6 +1492,9 @@ H5_DLL H5_ATTR_CONST int Nflock(int fd, int operation);
#ifndef HDtimes
#define HDtimes(T) times(T)
#endif
+#ifndef HDtimespec_get
+#define HDtimespec_get(T, B) timespec_get(T, B)
+#endif
#ifndef HDtimespeccmp
#ifdef H5_HAVE_TIMESPECCMP
@@ -2006,7 +1994,7 @@ extern H5_api_t H5_g;
#define H5_API_LOCK
#define H5_API_UNLOCK
-/* disable cancelability (sequential version) */
+/* disable cancellability (sequential version) */
#define H5_API_UNSET_CANCEL
#define H5_API_SET_CANCEL
@@ -2036,32 +2024,15 @@ extern hbool_t H5_libterm_g; /* Is the library being shutdown? */
extern hbool_t H5_MPEinit_g; /* Has the MPE Library been initialized? */
#endif
-/* Macros for referencing package initialization symbols */
-#define H5_PACKAGE_INIT_VAR(x) H5_GLUE(x, _init_g)
-#define H5_PACKAGE_INIT_FUNC(x) H5_GLUE(x, __init_package)
-
-/* Macros for defining package initialization routines */
-#ifdef H5_MY_PKG
-#define H5_PKG_INIT_VAR H5_PACKAGE_INIT_VAR(H5_MY_PKG)
-#define H5_PKG_INIT_FUNC H5_PACKAGE_INIT_FUNC(H5_MY_PKG)
-#define H5_PACKAGE_YES_INIT(err) \
- /* Initialize this interface or bust */ \
- if (!H5_PKG_INIT_VAR && !H5_TERM_GLOBAL) { \
- H5_PKG_INIT_VAR = TRUE; \
- if (H5_PKG_INIT_FUNC() < 0) { \
- H5_PKG_INIT_VAR = FALSE; \
- HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, err, "interface initialization failed") \
- } \
- }
-#define H5_PACKAGE_NO_INIT(err) \
- /* Initialize this interface or bust */ \
- if (!H5_PKG_INIT_VAR && !H5_TERM_GLOBAL) \
- H5_PKG_INIT_VAR = TRUE;
-#define H5_PACKAGE_INIT(pkg_init, err) H5_GLUE3(H5_PACKAGE_, pkg_init, _INIT)(err)
-#else /* H5_MY_PKG */
-#define H5_PKG_INIT_VAR (TRUE)
-#define H5_PACKAGE_INIT(pkg_init, err)
-#endif /* H5_MY_PKG */
+/* Typedef for the VFD SWMR end-of-tick queue */
+typedef TAILQ_HEAD(eot_queue, eot_queue_entry) eot_queue_t;
+
+/* VFD SWMR globals used in FUNC macros */
+H5_DLLVAR unsigned int vfd_swmr_api_entries_g;
+H5_DLLVAR eot_queue_t eot_queue_g;
+
+/* Forward declaration of H5F_vfd_swmr_process_eot_queue() */
+H5_DLL herr_t H5F_vfd_swmr_process_eot_queue(hbool_t entering_api);
/* Forward declaration of H5CXpush() / H5CXpop() */
/* (Including H5CXprivate.h creates bad circular dependencies - QAK, 3/18/2018) */
@@ -2116,13 +2087,9 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
#define FUNC_ENTER_API_INIT(err) \
/* Initialize the library */ \
if (!H5_INIT_GLOBAL && !H5_TERM_GLOBAL) { \
- H5_INIT_GLOBAL = TRUE; \
if (H5_init_library() < 0) \
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, err, "library initialization failed") \
- } /* end if */ \
- \
- /* Initialize the package, if appropriate */ \
- H5_PACKAGE_INIT(H5_MY_PKG_INIT, err)
+ }
#define FUNC_ENTER_API_PUSH(err) \
/* Push the name of this function on the function stack */ \
@@ -2131,11 +2098,11 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
/* Push the API context */ \
if (H5CX_push() < 0) \
HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, err, "can't set API context") \
+ else \
+ api_ctx_pushed = TRUE; \
\
BEGIN_MPE_LOG
-#include "H5FDvfd_swmr_private.h"
-
#define VFD_SWMR_ENTER(err) \
do { \
/* TBD assert that the API lock is held. The API lock */ \
@@ -2160,7 +2127,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
; /* Do nothing: an error occurred. */ \
else if (TAILQ_EMPTY(&eot_queue_g)) \
; /* Nothing to do. */ \
- else if (H5F_vfd_swmr_process_eot_queue(false) < 0) { \
+ else if (H5F_vfd_swmr_process_eot_queue(FALSE) < 0) { \
/* Report error instead of "err" */ \
HDONE_ERROR(H5E_FUNC, H5E_CANTSET, FALSE, "error processing EOT queue") \
} \
@@ -2170,6 +2137,8 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
#define FUNC_ENTER_API(err) \
{ \
{ \
+ hbool_t api_ctx_pushed = FALSE; \
+ \
FUNC_ENTER_API_COMMON \
FUNC_ENTER_API_INIT(err); \
FUNC_ENTER_API_PUSH(err); \
@@ -2182,6 +2151,8 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
#define FUNC_ENTER_API_NO_EOT(err) \
{ \
{ \
+ hbool_t api_ctx_pushed = FALSE; \
+ \
FUNC_ENTER_API_COMMON \
FUNC_ENTER_API_INIT(err); \
FUNC_ENTER_API_PUSH(err); \
@@ -2196,6 +2167,8 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
#define FUNC_ENTER_API_NOCLEAR(err) \
{ \
{ \
+ hbool_t api_ctx_pushed = FALSE; \
+ \
FUNC_ENTER_API_COMMON \
FUNC_ENTER_API_INIT(err); \
FUNC_ENTER_API_PUSH(err); \
@@ -2270,27 +2243,19 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
FUNC_ENTER_COMMON_NOERR(H5_IS_API(__func__)); \
{
-/* Note: this macro only works when there's _no_ interface initialization routine for the module */
-#define FUNC_ENTER_NOAPI_INIT(err) \
- /* Initialize the package, if appropriate */ \
- H5_PACKAGE_INIT(H5_MY_PKG_INIT, err) \
- \
- /* Push the name of this function on the function stack */ \
- H5_PUSH_FUNC
-
/* Use this macro for all "normal" non-API functions */
#define FUNC_ENTER_NOAPI(err) \
{ \
FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \
- FUNC_ENTER_NOAPI_INIT(err) \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ H5_PUSH_FUNC \
+ {
/* Use this macro for all non-API functions, which propagate errors, but don't issue them */
#define FUNC_ENTER_NOAPI_NOERR \
{ \
FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \
- FUNC_ENTER_NOAPI_INIT(-) \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ H5_PUSH_FUNC \
+ {
/*
* Use this macro for non-API functions which fall into these categories:
@@ -2304,7 +2269,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
{ \
FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/*
* Use this macro for non-API functions which fall into these categories:
@@ -2319,7 +2284,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
{ \
FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/*
* Use this macro for non-API functions which fall into these categories:
@@ -2331,9 +2296,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
{ \
FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \
\
- /* Initialize the package, if appropriate */ \
- H5_PACKAGE_INIT(H5_MY_PKG_INIT, err) \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/*
* Use this macro for non-API functions which fall into these categories:
@@ -2347,7 +2310,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
#define FUNC_ENTER_NOAPI_NOERR_NOFS \
{ \
FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/*
* Use this macro for non-API functions that shouldn't perform _any_ initialization
@@ -2369,8 +2332,8 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
\
FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \
H5AC_tag(tag, &prev_tag); \
- FUNC_ENTER_NOAPI_INIT(err) \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ H5_PUSH_FUNC \
+ {
#define FUNC_ENTER_NOAPI_NOINIT_TAG(tag) \
{ \
@@ -2379,21 +2342,21 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \
H5AC_tag(tag, &prev_tag); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/* Use this macro for all "normal" package-level functions */
#define FUNC_ENTER_PACKAGE \
{ \
FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/* Use this macro for package-level functions which propgate errors, but don't issue them */
#define FUNC_ENTER_PACKAGE_NOERR \
{ \
FUNC_ENTER_COMMON_NOERR(H5_IS_PKG(__func__)); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/* Use the following macro as replacement for the FUNC_ENTER_PACKAGE
* macro when the function needs to set up a metadata tag. */
@@ -2404,28 +2367,28 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \
H5AC_tag(tag, &prev_tag); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/* Use this macro for all "normal" staticly-scoped functions */
#define FUNC_ENTER_STATIC \
{ \
FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/* Use this macro for staticly-scoped functions which propgate errors, but don't issue them */
#define FUNC_ENTER_STATIC_NOERR \
{ \
FUNC_ENTER_COMMON_NOERR(H5_IS_PKG(__func__)); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/* Use this macro for staticly-scoped functions which propgate errors, but don't issue them */
/* And that shouldn't push their name on the function stack */
#define FUNC_ENTER_STATIC_NOERR_NOFS \
{ \
FUNC_ENTER_COMMON_NOERR(H5_IS_PKG(__func__)); \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/*
* Use this macro for non-API functions that shouldn't perform _any_ initialization
@@ -2447,7 +2410,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \
H5AC_tag(tag, &prev_tag); \
H5_PUSH_FUNC \
- if (H5_PKG_INIT_VAR || !H5_TERM_GLOBAL) {
+ {
/*-------------------------------------------------------------------------
* Purpose: Register function exit for code profiling. This should be
@@ -2463,15 +2426,18 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
H5_API_SET_CANCEL
#define FUNC_LEAVE_API_COMMON(ret_value) \
- ; \
- } /*end scope from end of FUNC_ENTER*/ \
FINISH_MPE_LOG \
H5TRACE_RETURN(ret_value);
#define FUNC_LEAVE_API(ret_value) \
+ ; \
+ } /*end scope from end of FUNC_ENTER*/ \
VFD_SWMR_LEAVE(ret_value); \
FUNC_LEAVE_API_COMMON(ret_value); \
- (void)H5CX_pop(TRUE); \
+ if (api_ctx_pushed) { \
+ (void)H5CX_pop(TRUE); \
+ api_ctx_pushed = FALSE; \
+ } \
H5_POP_FUNC \
if (err_occurred) \
(void)H5E_dump_api_stack(TRUE); \
@@ -2482,8 +2448,13 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
/* Use this macro when VFD SWMR EOT is not used on leaving an API function */
#define FUNC_LEAVE_API_NO_EOT(ret_value) \
+ ; \
+ } /*end scope from end of FUNC_ENTER*/ \
FUNC_LEAVE_API_COMMON(ret_value); \
- (void)H5CX_pop(TRUE); \
+ if (api_ctx_pushed) { \
+ (void)H5CX_pop(TRUE); \
+ api_ctx_pushed = FALSE; \
+ } \
H5_POP_FUNC \
if (err_occurred) \
(void)H5E_dump_api_stack(TRUE); \
@@ -2494,6 +2465,8 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
/* Use this macro to match the FUNC_ENTER_API_NOINIT macro */
#define FUNC_LEAVE_API_NOINIT(ret_value) \
+ ; \
+ } /*end scope from end of FUNC_ENTER*/ \
FUNC_LEAVE_API_COMMON(ret_value); \
H5_POP_FUNC \
if (err_occurred) \
@@ -2506,6 +2479,8 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
/* Use this macro to match the FUNC_ENTER_API_NOINIT_NOERR_NOFS macro */
#define FUNC_LEAVE_API_NOFS(ret_value) \
+ ; \
+ } /*end scope from end of FUNC_ENTER*/ \
FUNC_LEAVE_API_COMMON(ret_value); \
FUNC_LEAVE_API_THREADSAFE \
return (ret_value); \
@@ -2582,27 +2557,6 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
return (ret_value); \
} /*end scope from beginning of FUNC_ENTER*/
-/* Macros to declare package initialization function, if a package initialization routine is defined */
-#ifdef H5_PKG_SINGLE_SOURCE
-#define H5_PKG_DECLARE_YES_FUNC(pkg) static herr_t H5_PACKAGE_INIT_FUNC(pkg)(void);
-#else
-#define H5_PKG_DECLARE_YES_FUNC(pkg) extern herr_t H5_PACKAGE_INIT_FUNC(pkg)(void);
-#endif
-#define H5_PKG_DECLARE_NO_FUNC(pkg)
-
-/* Declare package initialization symbols (if in a package) */
-#ifdef H5_PKG_SINGLE_SOURCE
-#define H5_PKG_DECLARE_VAR(pkg) static hbool_t H5_PACKAGE_INIT_VAR(pkg);
-#else
-#define H5_PKG_DECLARE_VAR(pkg) extern hbool_t H5_PACKAGE_INIT_VAR(pkg);
-#endif
-#define H5_PKG_DECLARE_FUNC(pkg_init, pkg) H5_GLUE3(H5_PKG_DECLARE_, pkg_init, _FUNC)(pkg)
-
-#ifdef H5_MY_PKG
-H5_PKG_DECLARE_VAR(H5_MY_PKG)
-H5_PKG_DECLARE_FUNC(H5_MY_PKG_INIT, H5_MY_PKG)
-#endif
-
/* Macro to begin/end tagging (when FUNC_ENTER_*TAG macros are insufficient).
* Make sure to use HGOTO_ERROR_TAG and HGOTO_DONE_TAG between these macros! */
#define H5_BEGIN_TAG(tag) \
@@ -2723,7 +2677,8 @@ struct h5_long_options {
*/
};
-H5_DLL int H5_get_option(int argc, const char **argv, const char *opt, const struct h5_long_options *l_opt);
+H5_DLL int H5_get_option(int argc, const char *const *argv, const char *opt,
+ const struct h5_long_options *l_opt);
#ifdef H5_HAVE_PARALLEL
/* Generic MPI functions */
@@ -2737,6 +2692,14 @@ H5_DLL herr_t H5_mpi_comm_cmp(MPI_Comm comm1, MPI_Comm comm2, int *result);
H5_DLL herr_t H5_mpi_info_cmp(MPI_Info info1, MPI_Info info2, int *result);
H5_DLL herr_t H5_mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, MPI_Datatype old_type,
MPI_Datatype *new_type);
+H5_DLL herr_t H5_mpio_gatherv_alloc(void *send_buf, int send_count, MPI_Datatype send_type,
+ const int recv_counts[], const int displacements[],
+ MPI_Datatype recv_type, hbool_t allgather, int root, MPI_Comm comm,
+ int mpi_rank, int mpi_size, void **out_buf, size_t *out_buf_num_entries);
+H5_DLL herr_t H5_mpio_gatherv_alloc_simple(void *send_buf, int send_count, MPI_Datatype send_type,
+ MPI_Datatype recv_type, hbool_t allgather, int root, MPI_Comm comm,
+ int mpi_rank, int mpi_size, void **out_buf,
+ size_t *out_buf_num_entries);
#endif /* H5_HAVE_PARALLEL */
/* Functions for debugging */
diff --git a/src/H5public.h b/src/H5public.h
index 163deed..3f9848a 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -46,7 +46,7 @@
#include <stddef.h>
#include <stdint.h>
-/* Unlike most sys/ headers, which are POSIX-only, sys/types.h is avaible
+/* Unlike most sys/ headers, which are POSIX-only, sys/types.h is available
* on Windows, though it doesn't necessarily contain all the POSIX types
* we need for HDF5 (e.g. ssize_t).
*/
@@ -83,7 +83,7 @@
/**
* For tweaks, bug-fixes, or development
*/
-#define H5_VERS_RELEASE 1
+#define H5_VERS_RELEASE 2
/**
* For pre-releases like \c snap0. Empty string for official releases.
*/
@@ -91,7 +91,7 @@
/**
* Full version string
*/
-#define H5_VERS_INFO "HDF5 library version: 1.13.1-1"
+#define H5_VERS_INFO "HDF5 library version: 1.13.2-1"
#define H5check() H5check_version(H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE)
@@ -168,6 +168,58 @@
(((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE <= Rel)) || \
((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR < Min)) || (H5_VERS_MAJOR < Maj))
+/* Macros for various environment variables that HDF5 interprets */
+/**
+ * Used to specify the name of an HDF5 Virtual File Driver to use as
+ * the default file driver for file access. Setting this environment
+ * variable overrides the default file driver for File Access Property
+ * Lists.
+ */
+#define HDF5_DRIVER "HDF5_DRIVER"
+/**
+ * Used to specify a configuration string for the HDF5 Virtual File
+ * Driver being used for file access.
+ */
+#define HDF5_DRIVER_CONFIG "HDF5_DRIVER_CONFIG"
+/**
+ * Used to specify the name of an HDF5 Virtual Object Layer Connector
+ * to use as the default VOL connector for file access. Setting this
+ * environment variable overrides the default VOL connector for File
+ * Access Property Lists.
+ */
+#define HDF5_VOL_CONNECTOR "HDF5_VOL_CONNECTOR"
+/**
+ * Used to specify a delimiter-separated (currently, ';' for Windows
+ * and ':' for other systems) list of paths that HDF5 should search
+ * when loading plugins.
+ */
+#define HDF5_PLUGIN_PATH "HDF5_PLUGIN_PATH"
+/**
+ * Used to control the loading of HDF5 plugins at runtime. If this
+ * environment variable is set to the special string "::" (defined
+ * in H5PLpublic.h as H5PL_NO_PLUGIN), then dynamic loading of any
+ * HDF5 plugins will be disabled. No other values are valid for this
+ * environment variable.
+ */
+#define HDF5_PLUGIN_PRELOAD "HDF5_PLUGIN_PRELOAD"
+/**
+ * Used to control whether HDF5 uses file locking when creating or
+ * opening a file. Valid values for this environment variable are
+ * as follows:
+ *
+ * "TRUE" or "1" - Request that file locks should be used
+ * "FALSE" or "0" - Request that file locks should NOT be used
+ * "BEST_EFFORT" - Request that file locks should be used and
+ * that any locking errors caused by file
+ * locking being disabled on the system
+ * should be ignored
+ */
+#define HDF5_USE_FILE_LOCKING "HDF5_USE_FILE_LOCKING"
+/**
+ * Used to instruct HDF5 not to cleanup files created during testing.
+ */
+#define HDF5_NOCLEANUP "HDF5_NOCLEANUP"
+
/**
* Status return values. Failed integer functions in HDF5 result almost
* always in a negative value (unsigned failing functions sometimes return
@@ -237,6 +289,11 @@ typedef long long ssize_t;
* \internal Defined as a (minimum) 64-bit integer type.
*/
typedef uint64_t hsize_t;
+
+#ifdef H5_HAVE_PARALLEL
+#define HSIZE_AS_MPI_TYPE MPI_UINT64_T
+#endif
+
/**
* The size of file objects. Used when negative values are needed to indicate errors.
*
@@ -271,7 +328,7 @@ typedef uint64_t haddr_t;
#define HADDR_MAX (HADDR_UNDEF - 1)
#ifdef H5_HAVE_PARALLEL
-#define HADDR_AS_MPI_TYPE MPI_LONG_LONG_INT
+#define HADDR_AS_MPI_TYPE MPI_UINT64_T
#endif
//! <!-- [H5_iter_order_t_snip] -->
diff --git a/src/H5retry_private.h b/src/H5retry_private.h
index 5ff63d3..768211d 100644
--- a/src/H5retry_private.h
+++ b/src/H5retry_private.h
@@ -39,13 +39,13 @@ typedef struct h5_retry_t {
*
* XXX This is not part of the API. XXX
*/
-static inline bool
-h5_retry_decrement(struct h5_retry_t *r)
+static inline hbool_t
+H5__retry_decrement(struct h5_retry_t *r)
{
if (r->tries == 0)
- return false;
+ return FALSE;
--r->tries;
- return true;
+ return TRUE;
}
/* Establish state for a retry loop in `r`. The loop will retry no
@@ -69,28 +69,28 @@ h5_retry_decrement(struct h5_retry_t *r)
* Note well: the program will enter the body of the loop, above, no more
* than 101 times: once for an initial try, and then 100 times for retries.
*/
-static inline bool
-h5_retry_init(struct h5_retry_t *r, unsigned int maxtries, uint64_t minival, uint64_t maxival)
+static inline hbool_t
+H5_retry_init(h5_retry_t *r, unsigned int maxtries, uint64_t minival, uint64_t maxival)
{
- memset(r, '\0', sizeof(*r));
- assert(0 < maxtries);
- assert(0 < minival && minival <= maxival);
+ HDmemset(r, '\0', sizeof(*r));
+ HDassert(0 < maxtries);
+ HDassert(0 < minival && minival <= maxival);
r->tries = r->maxtries = maxtries;
r->ival = minival;
r->maxival = maxival;
- return h5_retry_decrement(r);
+ return H5__retry_decrement(r);
}
-/* If any tries remain, sleep for the mininum interval, or twice the
+/* If any tries remain, sleep for the minimum interval, or twice the
* previous sleep time, and return true. If no tries remain, return false.
*/
-static inline bool
-h5_retry_next(struct h5_retry_t *r)
+static inline hbool_t
+H5_retry_next(h5_retry_t *r)
{
uint64_t ival;
- if (!h5_retry_decrement(r))
- return false;
+ if (!H5__retry_decrement(r))
+ return FALSE;
ival = r->ival;
if (r->maxival < ival)
ival = r->maxival;
@@ -99,14 +99,14 @@ h5_retry_next(struct h5_retry_t *r)
H5_nanosleep(ival);
- return true;
+ return TRUE;
}
/* Return the number of tries performed since `h5_retry_init()`
* was called on `r`.
*/
static inline unsigned
-h5_retry_tries(struct h5_retry_t *r)
+H5_retry_tries(h5_retry_t *r)
{
return r->maxtries - r->tries;
}
diff --git a/src/H5system.c b/src/H5system.c
index e671ea9..1104f3b 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -862,7 +862,7 @@ H5_nanosleep(uint64_t nanosec)
#else
- const uint64_t nanosec_per_sec = 1000 * 1000 * 1000;
+ const uint64_t nanosec_per_sec = 1000 * 1000L * 1000;
struct timespec sleeptime; /* Struct to hold time to sleep */
/* Set up time to sleep
@@ -1096,7 +1096,7 @@ const char *H5_optarg; /* Flag argument (or value) */
*-------------------------------------------------------------------------
*/
int
-H5_get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts)
+H5_get_option(int argc, const char *const *argv, const char *opts, const struct h5_long_options *l_opts)
{
static int sp = 1; /* character index in current token */
int optchar = '?'; /* option character passed back to user */
@@ -1173,7 +1173,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon
HDfree(arg);
}
else {
- register char *cp; /* pointer into current token */
+ char *cp; /* pointer into current token */
/* short command line option */
optchar = argv[H5_optind][sp];
diff --git a/src/H5timer.c b/src/H5timer.c
index b2cc5f0..b5dba97 100644
--- a/src/H5timer.c
+++ b/src/H5timer.c
@@ -193,17 +193,26 @@ H5_now_usec(void)
struct timespec ts;
HDclock_gettime(CLOCK_MONOTONIC, &ts);
- now = (uint64_t)(ts.tv_sec * (1000 * 1000)) + (uint64_t)(ts.tv_nsec / 1000);
+
+ /* Cast all values in this expression to uint64_t to ensure that all intermediate
+ * calculations are done in 64 bit, to prevent overflow */
+ now = ((uint64_t)ts.tv_sec * ((uint64_t)1000 * (uint64_t)1000)) +
+ ((uint64_t)ts.tv_nsec / (uint64_t)1000);
}
#elif defined(H5_HAVE_GETTIMEOFDAY)
{
struct timeval now_tv;
HDgettimeofday(&now_tv, NULL);
- now = (uint64_t)(now_tv.tv_sec * (1000 * 1000)) + (uint64_t)now_tv.tv_usec;
+
+ /* Cast all values in this expression to uint64_t to ensure that all intermediate
+ * calculations are done in 64 bit, to prevent overflow */
+ now = ((uint64_t)now_tv.tv_sec * ((uint64_t)1000 * (uint64_t)1000)) + (uint64_t)now_tv.tv_usec;
}
#else /* H5_HAVE_GETTIMEOFDAY */
- now = (uint64_t)(HDtime(NULL) * (1000 * 1000));
+ /* Cast all values in this expression to uint64_t to ensure that all intermediate calculations
+ * are done in 64 bit, to prevent overflow */
+ now = ((uint64_t)HDtime(NULL) * ((uint64_t)1000 * (uint64_t)1000));
#endif /* H5_HAVE_GETTIMEOFDAY */
return (now);
diff --git a/src/H5trace.c b/src/H5trace.c
index 8daa17d..8defbc1 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -1046,6 +1046,68 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
} /* end block */
break;
+ case 'V': /* H5FD_class_value_t */
+ {
+ H5FD_class_value_t class_val =
+ (H5FD_class_value_t)HDva_arg(ap, H5FD_class_value_t);
+
+ switch (class_val) {
+ case H5_VFD_INVALID:
+ H5RS_acat(rs, "H5_VFD_INVALID");
+ break;
+ case H5_VFD_SEC2:
+ H5RS_acat(rs, "H5_VFD_SEC2");
+ break;
+ case H5_VFD_CORE:
+ H5RS_acat(rs, "H5_VFD_CORE");
+ break;
+ case H5_VFD_LOG:
+ H5RS_acat(rs, "H5_VFD_LOG");
+ break;
+ case H5_VFD_FAMILY:
+ H5RS_acat(rs, "H5_VFD_FAMILY");
+ break;
+ case H5_VFD_MULTI:
+ H5RS_acat(rs, "H5_VFD_MULTI");
+ break;
+ case H5_VFD_STDIO:
+ H5RS_acat(rs, "H5_VFD_STDIO");
+ break;
+#ifdef H5_HAVE_PARALLEL
+ case H5_VFD_MPIO:
+ H5RS_acat(rs, "H5_VFD_MPIO");
+ break;
+#endif
+#ifdef H5_HAVE_DIRECT
+ case H5_VFD_DIRECT:
+ H5RS_acat(rs, "H5_VFD_DIRECT");
+ break;
+#endif
+#ifdef H5_HAVE_MIRROR_VFD
+ case H5_VFD_MIRROR:
+ H5RS_acat(rs, "H5_VFD_MIRROR");
+ break;
+#endif
+#ifdef H5_HAVE_LIBHDFS
+ case H5_VFD_HDFS:
+ H5RS_acat(rs, "H5_VFD_HDFS");
+ break;
+#endif
+#ifdef H5_HAVE_ROS3_VFD
+ case H5_VFD_ROS3:
+ H5RS_acat(rs, "H5_VFD_ROS3");
+ break;
+#endif
+ case H5_VFD_SWMR:
+ H5RS_acat(rs, "H5_VFD_SWMR");
+ break;
+ default:
+ H5RS_asprintf_cat(rs, "%ld", (long)class_val);
+ break;
+ }
+ } /* end block */
+ break;
+
default:
H5RS_asprintf_cat(rs, "BADTYPE(D%c)", type[1]);
goto error;
@@ -1189,7 +1251,7 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
{
H5FD_class_t cls = HDva_arg(ap, H5FD_class_t);
- H5RS_asprintf_cat(rs, "{'%s', " H5_PRINTF_HADDR_FMT ", ", cls.name, cls.maxaddr);
+ H5RS_asprintf_cat(rs, "{'%s', %" PRIuHADDR ", ", cls.name, cls.maxaddr);
H5_trace_args_close_degree(rs, cls.fc_degree);
H5RS_acat(rs, ", ...}");
} /* end block */
@@ -3964,7 +4026,7 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
H5_timer_get_times(function_timer, &function_times);
H5_timer_get_times(running_timer, &running_times);
- HDsprintf(tmp, "%.6f", (function_times.elapsed - running_times.elapsed));
+ HDsnprintf(tmp, sizeof(tmp), "%.6f", (function_times.elapsed - running_times.elapsed));
H5RS_asprintf_cat(rs, " %*s ", (int)HDstrlen(tmp), "");
}
for (i = 0; i < current_depth; i++)
diff --git a/src/Makefile.am b/src/Makefile.am
index ae058f4..931d335 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -63,9 +63,8 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \
H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \
H5FAint.c H5FAstat.c H5FAtest.c \
H5FD.c H5FDcore.c H5FDfamily.c H5FDint.c H5FDlog.c \
- H5FDmulti.c H5FDsec2.c H5FDspace.c \
- H5FDsplitter.c H5FDstdio.c H5FDtest.c \
- H5FDvfd_swmr.c H5FDvfd_swmr_instr.c \
+ H5FDmulti.c H5FDperform.c H5FDsec2.c H5FDspace.c \
+ H5FDsplitter.c H5FDstdio.c H5FDtest.c H5FDvfd_swmr.c \
H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSint.c H5FSsection.c \
H5FSstat.c H5FStest.c \
H5G.c H5Gbtree2.c H5Gcache.c H5Gcompact.c H5Gdense.c H5Gdeprec.c \
@@ -76,13 +75,12 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \
H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \
H5HG.c H5HGcache.c H5HGdbg.c H5HGquery.c \
H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c H5HLprfx.c H5HLdblk.c \
- H5HP.c \
H5I.c H5Idbg.c H5Iint.c H5Itest.c \
H5L.c H5Ldeprec.c H5Lexternal.c H5Lint.c \
H5M.c \
H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
+ H5MM.c \
H5MV.c H5MVsection.c \
- H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Odeprec.c H5Oainfo.c H5Oalloc.c H5Oattr.c H5Oattribute.c \
H5Obogus.c H5Obtreek.c H5Ocache.c H5Ocache_image.c H5Ochunk.c \
H5Ocont.c H5Ocopy.c H5Ocopy_ref.c H5Odbg.c H5Odrvinfo.c H5Odtype.c \