hdf5/doc/library-init-shutdown.md
David Young a0445d806c
Simplify function enter macros for performance benefits (#1024)
* Take a stab at using constructors to initialize instead of
function-entry macros.  This is a work in progress.  It's good enough to
run `many_dsets`.

* Committing clang-format changes

* Add the `many_dsets` benchmark and some scripts I used on jelly for
setting up the build/test environment and for recording/flame-graphing
profiles.

* Committing clang-format changes

* Change my Makefile and environment script to work both on jelly
and on mayll (and probably on Summit).

* Disable clang-format "fix."

* Replace the `if (!H5_TERM_GLOBAL)` test in each FUNC_ENTER_ macro with
`if (true)`.

* Fix bad grammar in a comment.

* Instead of labeling the H5*__init_package routines constructors, fold
each into an initialization routine, H5*_init(), and call each of
the H5*_init() routines.  Call most of the H5*_init() routines from
H5_init_library() in an explicit order that I found out earlier by
instrumenting each __init_package routine and running the library
tests.  Roll H5FD*__init_package routines into H5FD*_init() routines.
This change ends just-in-time initialization of package dependencies by
package initializers.

Don't track in per-package variables (H5_PKG_INIT_VAR) whether each
package has been initialized.  Instead, track in a single library
variable whether the whole library is initialized or not.

Drive the initialization of packages by H5_init_library() with a table
of initializer routines.  Also drive the termination of packages by
H5_term_library() with a table.

Perform initialization as needed from FUNC_ENTER_API_INIT(err).  This
basically restores the old behavior of that macro.

Delete a bunch of #definitions in H5private.h that have fallen out of
use with these changes.

* Committing clang-format changes

* Undo the bad auto-formatting that appears to have occurred in spite
of my disabling it.  Bracket some code in /* clang-format off */ /*
clang-format on */ to prevent a recurrence.

* Remove a diagnostic abort().

* Fix a logic error: print a comma between every package terminator run,
and don't print an initial comma.

* Complete the changes I started in H5_term_library() that undo the bad
auto-formatting.

Stop tracking whether package "tops" were initialized in per-package
variables H5*_top_package_initialize_s.  H5_term_library() takes care of
that for them.

Remove H5R_top_term_package() and H5R_term_package(), they don't do
anything.

* Committing clang-format changes

* NFCI.  Simplify macro text: replace `if (true) {` with `{`.

* Fix formatting and suppress clang-format on a longer range.

* Quiet some unused label, unused variable complaints that cropped up
after I simplified the FUNC_ENTER_ macros for the sake of performance.

* Committing clang-format changes

* Delete some programs and scripts that don't belong in the pull request.

* Use the right function-entry macro.

* Use a sensible format and disable auto-formatting.

* Stop calling do-nothing initializer H5FS_init().  Delete it.

* Document what changes to make if the default VFD changes.

* While I am here, change an `await_prior` flag on the terminator table
to `true` to match the previous, non-table-driven code that was here.
Found the oversight making the following changes:

NFCI: insert an empty line and copy over slightly-edited comments from
the previous version, where those comments still correctly explained how
library termination operated.

* NFCI: lower a staircase.

* Replace every occurrence of FUNC_ENTER_NOAPI_INIT(...) with H5_PUSH_FUNC
since that is all that that macro does any more.

Quiet a bunch of new warnings by changing FUNC_ENTER_NOAPI(...) to
FUNC_ENTER_NOAPI_NOERR and removing disused `done:` labels.

* NFCI: add curly braces around a multiline statement.

* Quiet a signed/unsigned comparison warning.

* Add some documentation about library initialization and shutdown.

* Make sure that the library is initialized, or else that initialization
is already underway, before performing any VFD's initialization.

* Committing clang-format changes

* Committing clang-format changes

* Reduce differences from `develop` branch.

* Always initialize `tot_init`.

* Committing clang-format changes

* Fix typo: H5SL_init initializes skip lists, not VOL.

* Remove H5_TERM_GLOBAL test in H5T_init.  H5T_init was unusual in that
it tested H5_TERM_GLOBAL and exited early if it was set.  No other
module initializers did that, and I cannot find any reason that should
be necessary.  Tests still pass when I remove it, so away it goes.

* Use HD prefix.

* Add function header comments.

* Drop the intermediate variable, it's only used once.

* Extract subroutine `H5FDperform_init(hid_t (*init)(void))` that
initializes the library, if necessary, before calling its VFD-initializer
argument.  Use H5FDperform_init in the definition of the symbols
H5FD_<vfd> (e.g., H5FD_SEC2), which may be evaluated before the library
is initialized, like so:

```
```

I implement H5FDperform_init in its own source file, H5FDperform.c,
and exclude that file from trace processing because the `bin/trace`
cannot deal with the function-pointer type.

* Straggler from last: add new source file src/H5FDperform.c.

* Committing clang-format changes

* Add a missing file to the MANIFEST.

* Switch to FUNC_ENTER_API_NOINIT in H5FDperform_init() and hbool_t in
H5_term_library().

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2021-11-08 15:08:07 -06:00

57 lines
2.6 KiB
Markdown

# HDF5 Library initialization and shutdown
## Application perspective
### Implicit initialization and shutdown
When a developer exports a new symbol as part of the HDF5 library,
they should make sure that an application cannot enter the library in an
uninitialized state through a new API function, or read an uninitialized
value from a non-function HDF5 symbol.
The HDF5 library initializes itself when an application either enters
the library through an API function call such as `H5Fopen`, or when
an application evaluates an HDF5 symbol that represents either a
property-list identifier such as `H5F_ACC_RDONLY` or `H5F_ACC_RDWR`,
a property-list class identifier such as `H5P_FILE_ACCESS`, a VFD
identifier such as `H5FD_FAMILY` or `H5FD_SEC2`, or a type identifier
such as `H5T_NATIVE_INT64`.
The library sets a flag when initialization occurs and as long as the
flag is set, skips initialization.
The library provides a couple of macros that initialize the library
as necessary. The library is initialized as a side-effect of the
`FUNC_ENTER_API*` macros used at the top of most API functions. HDF5
library symbols other than functions are provided through `#define`s
that use `H5OPEN` to introduce a library-initialization call (`H5open`)
at each site where a non-function symbol is used.
Ordinarily the library registers an `atexit(3)` handler to shut itself
down when the application exits.
### Explicit initialization and shutdown
An application may use an API call, `H5open`, to explicitly initialize
the library. `H5close` explicitly shuts down the library.
## Library internals perspective
No matter how library initializion begins, eventually the internal
function `H5_init_library` will be called. `H5_init_library` is
responsible for calling the initializers for every internal HDF5
library module (aka "package") in the correct order so that no module is
initialized before its prerequisite modules. A table in `H5_init_library`
establishes the order of initialization. If a developer adds a
module to the library that it is appropriate to initialize with the rest
of the library, then they should insert its initializer into the right
place in the table.
`H5_term_library` drives library shutdown. Library shutdown is
table-driven, too. If a developer adds a module that needs to release
resources during library shutdown, then they should add a call at the
right place to the shutdown table. Note that some entries in the shutdown
table are marked as "barriers," and if a new module should only be
shutdown *strictly after* the preceding modules, then it should be marked
as a barrier. See the comments in `H5_term_library` for more information.