Skip to content

Commit 331193f

Browse files
authored
Add new multithreaded concurrency configuration (HDFGroup#5015)
Added infrastructure support for multithreaded concurrency by adding an optional way to switch to using a non-recursive R/W lock for the global API lock. This is enabled with a new 'concurrency' configuration flag for the autotools & CMake builds, which is disabled by default. When the 'concurrency' build option is chosen, the global API lock will use the R/W lock and all API calls currently will acquire a write lock, ensuring exclusive access by one thread. Over time, the API routines that are converted to support multithreaded concurrency will switch to acquiring a read lock instead. Reentering the library from application callbacks is managed by the 'disable locking for this thread' (DLFTT) threadsafety protocol. This is internally handled within the H5_API_LOCK / H5_API_UNLOCK macros in H5private.h (as before), which invoke the 'dlftt' routines in H5TSint.c. To support this change, the threadsafety configuration macros for the library have been updated: - --enable-threadsafe now defines the H5_HAVE_THREADSAFE macro - --enable-concurrency defines the H5_HAVE_CONCURRENCY macro The new H5_HAVE_THREADSAFE_API macro is set if either H5_HAVE_THREADSAFE or H5_HAVE_CONCURRENCY is enabled. New Github actions are added to include the concurrency configuration in the CI for the develop branch. To support the new non-recursive R/W locking for API routines, some other changes are necessary: Added macro wrappers around all callback invocations that could call an application function, and therefore re-enter the library: H5_BEFORE_USER_CB* / H5_AFTER_USER_CB* Added H5_user_cb_prepare / H5_user_cb_restore routines that save the state of the library when callback leaves the library. Includes error stack and threadsafe reentry state currently. There's also some small cleanups to various places in the library: Moved the H5E_mpi_error_str / H5E_mpi_error_str_len globals to be local for pushing MPI errors, so that multiple threads can't interfere with each other. Added H5TS_rwlock_trywrlock() routine to R/W lock interface. Emulate R/W locks on MacOS because its implementation of pthread_rwlock_wrlock() does not conform to the POSIX standard. Don't acquire the global API lock in H5close, since it's acquired in H5_term_library, which is necessary because H5_term_library is invoked via other code paths that don't hold the global API lock. Don't call H5Eget_auto2 API routine within H5_term_library. Switched 'return NULL' in H5allocate_memory to HGOTO_DONE(NULL). Switched H5Pget_file_space_strategy / H5Pset_file_space_strategy to use internal routines instead of API routines. Switched H5Oopen_by_addr & H5Ovisit1 to use internal routines instead of API routines. Fixed a few places in src/H5Odeprec.c where a major error ID was passed as a minor ID.
1 parent f9d60b5 commit 331193f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+4385
-1252
lines changed

.clang-format

+3-4
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ IndentCaseLabels: true
5858
IndentGotoLabels: false
5959
#llvm11: IndentExternBlock: AfterExternBlock
6060
#llvm11: InsertTrailingCommas: None
61-
MacroBlockBegin: "^BEGIN_FUNC"
62-
MacroBlockEnd: "^END_FUNC"
61+
MacroBlockBegin: "^H5_BEFORE_USER_CB*|^H5E_PAUSE_ERRORS"
62+
MacroBlockEnd: "^H5_AFTER_USER_CB*|^H5E_RESUME_ERRORS"
6363
ObjCBlockIndentWidth: 4
6464
#llvm11: ObjCBreakBeforeNestedBlockParam: true
6565
ReflowComments: true
@@ -81,9 +81,8 @@ StatementMacros:
8181
- FUNC_LEAVE_NOAPI_NAMECHECK_ONLY
8282
- FUNC_LEAVE_NOAPI_VOID_NAMECHECK_ONLY
8383
- FUNC_LEAVE_NOAPI_NOFS
84+
- H5E_BEGIN_TRY
8485
- H5E_END_TRY
85-
- H5E_PRINTF
86-
- H5E_THROW
8786
- H5_BEGIN_TAG
8887
- H5_END_TAG
8988
- H5_GCC_DIAG_OFF

.github/workflows/autotools.yml

+20
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,51 @@ jobs:
4444
with:
4545
build_mode: "production"
4646

47+
call-debug-concurrent-autotools:
48+
name: "Autotools Debug Concurrency Workflows"
49+
uses: ./.github/workflows/main-auto.yml
50+
with:
51+
concurrent: enable
52+
thread_safety: disable
53+
build_mode: "debug"
54+
55+
call-release-concurrent-autotools:
56+
name: "Autotools Release Concurrency Workflows"
57+
uses: ./.github/workflows/main-auto.yml
58+
with:
59+
concurrent: enable
60+
thread_safety: disable
61+
build_mode: "production"
62+
4763
call-debug-thread-autotools:
4864
name: "Autotools Debug Thread-Safety Workflows"
4965
uses: ./.github/workflows/main-auto.yml
5066
with:
67+
concurrent: disable
5168
thread_safety: enable
5269
build_mode: "debug"
5370

5471
call-release-thread-autotools:
5572
name: "Autotools Release Thread-Safety Workflows"
5673
uses: ./.github/workflows/main-auto.yml
5774
with:
75+
concurrent: disable
5876
thread_safety: enable
5977
build_mode: "production"
6078

6179
call-debug-autotools:
6280
name: "Autotools Debug Workflows"
6381
uses: ./.github/workflows/main-auto.yml
6482
with:
83+
concurrent: disable
6584
thread_safety: disable
6685
build_mode: "debug"
6786

6887
call-release-autotools:
6988
name: "Autotools Release Workflows"
7089
uses: ./.github/workflows/main-auto.yml
7190
with:
91+
concurrent: disable
7292
thread_safety: disable
7393
build_mode: "production"
7494

.github/workflows/cmake.yml

+20
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,51 @@ jobs:
2828
name: "CMake Special Workflows"
2929
uses: ./.github/workflows/main-cmake-spc.yml
3030

31+
call-debug-concurrent-cmake:
32+
name: "CMake Debug Concurrency Workflows"
33+
uses: ./.github/workflows/main-cmake.yml
34+
with:
35+
concurrent: "CC"
36+
thread_safety: ""
37+
build_mode: "Debug"
38+
39+
call-release-concurrent-cmake:
40+
name: "CMake Release Concurrency Workflows"
41+
uses: ./.github/workflows/main-cmake.yml
42+
with:
43+
concurrent: "CC"
44+
thread_safety: ""
45+
build_mode: "Release"
46+
3147
call-debug-thread-cmake:
3248
name: "CMake Debug Thread-Safety Workflows"
3349
uses: ./.github/workflows/main-cmake.yml
3450
with:
51+
concurrent: ""
3552
thread_safety: "TS"
3653
build_mode: "Debug"
3754

3855
call-release-thread-cmake:
3956
name: "CMake Release Thread-Safety Workflows"
4057
uses: ./.github/workflows/main-cmake.yml
4158
with:
59+
concurrent: ""
4260
thread_safety: "TS"
4361
build_mode: "Release"
4462

4563
call-debug-cmake:
4664
name: "CMake Debug Workflows"
4765
uses: ./.github/workflows/main-cmake.yml
4866
with:
67+
concurrent: ""
4968
thread_safety: ""
5069
build_mode: "Debug"
5170

5271
call-release-cmake:
5372
name: "CMake Release Workflows"
5473
uses: ./.github/workflows/main-cmake.yml
5574
with:
75+
concurrent: ""
5676
thread_safety: ""
5777
build_mode: "Release"
5878

.github/workflows/main-auto.yml

+28-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ on:
88
description: "thread-safety enable/disable"
99
required: true
1010
type: string
11+
concurrent:
12+
description: "concurrency enable/disable"
13+
required: true
14+
type: string
1115
build_mode:
1216
description: "release vs. debug build"
1317
required: true
@@ -22,7 +26,7 @@ jobs:
2226
# Linux (Ubuntu) w/ gcc + Autotools
2327
#
2428
Autotools_build_and_test:
25-
name: "GCC-${{ inputs.build_mode }}-TS=${{ inputs.thread_safety }}d"
29+
name: "GCC-${{ inputs.build_mode }}-TS=${{ inputs.thread_safety }}d-CC=${{ inputs.concurrent }}d"
2630
# Don't run the action if the commit message says to skip CI
2731
if: "!contains(github.event.head_commit.message, 'skip-ci')"
2832

@@ -60,6 +64,7 @@ jobs:
6064
--enable-shared \
6165
--disable-parallel \
6266
--${{ inputs.thread_safety }}-threadsafe \
67+
--${{ inputs.concurrent }}-concurrency \
6368
--enable-cxx \
6469
--enable-fortran \
6570
--enable-java \
@@ -68,7 +73,7 @@ jobs:
6873
--enable-ros3-vfd \
6974
--with-szlib=yes
7075
shell: bash
71-
if: ${{ inputs.thread_safety == 'disable' }}
76+
if: ${{ inputs.thread_safety == 'disable' && inputs.concurrent == 'disable'}}
7277

7378
- name: Autotools Configure (Thread-Safe)
7479
run: |
@@ -79,14 +84,34 @@ jobs:
7984
--enable-build-mode=${{ inputs.build_mode }} \
8085
--enable-shared \
8186
--${{ inputs.thread_safety }}-threadsafe \
87+
--${{ inputs.concurrent }}-concurrency \
8288
--disable-hl \
8389
--disable-parallel \
8490
--enable-mirror-vfd \
8591
--enable-direct-vfd \
8692
--enable-ros3-vfd \
8793
--with-szlib=yes
8894
shell: bash
89-
if: ${{ inputs.thread_safety == 'enable' }}
95+
if: ${{ inputs.thread_safety == 'enable' && inputs.concurrent == 'disable' }}
96+
97+
- name: Autotools Configure (Concurrency)
98+
run: |
99+
sh ./autogen.sh
100+
mkdir "${{ runner.workspace }}/build"
101+
cd "${{ runner.workspace }}/build"
102+
$GITHUB_WORKSPACE/configure \
103+
--enable-build-mode=${{ inputs.build_mode }} \
104+
--enable-shared \
105+
--${{ inputs.thread_safety }}-threadsafe \
106+
--${{ inputs.concurrent }}-concurrency \
107+
--disable-hl \
108+
--disable-parallel \
109+
--enable-mirror-vfd \
110+
--enable-direct-vfd \
111+
--enable-ros3-vfd \
112+
--with-szlib=yes
113+
shell: bash
114+
if: ${{ inputs.thread_safety == 'disable' && inputs.concurrent == 'enable' }}
90115

91116
- name: Autotools Build
92117
run: make -j3

.github/workflows/main-cmake.yml

+40-13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ on:
88
description: "TS or empty"
99
required: true
1010
type: string
11+
concurrent:
12+
description: "CC or empty"
13+
required: true
14+
type: string
1115
build_mode:
1216
description: "release vs. debug build"
1317
required: true
@@ -103,7 +107,7 @@ jobs:
103107
run_tests: true
104108

105109
# Sets the job's name from the properties
106-
name: "${{ matrix.name }}-${{ inputs.build_mode }}-${{ inputs.thread_safety }}"
110+
name: "${{ matrix.name }}-${{ inputs.build_mode }}-${{ inputs.thread_safety }}-${{ inputs.concurrent }}"
107111

108112
# Don't run the action if the commit message says to skip CI
109113
if: "!contains(github.event.head_commit.message, 'skip-ci')"
@@ -186,7 +190,7 @@ jobs:
186190
-DHDF5_PACK_MACOSX_DMG:BOOL=OFF \
187191
$GITHUB_WORKSPACE
188192
shell: bash
189-
if: ${{ inputs.thread_safety != 'TS' }}
193+
if: ${{ inputs.thread_safety != 'TS' && inputs.concurrent != 'CC'}}
190194

191195
- name: CMake Configure (Thread-Safe)
192196
run: |
@@ -199,6 +203,7 @@ jobs:
199203
-DBUILD_STATIC_LIBS:BOOL=${{ (matrix.os != 'windows-latest') }} \
200204
-DHDF5_ENABLE_ALL_WARNINGS:BOOL=ON \
201205
-DHDF5_ENABLE_THREADSAFE:BOOL=ON \
206+
-DHDF5_ENABLE_CONCURRENCY:BOOL=OFF \
202207
-DHDF5_ENABLE_PARALLEL:BOOL=${{ matrix.parallel }} \
203208
-DHDF5_BUILD_CPP_LIB:BOOL=OFF \
204209
-DHDF5_BUILD_FORTRAN:BOOL=OFF \
@@ -214,7 +219,35 @@ jobs:
214219
-DHDF5_PACK_MACOSX_DMG:BOOL=OFF \
215220
$GITHUB_WORKSPACE
216221
shell: bash
217-
if: ${{ inputs.thread_safety == 'TS' }}
222+
if: ${{ inputs.thread_safety == 'TS' && inputs.concurrent != 'CC'}}
223+
224+
- name: CMake Configure (Concurrency)
225+
run: |
226+
mkdir "${{ runner.workspace }}/build"
227+
cd "${{ runner.workspace }}/build"
228+
cmake -C $GITHUB_WORKSPACE/config/cmake/cacheinit.cmake \
229+
${{ matrix.generator }} \
230+
-DCMAKE_BUILD_TYPE=${{ inputs.build_mode }} \
231+
-DBUILD_SHARED_LIBS=ON \
232+
-DBUILD_STATIC_LIBS=${{ (matrix.os != 'windows-latest') }} \
233+
-DHDF5_ENABLE_ALL_WARNINGS=ON \
234+
-DHDF5_ENABLE_THREADSAFE:BOOL=OFF \
235+
-DHDF5_ENABLE_CONCURRENCY:BOOL=ON \
236+
-DHDF5_ENABLE_PARALLEL:BOOL=${{ matrix.parallel }} \
237+
-DHDF5_BUILD_CPP_LIB:BOOL=OFF \
238+
-DHDF5_BUILD_FORTRAN:BOOL=OFF \
239+
-DHDF5_BUILD_JAVA:BOOL=OFF \
240+
-DHDF5_BUILD_HL_LIB:BOOL=OFF \
241+
-DHDF5_BUILD_DOC=OFF \
242+
-DLIBAEC_USE_LOCALCONTENT=${{ matrix.localaec }} \
243+
-DZLIB_USE_LOCALCONTENT=${{ matrix.localzlib }} \
244+
-DHDF5_ENABLE_MIRROR_VFD:BOOL=${{ matrix.mirror_vfd }} \
245+
-DHDF5_ENABLE_DIRECT_VFD:BOOL=${{ matrix.direct_vfd }} \
246+
-DHDF5_ENABLE_ROS3_VFD:BOOL=${{ matrix.ros3_vfd }} \
247+
-DHDF5_PACK_EXAMPLES:BOOL=ON \
248+
$GITHUB_WORKSPACE
249+
shell: bash
250+
if: ${{ inputs.thread_safety != 'TS' && inputs.concurrent == 'CC'}}
218251

219252
# BUILD
220253
- name: CMake Build
@@ -225,13 +258,7 @@ jobs:
225258
- name: CMake Run Tests
226259
run: ctest . --parallel 2 -C ${{ inputs.build_mode }} -V
227260
working-directory: ${{ runner.workspace }}/build
228-
if: ${{ matrix.run_tests && (inputs.thread_safety != 'TS') }}
229-
230-
# THREAD-SAFE
231-
- name: CMake Run Thread-Safe Tests
232-
run: ctest . --parallel 2 -C ${{ inputs.build_mode }} -V -R ttsafe
233-
working-directory: ${{ runner.workspace }}/build
234-
if: ${{ matrix.run_tests && (inputs.thread_safety == 'TS') }}
261+
if: ${{ matrix.run_tests }}
235262

236263
- name: CMake Run Package
237264
run: cpack -C ${{ inputs.build_mode }} -V
@@ -253,20 +280,20 @@ jobs:
253280
name: zip-vs2022_cl-${{ inputs.build_mode }}-binary
254281
path: ${{ runner.workspace }}/build/HDF5-*-win64.zip
255282
if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn`
256-
if: ${{ (matrix.os == 'windows-latest') && (inputs.thread_safety != 'TS') && ( inputs.build_mode != 'Debug') }}
283+
if: ${{ (matrix.os == 'windows-latest') && (inputs.thread_safety != 'TS') && (inputs.concurrent != 'CC') && ( inputs.build_mode != 'Debug') }}
257284

258285
- name: Save published binary (linux)
259286
uses: actions/upload-artifact@v4
260287
with:
261288
name: tgz-ubuntu-2404_gcc-${{ inputs.build_mode }}-binary
262289
path: ${{ runner.workspace }}/build/HDF5-*-Linux.tar.gz
263290
if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn`
264-
if: ${{ (matrix.os == 'ubuntu-latest') && (inputs.thread_safety != 'TS') && ( inputs.build_mode != 'Debug') }}
291+
if: ${{ (matrix.os == 'ubuntu-latest') && (inputs.thread_safety != 'TS') && (inputs.concurrent != 'CC') && ( inputs.build_mode != 'Debug') }}
265292

266293
- name: Save published binary (Mac_latest)
267294
uses: actions/upload-artifact@v4
268295
with:
269296
name: tgz-macos14_clang-${{ inputs.build_mode }}-binary
270297
path: ${{ runner.workspace }}/build/HDF5-*-Darwin.tar.gz
271298
if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn`
272-
if: ${{ (matrix.os == 'macos-latest') && (inputs.thread_safety != 'TS') && ( inputs.build_mode != 'Debug') }}
299+
if: ${{ (matrix.os == 'macos-latest') && (inputs.thread_safety != 'TS') && (inputs.concurrent != 'CC') && ( inputs.build_mode != 'Debug') }}

CMakeLists.txt

+53
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,59 @@ if (HDF5_ENABLE_THREADSAFE)
985985
set (H5_HAVE_THREADSAFE 1)
986986
endif ()
987987

988+
#-----------------------------------------------------------------------------
989+
# Option to use multi-threaded concurrency
990+
#-----------------------------------------------------------------------------
991+
option (HDF5_ENABLE_CONCURRENCY "Enable multi-threaded concurrency" OFF)
992+
if (HDF5_ENABLE_CONCURRENCY)
993+
# check for unsupported options
994+
if (WIN32)
995+
if (BUILD_STATIC_LIBS)
996+
message (FATAL_ERROR " **** multi-threaded concurrency option not supported with static library **** ")
997+
endif ()
998+
endif ()
999+
if (HDF_ENABLE_PARALLEL)
1000+
if (NOT ALLOW_UNSUPPORTED)
1001+
message (FATAL_ERROR " **** Parallel and multi-threaded concurrency options are not supported, override with ALLOW_UNSUPPORTED option **** ")
1002+
else ()
1003+
message (VERBOSE " **** Allowing unsupported parallel and multi-threaded concurrency options **** ")
1004+
endif ()
1005+
endif ()
1006+
if (HDF5_BUILD_FORTRAN)
1007+
if (NOT ALLOW_UNSUPPORTED)
1008+
message (FATAL_ERROR " **** Fortran and multi-threaded concurrency options are not supported, override with ALLOW_UNSUPPORTED option **** ")
1009+
else ()
1010+
message (VERBOSE " **** Allowing unsupported Fortran and multi-threaded concurrency options **** ")
1011+
endif ()
1012+
endif ()
1013+
if (HDF5_BUILD_CPP_LIB)
1014+
if (NOT ALLOW_UNSUPPORTED)
1015+
message (FATAL_ERROR " **** C++ and multi-threaded concurrency options are not supported, override with ALLOW_UNSUPPORTED option **** ")
1016+
else ()
1017+
message (VERBOSE " **** Allowing unsupported C++ and multi-threaded concurrency options **** ")
1018+
endif ()
1019+
endif ()
1020+
if (HDF5_BUILD_HL_LIB)
1021+
if (NOT ALLOW_UNSUPPORTED)
1022+
message (FATAL_ERROR " **** HL and multi-threaded concurrency options are not supported, override with ALLOW_UNSUPPORTED option **** ")
1023+
else ()
1024+
message (VERBOSE " **** Allowing unsupported HL and multi-threaded concurrency options **** ")
1025+
endif ()
1026+
endif ()
1027+
1028+
# Check for threading package
1029+
if (NOT Threads_FOUND)
1030+
message (FATAL_ERROR " **** multi-threaded concurrency option requires a threading package and none was found **** ")
1031+
endif ()
1032+
1033+
# Multi-threaded concurrency and threadsafe options are mutually exclusive
1034+
if (HDF5_ENABLE_THREADSAFE)
1035+
message (FATAL_ERROR " **** multi-threaded concurrency and threadsafe options are mutually exclusive **** ")
1036+
endif ()
1037+
1038+
set (H5_HAVE_CONCURRENCY 1)
1039+
endif ()
1040+
9881041
#-----------------------------------------------------------------------------
9891042
# Option to build the map API
9901043
#-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)