Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added selective async APIs #150

Merged
merged 4 commits into from
Dec 12, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
495 changes: 415 additions & 80 deletions src/H5M.c

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions src/H5Mpublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,25 +83,49 @@ extern "C" {

H5_DLL hid_t H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id,
hid_t mcpl_id, hid_t mapl_id);
H5_DLL hid_t H5Mcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, hid_t es_id);
H5_DLL hid_t H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id);
H5_DLL hid_t H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id);
H5_DLL hid_t H5Mopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, hid_t mapl_id, hid_t es_id);
H5_DLL herr_t H5Mclose(hid_t map_id);
H5_DLL herr_t H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t es_id);
H5_DLL hid_t H5Mget_key_type(hid_t map_id);
H5_DLL hid_t H5Mget_val_type(hid_t map_id);
H5_DLL hid_t H5Mget_create_plist(hid_t map_id);
H5_DLL hid_t H5Mget_access_plist(hid_t map_id);
H5_DLL herr_t H5Mget_count(hid_t map_id, hsize_t *count, hid_t dxpl_id);
H5_DLL herr_t H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
const void *value, hid_t dxpl_id);
H5_DLL herr_t H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id, hid_t es_id);
H5_DLL herr_t H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
hid_t dxpl_id);
H5_DLL herr_t H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id, hid_t es_id);
H5_DLL herr_t H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id);
H5_DLL herr_t H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data,
hid_t dxpl_id);
H5_DLL herr_t H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_mem_type_id,
H5M_iterate_t op, void *op_data, hid_t dxpl_id, hid_t lapl_id);
H5_DLL herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id);

/* API Wrappers for async routines */
/* (Must be defined _after_ the function prototype) */
/* (And must only defined when included in application code, not the library) */
#ifndef H5M_MODULE
#define H5Mcreate_async(...) H5Mcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
#define H5Mopen_async(...) H5Mopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
#define H5Mclose_async(...) H5Mclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
#define H5Mput_async(...) H5Mput_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
#define H5Mget_async(...) H5Mget_async(__FILE__, __func__, __LINE__, __VA_ARGS__)

/* Define "wrapper" versions of function calls, to allow compile-time values to
* be passed in by language wrapper or library layer on top of HDF5. */
#define H5Mcreate_async_wrap H5_NO_EXPAND(H5Mcreate_async)
#define H5Mopen_async_wrap H5_NO_EXPAND(H5Mopen_async)
#define H5Mclose_async_wrap H5_NO_EXPAND(H5Mclose_async)
#define H5Mput_async_wrap H5_NO_EXPAND(H5Mput_async)
#define H5Mget_async_wrap H5_NO_EXPAND(H5Mget_async)
#endif /* H5M_MODULE */

/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
* Use of these symbols is deprecated.
Expand Down
341 changes: 273 additions & 68 deletions src/H5R.c

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions src/H5Rpublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,11 @@ H5_DLL herr_t H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr);

/* Dereference */
H5_DLL hid_t H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id);
H5_DLL hid_t H5Ropen_object_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, hid_t es_id);
H5_DLL hid_t H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id);
H5_DLL hid_t H5Ropen_region_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, hid_t es_id);
H5_DLL hid_t H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id);
H5_DLL hid_t H5Ropen_attr_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id, hid_t es_id);

/* Get type */
H5_DLL herr_t H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type);
Expand All @@ -124,6 +127,21 @@ H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size
H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size);
H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size);

/* API Wrappers for async routines */
/* (Must be defined _after_ the function prototype) */
/* (And must only defined when included in application code, not the library) */
#ifndef H5R_MODULE
#define H5Ropen_object_async(...) H5Ropen_object_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
#define H5Ropen_region_async(...) H5Ropen_region_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
#define H5Ropen_attr_async(...) H5Ropen_attr_async(__FILE__, __func__, __LINE__, __VA_ARGS__)

/* Define "wrapper" versions of function calls, to allow compile-time values to
* be passed in by language wrapper or library layer on top of HDF5. */
#define H5Ropen_object_async_wrap H5_NO_EXPAND(H5Ropen_object_async)
#define H5Ropen_region_async_wrap H5_NO_EXPAND(H5Ropen_region_async)
#define H5Ropen_attr_async_wrap H5_NO_EXPAND(H5Ropen_attr_async)
#endif /* H5R_MODULE */

