Skip to content

Commit

Permalink
Make global type info access threadsafe
Browse files Browse the repository at this point in the history
Signed-off-by: Quincey Koziol <[email protected]>
  • Loading branch information
qkoziol committed Dec 5, 2024
1 parent 0f7e26c commit 2de8e28
Show file tree
Hide file tree
Showing 23 changed files with 854 additions and 192 deletions.
2 changes: 2 additions & 0 deletions config/cmake/HDFCompilerFlags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ if (HDF5_ENABLE_DEBUG_APIS)
H5D_DEBUG
H5D_CHUNK_DEBUG
H5F_DEBUG
H5I_DEBUG
H5MM_DEBUG
H5O_DEBUG
H5T_DEBUG
H5TS_DEBUG
H5Z_DEBUG
)
endif ()
Expand Down
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3072,8 +3072,8 @@ AC_SUBST([INTERNAL_DEBUG_OUTPUT])
## too specialized or have huge performance hits. These
## are not listed in the "all" packages list.
##
## all_packages="AC,B2,CX,D,F,FA,FL,FS,MM,O,T,TS,Z"
all_packages="AC,B2,CX,D,F,MM,O,T,TS,Z"
## all_packages="AC,B2,CX,D,F,FA,FL,FS,I,MM,O,T,TS,Z"
all_packages="AC,B2,CX,D,F,I,MM,O,T,TS,Z"

case "X-$INTERNAL_DEBUG_OUTPUT" in
X-yes|X-all)
Expand Down
2 changes: 1 addition & 1 deletion src/H5Aint.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ typedef H5A_t *H5A_t_ptr;
H5FL_SEQ_DEFINE_STATIC(H5A_t_ptr);

