diff options
author | Dana Robinson <derobins@hdfgroup.org> | 2016-06-15 18:55:59 (GMT) |
---|---|---|
committer | Dana Robinson <derobins@hdfgroup.org> | 2016-06-15 18:55:59 (GMT) |
commit | 75aa26981b4becc6926f4100707d9614e84a041c (patch) | |
tree | 5b2be7e3509907340ab99f272ba50d5e7cac98ac /src | |
parent | 77a223347552ceb2029c1d2677f7aec4d3cd6684 (diff) | |
download | hdf5-75aa26981b4becc6926f4100707d9614e84a041c.zip hdf5-75aa26981b4becc6926f4100707d9614e84a041c.tar.gz hdf5-75aa26981b4becc6926f4100707d9614e84a041c.tar.bz2 |
[svn-r30084] First pass at the evict-on-close feature.
The features is controlled via H5Pset/get_evict_on_close()
and is currently enabled by default (it will be disabled
by default in the final implementation).
There is a bug in the code where the eviction of tagged
metadata fails due to some of the metadata being dirty,
resulting in error return values and test failures.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5D.c | 30 | ||||
-rw-r--r-- | src/H5Fint.c | 16 | ||||
-rw-r--r-- | src/H5Fpkg.h | 1 | ||||
-rw-r--r-- | src/H5Fprivate.h | 6 | ||||
-rw-r--r-- | src/H5Fquery.c | 27 | ||||
-rw-r--r-- | src/H5Pfapl.c | 87 | ||||
-rw-r--r-- | src/H5Ppublic.h | 2 |
7 files changed, 164 insertions, 5 deletions
@@ -324,21 +324,43 @@ done: herr_t H5Dclose(hid_t dset_id) { - herr_t ret_value = SUCCEED; /* Return value */ + H5D_t *dset = NULL; /* Dataset */ + H5F_t *file = NULL; /* File */ + hbool_t evict = FALSE; /* Evict metadata on close? */ + haddr_t tag = HADDR_UNDEF; /* Metadata tag for evictions */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); /* Check args */ - if(NULL == H5I_object_verify(dset_id, H5I_DATASET)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + /* Check if this is the last object reference and we'll be evicting + * on close. We need to cache this info since it will be gone after the + * decrement call frees the struct. + */ + file = dset->oloc.file; + if(1 == dset->shared->fo_count && H5F_EVICT_ON_CLOSE(file)) { + evict = TRUE; + tag = dset->oloc.addr; + } /* end if */ /* * Decrement the counter on the dataset. It will be freed if the count * reaches zero. */ if(H5I_dec_app_ref_always_close(dset_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + + /* Clean up metadata in the metadata cache if evicting on close */ + if(evict && H5F_SHARED(file)) { + if(H5F_flush_tagged_metadata(file, tag, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") + if(H5F_evict_tagged_metadata(file, tag, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to evict tagged metadata") + } /* end if */ done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Fint.c b/src/H5Fint.c index 80c593b..5b7fdda 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -954,6 +954,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_class_t *drvr; /*file driver class info */ H5P_genplist_t *a_plist; /*file access property list */ H5F_close_degree_t fc_degree; /*file close degree */ + hbool_t evict_on_close; /* evict on close value from plist */ H5F_t *ret_value = NULL; /*actual return value */ FUNC_ENTER_NOAPI(NULL) @@ -1118,6 +1119,21 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") } /* end if */ + /* Record the evict-on-close MDC behavior. If it's the first time opening + * the file, set it to access property list value; if it's the second time + * or later, verify that the access property list value matches the value + * in shared file structure. + */ + if(H5P_get(a_plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, &evict_on_close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get evict on close value") + + if(shared->nrefs == 1) { + shared->evict_on_close = evict_on_close; + } else if(shared->nrefs > 1) { + if(shared->evict_on_close != evict_on_close) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file evict-on-close value doesn't match") + } /* end if */ + /* Formulate the absolute path for later search of target file for external links */ if(H5_build_extpath(name, &file->extpath) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index c5aed3b..8ec2a93 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -261,6 +261,7 @@ struct H5F_file_t { /* not change thereafter. */ hid_t fcpl_id; /* File creation property list ID */ H5F_close_degree_t fc_degree; /* File close behavior degree */ + hbool_t evict_on_close; /* If the file's objects should be evicted from the metadata cache on close */ size_t rdcc_nslots; /* Size of raw data chunk cache (slots) */ size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */ double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 34a5277..e3b5547 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -279,7 +279,7 @@ #define H5F_ACTUAL_NAME(F) ((F)->actual_name) #define H5F_EXTPATH(F) ((F)->extpath) #define H5F_SHARED(F) ((F)->shared) -#define H5F_SAME_SHARED(F1, F2) ((F1)->shared == (F2)->shared)) +#define H5F_SAME_SHARED(F1, F2) ((F1)->shared == (F2)->shared) #define H5F_NOPEN_OBJS(F) ((F)->nopen_objs) #define H5F_INCR_NOPEN_OBJS(F) ((F)->nopen_objs++) #define H5F_DECR_NOPEN_OBJS(F) ((F)->nopen_objs--) @@ -303,6 +303,7 @@ #define H5F_SET_SOHM_NINDEXES(F, N) ((F)->shared->sohm_nindexes = (N)) #define H5F_FCPL(F) ((F)->shared->fcpl_id) #define H5F_GET_FC_DEGREE(F) ((F)->shared->fc_degree) +#define H5F_EVICT_ON_CLOSE(F) ((F)->shared->evict_on_close) #define H5F_RDCC_NSLOTS(F) ((F)->shared->rdcc_nslots) #define H5F_RDCC_NBYTES(F) ((F)->shared->rdcc_nbytes) #define H5F_RDCC_W0(F) ((F)->shared->rdcc_w0) @@ -348,6 +349,7 @@ #define H5F_SET_SOHM_NINDEXES(F, N) (H5F_set_sohm_nindexes((F), (N))) #define H5F_FCPL(F) (H5F_get_fcpl(F)) #define H5F_GET_FC_DEGREE(F) (H5F_get_fc_degree(F)) +#define H5F_EVICT_ON_CLOSE(F) (H5F_get_evict_on_close(F)) #define H5F_RDCC_NSLOTS(F) (H5F_rdcc_nslots(F)) #define H5F_RDCC_NBYTES(F) (H5F_rdcc_nbytes(F)) #define H5F_RDCC_W0(F) (H5F_rdcc_w0(F)) @@ -463,6 +465,7 @@ #define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */ #define H5F_ACS_FILE_IMAGE_INFO_NAME "file_image_info" /* struct containing initial file image and callback info */ #define H5F_ACS_CORE_WRITE_TRACKING_FLAG_NAME "core_write_tracking_flag" /* Whether or not core VFD backing store write tracking is enabled */ +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME "evict_on_close_flag" /* Whether or not the metadata cache will evict objects on close */ #define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_NAME "core_write_tracking_page_size" /* The page size in kiB when core VFD write tracking is enabled */ #define H5F_ACS_COLL_MD_WRITE_FLAG_NAME "collective_metadata_write" /* property indicating whether metadata writes are done collectively or not */ @@ -660,6 +663,7 @@ H5_DLL unsigned H5F_get_sohm_nindexes(const H5F_t *f); H5_DLL herr_t H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes); H5_DLL hid_t H5F_get_fcpl(const H5F_t *f); H5_DLL H5F_close_degree_t H5F_get_fc_degree(const H5F_t *f); +H5_DLL hbool_t H5F_get_evict_on_close(const H5F_t *f); H5_DLL size_t H5F_rdcc_nbytes(const H5F_t *f); H5_DLL size_t H5F_rdcc_nslots(const H5F_t *f); H5_DLL double H5F_rdcc_w0(const H5F_t *f); diff --git a/src/H5Fquery.c b/src/H5Fquery.c index dd6e8e3..f59a9b7 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -835,6 +835,33 @@ H5F_get_fc_degree(const H5F_t *f) /*------------------------------------------------------------------------- + * Function: H5F_get_evict_on_close + * + * Purpose: Retrieve the 'file close degree' for the file. + * + * Return: Success: Flag indicating whether the evict-on-close + * property was set for the file. + * Failure: (can't happen) + * + * Programmer: Dana Robinson + * Spring 2016 + * + *------------------------------------------------------------------------- + */ +hbool_t +H5F_get_evict_on_close(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + HDassert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->evict_on_close) +} /* end H5F_get_evict_on_close() */ + + +/*------------------------------------------------------------------------- * Function: H5F_store_msg_crt_idx * * Purpose: Retrieve the 'store message creation index' flag for the file. diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index a315f92..c3108c5 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -181,6 +181,11 @@ /* Definition for object flush callback */ #define H5F_ACS_OBJECT_FLUSH_CB_SIZE sizeof(H5F_object_flush_t) #define H5F_ACS_OBJECT_FLUSH_CB_DEF {NULL, NULL} +/* Definition for evict on close property */ +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_SIZE sizeof(hbool_t) +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_DEF TRUE +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_ENC H5P__encode_hbool_t +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_DEC H5P__decode_hbool_t #ifdef H5_HAVE_PARALLEL /* Definition of collective metadata read mode flag */ #define H5F_ACS_COLL_MD_READ_FLAG_SIZE sizeof(H5P_coll_md_read_flag_t) @@ -296,6 +301,7 @@ static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMA static const hbool_t H5F_def_core_write_tracking_flag_g = H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEF; /* Default setting for core VFD write tracking */ static const size_t H5F_def_core_write_tracking_page_size_g = H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEF; /* Default core VFD write tracking page size */ static const H5F_object_flush_t H5F_def_object_flush_cb_g = H5F_ACS_OBJECT_FLUSH_CB_DEF; /* Default setting for object flush callback */ +static const hbool_t H5F_def_evict_on_close_flag_g = H5F_ACS_EVICT_ON_CLOSE_FLAG_DEF; /* Default setting for evict on close property */ #ifdef H5_HAVE_PARALLEL static const H5P_coll_md_read_flag_t H5F_def_coll_md_read_flag_g = H5F_ACS_COLL_MD_READ_FLAG_DEF; /* Default setting for the collective metedata read flag */ static const hbool_t H5F_def_coll_md_write_flag_g = H5F_ACS_COLL_MD_WRITE_FLAG_DEF; /* Default setting for the collective metedata write flag */ @@ -462,6 +468,12 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the evict on close flag */ + if(H5P_register_real(pclass, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, H5F_ACS_EVICT_ON_CLOSE_FLAG_SIZE, &H5F_def_evict_on_close_flag_g, + NULL, NULL, NULL, H5F_ACS_EVICT_ON_CLOSE_FLAG_ENC, H5F_ACS_EVICT_ON_CLOSE_FLAG_DEC, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + #ifdef H5_HAVE_PARALLEL /* Register the metadata collective read flag */ if(H5P_register_real(pclass, H5_COLL_MD_READ_FLAG_NAME, H5F_ACS_COLL_MD_READ_FLAG_SIZE, &H5F_def_coll_md_read_flag_g, @@ -3605,6 +3617,81 @@ done: FUNC_LEAVE_API(ret_value) } /* H5Pget_obj_flush_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_evict_on_close + * + * Purpose: + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * Spring 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close) +{ + H5P_genplist_t *plist; /* property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ib", fapl_id, evict_on_close); + + /* Compare the property list's class against the other class */ + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not a file access plist") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set values */ + if(H5P_set(plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, &evict_on_close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set evict on close property") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_evict_on_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_evict_on_close + * + * Purpose: + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * Spring 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_evict_on_close(hid_t fapl_id, hbool_t *evict_on_close) +{ + H5P_genplist_t *plist; /* property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*b", fapl_id, evict_on_close); + + /* Compare the property list's class against the other class */ + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not an access plist") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + if(H5P_get(plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, evict_on_close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get evict on close property") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_evict_on_close() */ + #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 0318c8f..b807a37 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -353,6 +353,8 @@ H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, size H5_DLL herr_t H5Pget_core_write_tracking(hid_t fapl_id, hbool_t *is_enabled, size_t *page_size); H5_DLL herr_t H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata); H5_DLL herr_t H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata); +H5_DLL herr_t H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close); +H5_DLL herr_t H5Pget_evict_on_close(hid_t fapl_id, hbool_t *evict_on_close); #ifdef H5_HAVE_PARALLEL H5_DLL herr_t H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective); H5_DLL herr_t H5Pget_all_coll_metadata_ops(hid_t plist_id, hbool_t *is_collective); |