/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
* Use of these symbols is or will be deprecated.
Expand Down
186 changes: 164 additions & 22 deletions src/H5T.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 "H5FOprivate.h" /* File objects */
Expand Down Expand Up @@ -347,6 +348,7 @@ static herr_t H5T__unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T
static htri_t H5T__compiler_conv(H5T_t *src, H5T_t *dst);
static herr_t H5T__set_size(H5T_t *dt, size_t size);
static herr_t H5T__close_cb(H5T_t *dt, void **request);
static hid_t H5T__copy_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name,
H5T_conv_func_t *conv);
static hbool_t H5T__detect_vlen_ref(const H5T_t *dt);
Expand Down Expand Up @@ -1852,33 +1854,30 @@ H5Tcreate(H5T_class_t type, size_t size)
} /* end H5Tcreate() */

/*-------------------------------------------------------------------------
* Function: H5Tcopy
* Function: H5T__copy_api_common
*
* Purpose: Copies a datatype. The resulting datatype is not locked.
* The datatype should be closed when no longer needed by
* calling H5Tclose().
* Purpose: This is the common function for copying a datytype.
*
* Return: Success: The ID of a new datatype
*
* Failure: H5I_INVALID_HID
*
* Note: The returned type is always transient and unlocked. If the
* TYPE_ID argument is a dataset instead of a datatype then
* this function returns a transient, modifiable datatype
* which is a copy of the dataset's datatype.
*
*-------------------------------------------------------------------------
*/
hid_t
H5Tcopy(hid_t obj_id)
static hid_t
H5T__copy_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
H5VL_object_t **vol_obj_ptr =
(_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
H5VL_loc_params_t loc_params; /* Location parameters */

H5T_t *dt = NULL; /* Pointer to the datatype to copy */
H5T_t *new_dt = NULL; /* Pointer to the new datatype */
hid_t dset_tid = H5I_INVALID_HID; /* Datatype ID from dataset */
hid_t ret_value = H5I_INVALID_HID; /* Return value */

FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE1("i", "i", obj_id);
FUNC_ENTER_STATIC

switch (H5I_get_type(obj_id)) {
case H5I_DATATYPE:
Expand All @@ -1888,16 +1887,14 @@ H5Tcopy(hid_t obj_id)
break;

case H5I_DATASET: {
H5VL_object_t *vol_obj = NULL; /* Dataset structure */

/* The argument is a dataset handle */
if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(obj_id, H5I_DATASET)))
if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(obj_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "type_id is not a dataset ID")

/* Get the datatype from the dataset
* NOTE: This will have to be closed after we're done with it.
*/
if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL,
if (H5VL_dataset_get(*vol_obj_ptr, H5VL_DATASET_GET_TYPE, H5P_DATASET_XFER_DEFAULT, token_ptr,
&dset_tid) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5I_INVALID_HID,
"unable to get datatype from the dataset")
Expand Down Expand Up @@ -1942,25 +1939,110 @@ H5Tcopy(hid_t obj_id)
/* If we got a type ID from a passed-in dataset, we need to close that */
if (dset_tid != H5I_INVALID_HID)
if (H5I_dec_app_ref(dset_tid) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_BADATOM, FAIL, "problem freeing temporary dataset type ID")
HGOTO_ERROR(H5E_DATATYPE, H5E_BADATOM, H5I_INVALID_HID, "problem freeing temporary dataset type ID")

/* Close the new datatype on errors */
if (H5I_INVALID_HID == ret_value)
if (new_dt && H5T_close_real(new_dt) < 0)
HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to release datatype info")

FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__copy_api_common() */

/*-------------------------------------------------------------------------
* Function: H5Tcopy
*
* Purpose: Copies a datatype. The resulting datatype is not locked.
* The datatype should be closed when no longer needed by
* calling H5Tclose().
*
* Return: Success: The ID of a new datatype
*
* Failure: H5I_INVALID_HID
*
* Note: The returned type is always transient and unlocked. If the
* TYPE_ID argument is a dataset instead of a datatype then
* this function returns a transient, modifiable datatype
* which is a copy of the dataset's datatype.
*
*-------------------------------------------------------------------------
*/
hid_t
H5Tcopy(hid_t obj_id)
{
H5T_t *dt = NULL; /* Pointer to the datatype to copy */
H5T_t *new_dt = NULL; /* Pointer to the new datatype */
hid_t dset_tid = H5I_INVALID_HID; /* Datatype ID from dataset */
hid_t ret_value = H5I_INVALID_HID; /* Return value */

FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE1("i", "i", obj_id);

/* Copy the object's datatype synchronously */
if ((ret_value = H5T__copy_api_common(obj_id, NULL, NULL)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5I_INVALID_HID, "unable to copy datatype synchronously")

done:
FUNC_LEAVE_API(ret_value)
} /* end H5Tcopy() */

/*-------------------------------------------------------------------------
* Function: H5Tcopy_async
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not entirely convinced we need an async version of H5Tcopy, since it's not really an operation that deals with the file. I see that it could trigger a VOL callback, but I would defer delivering this to users until later, since I think that adding an asynchronous version of an operation that isn't really about VOL object could be a slippery slope into "asynchronous operations for all API routines", which is a Pandora's Box that I'd rather open later. :-) So, I would suggest reverting the changes to H5Tcopy and just let it execute synchronously for situations where it triggered the VOL callback. (We can always add it later)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, put it simply, take everything new related to H5Tcopy out and put original H5Tcopy back, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes :-)

*
* Purpose: Asynchronous version of H5Tcopy.
*
* Return: Success: The ID of a new datatype
*
* Failure: H5I_INVALID_HID
*
* Note: The returned type is always transient and unlocked. If the
* TYPE_ID argument is a dataset instead of a datatype then
* this function returns a transient, modifiable datatype
* which is a copy of the dataset's datatype.
*
*-------------------------------------------------------------------------
*/
hid_t
H5Tcopy_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, hid_t es_id)
{
H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
void * token = NULL; /* Request token for async operation */
void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
hid_t ret_value = H5I_INVALID_HID; /* Return value */

FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE5("i", "*s*sIuii", app_file, app_func, app_line, obj_id, es_id);

/* Set up request token pointer for asynchronous operation */
if (H5ES_NONE != es_id)
token_ptr = &token; /* Point at token for VOL connector to set up */

/* Copy the object's datatype asynchronously */
if ((ret_value = H5T__copy_api_common(obj_id, token_ptr, &vol_obj)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5I_INVALID_HID, "unable to copy datatype asynchronously")

/* If a token was created, add the token to the event set */
if (NULL != token)
if (H5ES_insert(es_id, vol_obj->connector, token,
H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, obj_id, es_id)) < 0) {
if (H5I_dec_app_ref_always_close(ret_value) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on datatype ID")
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
} /* end if */

done:
FUNC_LEAVE_API(ret_value)
} /* end H5Tcopy_async() */

/*-------------------------------------------------------------------------
* Function: H5Tclose
*
* Purpose: Frees a datatype and all associated memory.
* Purpose: Frees a datatype and all associated memory.
*
* Return: Non-negative on success/Negative on failure
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* Tuesday, December 9, 1997
* Programmer: Robb Matzke
* Tuesday, December 9, 1997
*-------------------------------------------------------------------------
*/
herr_t
Expand All @@ -1986,6 +2068,66 @@ H5Tclose(hid_t type_id)
FUNC_LEAVE_API(ret_value)
} /* end H5Tclose() */

/*-------------------------------------------------------------------------
* Function: H5Tclose_async
*
* Purpose: Asynchronous version of H5Tclose.
*
* Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
herr_t
H5Tclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id, hid_t es_id)
{
H5T_t * dt; /* Pointer to datatype to close */
void * token = NULL; /* Request token for async operation */
void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */
H5VL_t * connector = NULL; /* VOL connector */
herr_t ret_value = SUCCEED; /* Return value */

FUNC_ENTER_API(FAIL)
H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, type_id, es_id);

/* Check args */
if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
if (H5T_STATE_IMMUTABLE == dt->shared->state)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype")

/* Get dataset object's connector */
if (NULL == (vol_obj = H5VL_vol_object(type_id)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get VOL object for dataset")

/* Prepare for possible asynchronous operation */
if (H5ES_NONE != es_id) {
/* Increase connector's refcount, so it doesn't get closed if closing
* the dataset closes the file */
connector = vol_obj->connector;
H5VL_conn_inc_rc(connector);

/* Point at token for operation to set up */
token_ptr = &token;
} /* end if */

/* When the reference count reaches zero the resources are freed */
if (H5I_dec_app_ref(type_id) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id")

/* If a token was created, add the token to the event set */
if (NULL != token)
if (H5ES_insert(es_id, vol_obj->connector, token,
H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, type_id, es_id)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert token into event set")

done:
if (connector && H5VL_conn_dec_rc(connector) < 0)
HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")

FUNC_LEAVE_API(ret_value)
} /* end H5Tclose_async() */

/*-------------------------------------------------------------------------
* Function: H5Tequal
*
Expand Down
Loading