/* Attribute ID class */
static const H5I_class_t H5I_ATTR_CLS[1] = {{
static H5I_class_t H5I_ATTR_CLS[1] = {{
H5I_ATTR, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
Expand Down
2 changes: 1 addition & 1 deletion src/H5Dint.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static H5D_shared_t H5D_def_dset;
H5_GCC_DIAG_ON("larger-than=")

/* Dataset ID class */
static const H5I_class_t H5I_DATASET_CLS[1] = {{
static H5I_class_t H5I_DATASET_CLS[1] = {{
H5I_DATASET, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
Expand Down
2 changes: 1 addition & 1 deletion src/H5ESint.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ bool H5_PKG_INIT_VAR = false;
/*******************/

/* Event Set ID class */
static const H5I_class_t H5I_EVENTSET_CLS[1] = {{
static H5I_class_t H5I_EVENTSET_CLS[1] = {{
H5I_EVENTSET, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
Expand Down
6 changes: 3 additions & 3 deletions src/H5Eint.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,23 +173,23 @@ hid_t H5E_first_min_id_g = H5I_INVALID_HID;
hid_t H5E_last_min_id_g = H5I_INVALID_HID;

/* Error class ID class */
static const H5I_class_t H5I_ERRCLS_CLS[1] = {{
static H5I_class_t H5I_ERRCLS_CLS[1] = {{
H5I_ERROR_CLASS, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5E__unregister_class /* Callback routine for closing objects of this class */
}};

/* Error message ID class */
static const H5I_class_t H5I_ERRMSG_CLS[1] = {{
static H5I_class_t H5I_ERRMSG_CLS[1] = {{
H5I_ERROR_MSG, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
(H5I_free_t)H5E__close_msg /* Callback routine for closing objects of this class */
}};

/* Error stack ID class */
static const H5I_class_t H5I_ERRSTK_CLS[1] = {{
static H5I_class_t H5I_ERRSTK_CLS[1] = {{
H5I_ERROR_STACK, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
Expand Down
2 changes: 1 addition & 1 deletion src/H5FD.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ htri_t H5FD_ignore_disabled_file_locks_p = FAIL;
static unsigned long H5FD_file_serial_no_g;

/* File driver ID class */
static const H5I_class_t H5I_VFL_CLS[1] = {{
static H5I_class_t H5I_VFL_CLS[1] = {{
H5I_VFL, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
Expand Down
2 changes: 1 addition & 1 deletion src/H5Fint.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ H5FL_DEFINE(H5F_t);
H5FL_DEFINE(H5F_shared_t);

/* File ID class */
static const H5I_class_t H5I_FILE_CLS[1] = {{
static H5I_class_t H5I_FILE_CLS[1] = {{
H5I_FILE, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
Expand Down
2 changes: 1 addition & 1 deletion src/H5Gint.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ H5FL_DEFINE(H5_obj_t);
/*******************/

/* Group ID class */
static const H5I_class_t H5I_GROUP_CLS[1] = {{
static H5I_class_t H5I_GROUP_CLS[1] = {{
H5I_GROUP, /* ID class value */
0, /* Class flags */
0, /* # of reserved IDs for class */
Expand Down
61 changes: 21 additions & 40 deletions src/H5I.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "H5Ipkg.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5TSprivate.h" /* Threadsafety */

/****************/
/* Local Macros */
Expand Down Expand Up @@ -93,53 +94,29 @@ H5I_type_t
H5Iregister_type(size_t H5_ATTR_UNUSED hash_size, unsigned reserved, H5I_free_t free_func)
{
H5I_class_t *cls = NULL; /* New ID class */
H5I_type_t new_type = H5I_BADID; /* New ID type value */
H5I_type_t ret_value = H5I_BADID; /* Return value */

FUNC_ENTER_API(H5I_BADID)

/* Generate a new H5I_type_t value */

/* Increment the number of types */
if (H5I_next_type_g < H5I_MAX_NUM_TYPES) {
new_type = (H5I_type_t)H5I_next_type_g;
H5I_next_type_g++;
}
else {
bool done; /* Indicate that search was successful */
int i;

/* Look for a free type to give out */
done = false;
for (i = H5I_NTYPES; i < H5I_MAX_NUM_TYPES && done == false; i++) {
if (NULL == H5I_type_info_array_g[i]) {
/* Found a free type ID */
new_type = (H5I_type_t)i;
done = true;
}
}

/* Verify that we found a type to give out */
if (done == false)
HGOTO_ERROR(H5E_ID, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded");
}

/* Allocate new ID class */
if (NULL == (cls = H5MM_calloc(sizeof(H5I_class_t))))
HGOTO_ERROR(H5E_ID, H5E_CANTALLOC, H5I_BADID, "ID class allocation failed");

/* Initialize class fields */
cls->type = new_type;
cls->flags = H5I_CLASS_IS_APPLICATION;
/* Initialize non-zero class fields */
cls->type = H5I_UNINIT;
cls->reserved = reserved;
cls->free_func = free_func;

/* Register the new ID class */
if (H5I_register_type(cls) < 0)
HGOTO_ERROR(H5E_ID, H5E_CANTINIT, H5I_BADID, "can't initialize ID class");

/* Indicate that the class object should be freed when the type is destroyed */
/* (Should be set after errors could occur) */
cls->flags = H5I_CLASS_IS_APPLICATION;

/* Set return value */
ret_value = new_type;
ret_value = cls->type;

done:
/* Clean up on error */
Expand Down Expand Up @@ -170,11 +147,12 @@ H5Itype_exists(H5I_type_t type)
/* Validate parameter */
if (H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type");
if (type <= H5I_BADID || (int)type >= H5I_next_type_g)
if (type <= H5I_BADID || (int)type >= H5TS_ATOMIC_LOAD_INT(&H5I_next_type_g))
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");

if (NULL == H5I_type_info_array_g[type])
ret_value = false;
/* Check for valid type */
if ((ret_value = H5I__is_type_valid(type)) < 0)
HGOTO_ERROR(H5E_ID, H5E_CANTGET, FAIL, "can't check if ID is valid");

done:
FUNC_LEAVE_API(ret_value)
Expand All @@ -195,6 +173,7 @@ H5Itype_exists(H5I_type_t type)
herr_t
H5Inmembers(H5I_type_t type, hsize_t *num_members)
{
htri_t is_valid; /* Whether type is valid */
herr_t ret_value = SUCCEED; /* Return value */

FUNC_ENTER_API(FAIL)
Expand All @@ -206,9 +185,11 @@ H5Inmembers(H5I_type_t type, hsize_t *num_members)
* the private interface handle it, because the public interface throws
* an error when the supplied type does not exist.
*/
if (type <= H5I_BADID || (int)type >= H5I_next_type_g)
if (type <= H5I_BADID || (int)type >= H5TS_ATOMIC_LOAD_INT(&H5I_next_type_g))
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
if (NULL == H5I_type_info_array_g[type])
if ((is_valid = H5I__is_type_valid(type)) < 0)
HGOTO_ERROR(H5E_ID, H5E_CANTGET, FAIL, "can't check if ID is valid");
else if (false == is_valid)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "supplied type does not exist");

if (num_members) {
Expand Down Expand Up @@ -363,7 +344,7 @@ H5Iobject_verify(hid_t id, H5I_type_t type)
/* Validate parameters */
if (H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "cannot call public function on library type");
if (type < 1 || (int)type >= H5I_next_type_g)
if (type < 1 || (int)type >= H5TS_ATOMIC_LOAD_INT(&H5I_next_type_g))
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "identifier has invalid type");

ret_value = H5I_object_verify(id, type);
Expand Down Expand Up @@ -396,7 +377,7 @@ H5Iget_type(hid_t id)

ret_value = H5I_get_type(id);

if (ret_value <= H5I_BADID || (int)ret_value >= H5I_next_type_g || NULL == H5I_object(id))
if (ret_value <= H5I_BADID || (int)ret_value >= H5TS_ATOMIC_LOAD_INT(&H5I_next_type_g )|| NULL == H5I_object(id))
HGOTO_DONE(H5I_BADID);

done:
Expand Down Expand Up @@ -541,7 +522,7 @@ H5Iinc_type_ref(H5I_type_t type)
FUNC_ENTER_API((-1))

/* Check arguments */
if (type <= 0 || (int)type >= H5I_next_type_g)
if (type <= 0 || (int)type >= H5TS_ATOMIC_LOAD_INT(&H5I_next_type_g))
HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID type");
if (H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, (-1), "cannot call public function on library type");
Expand Down Expand Up @@ -612,7 +593,7 @@ H5Iget_type_ref(H5I_type_t type)
FUNC_ENTER_API((-1))

/* Check arguments */
if (type <= 0 || (int)type >= H5I_next_type_g)
if (type <= 0 || (int)type >= H5TS_ATOMIC_LOAD_INT(&H5I_next_type_g))
HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID type");
if (H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, (-1), "cannot call public function on library type");
Expand Down
24 changes: 20 additions & 4 deletions src/H5Idbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "H5Tprivate.h" /* Datatypes */
#include "H5VLprivate.h" /* Virtual Object Layer */

#ifdef H5I_DEBUG

/****************/
/* Local Macros */
/****************/
Expand Down Expand Up @@ -164,14 +166,22 @@ herr_t
H5I_dump_ids_for_type(H5I_type_t type)
{
H5I_type_info_t *type_info = NULL;
bool have_lock = false; /* Whether the type's lock is held */
herr_t ret_value = SUCCEED; /* Return value */

FUNC_ENTER_NOAPI_NOERR
FUNC_ENTER_NOAPI(FAIL)

fprintf(stderr, "Dumping ID type %d\n", (int)type);
type_info = H5I_type_info_array_g[type];

if (type_info) {
/* Acquire the mutex protecting the global type info */
if (H5I__type_info_acquire(type) < 0)
HGOTO_ERROR(H5E_ID, H5E_CANTLOCK, FAIL, "can't lock type info's mutex");
have_lock = true;

/* Get the pointer to the type info */
type_info = H5I_type_info_array_g[type].type_info;

if (type_info) {
H5I_id_info_t *item = NULL;
H5I_id_info_t *tmp = NULL;

Expand Down Expand Up @@ -200,5 +210,11 @@ H5I_dump_ids_for_type(H5I_type_t type)
else
fprintf(stderr, "Global type info/tracking pointer for that type is NULL\n");

FUNC_LEAVE_NOAPI(SUCCEED)
done:
/* Release exclusive access for the type */
if (have_lock && H5I__type_info_release(type) < 0)
HDONE_ERROR(H5E_ID, H5E_CANTUNLOCK, FAIL, "can't release lock on type");

FUNC_LEAVE_NOAPI(ret_value)
} /* end H5I_dump_ids_for_type() */
#endif /* H5I_DEBUG */
Loading

0 comments on commit 2de8e28

Please sign in to comment.