From cdc17466372df564ed2b9d603b278803000c027c Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 4 Jun 2009 10:13:15 -0500 Subject: [svn-r17002] Description: Rename H5O_protect/H5O_unprotect to be H5O_pin/H5O_unpin, since that's what that are actually doing. Add counter of the number of times the object header is pinned, to allow H5O_pin/H5O_unpin to be called reentrantly. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.7 (amazon) in debug mode Mac OS X/32 10.5.7 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- src/H5Dint.c | 16 ++++++------- src/H5Gobj.c | 12 +++++----- src/H5O.c | 72 ++++++++++++++++++++++++++++++++++++-------------------- src/H5Opkg.h | 5 ++++ src/H5Oprivate.h | 4 ++-- 5 files changed, 67 insertions(+), 42 deletions(-) diff --git a/src/H5Dint.c b/src/H5Dint.c index 00bc347..36ad640 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -844,8 +844,8 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) HDassert(file == dset->oloc.file); /* Get a pointer to the object header itself */ - if((oh = H5O_protect(oloc, dxpl_id)) == NULL) - HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect dataset object header") + if(NULL == (oh = H5O_pin(oloc, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header") /* Write new fill value message */ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_FILL_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, fill_prop) < 0) @@ -981,8 +981,8 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) done: /* Release pointer to object header itself */ if(oloc != NULL && oh != NULL) - if(H5O_unprotect(oloc, oh) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect dataset object header") + if(H5O_unpin(oloc, oh) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_update_oh_info() */ @@ -2410,8 +2410,8 @@ H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags) unsigned update_flags = H5O_UPDATE_TIME; /* Modification time flag */ /* Get a pointer to the dataset's object header */ - if((oh = H5O_protect(&dataset->oloc, dxpl_id)) == NULL) - HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect dataset object header") + if(NULL == (oh = H5O_pin(&dataset->oloc, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header") /* Update the layout on disk, if it's been changed */ if(dataset->shared->layout_dirty) { @@ -2479,8 +2479,8 @@ H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags) done: /* Release pointer to object header */ if(oh != NULL) - if(H5O_unprotect(&(dataset->oloc), oh) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect dataset object header") + if(H5O_unpin(&(dataset->oloc), oh) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_flush_real() */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 08a9268..a11dc13 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -806,8 +806,8 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") /* Get a pointer to the object header itself */ - if((oh = H5O_protect(oloc, dxpl_id)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to protect dataset object header") + if(NULL == (oh = H5O_pin(oloc, dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTPIN, FAIL, "unable to pin group object header") /* Inspect links in table for ones that can't be converted back * into link message form (currently only links which can't fit @@ -825,8 +825,8 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) for(u = 0; u < linfo->nlinks; u++) if(H5O_msg_append_oh(oloc->file, dxpl_id, oh, H5O_LINK_ID, 0, H5O_UPDATE_TIME, &(ltable.lnks[u])) < 0) { /* Release object header */ - if(H5O_unprotect(oloc, oh) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header") + if(H5O_unpin(oloc, oh) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTUNPIN, FAIL, "unable to unpin group object header") HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") } /* end if */ @@ -837,8 +837,8 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) } /* end if */ /* Release object header */ - if(H5O_unprotect(oloc, oh) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header") + if(H5O_unpin(oloc, oh) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTUNPIN, FAIL, "unable to unpin group object header") /* Free link table information */ if(H5G_link_release_table(<able) < 0) diff --git a/src/H5O.c b/src/H5O.c index 8b684d4..2017e1c 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -439,8 +439,11 @@ H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!new_name || !*new_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") +/* Avoid compiler warning on 32-bit machines */ +#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T if(HDstrlen(new_name) > H5L_MAX_LINK_NAME_LEN) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "name too long") +#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */ if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") @@ -1128,9 +1131,13 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, oh->flags |= H5O_HDR_ATTR_STORE_PHASE_CHANGE; /* Determine correct value for chunk #0 size bits */ +/* Avoid compiler warning on 32-bit machines */ +#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T if(size_hint > 4294967295) oh->flags |= H5O_HDR_CHUNK0_8; - else if(size_hint > 65535) + else +#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */ + if(size_hint > 65535) oh->flags |= H5O_HDR_CHUNK0_4; else if(size_hint > 255) oh->flags |= H5O_HDR_CHUNK0_2; @@ -1545,15 +1552,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_protect + * Function: H5O_pin * - * Purpose: Wrapper around H5AC_protect for use during a H5O_protect-> - * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls - * during an object's creation. + * Purpose: Pin an object header down for use during a sequence of message + * operations, which prevents the object header from being + * evicted from the cache. * * Return: Success: Pointer to the object header structure for the * object. - * * Failure: NULL * * Programmer: Quincey Koziol @@ -1563,11 +1569,12 @@ done: *------------------------------------------------------------------------- */ H5O_t * -H5O_protect(H5O_loc_t *loc, hid_t dxpl_id) +H5O_pin(H5O_loc_t *loc, hid_t dxpl_id) { - H5O_t *ret_value; /* Return value */ + H5O_t *oh = NULL; /* Object header */ + H5O_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_protect, NULL) + FUNC_ENTER_NOAPI(H5O_pin, NULL) /* check args */ HDassert(loc); @@ -1579,31 +1586,38 @@ H5O_protect(H5O_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file") /* Lock the object header into the cache */ - if(NULL == (ret_value = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header") - /* Mark object header as un-evictable */ - if(H5AC_pin_protected_entry(loc->file, ret_value) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, NULL, "unable to pin object header") + /* Check if the object header needs to be pinned */ + if(0 == oh->npins) { + /* Mark object header as un-evictable */ + if(H5AC_pin_protected_entry(loc->file, oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, NULL, "unable to pin object header") + } /* end if */ + + /* Increment the pin count */ + oh->npins++; + + /* Set the return value */ + ret_value = oh; done: /* Release the object header from the cache */ - if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0) + if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, ret_value, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_protect() */ +} /* end H5O_pin() */ /*------------------------------------------------------------------------- - * Function: H5O_unprotect + * Function: H5O_unpin * - * Purpose: Wrapper around H5AC_unprotect for use during a H5O_protect-> - * H5O_msg_append->...->H5O_msg_append->H5O_unprotect sequence of calls - * during an object's creation. + * Purpose: Unpin an object header, allowing it to be evicted from the + * metadata cache. * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Quincey Koziol @@ -1613,11 +1627,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_unprotect(H5O_loc_t *loc, H5O_t *oh) +H5O_unpin(H5O_loc_t *loc, H5O_t *oh) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_unprotect, FAIL) + FUNC_ENTER_NOAPI(H5O_unpin, FAIL) /* check args */ HDassert(loc); @@ -1625,13 +1639,19 @@ H5O_unprotect(H5O_loc_t *loc, H5O_t *oh) HDassert(H5F_addr_defined(loc->addr)); HDassert(oh); - /* Mark object header as evictable again */ - if(H5AC_unpin_entry(loc->file, oh) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") + /* Check if this is the last unpin operation */ + if(1 == oh->npins) { + /* Mark object header as evictable again */ + if(H5AC_unpin_entry(loc->file, oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to unpin object header") + } /* end if */ + + /* Decrement the pin count */ + oh->npins--; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_unprotect() */ +} /* end H5O_unpin() */ /*------------------------------------------------------------------------- diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 9981461..8569119 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -266,6 +266,11 @@ struct H5O_t { /* File-specific information (not stored) */ size_t sizeof_size; /* Size of file sizes */ size_t sizeof_addr; /* Size of file addresses */ + + /* Misc. information (not stored) */ + unsigned npins; /* Number of times the header is pinned */ + + /* Debugging information (not stored) */ #ifdef H5O_ENABLE_BAD_MESG_COUNT hbool_t store_bad_mesg_count; /* Flag to indicate that a bad message count should be stored */ /* (This is to simulate a bug in earlier diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 018bc77..bf416f4 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -578,8 +578,8 @@ H5_DLL herr_t H5O_open(H5O_loc_t *loc); H5_DLL herr_t H5O_close(H5O_loc_t *loc); H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id); H5_DLL int H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, unsigned *oh_flags); -H5_DLL H5O_t *H5O_protect(H5O_loc_t *loc, hid_t dxpl_id); -H5_DLL herr_t H5O_unprotect(H5O_loc_t *loc, H5O_t *oh); +H5_DLL H5O_t *H5O_pin(H5O_loc_t *loc, hid_t dxpl_id); +H5_DLL herr_t H5O_unpin(H5O_loc_t *loc, H5O_t *oh); H5_DLL herr_t H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id); H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force); -- cgit v0.12