From 670d598ff7a017cc4cbe1331b30ad645f04514a9 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 10 May 2007 15:35:35 -0500 Subject: [svn-r13745] Description: Take further advantage of the readers/writer locking in the metadata cache and push the locking of the local heap up to the routines which call B-tree routines, which should drastically lower the number of metadata cache protect/ unprotect calls. Tested on: Mac OS X/32 10.4.9 (amazon) Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2) --- src/H5AC.c | 4 + src/H5D.c | 42 ++++++--- src/H5Fdbg.c | 4 +- src/H5Fprivate.h | 2 +- src/H5Gent.c | 30 +++---- src/H5Glink.c | 48 +++------- src/H5Gnode.c | 247 ++++++++++++++++++++------------------------------- src/H5Gpkg.h | 55 +++--------- src/H5Gstab.c | 236 +++++++++++++++++++++++++++++------------------- src/H5HL.c | 213 +++++--------------------------------------- src/H5HLprivate.h | 9 +- src/H5Lexternal.c | 2 +- src/H5Oefl.c | 40 +++++---- src/H5Omessage.c | 2 +- test/lheap.c | 18 ++-- tools/misc/h5debug.c | 2 +- 16 files changed, 384 insertions(+), 570 deletions(-) diff --git a/src/H5AC.c b/src/H5AC.c index 720e663..31f757f 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -1912,6 +1912,10 @@ H5AC_protect(H5F_t *f, HDassert(type->load); HDassert(H5F_addr_defined(addr)); + /* Check for invalid access request */ + if(0 == (f->intent & H5F_ACC_RDWR) && rw == H5AC_WRITE) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "no write intent on file") + #if H5AC__TRACE_FILE_ENABLED /* For the protect call, only the addr and type id is really necessary * in the trace file. Include the size of the entry protected as a diff --git a/src/H5D.c b/src/H5D.c index 3594ab0..c29bf26 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -562,7 +562,7 @@ done: } /* end if */ else { if(loc_found && H5G_loc_free(&dset_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't free location") } /* end else */ } /* end if */ @@ -861,7 +861,7 @@ H5Dget_create_plist(hid_t dset_id) /* Retrieve any object creation properties */ if(H5O_get_create_plist(&dset->oloc, H5AC_ind_dxpl_id, new_plist) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object creation info") + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object creation info") /* Get the fill value property */ if(H5P_get(new_plist, H5D_CRT_FILL_VALUE_NAME, &copied_fill) < 0) @@ -1194,6 +1194,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) /* Update external storage message, if it's used */ if(dset->shared->dcpl_cache.efl.nused > 0) { H5O_efl_t *efl = &dset->shared->dcpl_cache.efl; /* Dataset's external file list */ + H5HL_t *heap; /* Pointer to local heap for EFL file names */ size_t heap_size = H5HL_ALIGN(1); size_t u; @@ -1201,22 +1202,41 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) for(u = 0; u < efl->nused; ++u) heap_size += H5HL_ALIGN(HDstrlen(efl->slot[u].name) + 1); - if(H5HL_create(file, dxpl_id, heap_size, &efl->heap_addr/*out*/) < 0 || - H5HL_insert(file, dxpl_id, efl->heap_addr, (size_t)1, "") == (size_t)(-1)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create external file list name heap") + /* Create the heap for the EFL file names */ + if(H5HL_create(file, dxpl_id, heap_size, &efl->heap_addr/*out*/) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create EFL file name heap") - for(u = 0; u < efl->nused; ++u) { - size_t offset = H5HL_insert(file, dxpl_id, efl->heap_addr, - HDstrlen(efl->slot[u].name) + 1, efl->slot[u].name); + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(file, dxpl_id, efl->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_DATASET, H5E_PROTECT, FAIL, "unable to protect EFL file name heap") - HDassert(0 == efl->slot[u].name_offset); + /* Insert "empty" name first */ + if((size_t)(-1) == H5HL_insert(file, dxpl_id, heap, (size_t)1, "")) { + H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr); + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap") + } /* end if */ + + for(u = 0; u < efl->nused; ++u) { + size_t offset; /* Offset of file name in heap */ - if(offset == (size_t)(-1)) - HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, FAIL, "unable to insert URL into name heap") + /* Insert file name into heap */ + if((size_t)(-1) == (offset = H5HL_insert(file, dxpl_id, heap, + HDstrlen(efl->slot[u].name) + 1, efl->slot[u].name))) { + H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr); + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap") + } /* end if */ + /* Store EFL file name offset */ + HDassert(0 == efl->slot[u].name_offset); efl->slot[u].name_offset = offset; } /* end for */ + /* Release the heap */ + if(H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_PROTECT, FAIL, "unable to unprotect EFL file name heap") + heap = NULL; + + /* Insert EFL message into dataset object header */ if(H5O_msg_append(file, dxpl_id, oh, H5O_EFL_ID, H5O_MSG_FLAG_CONSTANT, 0, efl) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update external file list message") } /* end if */ diff --git a/src/H5Fdbg.c b/src/H5Fdbg.c index 1651004..15ca0d9 100644 --- a/src/H5Fdbg.c +++ b/src/H5Fdbg.c @@ -47,7 +47,7 @@ *------------------------------------------------------------------------- */ herr_t -H5F_debug(H5F_t *f, hid_t dxpl_id, FILE * stream, int indent, int fwidth) +H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth) { H5P_genplist_t *plist; /* File creation property list */ hsize_t userblock_size; /* Userblock size */ @@ -139,7 +139,7 @@ H5F_debug(H5F_t *f, hid_t dxpl_id, FILE * stream, int indent, int fwidth) root_ent.file = f; /* Display root group symbol table entry info */ - H5G_ent_debug(f, dxpl_id, &root_ent, stream, indent + 3, MAX(0, fwidth - 3), HADDR_UNDEF); + H5G_ent_debug(f, &root_ent, stream, indent + 3, MAX(0, fwidth - 3), NULL); } /* end if */ done: diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 14e3c85..f9a1f57 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -472,7 +472,7 @@ H5_DLL H5F_t *H5F_fake_alloc(size_t sizeof_size); H5_DLL herr_t H5F_fake_free(H5F_t *f); /* Debugging functions */ -H5_DLL herr_t H5F_debug(H5F_t *f, hid_t dxpl_id, FILE * stream, int indent, int fwidth); +H5_DLL herr_t H5F_debug(H5F_t *f, FILE * stream, int indent, int fwidth); #endif /* _H5Fprivate_H */ diff --git a/src/H5Gent.c b/src/H5Gent.c index 9aeb91b..e7be62f 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -373,8 +373,8 @@ H5G_ent_reset(H5G_entry_t *ent) *------------------------------------------------------------------------- */ herr_t -H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t *lnk, - H5G_entry_t *ent, hid_t dxpl_id) +H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, const char *name, + const H5O_link_t *lnk, H5G_entry_t *ent) { size_t name_offset; /* Offset of name in heap */ herr_t ret_value = SUCCEED; /* Return value */ @@ -383,7 +383,7 @@ H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t /* check arguments */ HDassert(f); - HDassert(H5F_addr_defined(heap_addr)); + HDassert(heap); HDassert(name); HDassert(lnk); @@ -393,7 +393,7 @@ H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t /* * Add the new name to the heap. */ - name_offset = H5HL_insert(f, dxpl_id, heap_addr, HDstrlen(name) + 1, name); + name_offset = H5HL_insert(f, dxpl_id, heap, HDstrlen(name) + 1, name); if(0 == name_offset || (size_t)(-1) == name_offset) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert symbol name into heap") ent->name_off = name_offset; @@ -410,7 +410,7 @@ H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t size_t lnk_offset; /* Offset to sym-link value */ /* Insert link value into local heap */ - if((size_t)(-1) == (lnk_offset = H5HL_insert(f, dxpl_id, heap_addr, + if((size_t)(-1) == (lnk_offset = H5HL_insert(f, dxpl_id, heap, HDstrlen(lnk->u.soft.name) + 1, lnk->u.soft.name))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write link value to local heap") @@ -445,17 +445,17 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * stream, - int indent, int fwidth, haddr_t heap_addr) +H5G_ent_debug(H5F_t UNUSED *f, const H5G_entry_t *ent, FILE *stream, + int indent, int fwidth, H5HL_t *heap) { const char *lval = NULL; int nested_indent, nested_fwidth; - FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_debug); + FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_debug) /* Calculate the indent & field width values for nested information */ - nested_indent=indent+3; - nested_fwidth=MAX(0,fwidth-3); + nested_indent = indent + 3; + nested_fwidth = MAX(0, fwidth - 3); HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, "Name offset into private heap:", @@ -493,15 +493,11 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str HDfprintf(stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, "Link value offset:", (unsigned long)(ent->cache.slink.lval_offset)); - if(heap_addr > 0 && H5F_addr_defined(heap_addr)) { - H5HL_t *heap; - - heap = H5HL_protect(ent->file, dxpl_id, heap_addr, H5AC_READ); + if(heap) { lval = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset); HDfprintf(stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth, "Link value:", lval); - H5HL_unprotect(ent->file, dxpl_id, heap, heap_addr, H5AC__NO_FLAGS_SET); } /* end if */ else HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given, name not displayed!"); @@ -512,6 +508,6 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str break; } /* end switch */ - FUNC_LEAVE_NOAPI(SUCCEED); -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G_ent_debug() */ diff --git a/src/H5Glink.c b/src/H5Glink.c index d63a7ad..da3e60d 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -217,18 +217,15 @@ H5G_link_cmp_corder_dec(const void *lnk1, const void *lnk2) *------------------------------------------------------------------------- */ herr_t -H5G_ent_to_link(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, - H5HL_t *_heap, const H5G_entry_t *ent, const char *name) +H5G_ent_to_link(H5F_t *f, H5O_link_t *lnk, const H5HL_t *heap, + const H5G_entry_t *ent, const char *name) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_ent_to_link, FAIL) + FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_to_link) /* check arguments */ HDassert(f); HDassert(lnk); - HDassert(H5F_addr_defined(lheap_addr) || _heap); - HDassert(!(H5F_addr_defined(lheap_addr) && _heap)); + HDassert(heap); HDassert(ent); HDassert(name); @@ -242,25 +239,13 @@ H5G_ent_to_link(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, /* Object is a symbolic or hard link */ if(ent->type == H5G_CACHED_SLINK) { const char *s; /* Pointer to link value */ - H5HL_t *heap = _heap; /* Pointer to local heap for group */ - - /* Check if the heap pointer was passed in */ - if(!heap) { - /* Lock the local heap */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, lheap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect local heap") - } /* end if */ s = H5HL_offset_into(f, heap, ent->cache.slink.lval_offset); + HDassert(s); /* Copy the link value */ lnk->u.soft.name = H5MM_xstrdup(s); - /* Release the local heap, if we locked it */ - if(heap != _heap) - if(H5HL_unprotect(f, dxpl_id, heap, lheap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") - /* Set link type */ lnk->type = H5L_TYPE_SOFT; } /* end if */ @@ -272,8 +257,7 @@ H5G_ent_to_link(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, lnk->type = H5L_TYPE_HARD; } /* end else */ -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_ent_to_link() */ @@ -291,16 +275,15 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_ent_to_info(H5F_t *f, hid_t dxpl_id, H5L_info_t *info, haddr_t lheap_addr, +H5G_ent_to_info(H5F_t *f, H5L_info_t *info, const H5HL_t *heap, const H5G_entry_t *ent) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_ent_to_info, FAIL) + FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_to_info) /* check arguments */ HDassert(f); HDassert(info); + HDassert(heap); HDassert(ent); /* Set (default) common info for info */ @@ -311,21 +294,13 @@ H5G_ent_to_info(H5F_t *f, hid_t dxpl_id, H5L_info_t *info, haddr_t lheap_addr, /* Object is a symbolic or hard link */ if(ent->type == H5G_CACHED_SLINK) { const char *s; /* Pointer to link value */ - H5HL_t *heap; /* Pointer to local heap for group */ - - /* Lock the local heap */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, lheap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect local heap") s = H5HL_offset_into(f, heap, ent->cache.slink.lval_offset); + HDassert(s); /* Get the link value size */ info->u.val_size = HDstrlen(s) + 1; - /* Release the local heap */ - if(H5HL_unprotect(f, dxpl_id, heap, lheap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to unprotect local heap") - /* Set link type */ info->type = H5L_TYPE_SOFT; } /* end if */ @@ -337,8 +312,7 @@ H5G_ent_to_info(H5F_t *f, hid_t dxpl_id, H5L_info_t *info, haddr_t lheap_addr, info->type = H5L_TYPE_HARD; } /* end else */ -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_ent_to_info() */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 59e31f9..aac96b8 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -264,40 +264,31 @@ H5G_node_encode_key(const H5F_t *f, const H5B_t UNUSED *bt, uint8_t *raw, void * *------------------------------------------------------------------------- */ static herr_t -H5G_node_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id, int indent, int fwidth, - const void *_key, const void *_udata) +H5G_node_debug_key(FILE *stream, H5F_t *f, hid_t UNUSED dxpl_id, int indent, + int fwidth, const void *_key, const void *_udata) { const H5G_node_key_t *key = (const H5G_node_key_t *) _key; - const H5G_bt_common_t *udata = (const H5G_bt_common_t *) _udata; - herr_t ret_value = SUCCEED; /* Return value */ + const H5G_bt_common_t *udata = (const H5G_bt_common_t *) _udata; - FUNC_ENTER_NOAPI_NOINIT(H5G_node_debug_key) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_debug_key) HDassert(key); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Heap offset:", (unsigned)key->offset); - if(udata->heap_addr != 0) { - H5HL_t *heap; + if(udata->heap) { const char *s; HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:"); - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") - - s = H5HL_offset_into(f, heap, key->offset); + s = H5HL_offset_into(f, udata->heap, key->offset); HDfprintf(stream, "%s\n", s); - - if(H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") } /* end if */ else HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Cannot get name; heap address not specified\n"); -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_node_debug_key() */ @@ -777,27 +768,26 @@ done: *------------------------------------------------------------------------- */ static int -H5G_node_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, void *_rt_key) +H5G_node_cmp2(H5F_t *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, + void *_rt_key) { H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - H5HL_t *heap = NULL; const char *s1, *s2; const char *base; /* Base of heap */ int ret_value; - FUNC_ENTER_NOAPI_NOINIT(H5G_node_cmp2) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_cmp2) - HDassert(udata); + /* Sanity checks */ + HDassert(udata && udata->heap); HDassert(lt_key); HDassert(rt_key); /* Get base address of heap */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") - - base = H5HL_offset_into(f, heap, (size_t)0); + base = H5HL_offset_into(f, udata->heap, (size_t)0); + HDassert(base); /* Get pointers to string names */ s1 = base + lt_key->offset; @@ -806,10 +796,6 @@ H5G_node_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, void *_rt_ke /* Set return value */ ret_value = HDstrcmp(s1, s2); -done: - if(heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") - FUNC_LEAVE_NOAPI(ret_value) } /* H5G_node_cmp2() */ @@ -842,37 +828,37 @@ done: *------------------------------------------------------------------------- */ static int -H5G_node_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, void *_rt_key) +H5G_node_cmp3(H5F_t *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, + void *_rt_key) { H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - H5HL_t *heap = NULL; const char *s; const char *base; /* Base of heap */ - int ret_value=0; /* Return value */ + int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_node_cmp3) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_cmp3) - /* Get base address of heap */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") + /* Sanity checks */ + HDassert(udata && udata->heap); + HDassert(lt_key); + HDassert(rt_key); - base = H5HL_offset_into(f, heap, (size_t)0); + /* Get base address of heap */ + base = H5HL_offset_into(f, udata->heap, (size_t)0); + HDassert(base); /* left side */ s = base + lt_key->offset; if(HDstrcmp(udata->name, s) <= 0) - HGOTO_DONE(-1); - - /* right side */ - s = base + rt_key->offset; - if(HDstrcmp(udata->name, s) > 0) - HGOTO_DONE(1); - -done: - if(heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") + ret_value = (-1); + else { + /* right side */ + s = base + rt_key->offset; + if(HDstrcmp(udata->name, s) > 0) + ret_value = 1; + } /* end else */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_node_cmp3() */ @@ -906,11 +892,10 @@ done: */ static herr_t H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key, - void *_udata) + void *_udata) { - H5G_bt_lkp_t *udata = (H5G_bt_lkp_t *) _udata; + H5G_bt_lkp_t *udata = (H5G_bt_lkp_t *)_udata; H5G_node_t *sn = NULL; - H5HL_t *heap = NULL; unsigned lt = 0, idx = 0, rt; int cmp = 1; const char *s; @@ -924,7 +909,7 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(udata); + HDassert(udata && udata->common.heap); /* * Load the symbol table node for exclusive access. @@ -933,10 +918,8 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node") /* Get base address of heap */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") - - base = H5HL_offset_into(f, heap, (size_t)0); + base = H5HL_offset_into(f, udata->common.heap, (size_t)0); + HDassert(base); /* * Binary search. @@ -953,10 +936,6 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key lt = idx + 1; } /* end while */ - if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") - heap = NULL; base = NULL; - if(cmp) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found") @@ -1018,7 +997,6 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5G_bt_ins_t *udata = (H5G_bt_ins_t *) _udata; H5G_node_t *sn = NULL, *snrt = NULL; unsigned sn_flags = H5AC__NO_FLAGS_SET, snrt_flags = H5AC__NO_FLAGS_SET; - H5HL_t *heap = NULL; const char *s; const char *base; /* Base of heap */ unsigned lt = 0, rt; /* Binary search cntrs */ @@ -1036,7 +1014,7 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, HDassert(H5F_addr_defined(addr)); HDassert(md_key); HDassert(rt_key); - HDassert(udata); + HDassert(udata && udata->common.heap); HDassert(new_node_p); /* @@ -1046,10 +1024,8 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node") /* Get base address of heap */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name") - - base = H5HL_offset_into(f, heap, (size_t)0); + base = H5HL_offset_into(f, udata->common.heap, (size_t)0); + HDassert(base); /* * Where does the new symbol get inserted? We use a binary search. @@ -1059,15 +1035,9 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, idx = (lt + rt) / 2; s = base + sn->entry[idx].name_off; - if(0 == (cmp = HDstrcmp(udata->common.name, s))) /*already present */ { - HCOMMON_ERROR(H5E_SYM, H5E_CANTINSERT, "symbol is already present in symbol table"); - - if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name") - heap = NULL; base = NULL; - - HGOTO_DONE(H5B_INS_ERROR) - } /* end if */ + /* Check if symbol is already present */ + if(0 == (cmp = HDstrcmp(udata->common.name, s))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "symbol is already present in symbol table") if (cmp < 0) rt = idx; @@ -1076,12 +1046,8 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, } /* end while */ idx += cmp > 0 ? 1 : 0; - if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name") - heap = NULL; base = NULL; - /* Convert link information & name to symbol table entry */ - if(H5G_ent_convert(f, udata->common.heap_addr, udata->common.name, udata->lnk, &ent, dxpl_id) < 0) + if(H5G_ent_convert(f, dxpl_id, udata->common.heap, udata->common.name, udata->lnk, &ent) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5B_INS_ERROR, "unable to convert link") /* Determine where to place entry in node */ @@ -1200,8 +1166,6 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, H5G_bt_rm_t *udata = (H5G_bt_rm_t *)_udata; H5G_node_t *sn = NULL; unsigned sn_flags = H5AC__NO_FLAGS_SET; - H5HL_t *heap = NULL; - unsigned heap_flags = H5AC__NO_FLAGS_SET; unsigned lt = 0, rt, idx = 0; int cmp = 1; H5B_ins_t ret_value = H5B_INS_ERROR; @@ -1213,7 +1177,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, HDassert(H5F_addr_defined(addr)); HDassert(lt_key); HDassert(rt_key); - HDassert(udata); + HDassert(udata && udata->common.heap); /* Load the symbol table */ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE))) @@ -1227,12 +1191,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, const char *base; /* Base of heap */ const char *s; /* Pointer to string in local heap */ - /* Lock the heap down */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr, H5AC_WRITE))) - HGOTO_ERROR(H5E_SYM, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to protect local heap") - /* Get base address of heap */ - base = H5HL_offset_into(f, heap, (size_t)0); + base = H5HL_offset_into(f, udata->common.heap, (size_t)0); /* Find the name with a binary search */ rt = sn->nsyms; @@ -1255,10 +1215,10 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, lnk_addr = HADDR_UNDEF; /* Remove the soft link's value from the local heap */ - s = H5HL_offset_into(f, heap, sn->entry[idx].cache.slink.lval_offset); + s = H5HL_offset_into(f, udata->common.heap, sn->entry[idx].cache.slink.lval_offset); if(s) { len = HDstrlen(s) + 1; - if(H5HL_remove(f, dxpl_id, heap, sn->entry[idx].cache.slink.lval_offset, len, &heap_flags) < 0) + if(H5HL_remove(f, dxpl_id, udata->common.heap, sn->entry[idx].cache.slink.lval_offset, len) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, H5B_INS_ERROR, "unable to remove soft link from local heap") } /* end if */ } /* end if */ @@ -1270,7 +1230,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, } /* end else */ /* Get a pointer to the name of the link */ - if(NULL == (s = H5HL_offset_into(f, heap, sn->entry[idx].name_off))) + if(NULL == (s = H5HL_offset_into(f, udata->common.heap, sn->entry[idx].name_off))) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get link name") /* Get the object's type */ @@ -1291,7 +1251,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, /* Remove the link's name from the local heap */ len = HDstrlen(s) + 1; - if(H5HL_remove(f, dxpl_id, heap, sn->entry[idx].name_off, len, &heap_flags) < 0) + if(H5HL_remove(f, dxpl_id, udata->common.heap, sn->entry[idx].name_off, len) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, H5B_INS_ERROR, "unable to remove link name from local heap") /* Remove the entry from the symbol table node */ @@ -1391,9 +1351,6 @@ done: if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, sn_flags) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release symbol table node") - if(heap && H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, heap_flags) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to unprotect local heap") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_node_remove() */ @@ -1417,7 +1374,6 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad { H5G_bt_it_it_t *udata = (H5G_bt_it_it_t *)_udata; H5G_node_t *sn = NULL; - H5HL_t *heap = NULL; H5G_entry_t *ents; /* Pointer to entries in this node */ unsigned u; /* Local index variable */ int ret_value = H5_ITER_CONT; @@ -1429,13 +1385,11 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(udata); + HDassert(udata && udata->heap); /* Protect the symbol table node & local heap while we iterate over entries */ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5_ITER_ERROR, "unable to protect symbol name") /* * Iterate over the symbol table node entries. @@ -1447,7 +1401,7 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad const char *name; /* Pointer to link name in heap */ /* Get the pointer to the name of the link in the heap */ - name = H5HL_offset_into(f, heap, ents[u].name_off); + name = H5HL_offset_into(f, udata->heap, ents[u].name_off); HDassert(name); /* Check which type of callback to make */ @@ -1462,7 +1416,7 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad H5L_info_t info; /* Link info for entry */ /* Make a link info for an entry */ - if(H5G_ent_to_info(f, dxpl_id, &info, udata->heap_addr, &ents[u]) < 0) + if(H5G_ent_to_info(f, &info, udata->heap, &ents[u]) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for symbol table entry") /* Make the application callback */ @@ -1476,7 +1430,7 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad H5O_link_t lnk; /* Link for entry */ /* Convert the entry to a link */ - if(H5G_ent_to_link(f, dxpl_id, &lnk, udata->heap_addr, NULL, &ents[u], name) < 0) + if(H5G_ent_to_link(f, &lnk, udata->heap, &ents[u], name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5_ITER_ERROR, "unable to convert symbol table entry to link") /* Call the library's callback */ @@ -1499,8 +1453,6 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad done: /* Release resources */ - if(heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5_ITER_ERROR, "unable to unprotect symbol name") if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5_ITER_ERROR, "unable to release object header") @@ -1859,7 +1811,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, } /* end of for (i=0; insyms; i++) */ done: - if (heap && H5HL_unprotect(f, dxpl_id, heap, udata->src_heap_addr, H5AC__NO_FLAGS_SET) < 0) + if (heap && H5HL_unprotect(f, dxpl_id, heap, udata->src_heap_addr) < 0) HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5_ITER_ERROR, "unable to unprotect symbol name") if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) @@ -1888,7 +1840,6 @@ H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_ { H5G_bt_it_bt_t *udata = (H5G_bt_it_bt_t *)_udata; H5G_node_t *sn = NULL; /* Symbol table node */ - H5HL_t *heap = NULL; /* Local heap for group */ unsigned u; /* Local index variable */ int ret_value = H5_ITER_CONT; @@ -1899,7 +1850,7 @@ H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_ */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(udata); + HDassert(udata && udata->heap); /* * Save information about the symbol table node since we can't lock it @@ -1908,10 +1859,6 @@ H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node") - /* Lock down the heap for this group */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5_ITER_ERROR, "unable to protect symbol name") - /* Check if the link table needs to be extended */ if((udata->ltable->nlinks + sn->nsyms) >= udata->alloc_nlinks) { size_t na = MAX((udata->ltable->nlinks + sn->nsyms), (udata->alloc_nlinks * 2)); /* Double # of links allocated */ @@ -1929,21 +1876,19 @@ H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_ unsigned linkno; /* Link allocated */ /* Get pointer to link's name in the heap */ - name = H5HL_offset_into(f, heap, sn->entry[u].name_off); + name = H5HL_offset_into(f, udata->heap, sn->entry[u].name_off); HDassert(name); /* Determine the link to operate on in the table */ linkno = udata->ltable->nlinks++; /* Convert the entry to a link */ - if(H5G_ent_to_link(f, dxpl_id, &udata->ltable->lnks[linkno], HADDR_UNDEF, heap, &sn->entry[u], name) < 0) + if(H5G_ent_to_link(f, &udata->ltable->lnks[linkno], udata->heap, &sn->entry[u], name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5_ITER_ERROR, "unable to convert symbol table entry to link") } /* end for */ done: /* Release the locked items */ - if(heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5_ITER_ERROR, "unable to unprotect symbol name") if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5_ITER_ERROR, "unable to release object header") @@ -1967,10 +1912,9 @@ done: */ herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, - int fwidth, haddr_t heap_addr) + int fwidth, haddr_t heap_addr) { H5G_node_t *sn = NULL; - const char *s; H5HL_t *heap = NULL; unsigned u; herr_t ret_value = SUCCEED; /* Return value */ @@ -1986,6 +1930,11 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, HDassert(indent >= 0); HDassert(fwidth >= 0); + /* Pin the heap down in memory */ + if(heap_addr > 0 && H5F_addr_defined(heap_addr)) + if(NULL == (heap = H5HL_protect(f, dxpl_id, heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table heap") + /* * If we couldn't load the symbol table node, then try loading the * B-tree node. @@ -1994,48 +1943,44 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, H5G_bt_common_t udata; /*data to pass through B-tree */ H5E_clear_stack(NULL); /* discard that error */ - udata.heap_addr = heap_addr; - if ( H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_SNODE, &udata) < 0) + udata.heap = heap; + if(H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_SNODE, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to debug B-tree node"); - HGOTO_DONE(SUCCEED); - } - fprintf(stream, "%*sSymbol Table Node...\n", indent, ""); - fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Dirty:", - sn->cache_info.is_dirty ? "Yes" : "No"); - fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Size of Node (in bytes):", (unsigned)H5G_node_size(f)); - fprintf(stream, "%*s%-*s %u of %u\n", indent, "", fwidth, - "Number of Symbols:", - sn->nsyms, (unsigned)(2 * H5F_SYM_LEAF_K(f))); - - indent += 3; - fwidth = MAX(0, fwidth - 3); - for(u = 0; u < sn->nsyms; u++) { - fprintf(stream, "%*sSymbol %u:\n", indent - 3, "", u); - - if(heap_addr > 0 && H5F_addr_defined(heap_addr)) { - if(NULL == (heap = H5HL_protect(f, dxpl_id, heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); - - s = H5HL_offset_into(f, heap, sn->entry[u].name_off); - - if(s) - fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, "Name:", s); - - if(H5HL_unprotect(f, dxpl_id, heap, heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") - heap = NULL; s = NULL; - } - else - fprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Warning: Invalid heap address given, name not displayed!"); + } /* end if */ + else { + fprintf(stream, "%*sSymbol Table Node...\n", indent, ""); + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Dirty:", + sn->cache_info.is_dirty ? "Yes" : "No"); + fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Size of Node (in bytes):", (unsigned)H5G_node_size(f)); + fprintf(stream, "%*s%-*s %u of %u\n", indent, "", fwidth, + "Number of Symbols:", + sn->nsyms, (unsigned)(2 * H5F_SYM_LEAF_K(f))); + + indent += 3; + fwidth = MAX(0, fwidth - 3); + for(u = 0; u < sn->nsyms; u++) { + fprintf(stream, "%*sSymbol %u:\n", indent - 3, "", u); + + if(heap) { + const char *s = H5HL_offset_into(f, heap, sn->entry[u].name_off); + + if(s) + fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, "Name:", s); + } /* end if */ + else + fprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Warning: Invalid heap address given, name not displayed!"); - H5G_ent_debug(f, dxpl_id, sn->entry + u, stream, indent, fwidth, heap_addr); - } /* end for */ + H5G_ent_debug(f, sn->entry + u, stream, indent, fwidth, heap); + } /* end for */ + } /* end if */ done: if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node") + if(heap && H5HL_unprotect(f, dxpl_id, heap, heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_node_debug() */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 928da33..3da3417 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -35,6 +35,7 @@ #include "H5ACprivate.h" /* Metadata cache */ #include "H5B2private.h" /* v2 B-trees */ #include "H5HFprivate.h" /* Fractal heaps */ +#include "H5HLprivate.h" /* Local Heaps */ #include "H5Oprivate.h" /* Object headers */ #include "H5SLprivate.h" /* Skip lists */ @@ -160,7 +161,7 @@ typedef struct { typedef struct H5G_bt_common_t { /* downward */ const char *name; /*points to temporary memory */ - haddr_t heap_addr; /*symbol table heap address */ + H5HL_t *heap; /*symbol table heap */ } H5G_bt_common_t; /* @@ -206,7 +207,7 @@ typedef struct H5G_bt_lkp_t { typedef struct H5G_bt_it_it_t { /* downward */ hid_t group_id; /*group id to pass to iteration operator */ - haddr_t heap_addr; /*symbol table heap address */ + H5HL_t *heap; /*symbol table heap */ hsize_t skip; /*initial entries to skip */ H5G_link_iterate_t *lnk_op; /*iteration operator */ void *op_data; /*user-defined operator data */ @@ -228,47 +229,16 @@ typedef struct H5G_bt_it_cpy_t { typedef struct H5G_bt_it_idx_common_t { /* downward */ H5F_t *f; /* Pointer to file that symbol table is in */ - hid_t dxpl_id; /* DXPL for operation */ hsize_t idx; /* Index of group member to be queried */ hsize_t num_objs; /* The number of objects having been traversed */ H5G_bt_find_op_t op; /* Operator to call when correct entry is found */ } H5G_bt_it_idx_common_t; -/* Data passed through B-tree iteration for looking up a name by index */ -typedef struct H5G_bt_it_gnbi_t { - /* downward */ - H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ - haddr_t heap_addr; /*symbol table heap address */ - - /* upward */ - char *name; /*member name to be returned */ -} H5G_bt_it_gnbi_t; - -/* Data passed through B-tree iteration for looking up a type by index */ -typedef struct H5G_bt_it_gtbi_t { - /* downward */ - H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ - - /* upward */ - H5G_obj_t type; /*member type to be returned */ -} H5G_bt_it_gtbi_t; - -/* Data passed through B-tree iteration for looking up a link by index */ -typedef struct H5G_bt_it_lbi_t { - /* downward */ - H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ - haddr_t heap_addr; /*symbol table heap address */ - - /* upward */ - H5O_link_t *lnk; /*link to be returned */ - hbool_t found; /*whether we found the link */ -} H5G_bt_it_lbi_t; - /* Data passed through B-tree iteration for building a table of the links */ typedef struct H5G_bt_it_bt_t { /* downward */ size_t alloc_nlinks; /* Number of links allocated in table */ - haddr_t heap_addr; /* Symbol table heap address */ + H5HL_t *heap; /*symbol table heap */ /* upward */ H5G_link_table_t *ltable; /* Link table to add information to */ @@ -425,10 +395,10 @@ H5_DLL herr_t H5G_ent_decode_vec(H5F_t *f, const uint8_t **pp, H5G_entry_t *ent, unsigned n); H5_DLL herr_t H5G_ent_encode_vec(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent, unsigned n); -H5_DLL herr_t H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, - const H5O_link_t *lnk, H5G_entry_t *ent, hid_t dxpl_id); -H5_DLL herr_t H5G_ent_debug(H5F_t *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * stream, - int indent, int fwidth, haddr_t heap); +H5_DLL herr_t H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, + const char *name, const H5O_link_t *lnk, H5G_entry_t *ent); +H5_DLL herr_t H5G_ent_debug(H5F_t *f, const H5G_entry_t *ent, + FILE * stream, int indent, int fwidth, H5HL_t *heap); /* Functions that understand symbol table nodes */ H5_DLL herr_t H5G_node_init(H5F_t *f); @@ -444,15 +414,14 @@ H5_DLL int H5G_node_build_table(H5F_t *f, hid_t dxpl_id, const void *_lt_key, ha const void *_rt_key, void *_udata); /* Functions that understand links in groups */ -struct H5HL_t; H5_DLL int H5G_link_cmp_name_inc(const void *lnk1, const void *lnk2); H5_DLL int H5G_link_cmp_name_dec(const void *lnk1, const void *lnk2); H5_DLL int H5G_link_cmp_corder_inc(const void *lnk1, const void *lnk2); H5_DLL int H5G_link_cmp_corder_dec(const void *lnk1, const void *lnk2); -H5_DLL herr_t H5G_ent_to_link(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, - haddr_t lheap_addr, struct H5HL_t *heap, const H5G_entry_t *ent, const char *name); -H5_DLL herr_t H5G_ent_to_info(H5F_t *f, hid_t dxpl_id, H5L_info_t *info, - haddr_t lheap_addr, const H5G_entry_t *ent); +H5_DLL herr_t H5G_ent_to_link(H5F_t *f, H5O_link_t *lnk, const H5HL_t *heap, + const H5G_entry_t *ent, const char *name); +H5_DLL herr_t H5G_ent_to_info(H5F_t *f, H5L_info_t *info, const H5HL_t *heap, + const H5G_entry_t *ent); H5_DLL herr_t H5G_link_to_info(const H5O_link_t *lnk, H5L_info_t *linfo); H5_DLL herr_t H5G_link_to_loc(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, H5G_loc_t *obj_loc); diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 7bb07aa..22d90a7 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -30,50 +30,47 @@ #include "H5MMprivate.h" /* Memory management */ /* Private typedefs */ -/* User data for finding a name in the link messages */ +/* User data for finding link information from B-tree */ typedef struct { /* downward */ - H5F_t *f; /* Pointer to file for insertion */ + H5F_t *file; /* Pointer to file for query */ const char *name; /* Name to search for */ + H5HL_t *heap; /* Local heap for group */ /* upward */ - H5G_entry_t *ent; /* Entry to update when match found */ -} H5G_stab_ud1_t; + H5O_link_t *lnk; /* Caller's link location */ +} H5G_stab_fnd_ud_t; -/* User data for finding object info from B-tree */ -typedef struct { +/* Data passed through B-tree iteration for looking up a name by index */ +typedef struct H5G_bt_it_gnbi_t { /* downward */ - H5O_loc_t *grp_oloc; /* Object location of group */ - hid_t dxpl_id; /* DXPL during operation */ - haddr_t heap_addr; /* Local heap address for group */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ + H5HL_t *heap; /*symbol table heap */ /* upward */ - H5G_stat_t *statbuf; /* Caller's statbuf */ -} H5G_stab_fnd_ud1_t; + char *name; /*member name to be returned */ +} H5G_bt_it_gnbi_t; -/* User data for finding link information from B-tree */ -typedef struct { +/* Data passed through B-tree iteration for looking up a type by index */ +typedef struct H5G_bt_it_gtbi_t { /* downward */ - H5F_t *file; /* Pointer to file for query */ - hid_t dxpl_id; /* DXPL during operation */ - const char *name; /* Name to search for */ - haddr_t heap_addr; /* Local heap address for group */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ + hid_t dxpl_id; /* DXPL for operation */ /* upward */ - H5O_link_t *lnk; /* Caller's link location */ -} H5G_stab_fnd_ud2_t; + H5G_obj_t type; /*member type to be returned */ +} H5G_bt_it_gtbi_t; -/* User data for finding object location from B-tree */ -typedef struct { +/* Data passed through B-tree iteration for looking up a link by index */ +typedef struct H5G_bt_it_lbi_t { /* downward */ - H5F_t *file; /* Pointer to file for query */ - size_t size; /* Buffer size for link value */ - haddr_t heap_addr; /* Local heap address for group */ - hid_t dxpl_id; /* DXPL during operation */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ + H5HL_t *heap; /*symbol table heap */ /* upward */ - char *buf; /* Buffer to fill with link value */ -} H5G_stab_fnd_ud3_t; + H5O_link_t *lnk; /*link to be returned */ + hbool_t found; /*whether we found the link */ +} H5G_bt_it_lbi_t; /* Private prototypes */ @@ -100,6 +97,7 @@ typedef struct { herr_t H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ size_t name_offset; /* Offset of "" name */ herr_t ret_value = SUCCEED; /* Return value */ @@ -119,9 +117,14 @@ H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t d /* Create symbol table private heap */ if(H5HL_create(f, dxpl_id, size_hint, &(stab->heap_addr)/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap") - name_offset = H5HL_insert(f, dxpl_id, stab->heap_addr, (size_t)1, ""); - if((size_t)(-1) == name_offset) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap") + + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + + /* Insert name into the heap */ + if((size_t)(-1) == (name_offset = H5HL_insert(f, dxpl_id, heap, (size_t)1, ""))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert name into heap") /* * B-tree's won't work if the first name isn't at the beginning @@ -130,6 +133,10 @@ H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t d HDassert(0 == name_offset); done: + /* Release resources */ + if(heap && H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_create_components() */ @@ -214,6 +221,7 @@ herr_t H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, H5O_link_t *obj_lnk, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_ins_t udata; /* Data to pass through B-tree */ herr_t ret_value = SUCCEED; /* Return value */ @@ -225,9 +233,13 @@ H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, HDassert(name && *name); HDassert(obj_lnk); + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Initialize data to pass through B-tree */ udata.common.name = name; - udata.common.heap_addr = stab->heap_addr; + udata.common.heap = heap; udata.lnk = obj_lnk; /* Insert into symbol table */ @@ -235,6 +247,10 @@ H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry") done: + /* Release resources */ + if(heap && H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_insert_real() */ @@ -296,8 +312,9 @@ herr_t H5G_stab_remove(H5O_loc_t *loc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, const char *name) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5O_stab_t stab; /*symbol table message */ - H5G_bt_rm_t udata; /*data to pass through B-tree */ + H5G_bt_rm_t udata; /*data to pass through B-tree */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_stab_remove, FAIL) @@ -309,9 +326,13 @@ H5G_stab_remove(H5O_loc_t *loc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, if(NULL == H5O_msg_read(loc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(loc->file, dxpl_id, stab.heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Initialize data to pass through B-tree */ udata.common.name = name; - udata.common.heap_addr = stab.heap_addr; + udata.common.heap = heap; udata.grp_full_path_r = grp_full_path_r; /* Remove from symbol table */ @@ -319,6 +340,10 @@ H5G_stab_remove(H5O_loc_t *loc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry") done: + /* Release resources */ + if(heap && H5HL_unprotect(loc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_remove() */ @@ -339,6 +364,7 @@ herr_t H5G_stab_remove_by_idx(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, H5_iter_order_t order, hsize_t n) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5O_stab_t stab; /* Symbol table message */ H5G_bt_rm_t udata; /* Data to pass through B-tree */ H5O_link_t obj_lnk; /* Object's link within group */ @@ -358,9 +384,13 @@ H5G_stab_remove_by_idx(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5RS_str_t *grp_full_ if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Initialize data to pass through B-tree */ udata.common.name = obj_lnk.name; - udata.common.heap_addr = stab.heap_addr; + udata.common.heap = heap; udata.grp_full_path_r = grp_full_path_r; /* Remove link from symbol table */ @@ -368,12 +398,16 @@ H5G_stab_remove_by_idx(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5RS_str_t *grp_full_ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry") done: + /* Release resources */ + if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + /* Reset the link information, if we have a copy */ if(lnk_copied) H5O_msg_reset(H5O_LINK_ID, &obj_lnk); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_stab_remove() */ +} /* end H5G_stab_remove_by_idx() */ /*------------------------------------------------------------------------- @@ -393,6 +427,7 @@ done: herr_t H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_rm_t udata; /*data to pass through B-tree */ herr_t ret_value = SUCCEED; @@ -403,19 +438,32 @@ H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab) HDassert(H5F_addr_defined(stab->btree_addr)); HDassert(H5F_addr_defined(stab->heap_addr)); + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Set up user data for B-tree deletion */ udata.common.name = NULL; - udata.common.heap_addr = stab->heap_addr; + udata.common.heap = heap; /* Delete entire B-tree */ if(H5B_delete(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table B-tree") + /* Release resources */ + if(H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + heap = NULL; + /* Delete local heap for names */ if(H5HL_delete(f, dxpl_id, stab->heap_addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table heap") done: + /* Release resources */ + if(heap && H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_delete() */ @@ -437,6 +485,7 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data) { + H5HL_t *heap = NULL; /* Local heap for group */ H5O_stab_t stab; /* Info about symbol table */ H5G_link_table_t ltable = {0, NULL}; /* Link table */ herr_t ret_value; @@ -451,6 +500,10 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Check on iteration order */ /* ("native" iteration order is increasing for this link storage mechanism) */ if(order != H5_ITER_DEC) { @@ -458,15 +511,14 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ udata.group_id = gid; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.skip = skip; udata.final_ent = last_lnk; udata.lnk_op = lnk_op; udata.op_data = op_data; /* Iterate over the group members */ - if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, - H5G_node_iterate, stab.btree_addr, &udata)) < 0) + if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_iterate, stab.btree_addr, &udata)) < 0) HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); /* Check for too high of a starting index (ex post facto :-) */ @@ -477,9 +529,9 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, else { H5G_bt_it_bt_t udata; /* User data to pass to B-tree callback */ - /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ + /* Build udata to pass through H5B_iterate() to H5G_node_build_table() */ udata.alloc_nlinks = 0; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.ltable = <able; /* Iterate over the group members */ @@ -502,8 +554,10 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, done: /* Release resources */ + if(heap && H5HL_unprotect(oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") if(ltable.lnks && H5G_link_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5G_UNKNOWN, "unable to release link table") + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_iterate() */ @@ -567,34 +621,23 @@ static herr_t H5G_stab_get_name_by_idx_cb(const H5G_entry_t *ent, void *_udata) { H5G_bt_it_gnbi_t *udata = (H5G_bt_it_gnbi_t *)_udata; - H5HL_t *heap = NULL; /* Pointer to local heap for group */ size_t name_off; /* Offset of name in heap */ const char *name; /* Pointer to name string in heap */ - herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_stab_get_name_by_idx_cb) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_stab_get_name_by_idx_cb) /* Sanity check */ HDassert(ent); - HDassert(udata); + HDassert(udata && udata->heap); /* Get name offset in heap */ name_off = ent->name_off; - - /* Pin the heap down in memory */ - if(NULL == (heap = H5HL_protect(udata->common.f, udata->common.dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") - - name = H5HL_offset_into(udata->common.f, heap, name_off); + name = H5HL_offset_into(udata->common.f, udata->heap, name_off); HDassert(name); udata->name = H5MM_strdup(name); HDassert(udata->name); -done: - if(heap && H5HL_unprotect(udata->common.f, udata->common.dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") - - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_stab_get_name_by_idx_cb */ @@ -615,6 +658,7 @@ ssize_t H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char* name, size_t size, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5O_stab_t stab; /* Info about local heap & B-tree */ H5G_bt_it_gnbi_t udata; /* Iteration information */ ssize_t ret_value; /* Return value */ @@ -628,6 +672,10 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Remap index for decreasing iteration order */ if(order == H5_ITER_DEC) { hsize_t nlinks = 0; /* Number of links in group */ @@ -642,11 +690,10 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, /* Set iteration information */ udata.common.f = oloc->file; - udata.common.dxpl_id = dxpl_id; udata.common.idx = n; udata.common.num_objs = 0; udata.common.op = H5G_stab_get_name_by_idx_cb; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.name = NULL; /* Iterate over the group members */ @@ -668,6 +715,10 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, } /* end if */ done: + /* Release resources */ + if(heap && H5HL_unprotect(oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + /* Free the duplicated name */ if(udata.name != NULL) H5MM_xfree(udata.name); @@ -719,7 +770,7 @@ H5G_stab_get_type_by_idx_cb(const H5G_entry_t *ent, void *_udata) tmp_oloc.addr = ent->header; /* Get the type of the object */ - if(H5O_obj_type(&tmp_oloc, &obj_type, udata->common.dxpl_id) < 0) + if(H5O_obj_type(&tmp_oloc, &obj_type, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object type") udata->type = H5G_map_obj_type(obj_type); } @@ -764,10 +815,10 @@ H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) /* Set iteration information */ udata.common.f = oloc->file; - udata.common.dxpl_id = dxpl_id; udata.common.idx = idx; udata.common.num_objs = 0; udata.common.op = H5G_stab_get_type_by_idx_cb; + udata.dxpl_id = dxpl_id; udata.type = H5G_UNKNOWN; /* Iterate over the group members */ @@ -803,18 +854,16 @@ done: static herr_t H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) { - H5G_stab_fnd_ud2_t *udata = (H5G_stab_fnd_ud2_t *)_udata; /* 'User data' passed in */ + H5G_stab_fnd_ud_t *udata = (H5G_stab_fnd_ud_t *)_udata; /* 'User data' passed in */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_stab_lookup_cb) - /* Set link info */ - if(udata->lnk) { + /* Check for setting link info */ + if(udata->lnk) /* Convert the entry to a link */ - if(H5G_ent_to_link(udata->file, udata->dxpl_id, udata->lnk, udata->heap_addr, - NULL, ent, udata->name) < 0) + if(H5G_ent_to_link(udata->file, udata->lnk, udata->heap, ent, udata->name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link") - } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -838,8 +887,9 @@ herr_t H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */ - H5G_stab_fnd_ud2_t udata; /* 'User data' to give to callback */ + H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */ H5O_stab_t stab; /* Symbol table message */ herr_t ret_value = SUCCEED; /* Return value */ @@ -850,28 +900,35 @@ H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, HDassert(name && *name); HDassert(lnk); + /* Retrieve the symbol table message for the group */ + if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message") + + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Set up user data to pass to 'find' operation callback */ udata.file = grp_oloc->file; - udata.dxpl_id = dxpl_id; udata.name = name; udata.lnk = lnk; + udata.heap = heap; /* Set up the user data for actual B-tree find operation */ - if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message") bt_udata.common.name = name; - bt_udata.common.heap_addr = stab.heap_addr; + bt_udata.common.heap = heap; bt_udata.op = H5G_stab_lookup_cb; bt_udata.op_data = &udata; - /* Finish up user data to pass to 'find' operation callback */ - udata.heap_addr = stab.heap_addr; - /* Search the B-tree */ if(H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found") done: + /* Release resources */ + if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup() */ @@ -894,7 +951,6 @@ static herr_t H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata) { H5G_bt_it_lbi_t *udata = (H5G_bt_it_lbi_t *)_udata; - H5HL_t *heap = NULL; /* Pointer to local heap for group */ const char *name; /* Pointer to name string in heap */ herr_t ret_value = SUCCEED; /* Return value */ @@ -902,26 +958,18 @@ H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata) /* Sanity check */ HDassert(ent); - HDassert(udata); + HDassert(udata && udata->heap); - /* Pin the heap down in memory */ - if(NULL == (heap = H5HL_protect(udata->common.f, udata->common.dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") - - /* Duplicate the link name */ - name = H5HL_offset_into(udata->common.f, heap, ent->name_off); + /* Get a pointer to the link name */ + name = H5HL_offset_into(udata->common.f, udata->heap, ent->name_off); HDassert(name); /* Convert the entry to a link */ - if(H5G_ent_to_link(udata->common.f, udata->common.dxpl_id, udata->lnk, HADDR_UNDEF, heap, ent, name) < 0) + if(H5G_ent_to_link(udata->common.f, udata->lnk, udata->heap, ent, name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link") udata->found = TRUE; done: - /* Unlock the heap */ - if(heap && H5HL_unprotect(udata->common.f, udata->common.dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup_by_idx_cb */ @@ -943,6 +991,7 @@ herr_t H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_it_lbi_t udata; /* Iteration information */ H5O_stab_t stab; /* Symbol table message */ herr_t ret_value = SUCCEED; /* Return value */ @@ -957,6 +1006,10 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Remap index for decreasing iteration order */ if(order == H5_ITER_DEC) { hsize_t nlinks = 0; /* Number of links in group */ @@ -971,11 +1024,10 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, /* Set iteration information */ udata.common.f = grp_oloc->file; - udata.common.dxpl_id = dxpl_id; udata.common.idx = n; udata.common.num_objs = 0; udata.common.op = H5G_stab_lookup_by_idx_cb; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.lnk = lnk; udata.found = FALSE; @@ -988,6 +1040,10 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") done: + /* Release resources */ + if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup_by_idx() */ diff --git a/src/H5HL.c b/src/H5HL.c index 44d7a53..5f0860f 100644 --- a/src/H5HL.c +++ b/src/H5HL.c @@ -53,13 +53,6 @@ /* Private typedefs */ /* PRIVATE PROTOTYPES */ -#ifdef NOT_YET -static void *H5HL_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, - void *buf); -static herr_t H5HL_write(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, - const void *buf); -#endif /* NOT_YET */ - static herr_t H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf); static H5HL_free_t *H5HL_remove_free(H5HL_t *heap, H5HL_free_t *fl); static herr_t H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap); @@ -720,68 +713,6 @@ H5HL_compute_size(const H5F_t *f, const H5HL_t *heap, size_t *size_ptr) /*------------------------------------------------------------------------- - * Function: H5HL_read - * - * Purpose: Reads some object (or part of an object) from the heap - * whose address is ADDR in file F. OFFSET is the byte offset - * from the beginning of the heap at which to begin reading - * and SIZE is the number of bytes to read. - * - * If BUF is the null pointer then a buffer is allocated by - * this function. - * - * Attempting to read past the end of an object may cause this - * function to fail. - * - * Return: Success: BUF (or the allocated buffer) - * - * Failure: NULL - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -#ifdef NOT_YET -static void * -H5HL_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, void *buf) -{ - H5HL_t *heap = NULL; - void *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5HL_read, NULL); - - /* check arguments */ - assert(f); - assert (H5F_addr_defined(addr)); - - if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap"); - - assert(offset < heap->heap_alloc); - assert(offset + size <= heap->heap_alloc); - - if (!buf && NULL==(buf = H5MM_malloc(size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - HDmemcpy(buf, heap->chunk + H5HL_SIZEOF_HDR(f) + offset, size); - - /* Set return value */ - ret_value=buf; - -done: - if (heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, H5AC__NO_FLAGS_SET) != SUCCEED) - HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release object header"); - - FUNC_LEAVE_NOAPI(ret_value); -} -#endif /* NOT_YET */ - - -/*------------------------------------------------------------------------- * Function: H5HL_protect * * Purpose: This function is a wrapper for the H5AC_protect call. The @@ -878,7 +809,7 @@ H5HL_offset_into(H5F_t *f, const H5HL_t *heap, size_t offset) *------------------------------------------------------------------------- */ herr_t -H5HL_unprotect(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, haddr_t addr, unsigned heap_flags) +H5HL_unprotect(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, haddr_t addr) { herr_t ret_value = SUCCEED; @@ -889,7 +820,7 @@ H5HL_unprotect(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, haddr_t addr, unsigned hea HDassert(heap); HDassert(H5F_addr_defined(addr)); - if(H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, (void *)heap, heap_flags) != SUCCEED) + if(H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, (void *)heap, H5AC__NO_FLAGS_SET) != SUCCEED) HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header") done: @@ -940,26 +871,11 @@ H5HL_remove_free(H5HL_t *heap, H5HL_free_t *fl) * matzke@llnl.gov * Jul 17 1997 * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * John Mainzer, 6/7/05 - * Modified code to use the dirtied parameter of - * H5AC_unprotect() instead of manipulating the is_dirty - * field of the cache info directly. - * - * John Mainzer, 8/10/05 - * Modified code to allocate file space as needed, instead - * of allocating it on eviction. - * *------------------------------------------------------------------------- */ size_t -H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *buf) +H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void *buf) { - H5HL_t *heap = NULL; - unsigned heap_flags = H5AC__NO_FLAGS_SET; H5HL_free_t *fl = NULL, *last_fl = NULL; size_t offset = 0; size_t need_size; @@ -967,21 +883,22 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void * size_t sizeof_hdr; /* Cache H5HL header size for file */ size_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5HL_insert, (size_t)(-1)); + FUNC_ENTER_NOAPI(H5HL_insert, (size_t)(-1)) /* check arguments */ HDassert(f); - HDassert(H5F_addr_defined(addr)); + HDassert(heap); HDassert(buf_size > 0); HDassert(buf); - if(0 == (f->intent & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, (size_t)(-1), "no write intent on file") - - if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to load heap") - - heap_flags |= H5AC__DIRTIED_FLAG; + /* Mark heap as dirty in cache */ + /* (A bit early in the process, but it's difficult to determine in the + * code below where to mark the heap as dirty, especially in error cases, + * so we just accept that an extra flush of the heap info could occur + * if an error occurs -QAK) + */ + if(H5AC_mark_pinned_or_protected_entry_dirty(f, heap) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, (size_t)(-1), "unable to mark heap as dirty") /* Cache this for later */ sizeof_hdr = H5HL_SIZEOF_HDR(f); @@ -1153,78 +1070,9 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void * ret_value = offset; done: - if(heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, heap_flags) != SUCCEED) - HDONE_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to release object header") - FUNC_LEAVE_NOAPI(ret_value) } /* H5HL_insert() */ -#ifdef NOT_YET - -/*------------------------------------------------------------------------- - * Function: H5HL_write - * - * Purpose: Writes (overwrites) the object (or part of object) stored - * in BUF to the heap at file address ADDR in file F. The - * writing begins at byte offset OFFSET from the beginning of - * the heap and continues for SIZE bytes. - * - * Do not partially write an object to create it; the first - * write for an object must be for the entire object. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * John Mainzer, 6/7/05 - * Modified code to use the dirtied parameter of - * H5AC_unprotect() instead of manipulating the is_dirty - * field of the cache info directly. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HL_write(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, const void *buf) -{ - H5HL_t *heap = NULL; - unsigned heap_flags = H5AC__NO_FLAGS_SET; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5HL_write, FAIL); - - /* check arguments */ - assert(f); - assert(H5F_addr_defined(addr)); - assert(buf); - assert (offset==H5HL_ALIGN (offset)); - - if (0==(f->intent & H5F_ACC_RDWR)) - HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file"); - - if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to load heap"); - - assert(offset < heap->heap_alloc); - assert(offset + size <= heap->heap_alloc); - - heap_flags |= H5AC__DIRTIED_FLAG; - HDmemcpy(heap->chunk + H5HL_SIZEOF_HDR(f) + offset, buf, size); - -done: - if (heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, heap_flags) != SUCCEED && - ret_value != FAIL) - HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header"); - - FUNC_LEAVE_NOAPI(ret_value); -} -#endif /* NOT_YET */ - /*------------------------------------------------------------------------- * Function: H5HL_remove @@ -1248,25 +1096,10 @@ done: * matzke@llnl.gov * Jul 16 1997 * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * John Mainzer, 6/7/05 - * Modified code to use the dirtied parameter of - * H5AC_unprotect() instead of manipulating the is_dirty - * field of the cache info directly. - * - * John Mainzer, 8/10/05 - * Modified code to attempt to decrease heap size if the - * entry removal results in a free list entry at the end - * of the heap that is at least half the size of the heap. - * *------------------------------------------------------------------------- */ herr_t -H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size, - unsigned *heap_flags) +H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size) { H5HL_free_t *fl = NULL; herr_t ret_value = SUCCEED; /* Return value */ @@ -1279,22 +1112,26 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size, HDassert(size > 0); HDassert(offset == H5HL_ALIGN(offset)); - if(0 == (f->intent & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file") - size = H5HL_ALIGN(size); HDassert(offset < heap->heap_alloc); HDassert(offset + size <= heap->heap_alloc); - fl = heap->freelist; - *heap_flags |= H5AC__DIRTIED_FLAG; + /* Mark heap as dirty in cache */ + /* (A bit early in the process, but it's difficult to determine in the + * code below where to mark the heap as dirty, especially in error cases, + * so we just accept that an extra flush of the heap info could occur + * if an error occurs -QAK) + */ + if(H5AC_mark_pinned_or_protected_entry_dirty(f, heap) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, (size_t)(-1), "unable to mark heap as dirty") /* * Check if this chunk can be prepended or appended to an already * free chunk. It might also fall between two chunks in such a way * that all three chunks can be combined into one. */ + fl = heap->freelist; while(fl) { H5HL_free_t *fl2 = NULL; @@ -1428,10 +1265,6 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) assert(f); assert(H5F_addr_defined(addr)); - /* Check for write access */ - if (0==(f->intent & H5F_ACC_RDWR)) - HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file"); - /* Cache this for later */ sizeof_hdr= H5HL_SIZEOF_HDR(f); diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h index eab55e3..4684d61 100644 --- a/src/H5HLprivate.h +++ b/src/H5HLprivate.h @@ -67,11 +67,10 @@ H5_DLL herr_t H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *ad H5_DLL H5HL_t *H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5AC_protect_t rw); H5_DLL void *H5HL_offset_into(H5F_t *f, const H5HL_t *heap, size_t offset); H5_DLL herr_t H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, - size_t size, unsigned *heap_flags); -H5_DLL herr_t H5HL_unprotect(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, - haddr_t addr, unsigned heap_flags); -H5_DLL size_t H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size, - const void *buf); + size_t size); +H5_DLL herr_t H5HL_unprotect(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, haddr_t addr); +H5_DLL size_t H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t size, + const void *buf); H5_DLL herr_t H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size); diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index d6053b7..5a8eb33 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -422,7 +422,7 @@ H5Lunpack_elink_val(const void *_ext_linkval, size_t link_size, lnk_flags = *ext_linkval & 0x0F; if(lnk_version > H5L_EXT_VERSION) HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad version number for external link") - if(lnk_flags & ~H5L_EXT_FLAGS_ALL) + if(lnk_flags & (unsigned)~H5L_EXT_FLAGS_ALL) HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad flags for external link") if(link_size <= 2) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid external link buffer") diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 9c03b20..cf34ead 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -128,7 +128,7 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags, HDassert(s && !*s); - if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr, H5AC__NO_FLAGS_SET) < 0) + if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value") heap = NULL; #endif @@ -157,7 +157,7 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, unsigned UNUSED mesg_flags, HDassert(mesg->slot[u].size > 0); } /* end for */ - if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr, H5AC__NO_FLAGS_SET) < 0) + if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value") heap = NULL; @@ -419,10 +419,11 @@ static void * H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t UNUSED *cpy_info, void UNUSED *_udata) { - H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src; - H5O_efl_t *efl_dst = NULL; - size_t idx, size, name_offset, heap_size; - void *ret_value; /* Return value */ + H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src; + H5O_efl_t *efl_dst = NULL; + H5HL_t *heap = NULL; /* Pointer to local heap for EFL file names */ + size_t idx, size, name_offset, heap_size; + void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_efl_copy_file) @@ -432,22 +433,27 @@ H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst, /* Allocate space for the destination efl */ if(NULL == (efl_dst = H5MM_calloc(sizeof(H5O_efl_t)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the "top level" information */ HDmemcpy(efl_dst, efl_src, sizeof(H5O_efl_t)); - /* create name heap */ - heap_size = H5HL_ALIGN(1); + /* Determine size needed for destination heap */ + heap_size = H5HL_ALIGN(1); /* "empty" name */ for(idx = 0; idx < efl_src->nused; idx++) heap_size += H5HL_ALIGN(HDstrlen(efl_src->slot[idx].name) + 1); + /* Create name heap */ if(H5HL_create(file_dst, dxpl_id, heap_size, &efl_dst->heap_addr/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create heap") + HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, NULL, "can't create heap") - name_offset = H5HL_insert(file_dst, dxpl_id, efl_dst->heap_addr, (size_t)1, ""); - if((size_t)(-1) == name_offset) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't initialize heap") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(file_dst, dxpl_id, efl_dst->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to protect EFL file name heap") + + /* Insert "empty" name first */ + if((size_t)(-1) == (name_offset = H5HL_insert(file_dst, dxpl_id, heap, (size_t)1, ""))) + HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap") HDassert(0 == name_offset); /* allocate array of external file entries */ @@ -463,14 +469,18 @@ H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst, /* copy the name from the source */ for(idx = 0; idx < efl_src->nused; idx++) { efl_dst->slot[idx].name = H5MM_xstrdup(efl_src->slot[idx].name); - efl_dst->slot[idx].name_offset = H5HL_insert(file_dst, dxpl_id, efl_dst->heap_addr, - HDstrlen(efl_dst->slot[idx].name) + 1, efl_dst->slot[idx].name); + if((size_t)(-1) == (efl_dst->slot[idx].name_offset = H5HL_insert(file_dst, dxpl_id, heap, + HDstrlen(efl_dst->slot[idx].name) + 1, efl_dst->slot[idx].name))) + HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap") } /* end for */ /* Set return value */ ret_value = efl_dst; done: + /* Release resources */ + if(heap && H5HL_unprotect(file_dst, dxpl_id, heap, efl_dst->heap_addr) < 0) + HDONE_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to unprotect EFL file name heap") if(!ret_value) if(efl_dst) H5MM_xfree(efl_dst); diff --git a/src/H5Omessage.c b/src/H5Omessage.c index a6e13b0..6eedc1f 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -1173,7 +1173,7 @@ H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t app_op, HDassert(type); /* Protect the object header to iterate over */ - if(NULL == (oh = (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_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Call the "real" iterate routine */ diff --git a/test/lheap.c b/test/lheap.c index 60c0b85..abf1bc0 100644 --- a/test/lheap.c +++ b/test/lheap.c @@ -58,6 +58,7 @@ main(void) H5F_t *f=NULL; /*hdf5 file pointer */ char filename[1024]; /*file name */ haddr_t heap_addr; /*local heap address */ + H5HL_t *heap = NULL; /*local heap */ size_t obj[NOBJS]; /*offsets within the heap */ int i, j; /*miscellaneous counters */ char buf[1024]; /*the value to store */ @@ -86,18 +87,27 @@ main(void) H5Eprint2(H5E_DEFAULT, stdout); goto error; } + if (NULL == (heap = H5HL_protect(f, H5P_DATASET_XFER_DEFAULT, heap_addr, H5AC_WRITE))) { + H5_FAILED(); + H5Eprint2(H5E_DEFAULT, stdout); + goto error; + } for(i = 0; i < NOBJS; i++) { sprintf(buf, "%03d-", i); for (j=4; j4) buf[j] = '\0'; - if ((size_t)(-1)==(obj[i]=H5HL_insert(f, H5P_DATASET_XFER_DEFAULT, heap_addr, strlen(buf)+1, - buf))) { + if ((size_t)(-1)==(obj[i]=H5HL_insert(f, H5P_DATASET_XFER_DEFAULT, heap, strlen(buf)+1, buf))) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } } + if (H5HL_unprotect(f, H5P_DATASET_XFER_DEFAULT, heap, heap_addr) < 0) { + H5_FAILED(); + H5Eprint2(H5E_DEFAULT, stdout); + goto error; + } if (H5Fclose(file)<0) goto error; PASSED(); @@ -119,8 +129,6 @@ main(void) goto error; } for (i=0; i4) buf[j] = '\0'; @@ -145,7 +153,7 @@ main(void) goto error; } - if (H5HL_unprotect(f, H5P_DATASET_XFER_DEFAULT, heap, heap_addr, H5AC__NO_FLAGS_SET) < 0) { + if (H5HL_unprotect(f, H5P_DATASET_XFER_DEFAULT, heap, heap_addr) < 0) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; diff --git a/tools/misc/h5debug.c b/tools/misc/h5debug.c index 2c79433..13bbe86 100644 --- a/tools/misc/h5debug.c +++ b/tools/misc/h5debug.c @@ -141,7 +141,7 @@ main(int argc, char *argv[]) /* * Debug the file's super block. */ - status = H5F_debug(f, H5P_DATASET_XFER_DEFAULT, stdout, 0, VCOL); + status = H5F_debug(f, stdout, 0, VCOL); } else if(!HDmemcmp(sig, H5HL_MAGIC, (size_t)H5HL_SIZEOF_MAGIC)) { /* -- cgit v0.12