diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2004-07-16 20:48:45 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2004-07-16 20:48:45 (GMT) |
commit | f81bf3b56fa1d62d2649ce8e08c34fbba433d179 (patch) | |
tree | 77e25ef24fa6a7f8b2e48f705b20dfd3953793b7 /src | |
parent | c1666563b7cd1bea9262efaf3365b5edfe3a3f21 (diff) | |
download | hdf5-f81bf3b56fa1d62d2649ce8e08c34fbba433d179.zip hdf5-f81bf3b56fa1d62d2649ce8e08c34fbba433d179.tar.gz hdf5-f81bf3b56fa1d62d2649ce8e08c34fbba433d179.tar.bz2 |
[svn-r8893] Purpose:
Code cleanup
Description:
Clean up a bunch of warnings and bring new code better inline with current
library coding practice.
Platforms tested:
FreeBSD 4.10 (sleipnir) w/parallel
Too minor to require h5committest
Misc. update:
Diffstat (limited to 'src')
-rw-r--r-- | src/H5F.c | 3 | ||||
-rw-r--r-- | src/H5Fprivate.h | 3 | ||||
-rw-r--r-- | src/H5G.c | 59 | ||||
-rw-r--r-- | src/H5Gent.c | 6 | ||||
-rw-r--r-- | src/H5Gnode.c | 238 | ||||
-rw-r--r-- | src/H5HL.c | 625 | ||||
-rw-r--r-- | src/H5HLprivate.h | 7 | ||||
-rw-r--r-- | src/H5MF.c | 143 | ||||
-rw-r--r-- | src/H5MFprivate.h | 4 | ||||
-rw-r--r-- | src/H5O.c | 71 | ||||
-rw-r--r-- | src/H5Oefl.c | 53 | ||||
-rw-r--r-- | src/H5Oprivate.h | 22 | ||||
-rw-r--r-- | src/H5private.h | 74 |
13 files changed, 825 insertions, 483 deletions
@@ -4551,7 +4551,6 @@ H5F_get_eoa(const H5F_t *f) { haddr_t ret_value; - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI(H5F_get_eoa, HADDR_UNDEF) assert(f); @@ -4563,7 +4562,7 @@ H5F_get_eoa(const H5F_t *f) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_base_addr() */ +} /* end H5F_get_eoa() */ #ifdef H5_HAVE_PARALLEL diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 83b8b57..695c3bc 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -213,6 +213,8 @@ typedef struct H5F_t H5F_t; #define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags&(FL)) /* B-tree node raw page */ #define H5F_GRP_BTREE_SHARED(F) ((F)->shared->grp_btree_shared) +/* Base address of file */ +#define H5F_BASE_ADDR(F) ((F)->shared->base_addr) #else /* H5F_PACKAGE */ #define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F)) #define H5F_SIZEOF_SIZE(F) (H5F_sizeof_size(F)) @@ -223,6 +225,7 @@ typedef struct H5F_t H5F_t; #define H5F_RDCC_W0(F) (H5F_rdcc_w0(F)) #define H5F_HAS_FEATURE(F,FL) (H5F_has_feature(F,FL)) #define H5F_GRP_BTREE_SHARED(F) (H5F_grp_btree_shared(F)) +#define H5F_BASE_ADDR(F) (H5F_base_addr(F)) #endif /* H5F_PACKAGE */ @@ -996,9 +996,9 @@ H5G_init_interface(void) /* * Initialize the type info table. Begin with the most general types and * end with the most specific. For instance, any object that has a data - * type message is a data type but only some of them are datasets. + * type message is a datatype but only some of them are datasets. */ - H5G_register_type(H5G_TYPE, H5T_isa, "data type"); + H5G_register_type(H5G_TYPE, H5T_isa, "datatype"); H5G_register_type(H5G_GROUP, H5G_isa, "group"); H5G_register_type(H5G_DATASET, H5D_isa, "dataset"); H5G_register_type(H5G_LINK, H5G_link_isa, "link"); @@ -1596,6 +1596,7 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/, char *linkval = NULL; /*the copied link value */ H5G_entry_t tmp_grp_ent; /* Temporary copy of group entry */ H5RS_str_t *tmp_user_path_r=NULL, *tmp_canon_path_r=NULL; /* Temporary pointer to object's user path & canonical path */ + const H5HL_t *heap; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_traverse_slink, FAIL); @@ -1606,10 +1607,17 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/, /* Get the link value */ if (NULL==H5O_read (grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address"); - if (NULL==(clv=H5HL_peek (grp_ent->file, dxpl_id, stab_mesg.heap_addr, - obj_ent->cache.slink.lval_offset))) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbolic link value"); + + if (NULL == (heap = H5HL_protect(grp_ent->file, dxpl_id, stab_mesg.heap_addr))) + HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") + + clv = H5HL_offset_into(grp_ent->file, heap, obj_ent->cache.slink.lval_offset); + linkval = H5MM_xstrdup (clv); + assert(linkval); + + if (H5HL_unprotect(grp_ent->file, dxpl_id, heap, stab_mesg.heap_addr) < 0) + HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") /* Hold the entry's name (& old_name) to restore later */ tmp_user_path_r=obj_ent->user_path_r; @@ -1842,7 +1850,7 @@ H5G_isa(H5G_entry_t *ent, hid_t dxpl_id) { htri_t ret_value; - FUNC_ENTER_NOAPI(H5G_isa, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5G_isa); assert(ent); @@ -2340,12 +2348,8 @@ H5G_loc (hid_t loc_id) case H5I_TEMPBUF: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of buffer"); - - case H5I_NGROUPS: - case H5I_BADID: - case H5I_FILE_CLOSING: - case H5I_REFERENCE: - case H5I_VFL: + + default: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object ID"); } @@ -2581,12 +2585,21 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, */ if (statbuf) { if (H5G_CACHED_SLINK==obj_ent.type) { + const H5HL_t *heap; + /* Named object is a symbolic link */ - if (NULL==H5O_read (&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id) || - NULL==(s=H5HL_peek (grp_ent.file, dxpl_id, stab_mesg.heap_addr, - obj_ent.cache.slink.lval_offset))) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value"); - statbuf->linklen = HDstrlen(s)+1; /*count the null terminator*/ + if (NULL == H5O_read(&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value") + + if (NULL == (heap = H5HL_protect(grp_ent.file, dxpl_id, stab_mesg.heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") + + s = H5HL_offset_into(grp_ent.file, heap, obj_ent.cache.slink.lval_offset); + + statbuf->linklen = HDstrlen(s) + 1; /*count the null terminator*/ + + if (H5HL_unprotect(grp_ent.file, dxpl_id, heap, stab_mesg.heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") statbuf->objno[0] = statbuf->objno[1] = 0; statbuf->nlink = 0; statbuf->type = H5G_LINK; @@ -2810,6 +2823,7 @@ H5G_linkval (H5G_entry_t *loc, const char *name, size_t size, char *buf/*out*/, const char *s = NULL; H5G_entry_t grp_ent, obj_ent; H5O_stab_t stab_mesg; + const H5HL_t *heap; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_linkval, FAIL); @@ -2830,14 +2844,19 @@ H5G_linkval (H5G_entry_t *loc, const char *name, size_t size, char *buf/*out*/, */ if (NULL==H5O_read (&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to determine local heap address"); - if (NULL==(s=H5HL_peek (grp_ent.file, dxpl_id, stab_mesg.heap_addr, - obj_ent.cache.slink.lval_offset))) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value"); + + if (NULL == (heap = H5HL_protect(grp_ent.file, dxpl_id, stab_mesg.heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") + s = H5HL_offset_into(grp_ent.file, heap, obj_ent.cache.slink.lval_offset); + /* Copy to output buffer */ if (size>0 && buf) HDstrncpy (buf, s, size); + if (H5HL_unprotect(grp_ent.file, dxpl_id, heap, stab_mesg.heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") + done: /* Free the ID to name buffers */ H5G_free_ent_name(&grp_ent); diff --git a/src/H5Gent.c b/src/H5Gent.c index b050453..4d9fe62 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -501,10 +501,14 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str "Link value offset:", (unsigned long)(ent->cache.slink.lval_offset)); if (heap>0 && H5F_addr_defined(heap)) { - lval = H5HL_peek (ent->file, dxpl_id, heap, ent->cache.slink.lval_offset); + const H5HL_t *heap_ptr; + + heap_ptr = H5HL_protect(ent->file, dxpl_id, heap); + lval = H5HL_offset_into(ent->file, heap_ptr, 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_ptr, heap); } else HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given, name not displayed!"); diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 851de13..eaa0089 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -300,20 +300,27 @@ H5G_node_debug_key (FILE *stream, H5F_t *f, hid_t dxpl_id, int indent, int fwidt { const H5G_node_key_t *key = (const H5G_node_key_t *) _key; const H5G_bt_ud1_t *udata = (const H5G_bt_ud1_t *) _udata; + const H5HL_t *heap = NULL; const char *s; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_node_debug_key, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_debug_key); assert (key); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Heap offset:", (unsigned)key->offset); HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:"); - if (NULL == (s = H5HL_peek(f, dxpl_id, udata->heap_addr, key->offset))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name"); + + if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); + + s = H5HL_offset_into(f, heap, key->offset); HDfprintf (stream, "%s\n", s); + if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name"); + done: FUNC_LEAVE_NOAPI(ret_value); } @@ -378,7 +385,7 @@ H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_udata1 const uint8_t *p = NULL; H5G_node_t *ret_value; /*for error handling */ - FUNC_ENTER_NOAPI(H5G_node_load, NULL); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_load); /* * Check arguments. @@ -469,7 +476,7 @@ H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_ int i; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_node_flush, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_flush); /* * Check arguments. @@ -755,19 +762,22 @@ H5G_node_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, void *_rt_ke H5G_bt_ud1_t *udata = (H5G_bt_ud1_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; + const H5HL_t *heap = NULL; const char *s1, *s2; const char *base; /* Base of heap */ int ret_value; - FUNC_ENTER_NOAPI(H5G_node_cmp2, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_cmp2); assert(udata); assert(lt_key); assert(rt_key); /* Get base address of heap */ - if (NULL == (base = H5HL_peek(f, dxpl_id, udata->heap_addr, 0))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name"); + if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); + + base = H5HL_offset_into(f, heap, 0); /* Get pointers to string names */ s1=base+lt_key->offset; @@ -777,6 +787,9 @@ H5G_node_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, void *_rt_ke ret_value = HDstrcmp(s1, s2); done: + if (heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name"); + FUNC_LEAVE_NOAPI(ret_value); } @@ -814,15 +827,18 @@ H5G_node_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, void *_rt_ke H5G_bt_ud1_t *udata = (H5G_bt_ud1_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; + const H5HL_t *heap = NULL; const char *s; const char *base; /* Base of heap */ int ret_value=0; /* Return value */ - FUNC_ENTER_NOAPI(H5G_node_cmp3, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_cmp3); /* Get base address of heap */ - if (NULL == (base = H5HL_peek(f, dxpl_id, udata->heap_addr, 0))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name"); + if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); + + base = H5HL_offset_into(f, heap, 0); /* left side */ s=base+lt_key->offset; @@ -835,6 +851,9 @@ H5G_node_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, void *_rt_ke HGOTO_DONE(1); done: + if (heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name"); + FUNC_LEAVE_NOAPI(ret_value); } @@ -874,12 +893,13 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key { H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; H5G_node_t *sn = NULL; + const H5HL_t *heap = NULL; int lt = 0, idx = 0, rt, cmp = 1; const char *s; const char *base; /* Base of heap */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_node_found, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_found); /* * Check arguments. @@ -895,8 +915,10 @@ 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 == (base = H5HL_peek(f, dxpl_id, bt_udata->heap_addr, 0))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbol name"); + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); + + base = H5HL_offset_into(f, heap, 0); /* * Binary search. @@ -913,20 +935,25 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key lt = idx + 1; } } + + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->heap_addr) < 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"); if (bt_udata->operation==H5G_OPER_FIND) /* - * The caller is querying the symbol entry. Return just a pointer to - * the entry. The pointer is valid until the next call to H5AC. + * The caller is querying the symbol entry, copy it into the UDATA + * entry field. (Hmm... should this use H5G_ent_copy()? - QAK) */ bt_udata->ent = sn->entry[idx]; else HGOTO_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, "internal erorr (unknown symbol find operation)"); done: - if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) < 0 && ret_value>=0) + if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) < 0) HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node"); FUNC_LEAVE_NOAPI(ret_value); @@ -981,6 +1008,7 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key, H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; H5G_node_t *sn = NULL, *snrt = NULL; + const H5HL_t *heap = NULL; size_t offset; /*offset of name in heap */ const char *s; const char *base; /* Base of heap */ @@ -989,7 +1017,7 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key, H5G_node_t *insert_into = NULL; /*node that gets new entry*/ H5B_ins_t ret_value = H5B_INS_ERROR; - FUNC_ENTER_NOAPI(H5G_node_insert, H5B_INS_ERROR); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_insert); /* * Check arguments. @@ -1008,8 +1036,10 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key, HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node"); /* Get base address of heap */ - if (NULL == (base = H5HL_peek(f, dxpl_id, bt_udata->heap_addr, 0))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to read symbol name"); + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name"); + + base = H5HL_offset_into(f, heap, 0); /* * Where does the new symbol get inserted? We use a binary search. @@ -1018,8 +1048,17 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key, while (lt < rt) { idx = (lt + rt) / 2; s=base+sn->entry[idx].name_off; - if (0 == (cmp = HDstrcmp(bt_udata->name, s))) /*already present */ - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "symbol is already present in symbol table"); + + if (0 == (cmp = HDstrcmp(bt_udata->name, s))) /*already present */ { + HCOMMON_ERROR(H5E_SYM, H5E_CANTINSERT, "symbol is already present in symbol table"); + + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name"); + heap=NULL; base=NULL; + + HGOTO_DONE(H5B_INS_ERROR); + } + if (cmp < 0) { rt = idx; } else { @@ -1028,6 +1067,10 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key, } idx += cmp > 0 ? 1 : 0; + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name"); + heap=NULL; base=NULL; + /* * Add the new name to the heap. */ @@ -1156,12 +1199,13 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, H5G_node_key_t *rt_key = (H5G_node_key_t*)_rt_key; H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t*)_udata; H5G_node_t *sn = NULL; + const H5HL_t *heap = NULL; int lt=0, rt, idx=0, cmp=1; const char *s = NULL; const char *base; /* Base of heap */ H5B_ins_t ret_value = H5B_INS_ERROR; - FUNC_ENTER_NOAPI(H5G_node_remove, H5B_INS_ERROR); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_remove); /* Check arguments */ assert(f); @@ -1174,12 +1218,17 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, if (NULL==(sn=H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node"); - /* Get base address of heap */ - if (NULL == (base = H5HL_peek(f, dxpl_id, bt_udata->heap_addr, 0))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to read symbol name"); - /* "Normal" removal of a single entry from the symbol table node */ if(bt_udata->name!=NULL) { + size_t len=0; + hbool_t found; /* Indicate that the string was found */ + + /* Get base address of heap */ + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name"); + + base = H5HL_offset_into(f, heap, 0); + /* Find the name with a binary search */ rt = sn->nsyms; while (lt<rt && cmp) { @@ -1192,14 +1241,35 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, lt = idx+1; } } + + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name"); + heap=NULL; base=NULL; + if (cmp) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "not found"); if (H5G_CACHED_SLINK==sn->entry[idx].type) { /* Remove the symbolic link value */ - if ((s=H5HL_peek(f, dxpl_id, bt_udata->heap_addr, sn->entry[idx].cache.slink.lval_offset))) - H5HL_remove(f, dxpl_id, bt_udata->heap_addr, sn->entry[idx].cache.slink.lval_offset, HDstrlen(s)+1); - H5E_clear(); /*no big deal*/ + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name"); + + s = H5HL_offset_into(f, heap, sn->entry[idx].cache.slink.lval_offset); + if (s) { + len=HDstrlen(s)+1; + found=1; + } /* end if */ + else + found=0; + + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name"); + heap=NULL; s=NULL; + + if (found) + H5HL_remove(f, dxpl_id, bt_udata->heap_addr, sn->entry[idx].cache.slink.lval_offset, len); + + H5E_clear(); /* no big deal */ } else { /* Decrement the reference count */ assert(H5F_addr_defined(sn->entry[idx].header)); @@ -1208,9 +1278,26 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, } /* Remove the name from the local heap */ - if ((s=H5HL_peek(f, dxpl_id, bt_udata->heap_addr, sn->entry[idx].name_off))) - H5HL_remove(f, dxpl_id, bt_udata->heap_addr, sn->entry[idx].name_off, HDstrlen(s)+1); - H5E_clear(); /*no big deal*/ + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name"); + + s = H5HL_offset_into(f, heap, sn->entry[idx].name_off); + + if (s) { + len=HDstrlen(s)+1; + found=1; + } /* end if */ + else + found=0; + + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name"); + heap=NULL; s=NULL; + + if (found) + H5HL_remove(f, dxpl_id, bt_udata->heap_addr, sn->entry[idx].name_off, len); + + H5E_clear(); /* no big deal */ /* Remove the entry from the symbol table node */ if (1==sn->nsyms) { @@ -1301,7 +1388,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, } /* end else */ done: - if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE)<0 && ret_value!=H5B_INS_ERROR) + if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE)<0) HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node"); FUNC_LEAVE_NOAPI(ret_value); @@ -1333,6 +1420,7 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, { H5G_bt_ud2_t *bt_udata = (H5G_bt_ud2_t *)_udata; H5G_node_t *sn = NULL; + const H5HL_t *heap = NULL; int i, nsyms; size_t n, *name_off=NULL; const char *name; @@ -1352,14 +1440,20 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, * Save information about the symbol table node since we can't lock it * because we're about to call an application function. */ - if (NULL == (sn = H5AC_find(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) + if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node"); nsyms = sn->nsyms; if (NULL==(name_off = H5MM_malloc (nsyms*sizeof(name_off[0])))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, H5B_ITER_ERROR, "memory allocation failed"); for (i=0; i<nsyms; i++) name_off[i] = sn->entry[i].name_off; - sn = NULL; + + if (H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) != SUCCEED) { + sn = NULL; + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); + } + + sn=NULL; /* Make certain future references will be caught */ /* * Iterate over the symbol table node entries. @@ -1368,7 +1462,10 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, if (bt_udata->skip>0) { --bt_udata->skip; } else { - name = H5HL_peek (f, dxpl_id, bt_udata->ent->cache.stab.heap_addr, name_off[i]); + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->ent->cache.stab.heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name"); + + name = H5HL_offset_into(f, heap, name_off[i]); assert (name); n = HDstrlen (name); @@ -1379,6 +1476,11 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, s = buf; } HDstrcpy (s, name); + + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->ent->cache.stab.heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name"); + heap=NULL; name=NULL; + ret_value = (bt_udata->op)(bt_udata->group_id, s, bt_udata->op_data); if (s!=buf) H5MM_xfree (s); @@ -1392,6 +1494,12 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, HERROR (H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); done: + if (heap && H5HL_unprotect(f, dxpl_id, heap, bt_udata->ent->cache.stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name"); + + if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) != SUCCEED) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); + name_off = H5MM_xfree (name_off); FUNC_LEAVE_NOAPI(ret_value); } @@ -1430,12 +1538,15 @@ H5G_node_sumup(H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, assert(num_objs); /* Find the object node and add the number of symbol entries. */ - if (NULL == (sn = H5AC_find(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) + if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node"); *num_objs += sn->nsyms; done: + if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) != SUCCEED) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); + FUNC_LEAVE_NOAPI(ret_value); } @@ -1461,6 +1572,7 @@ H5G_node_name(H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, void UNUSED *_rt_key, void *_udata) { H5G_bt_ud3_t *bt_udata = (H5G_bt_ud3_t *)_udata; + const H5HL_t *heap = NULL; size_t name_off; hsize_t loc_idx; const char *name; @@ -1476,23 +1588,35 @@ H5G_node_name(H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, assert(H5F_addr_defined(addr)); assert(bt_udata); - - if (NULL == (sn = H5AC_find(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) + if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node"); /* Find the node, locate the object symbol table entry and retrieve the name */ if(bt_udata->idx >= bt_udata->num_objs && bt_udata->idx < (bt_udata->num_objs+sn->nsyms)) { loc_idx = bt_udata->idx - bt_udata->num_objs; name_off = sn->entry[loc_idx].name_off; - name = H5HL_peek (f, dxpl_id, bt_udata->ent->cache.stab.heap_addr, name_off); + + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->ent->cache.stab.heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name"); + + name = H5HL_offset_into(f, heap, name_off); assert (name); bt_udata->name = H5MM_strdup (name); - HGOTO_DONE(H5B_ITER_STOP); - } + assert(bt_udata->name); - bt_udata->num_objs += sn->nsyms; + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->ent->cache.stab.heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name"); + heap=NULL; name=NULL; + + ret_value = H5B_ITER_STOP; + } else { + bt_udata->num_objs += sn->nsyms; + } done: + if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) != SUCCEED) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); + FUNC_LEAVE_NOAPI(ret_value); } @@ -1529,7 +1653,7 @@ H5G_node_type(H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, assert(bt_udata); /* Find the node, locate the object symbol table entry and retrieve the type */ - if (NULL == (sn = H5AC_find(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) + if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node"); if(bt_udata->idx >= bt_udata->num_objs && bt_udata->idx < (bt_udata->num_objs+sn->nsyms)) { @@ -1539,8 +1663,11 @@ H5G_node_type(H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, } else { bt_udata->num_objs += sn->nsyms; } - + done: + if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, FALSE) != SUCCEED) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); + FUNC_LEAVE_NOAPI(ret_value); } @@ -1691,6 +1818,7 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int i; H5G_node_t *sn = NULL; const char *s; + const H5HL_t *heap_ptr = NULL; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_node_debug, FAIL); @@ -1731,11 +1859,19 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, fwidth = MAX(0, fwidth - 3); for (i = 0; i < sn->nsyms; i++) { fprintf(stream, "%*sSymbol %d:\n", indent - 3, "", i); - if (heap>0 && H5F_addr_defined(heap) && - (s = H5HL_peek(f, dxpl_id, heap, sn->entry[i].name_off))) { - fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, - "Name:", - s); + + if (heap>0 && H5F_addr_defined(heap)) { + if (NULL == (heap_ptr = H5HL_protect(f, dxpl_id, heap))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); + + s = H5HL_offset_into(f, heap_ptr, sn->entry[i].name_off); + + if (s) + fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, "Name:", s); + + if (H5HL_unprotect(f, dxpl_id, heap_ptr, heap) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name"); + heap_ptr=NULL; s=NULL; } else fprintf(stream, "%*s%-*s\n", indent, "", fwidth, "Warning: Invalid heap address given, name not displayed!"); @@ -28,7 +28,11 @@ * *------------------------------------------------------------------------- */ -#define H5F_PACKAGE /*suppress error about including H5Fpkg */ +#define H5F_PACKAGE /* Suppress error about including H5Fpkg */ + +/* Pablo information */ +/* (Put before include files to avoid problems with inline functions) */ +#define PABLO_MASK H5HL_mask #include "H5private.h" /* Generic Functions */ #include "H5ACprivate.h" /* Metadata cache */ @@ -39,9 +43,6 @@ #include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ -/* Pablo information */ -#define PABLO_MASK H5HL_mask - /* Private macros */ #define H5HL_FREE_NULL 1 /*end of free list on disk */ #define H5HL_MIN_HEAP 256 /* Minimum size to reduce heap buffer to */ @@ -65,7 +66,7 @@ typedef struct H5HL_free_t { struct H5HL_free_t *next; /*next entry in free list */ } H5HL_free_t; -typedef struct H5HL_t { +struct H5HL_t { H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ /* first field in structure */ haddr_t addr; /*address of data */ @@ -74,7 +75,7 @@ typedef struct H5HL_t { size_t disk_resrv; /*data bytes "reserved" on disk */ uint8_t *chunk; /*the chunk, including header */ H5HL_free_t *freelist; /*the free list */ -} H5HL_t; +}; /* PRIVATE PROTOTYPES */ #ifdef NOT_YET @@ -83,7 +84,10 @@ static void *H5HL_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, siz 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 H5HL_free_t * H5HL_remove_free(H5HL_t *heap, H5HL_free_t *fl); + +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); /* Metadata cache callbacks */ static H5HL_t *H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, @@ -275,7 +279,7 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1, /* Allocate space in memory for the heap */ if (NULL==(heap = H5FL_CALLOC(H5HL_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - + /* heap data size */ H5F_DECODE_LENGTH(f, p, heap->disk_alloc); heap->mem_alloc = heap->disk_alloc; @@ -328,6 +332,219 @@ done: /*------------------------------------------------------------------------- + * Function: H5HL_minimize_heap_space + * + * Purpose: Go through the heap's freelist and determine if we can + * eliminate the free blocks at the tail of the buffer. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Bill Wendling + * wendling@ncsa.uiuc.edu + * Sept. 16, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap) +{ + herr_t ret_value = SUCCEED; + size_t sizeof_hdr; + + FUNC_ENTER_NOAPI(H5HL_minimize_heap_space, FAIL) + + /* check args */ + assert(f); + assert(heap); + + sizeof_hdr = H5HL_SIZEOF_HDR(f); /* cache H5HL header size for file */ + + /* + * When the heap is being flushed to disk, release the file space reserved + * for it. + */ + H5MF_free_reserved(f, (hsize_t)heap->disk_resrv); + heap->disk_resrv = 0; + + /* + * Check to see if we can reduce the size of the heap in memory by + * eliminating free blocks at the tail of the buffer before flushing the + * buffer out. + */ + if (heap->freelist) { + H5HL_free_t *tmp_fl; + H5HL_free_t *last_fl = NULL; + + /* Search for a free block at the end of the buffer */ + for (tmp_fl = heap->freelist; tmp_fl; tmp_fl = tmp_fl->next) + /* Check if the end of this free block is at the end of the buffer */ + if (tmp_fl->offset + tmp_fl->size == heap->mem_alloc) { + last_fl = tmp_fl; + break; + } + + /* + * Found free block at the end of the buffer, decide what to do + * about it + */ + if (last_fl) { + size_t new_mem_size = heap->mem_alloc; /* New size of memory buffer */ + + /* + * If the last free block's size is more than half the memory + * buffer size (and the memory buffer is larger than the + * minimum size), reduce or eliminate it. + */ + if (last_fl->size >= (heap->mem_alloc / 2) && heap->mem_alloc > H5HL_MIN_HEAP) { + /* + * Reduce size of buffer until it's too small or would + * eliminate the free block + */ + while (new_mem_size > H5HL_MIN_HEAP && + new_mem_size >= (last_fl->offset + H5HL_SIZEOF_FREE(f))) + new_mem_size /= 2; + + /* + * Check if reducing the memory buffer size would + * eliminate the free list + */ + if (new_mem_size < (last_fl->offset + H5HL_SIZEOF_FREE(f))) { + /* Check if this is the only block on the free list */ + if (last_fl->prev == NULL && last_fl->next == NULL) { + /* Double the new memory size */ + new_mem_size *= 2; + + /* Truncate the free block */ + last_fl->size = H5HL_ALIGN(new_mem_size - last_fl->offset); + new_mem_size = last_fl->offset + last_fl->size; + assert(last_fl->size >= H5HL_SIZEOF_FREE(f)); + } else { + /* + * Set the size of the memory buffer to the start + * of the free list + */ + new_mem_size = last_fl->offset; + + /* Eliminate the free block from the list */ + last_fl = H5HL_remove_free(heap, last_fl); + } + } else { + /* Truncate the free block */ + last_fl->size = H5HL_ALIGN(new_mem_size - last_fl->offset); + new_mem_size = last_fl->offset + last_fl->size; + assert(last_fl->size >= H5HL_SIZEOF_FREE(f)); + assert(last_fl->size == H5HL_ALIGN(last_fl->size)); + } + + /* Resize the memory buffer and reserved space in file */ + if (new_mem_size != heap->mem_alloc) { + + heap->mem_alloc = new_mem_size; + heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + new_mem_size)); + + if (!heap->chunk) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + } + } + } + } + + /* + * If the heap grew larger or smaller than disk storage then move the + * data segment of the heap to another contiguous block of disk + * storage. + */ + if (heap->mem_alloc != heap->disk_alloc) { + haddr_t old_addr = heap->addr, new_addr; + + /* Release old space on disk */ + H5_CHECK_OVERFLOW(heap->disk_alloc, size_t, hsize_t); + H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->disk_alloc); + H5E_clear(); /* don't really care if the free failed */ + + /* Allocate new space on disk */ + H5_CHECK_OVERFLOW(heap->mem_alloc, size_t, hsize_t); + + if (HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)heap->mem_alloc))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space for heap") + + heap->addr = new_addr; + + /* Set new size of block on disk */ + heap->disk_alloc = heap->mem_alloc; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5HL_serialize + * + * Purpose: Serialize the heap. This function will eliminate free + * blocks at the tail of the heap and also split the block + * if it needs to be split for the file. This is so that we + * can serialize it correctly. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Bill Wendling + * wendling@ncsa.uiuc.edu + * Sept. 16, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf) +{ + H5HL_free_t *fl; + uint8_t *p; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_serialize) + + /* check args */ + assert(buf); + assert(heap); + + /* serialize the header */ + p = buf; + fl = heap->freelist; + HDmemcpy(p, H5HL_MAGIC, H5HL_SIZEOF_MAGIC); + p += H5HL_SIZEOF_MAGIC; + *p++ = H5HL_VERSION; + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + H5F_ENCODE_LENGTH(f, p, heap->mem_alloc); + H5F_ENCODE_LENGTH(f, p, fl ? fl->offset : H5HL_FREE_NULL); + H5F_addr_encode(f, &p, heap->addr); + + /* serialize the free list */ + for (; fl; fl = fl->next) { + assert (fl->offset == H5HL_ALIGN (fl->offset)); + p = heap->chunk + H5HL_SIZEOF_HDR(f) + fl->offset; + + if (fl->next) { + H5F_ENCODE_LENGTH(f, p, fl->next->offset); + } else { + H5F_ENCODE_LENGTH(f, p, H5HL_FREE_NULL); + } + + H5F_ENCODE_LENGTH(f, p, fl->size); + } + + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5HL_flush * * Purpose: Flushes a heap from memory to disk if it's dirty. Optionally @@ -340,25 +557,24 @@ done: * Jul 17 1997 * * Modifications: - * rky, 1998-08-28 - * Only p0 writes metadata to disk. + * rky, 1998-08-28 + * Only p0 writes metadata to disk. * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. * * Quincey Koziol, 2002-7-180 * Added dxpl parameter to allow more control over I/O from metadata * cache. + * + * Bill Wendling, 2003-09-16 + * Separated out the bit that serializes the heap. *------------------------------------------------------------------------- */ static herr_t H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap) { - uint8_t *p; - H5HL_free_t *fl; - haddr_t hdr_end_addr; - size_t sizeof_hdr; /* Cache H5HL header size for file */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HL_flush, FAIL); @@ -368,176 +584,45 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap) assert(heap); if (heap->cache_info.dirty) { - /* Cache this for later */ - sizeof_hdr= H5HL_SIZEOF_HDR(f); + haddr_t hdr_end_addr; + size_t sizeof_hdr = H5HL_SIZEOF_HDR(f); /* cache H5HL header size for file */ - /* - * Since the file is being flushed to disk, release the file space reserved - * for it. - */ - H5MF_free_reserved(f, heap->disk_resrv); - heap->disk_resrv = 0; - - /* - * Check to see if we can reduce the size of the heap in memory by - * eliminating free blocks at the tail of the buffer before flushing the - * buffer out. - */ - if(heap->freelist) { - H5HL_free_t *tmp_fl=heap->freelist; - H5HL_free_t *last_fl=NULL; - - /* Search for a free block at the end of the buffer */ - while(tmp_fl!=NULL) { - /* Check if the end of this free block is at the end of the buffer */ - if(tmp_fl->offset + tmp_fl->size == heap->mem_alloc) { - last_fl=tmp_fl; - break; - } /* end if */ - tmp_fl=tmp_fl->next; - } /* end while */ - - /* Found free block at the end of the buffer, decide what to do about it */ - if(last_fl) { - size_t new_mem_size=heap->mem_alloc; /* New size of memory buffer */ - - /* - *If the last free block's size is more than half the memory - * buffer size (and the memory buffer is larger than the minimum - * size), reduce or eliminate it. - */ - if(last_fl->size>=(heap->mem_alloc/2) && heap->mem_alloc>H5HL_MIN_HEAP) { - /* Reduce size of buffer until it's too small or would eliminate the free block */ - while(new_mem_size>H5HL_MIN_HEAP && - new_mem_size>=(last_fl->offset+H5HL_SIZEOF_FREE(f))) - new_mem_size /= 2; - - /* Check if reducing the memory buffer size would eliminate the free list */ - if(new_mem_size<(last_fl->offset+H5HL_SIZEOF_FREE(f))) { - /* Check if this is the only block on the free list */ - if(last_fl->prev==NULL && last_fl->next==NULL) { - /* Double the new memory size */ - new_mem_size *=2; - - /* Truncate the free block */ - last_fl->size=H5HL_ALIGN(new_mem_size-last_fl->offset); - new_mem_size=last_fl->offset+last_fl->size; - assert(last_fl->size>=H5HL_SIZEOF_FREE(f)); - } /* end if */ - else { - /* Set the size of the memory buffer to the start of the free list */ - new_mem_size=last_fl->offset; - - /* Eliminate the free block from the list */ - last_fl = H5HL_remove_free(heap, last_fl); - } /* end else */ - } /* end if */ - else { - /* Truncate the free block */ - last_fl->size=H5HL_ALIGN(new_mem_size-last_fl->offset); - new_mem_size=last_fl->offset+last_fl->size; - assert(last_fl->size>=H5HL_SIZEOF_FREE(f)); - assert(last_fl->size==H5HL_ALIGN(last_fl->size)); - } /* end else */ - - /* Resize the memory buffer */ - if(new_mem_size!=heap->mem_alloc) { - heap->mem_alloc=new_mem_size; - heap->chunk = H5FL_BLK_REALLOC(heap_chunk,heap->chunk, - (sizeof_hdr + new_mem_size)); - if (NULL==heap->chunk) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - } /* end if */ - } /* end if */ - } /* end if */ - } /* end if */ - - /* - * If the heap grew larger or smaller than disk storage then move the - * data segment of the heap to another contiguous block of - * disk storage. - */ - if (heap->mem_alloc != heap->disk_alloc) { - haddr_t old_addr = heap->addr, new_addr; - - /* Release old space on disk */ - H5_CHECK_OVERFLOW(heap->disk_alloc,size_t,hsize_t); - H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->disk_alloc); - H5E_clear(); /*don't really care if the free failed */ - - /* Allocate new space on disk */ - H5_CHECK_OVERFLOW(heap->mem_alloc,size_t,hsize_t); - if (HADDR_UNDEF==(new_addr=H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, - (hsize_t)heap->mem_alloc))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space for heap"); - heap->addr = new_addr; - - /* Set new size of block on disk */ - heap->disk_alloc = heap->mem_alloc; - } + /* Minimize the heap space size if possible */ + if (H5HL_minimize_heap_space(f, dxpl_id, heap) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to minimize local heap space") - /* - * Write the header. - */ - p = heap->chunk; - fl=heap->freelist; - HDmemcpy(p, H5HL_MAGIC, H5HL_SIZEOF_MAGIC); - p += H5HL_SIZEOF_MAGIC; - *p++ = H5HL_VERSION; - *p++ = 0; /*reserved*/ - *p++ = 0; /*reserved*/ - *p++ = 0; /*reserved*/ - H5F_ENCODE_LENGTH(f, p, heap->mem_alloc); - H5F_ENCODE_LENGTH(f, p, fl ? fl->offset : H5HL_FREE_NULL); - H5F_addr_encode(f, &p, heap->addr); - - /* - * Write the free list. - */ - while (fl) { - assert (fl->offset == H5HL_ALIGN (fl->offset)); - p = heap->chunk + sizeof_hdr + fl->offset; - if (fl->next) { - H5F_ENCODE_LENGTH(f, p, fl->next->offset); - } else { - H5F_ENCODE_LENGTH(f, p, H5HL_FREE_NULL); - } - H5F_ENCODE_LENGTH(f, p, fl->size); - fl = fl->next; - } + /* Write the header */ + if (H5HL_serialize(f, heap, heap->chunk) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_WRITEERROR, FAIL, "unable to serialize local heap") - /* - * Copy buffer to disk. - */ + /* Copy buffer to disk */ hdr_end_addr = addr + (hsize_t)sizeof_hdr; + if (H5F_addr_eq(heap->addr, hdr_end_addr)) { /* The header and data are contiguous */ - if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, - (sizeof_hdr+heap->disk_alloc), + if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, (sizeof_hdr + heap->disk_alloc), dxpl_id, heap->chunk) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file"); + HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file") } else { - if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, - dxpl_id, heap->chunk)<0) - HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file"); + if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, heap->chunk) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file") + if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file"); + HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file") } - heap->cache_info.dirty = 0; + heap->cache_info.dirty = FALSE; } - /* - * Should we destroy the memory version? - */ + /* Should we destroy the memory version? */ if (destroy) { - if(H5HL_dest(f,heap)<0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap collection"); + if (H5HL_dest(f,heap) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap collection") } done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -567,7 +652,7 @@ H5HL_dest(H5F_t UNUSED *f, H5HL_t *heap) assert(heap); /* Verify that node is clean */ - assert (heap->cache_info.dirty==0); + assert (heap->cache_info.dirty==FALSE); if(heap->chunk) heap->chunk = H5FL_BLK_FREE(heap_chunk,heap->chunk); @@ -606,7 +691,7 @@ H5HL_clear(H5HL_t *heap) assert(heap); /* Mark heap as clean */ - heap->cache_info.dirty = 0; + heap->cache_info.dirty = FALSE; FUNC_LEAVE_NOAPI(SUCCEED); } /* end H5HL_clear() */ @@ -652,8 +737,9 @@ H5HL_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, voi assert(f); assert (H5F_addr_defined(addr)); - if (NULL == (heap = H5AC_find(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) + if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap"); + assert(offset < heap->mem_alloc); assert(offset + size <= heap->mem_alloc); @@ -665,60 +751,128 @@ H5HL_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, voi ret_value=buf; done: + if (heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, FALSE) != SUCCEED) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release object header"); + FUNC_LEAVE_NOAPI(ret_value); } #endif /* NOT_YET */ /*------------------------------------------------------------------------- - * Function: H5HL_peek + * Function: H5HL_protect + * + * Purpose: This function is a wrapper for the H5AC_protect call. The + * old H5HL_peek call (which this once was) wasn't "safe" + * for FPHDF5. (It'd get a read lock on an object but once + * it got that object, it'd release it keeping the old + * pointer value, which is no longer valid. This won't work + * since the pointer into some metdata block can become + * invalid.) + * + * N.B.: This function is always called in conjunction with + * the H5HL_offset_into function. The return from that + * function is the proper pointer to the heap's object. This + * is done so that the return from this function can be sent + * to H5HL_unprotect. + * + * Return: Success: Ptr to the object. The pointer points to a + * chunk of memory large enough to hold the + * object from the specified offset (usually the + * beginning of the object) to the end of the + * object. Do not attempt to read past the end + * of the object. + * Failure: NULL + * + * Programmer: Bill Wendling + * wendling@ncsa.uiuc.edu + * Sept. 17, 2003 * - * Purpose: This function is a more efficient version of H5HL_read. - * Instead of copying a heap object into a caller-supplied - * buffer, this function returns a pointer directly into the - * cache where the heap is being held. Thus, the return pointer - * is valid only until the next call to the cache. + * Modifications: * - * The address of the heap is ADDR in file F. OFFSET is the - * byte offset of the object from the beginning of the heap and - * may include an offset into the interior of the object. + *------------------------------------------------------------------------- + */ +const H5HL_t * +H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr) +{ + H5HL_t *ret_value = NULL; + + FUNC_ENTER_NOAPI(H5HL_protect, NULL); + + /* check arguments */ + assert(f); + assert(H5F_addr_defined(addr)); + + if (NULL == (ret_value = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5HL_offset_into * - * Return: Success: Ptr to the object. The pointer points to - * a chunk of memory large enough to hold the - * object from the specified offset (usually - * the beginning of the object) to the end - * of the object. Do not attempt to read past - * the end of the object. + * Purpose: Called directly after the call to H5HL_protect so that + * a pointer to the object in the heap can be got. * - * Failure: NULL + * Return: Success: Valid pointer. + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Bill Wendling + * wendling@ncsa.uiuc.edu + * Sept. 17, 2003 * * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. + * *------------------------------------------------------------------------- */ -const void * -H5HL_peek(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset) +void * +H5HL_offset_into(H5F_t *f, const H5HL_t *heap, size_t offset) { - H5HL_t *heap; - const void *ret_value; + /* + * We need to have called some other function before this to get a + * valid heap pointer. So, this can remain "FUNC_ENTER_NOAPI_NOINIT" + */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_offset_into) + assert(f); + assert(heap); + assert(offset < heap->mem_alloc); + FUNC_LEAVE_NOAPI(heap->chunk + H5HL_SIZEOF_HDR(f) + offset) +} - FUNC_ENTER_NOAPI(H5HL_peek, NULL); + +/*------------------------------------------------------------------------- + * Function: H5HL_unprotect + * + * Purpose: Unprotect the data retrieved by the H5HL_protect call. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Bill Wendling + * wendling@ncsa.uiuc.edu + * Sept. 17, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5HL_unprotect(H5F_t *f, hid_t dxpl_id, const H5HL_t *heap, haddr_t addr) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5HL_unprotect, FAIL); /* check arguments */ assert(f); + assert(heap); assert(H5F_addr_defined(addr)); - if (NULL == (heap = H5AC_find(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap"); - assert(offset < heap->mem_alloc); - - /* Set return value */ - ret_value = heap->chunk + H5HL_SIZEOF_HDR(f) + offset; + if (H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, (void *)heap, FALSE) != SUCCEED) + HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -781,7 +935,7 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void * size_t offset = 0; size_t need_size, old_size, need_more; hbool_t found; - size_t disk_resrv; /* Amount of additional space to reserve in file */ + size_t disk_resrv; /* Amount of additional space to reserve in file */ size_t sizeof_hdr; /* Cache H5HL header size for file */ size_t ret_value; /* Return value */ @@ -792,12 +946,14 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void * assert(H5F_addr_defined(addr)); assert(buf_size > 0); assert(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_find(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, (size_t)(-1), "unable to load heap"); - heap->cache_info.dirty += 1; + if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) + HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to load heap"); + + heap->cache_info.dirty=TRUE; /* Cache this for later */ sizeof_hdr= H5HL_SIZEOF_HDR(f); @@ -845,6 +1001,19 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void * if (found==FALSE) { need_more = MAX3(need_size, heap->mem_alloc, H5HL_SIZEOF_FREE(f)); + /* Reserve space in the file to hold the increased heap size + */ + if( heap->disk_resrv == heap->mem_alloc) + disk_resrv = need_more; + else + disk_resrv = heap->mem_alloc + need_more - heap->disk_resrv; + + if( H5MF_reserve(f, (hsize_t)disk_resrv) < 0 ) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "unable to reserve space in file"); + + /* Update heap's record of how much space it has reserved */ + heap->disk_resrv += disk_resrv; + if (max_fl && max_fl->offset + max_fl->size == heap->mem_alloc) { /* * Increase the size of the maximum free block. @@ -890,18 +1059,6 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void * } } - /* Reserve space in file to hold the increased heap size */ - if( heap->disk_resrv == heap->mem_alloc) - disk_resrv = need_more; - else - disk_resrv = heap->mem_alloc + need_more - heap->disk_resrv; - - if( H5MF_reserve(f, disk_resrv) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t) (-1), "unable to reserve space for heap"); - - /* Update heap's record of how much space it has reserved */ - heap->disk_resrv += disk_resrv; - #ifdef H5HL_DEBUG if (H5DEBUG(HL)) { fprintf(H5DEBUG(HL), @@ -929,6 +1086,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, FALSE) != SUCCEED) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to release object header"); + FUNC_LEAVE_NOAPI(ret_value); } @@ -969,18 +1129,23 @@ H5HL_write(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, co 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_find(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap"); + if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) + HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to load heap"); + assert(offset < heap->mem_alloc); assert(offset + size <= heap->mem_alloc); - heap->cache_info.dirty += 1; + heap->cache_info.dirty=TRUE; HDmemcpy(heap->chunk + H5HL_SIZEOF_HDR(f) + offset, buf, size); done: + if (heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, FALSE) != SUCCEED && ret_value != FAIL) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header"); + FUNC_LEAVE_NOAPI(ret_value); } #endif /* NOT_YET */ @@ -1027,17 +1192,20 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size) assert(H5F_addr_defined(addr)); assert(size > 0); assert (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); - if (NULL == (heap = H5AC_find(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap"); + + if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL))) + HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to load heap"); + assert(offset < heap->mem_alloc); assert(offset + size <= heap->mem_alloc); - fl = heap->freelist; - heap->cache_info.dirty += 1; + fl = heap->freelist; + heap->cache_info.dirty=TRUE; /* * Check if this chunk can be prepended or appended to an already @@ -1112,6 +1280,9 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size) heap->freelist = fl; done: + if (heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, FALSE) != SUCCEED) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release object header"); + FUNC_LEAVE_NOAPI(ret_value); } diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h index aa2a2d4..711f8b5 100644 --- a/src/H5HLprivate.h +++ b/src/H5HLprivate.h @@ -51,11 +51,16 @@ H5HL_ALIGN(H5F_SIZEOF_SIZE (F) + /*ptr to next free block */ \ H5F_SIZEOF_SIZE (F)) /*size of this free block */ +/* Typedef for local heap in memory (defined in H5HL.c) */ +typedef struct H5HL_t H5HL_t; + /* * Library prototypes... */ H5_DLL herr_t H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr/*out*/); -H5_DLL const void *H5HL_peek(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset); +H5_DLL const H5HL_t *H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr); +H5_DLL void *H5HL_offset_into(H5F_t *f, const H5HL_t *heap, size_t offset); +H5_DLL herr_t H5HL_unprotect(H5F_t *f, hid_t dxpl_id, const H5HL_t *heap, haddr_t addr); H5_DLL size_t H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf); H5_DLL herr_t H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size); @@ -32,14 +32,16 @@ */ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ +/* Pablo information */ +/* (Put before include files to avoid problems with inline functions) */ +#define PABLO_MASK H5MF_mask + #include "H5private.h" #include "H5Eprivate.h" #include "H5Fpkg.h" #include "H5FDprivate.h" #include "H5MFprivate.h" -#define PABLO_MASK H5MF_mask - /* Is the interface initialized? */ static int interface_initialize_g = 0; #define INTERFACE_INIT NULL @@ -80,13 +82,14 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) /* Fail if we don't have write access */ if (0==(f->intent & H5F_ACC_RDWR)) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "file is read-only"); + /* Check that the file can address the new space */ - if( H5MF_alloc_overflow(f, size) != 0 ) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "not enough address space in file"); + if( H5MF_alloc_overflow(f, size) ) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "not enough address space in file"); /* Allocate space from the virtual file layer */ if (HADDR_UNDEF==(ret_value=H5FD_alloc(f->shared->lf, type, dxpl_id, size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed"); /* Convert absolute file address to relative file address */ assert(ret_value>=f->shared->base_addr); @@ -197,6 +200,11 @@ H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t /* Convert old relative address to absolute address */ old_addr += f->shared->base_addr; + /* Check that the file can address the new space. */ + /* In the worst case, this means adding new_size bytes to the end of the file. */ + if( H5MF_alloc_overflow(f, new_size) ) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "not enough address space in file"); + /* Reallocate memory from the virtual file layer */ ret_value = H5FD_realloc(f->shared->lf, type, dxpl_id, old_addr, old_size, new_size); @@ -214,104 +222,119 @@ done: } /*------------------------------------------------------------------------- - * Function: H5MF_reserve + * Function: H5MF_reserve * - * Purpose: Sets aside file space that has not yet been allocated, but will - * be (or might be in the worst case). This number is used to - * ensure that there is room in the file when it is flushed to disk. + * Purpose: Sets aside file space that has not yet been allocated, but will + * be (or might be in the worst case). This number is used to + * ensure that there is room in the file when it is flushed to disk. * - * Nothing changes (and no error is generated) if the file is opened - * as read-only. + * Nothing changes (and no error is generated) if the file is opened + * as read-only. * - * Return: Success: 0 + * Return: Success: 0 * - * Failure: negative + * Failure: negative * - * Programmer: James Laird - * Nat Furrer + * Programmer: James Laird + * Nat Furrer * Thursday, May 27, 2004 * * Modifications: *------------------------------------------------------------------------- */ -herr_t H5MF_reserve(H5F_t *f, hsize_t size) +herr_t +H5MF_reserve(H5F_t *f, hsize_t size) { - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; + FUNC_ENTER_NOAPI(H5MF_reserve, FAIL); - /* Check arguments */ - assert(f); + /* Check arguments */ + assert(f); - /* Check that there is room in the file to reserve this space */ - if( H5MF_alloc_overflow( f, size ) != 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "not enough address space in file"); + /* Check that there is room in the file to reserve this space */ + if( H5MF_alloc_overflow( f, size ) ) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "not enough address space in file"); - f->shared->lf->reserved_alloc += size; + f->shared->lf->reserved_alloc += size; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value); } /*------------------------------------------------------------------------- - * Function: H5MF_free_reserved + * Function: H5MF_free_reserved * - * Purpose: Releases the file space set aside by H5MF_reserve. This should - * be called immediately before allocating the file space for which - * the space was reserved. + * Purpose: Releases the file space set aside by H5MF_reserve. This should + * be called immediately before allocating the file space for which + * the space was reserved. * - * Return: None + * Return: None * - * Programmer: James Laird - * Nat Furrer + * Programmer: James Laird + * Nat Furrer * Thursday, May 27, 2004 * * Modifications: *------------------------------------------------------------------------- */ -void H5MF_free_reserved(H5F_t *f, hsize_t size) +herr_t +H5MF_free_reserved(H5F_t *f, hsize_t size) { - /* Check arguments */ - assert(f); + herr_t ret_value = SUCCEED; - /* If this assert breaks, it means that HDF5 is trying to free file space - * that was never reserved. - */ - assert(size <= f->shared->lf->reserved_alloc); + FUNC_ENTER_NOAPI(H5MF_free_reserved,FAIL) + + /* Check arguments */ + assert(f); + + /* If this assert breaks, it means that HDF5 is trying to free file space + * that was never reserved. + */ + assert(size <= f->shared->lf->reserved_alloc); - f->shared->lf->reserved_alloc -= size; + f->shared->lf->reserved_alloc -= size; + +done: + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5MF_alloc_overflow + * Function: H5MF_alloc_overflow * - * Purpose: Checks if an allocation of file space would cause an overflow. + * Purpose: Checks if an allocation of file space would cause an overflow. * F is the file whose space is being allocated, SIZE is the amount * of space needed. * - * Return: 0 if no overflow would result + * Return: 0 if no overflow would result * 1 if overflow would result (the allocation should not be allowed) * - * Programmer: James Laird - * Nat Furrer + * Programmer: James Laird + * Nat Furrer * Tuesday, June 1, 2004 * * Modifications: *------------------------------------------------------------------------- */ -int H5MF_alloc_overflow(H5F_t *f, hsize_t size) +hbool_t +H5MF_alloc_overflow(H5F_t *f, hsize_t size) { - hsize_t space_needed; /* Accumulator variable */ - size_t c; + hsize_t space_needed; /* Accumulator variable */ + size_t c; /* Local index variable */ + hbool_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5MF_alloc_overflow,FALSE) /* Start with the current end of the file's address. */ - space_needed = f->shared->lf->cls->get_eoa(f->shared->lf); + space_needed = (hsize_t)H5F_get_eoa(f); + HDassert(H5F_addr_defined(space_needed)); /* Subtract the file's base address to get the actual amount of * space being used: * (end of allocated space - beginning of allocated space) */ - assert(f->shared->base_addr < space_needed); - space_needed -= f->shared->base_addr; + HDassert(H5F_BASE_ADDR(f) < space_needed); + space_needed -= (hsize_t)H5F_BASE_ADDR(f); /* Add the amount of space requested for this allocation */ space_needed += size; @@ -334,9 +357,12 @@ int H5MF_alloc_overflow(H5F_t *f, hsize_t size) space_needed = space_needed >> 16; if(space_needed != 0) - return 1; + ret_value=TRUE; else - return 0; + ret_value=FALSE; + +done: + FUNC_LEAVE_NOAPI(ret_value) } @@ -365,11 +391,11 @@ htri_t H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested) { htri_t ret_value; /* Return value */ - + FUNC_ENTER_NOAPI(H5MF_can_extend, FAIL); /* Convert old relative address to absolute address */ - addr += f->shared->base_addr; + addr += H5F_BASE_ADDR(f); /* Pass the request down to the virtual file layer */ if((ret_value=H5FD_can_extend(f->shared->lf, type, addr, size, extra_requested))<0) @@ -404,16 +430,16 @@ htri_t H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested) { htri_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5MF_extend, FAIL); - /* Convert old relative address to absolute address */ - addr += f->shared->base_addr; + FUNC_ENTER_NOAPI(H5MF_extend, FAIL); /* Make sure there is enough addressable space to satisfy the request */ if ( H5MF_alloc_overflow(f, extra_requested) ) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory: out of address space"); + /* Convert old relative address to absolute address */ + addr += H5F_BASE_ADDR(f); + /* Pass the request down to the virtual file layer */ if((ret_value=H5FD_extend(f->shared->lf, type, addr, size, extra_requested))<0) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory"); @@ -421,4 +447,3 @@ H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5MF_extend() */ - diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 2a129ea..ee35c2a 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -49,8 +49,8 @@ H5_DLL herr_t H5MF_xfree(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, H5_DLL haddr_t H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size, hsize_t new_size); H5_DLL herr_t H5MF_reserve(H5F_t *f, hsize_t size); -H5_DLL void H5MF_free_reserved(H5F_t *f, hsize_t size); -H5_DLL int H5MF_alloc_overflow(H5F_t *f, hsize_t size); +H5_DLL herr_t H5MF_free_reserved(H5F_t *f, hsize_t size); +H5_DLL hbool_t H5MF_alloc_overflow(H5F_t *f, hsize_t size); H5_DLL htri_t H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested); H5_DLL htri_t H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, @@ -716,11 +716,10 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh) assert(!H5F_addr_defined(oh->chunk[cont->chunkno].addr)); cont->size = oh->chunk[cont->chunkno].size; - /* Free the space we'd previously reserved to hold this chunk */ - H5MF_free_reserved(f, cont->size); + /* Free the space we'd reserved in the file to hold this chunk */ + H5MF_free_reserved(f, (hsize_t)cont->size); - if (HADDR_UNDEF==(cont->addr=H5MF_alloc(f, - H5FD_MEM_OHDR, dxpl_id, (hsize_t)cont->size))) + if (HADDR_UNDEF==(cont->addr=H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id, (hsize_t)cont->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate space for object header data"); oh->chunk[cont->chunkno].addr = cont->addr; } @@ -822,7 +821,7 @@ H5O_dest(H5F_t UNUSED *f, H5O_t *oh) assert(oh); /* Verify that node is clean */ - assert (oh->cache_info.dirty==0); + assert (oh->cache_info.dirty==FALSE); /* destroy chunks */ for (i = 0; i < oh->nchunks; i++) { @@ -914,7 +913,7 @@ H5O_clear(H5O_t *oh) *------------------------------------------------------------------------- */ herr_t -H5O_reset(hid_t type_id, void *native) +H5O_reset(unsigned type_id, void *native) { const H5O_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ @@ -922,7 +921,7 @@ H5O_reset(hid_t type_id, void *native) FUNC_ENTER_NOAPI(H5O_reset,FAIL); /* check args */ - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); @@ -994,7 +993,7 @@ done: *------------------------------------------------------------------------- */ void * -H5O_free (hid_t type_id, void *mesg) +H5O_free (unsigned type_id, void *mesg) { const H5O_class_t *type; /* Actual H5O class type for the ID */ void * ret_value; /* Return value */ @@ -1002,7 +1001,7 @@ H5O_free (hid_t type_id, void *mesg) FUNC_ENTER_NOAPI(H5O_free, NULL); /* check args */ - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); @@ -1075,7 +1074,7 @@ H5O_free_real(const H5O_class_t *type, void *mesg) *------------------------------------------------------------------------- */ void * -H5O_copy (hid_t type_id, const void *mesg, void *dst) +H5O_copy (unsigned type_id, const void *mesg, void *dst) { const H5O_class_t *type; /* Actual H5O class type for the ID */ void *ret_value; /* Return value */ @@ -1083,7 +1082,7 @@ H5O_copy (hid_t type_id, const void *mesg, void *dst) FUNC_ENTER_NOAPI(H5O_copy, NULL); /* check args */ - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); @@ -1251,7 +1250,7 @@ done: *------------------------------------------------------------------------- */ int -H5O_count (H5G_entry_t *ent, hid_t type_id, hid_t dxpl_id) +H5O_count (H5G_entry_t *ent, unsigned type_id, hid_t dxpl_id) { const H5O_class_t *type; /* Actual H5O class type for the ID */ int ret_value; /* Return value */ @@ -1262,7 +1261,7 @@ H5O_count (H5G_entry_t *ent, hid_t type_id, hid_t dxpl_id) assert (ent); assert (ent->file); assert (H5F_addr_defined(ent->header)); - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert (type); @@ -1353,7 +1352,7 @@ done: *------------------------------------------------------------------------- */ htri_t -H5O_exists(H5G_entry_t *ent, hid_t type_id, int sequence, hid_t dxpl_id) +H5O_exists(H5G_entry_t *ent, unsigned type_id, int sequence, hid_t dxpl_id) { const H5O_class_t *type; /* Actual H5O class type for the ID */ htri_t ret_value; /* Return value */ @@ -1362,7 +1361,7 @@ H5O_exists(H5G_entry_t *ent, hid_t type_id, int sequence, hid_t dxpl_id) assert(ent); assert(ent->file); - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); assert(sequence>=0); @@ -1463,7 +1462,7 @@ done: *------------------------------------------------------------------------- */ void * -H5O_read(H5G_entry_t *ent, hid_t type_id, int sequence, void *mesg, hid_t dxpl_id) +H5O_read(H5G_entry_t *ent, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id) { const H5O_class_t *type; /* Actual H5O class type for the ID */ void *ret_value; /* Return value */ @@ -1474,7 +1473,7 @@ H5O_read(H5G_entry_t *ent, hid_t type_id, int sequence, void *mesg, hid_t dxpl_i assert(ent); assert(ent->file); assert(H5F_addr_defined(ent->header)); - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); assert(sequence >= 0); @@ -1708,7 +1707,7 @@ done: *------------------------------------------------------------------------- */ int -H5O_modify(H5G_entry_t *ent, hid_t type_id, int overwrite, +H5O_modify(H5G_entry_t *ent, unsigned type_id, int overwrite, unsigned flags, unsigned update_time, const void *mesg, hid_t dxpl_id) { const H5O_class_t *type; /* Actual H5O class type for the ID */ @@ -1720,7 +1719,7 @@ H5O_modify(H5G_entry_t *ent, hid_t type_id, int overwrite, assert(ent); assert(ent->file); assert(H5F_addr_defined(ent->header)); - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); assert(mesg); @@ -1961,7 +1960,7 @@ done: *------------------------------------------------------------------------- */ int -H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hid_t type_id, unsigned flags, +H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags, const void *mesg) { const H5O_class_t *type; /* Actual H5O class type for the ID */ @@ -1972,7 +1971,7 @@ H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hid_t type_id, unsigned flags, /* check args */ assert(f); assert(oh); - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); assert(0==(flags & ~H5O_FLAG_BITS)); @@ -2413,7 +2412,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_remove(H5G_entry_t *ent, hid_t type_id, int sequence, hid_t dxpl_id) +H5O_remove(H5G_entry_t *ent, unsigned type_id, int sequence, hid_t dxpl_id) { const H5O_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ @@ -2424,7 +2423,7 @@ H5O_remove(H5G_entry_t *ent, hid_t type_id, int sequence, hid_t dxpl_id) assert(ent); assert(ent->file); assert(H5F_addr_defined(ent->header)); - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert(type); @@ -2540,9 +2539,9 @@ done: * that message will be extended with the chunk. Otherwise a * new null message is created. * - * F is the file into which the new chunk will be written. It is - * included to ensure that there is enough space to extend this - * chunk. + * F is the file in which the chunk will be written. It is + * included to ensure that there is enough space to extend + * this chunk. * * Return: Success: Message index for null message which * is large enough to hold SIZE bytes. @@ -2585,15 +2584,15 @@ H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh, unsigned chunkno, size_t size) for (idx=0; idx<oh->nmesgs; idx++) { if (oh->mesg[idx].chunkno==chunkno) { if (H5O_NULL_ID == oh->mesg[idx].type->id && - (oh->mesg[idx].raw + oh->mesg[idx].raw_size == - oh->chunk[chunkno].image + oh->chunk[chunkno].size)) { + (oh->mesg[idx].raw + oh->mesg[idx].raw_size == + oh->chunk[chunkno].image + oh->chunk[chunkno].size)) { delta = MAX (H5O_MIN_SIZE, aligned_size - oh->mesg[idx].raw_size); assert (delta=H5O_ALIGN (delta)); /* Reserve space in the file to hold the increased chunk size */ - if( H5MF_reserve(f, delta) < 0 ) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to reserve space for chunk"); + if( H5MF_reserve(f, (hsize_t)delta) < 0 ) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to reserve space in file"); oh->mesg[idx].dirty = TRUE; oh->mesg[idx].raw_size += delta; @@ -2626,7 +2625,7 @@ H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh, unsigned chunkno, size_t size) delta = MAX(H5O_MIN_SIZE, aligned_size+H5O_SIZEOF_MSGHDR(f)); delta = H5O_ALIGN(delta); - if( H5MF_reserve(f, delta) < 0 ) + if( H5MF_reserve(f, (hsize_t)delta) < 0 ) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to reserve space in file"); /* create a new null message */ @@ -2768,7 +2767,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) assert (size == H5O_ALIGN (size)); /* Reserve space in the file to hold the new chunk */ - if( H5MF_reserve(f, size) < 0 ) + if( H5MF_reserve(f, (hsize_t)size) < 0 ) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to reserve space in file for new chunk"); /* @@ -3072,7 +3071,7 @@ done: *------------------------------------------------------------------------- */ size_t -H5O_raw_size(hid_t type_id, H5F_t *f, const void *mesg) +H5O_raw_size(unsigned type_id, H5F_t *f, const void *mesg) { const H5O_class_t *type; /* Actual H5O class type for the ID */ size_t ret_value; /* Return value */ @@ -3080,7 +3079,7 @@ H5O_raw_size(hid_t type_id, H5F_t *f, const void *mesg) FUNC_ENTER_NOAPI(H5O_raw_size,0); /* Check args */ - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert (type); assert (type->raw_size); @@ -3116,7 +3115,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share) +H5O_get_share(unsigned type_id, H5F_t *f, const void *mesg, H5O_shared_t *share) { const H5O_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ @@ -3124,7 +3123,7 @@ H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share) FUNC_ENTER_NOAPI(H5O_get_share,FAIL); /* Check args */ - assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0]))); + assert(type_id<NELMTS(message_type_g)); type=message_type_g[type_id]; /* map the type ID to the actual type object */ assert (type); assert (type->get_share); diff --git a/src/H5Oefl.c b/src/H5Oefl.c index e77a691..1f389ce 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -92,10 +92,11 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *s H5O_efl_t *mesg = NULL; int version; const char *s = NULL; + const H5HL_t *heap; size_t u; /* Local index variable */ void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_efl_decode, NULL); + FUNC_ENTER_NOAPI_NOINIT(H5O_efl_decode); /* Check args */ assert(f); @@ -121,10 +122,19 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *s /* Heap address */ H5F_addr_decode(f, &p, &(mesg->heap_addr)); + #ifndef NDEBUG assert (H5F_addr_defined(mesg->heap_addr)); - s = H5HL_peek (f, dxpl_id, mesg->heap_addr, 0); + + if (NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value") + + s = H5HL_offset_into(f, heap, 0); + assert (s && !*s); + + if (H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value") #endif /* Decode the file list */ @@ -134,9 +144,17 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *s for (u=0; u<mesg->nused; u++) { /* Name */ H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset); - s = H5HL_peek(f, dxpl_id, mesg->heap_addr, mesg->slot[u].name_offset); + + if (NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value") + + s = H5HL_offset_into(f, heap, mesg->slot[u].name_offset); assert (s && *s); mesg->slot[u].name = H5MM_xstrdup (s); + assert(mesg->slot[u].name); + + if (H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value") /* File offset */ H5F_DECODE_LENGTH (f, p, mesg->slot[u].offset); @@ -184,9 +202,8 @@ H5O_efl_encode(H5F_t *f, uint8_t *p, const void *_mesg) { const H5O_efl_t *mesg = (const H5O_efl_t *)_mesg; size_t u; /* Local index variable */ - herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_efl_encode, FAIL); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_efl_encode); /* check args */ assert(f); @@ -223,8 +240,7 @@ H5O_efl_encode(H5F_t *f, uint8_t *p, const void *_mesg) H5F_ENCODE_LENGTH (f, p, mesg->slot[u].size); } -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } @@ -253,7 +269,7 @@ H5O_efl_copy(const void *_mesg, void *_dest) size_t u; /* Local index variable */ void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_efl_copy, NULL); + FUNC_ENTER_NOAPI_NOINIT(H5O_efl_copy); /* check args */ assert(mesg); @@ -310,7 +326,7 @@ H5O_efl_size(H5F_t *f, const void *_mesg) const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; size_t ret_value = 0; - FUNC_ENTER_NOAPI(H5O_efl_size, 0); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_efl_size); /* check args */ assert(f); @@ -324,7 +340,6 @@ H5O_efl_size(H5F_t *f, const void *_mesg) H5F_SIZEOF_SIZE(f) + /*file offset */ H5F_SIZEOF_SIZE(f)); /*file size */ -done: FUNC_LEAVE_NOAPI(ret_value); } @@ -349,9 +364,8 @@ H5O_efl_reset(void *_mesg) { H5O_efl_t *mesg = (H5O_efl_t *) _mesg; size_t u; /* Local index variable */ - herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_efl_reset, FAIL); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_efl_reset); /* check args */ assert(mesg); @@ -364,8 +378,7 @@ H5O_efl_reset(void *_mesg) if(mesg->slot) mesg->slot = H5MM_xfree(mesg->slot); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } @@ -391,7 +404,7 @@ H5O_efl_total_size (H5O_efl_t *efl) { hsize_t ret_value = 0, tmp; - FUNC_ENTER_NOAPI(H5O_efl_total_size, 0); + FUNC_ENTER_NOAPI_NOINIT(H5O_efl_total_size); if (efl->nused>0 && H5O_EFL_UNLIMITED==efl->slot[efl->nused-1].size) { @@ -443,7 +456,7 @@ H5O_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size, uint8_t *buf) size_t u; /* Local index variable */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_efl_read, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5O_efl_read); /* Check args */ assert (efl && efl->nused>0); @@ -529,7 +542,7 @@ H5O_efl_write (const H5O_efl_t *efl, haddr_t addr, size_t size, const uint8_t *b size_t u; /* Local index variable */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_efl_write, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5O_efl_write); /* Check args */ assert (efl && efl->nused>0); @@ -765,9 +778,8 @@ H5O_efl_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * s const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; char buf[64]; size_t u; - herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_efl_debug, FAIL); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_efl_debug); /* check args */ assert(f); @@ -804,6 +816,5 @@ H5O_efl_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * s (unsigned long)(mesg->slot[u].size)); } -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 8992bb4..9b05474 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -233,16 +233,16 @@ H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5_DLL herr_t H5O_open(H5G_entry_t *ent); H5_DLL herr_t H5O_close(H5G_entry_t *ent); H5_DLL int H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id); -H5_DLL int H5O_count(H5G_entry_t *ent, hid_t type_id, hid_t dxpl_id); -H5_DLL htri_t H5O_exists(H5G_entry_t *ent, hid_t type_id, int sequence, +H5_DLL int H5O_count(H5G_entry_t *ent, unsigned type_id, hid_t dxpl_id); +H5_DLL htri_t H5O_exists(H5G_entry_t *ent, unsigned type_id, int sequence, hid_t dxpl_id); -H5_DLL void *H5O_read(H5G_entry_t *ent, hid_t type_id, int sequence, +H5_DLL void *H5O_read(H5G_entry_t *ent, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id); -H5_DLL int H5O_modify(H5G_entry_t *ent, hid_t type_id, +H5_DLL int H5O_modify(H5G_entry_t *ent, unsigned type_id, int overwrite, unsigned flags, unsigned update_time, const void *mesg, hid_t dxpl_id); H5_DLL struct H5O_t * H5O_protect(H5G_entry_t *ent, hid_t dxpl_id); H5_DLL herr_t H5O_unprotect(H5G_entry_t *ent, struct H5O_t *oh, hid_t dxpl_id); -H5_DLL int H5O_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, hid_t type_id, +H5_DLL int H5O_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, unsigned type_id, unsigned flags, const void *mesg); H5_DLL herr_t H5O_touch(H5G_entry_t *ent, hbool_t force, hid_t dxpl_id); H5_DLL herr_t H5O_touch_oh(H5F_t *f, struct H5O_t *oh, hbool_t force); @@ -250,13 +250,13 @@ H5_DLL herr_t H5O_touch_oh(H5F_t *f, struct H5O_t *oh, hbool_t force); H5_DLL herr_t H5O_bogus(H5G_entry_t *ent, hid_t dxpl_id); H5_DLL herr_t H5O_bogus_oh(H5F_t *f, struct H5O_t *oh); #endif /* H5O_ENABLE_BOGUS */ -H5_DLL herr_t H5O_remove(H5G_entry_t *ent, hid_t type_id, int sequence, +H5_DLL herr_t H5O_remove(H5G_entry_t *ent, unsigned type_id, int sequence, hid_t dxpl_id); -H5_DLL herr_t H5O_reset(hid_t type_id, void *native); -H5_DLL void *H5O_free(hid_t type_id, void *mesg); -H5_DLL void *H5O_copy(hid_t type_id, const void *mesg, void *dst); -H5_DLL size_t H5O_raw_size(hid_t type_id, H5F_t *f, const void *mesg); -H5_DLL herr_t H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share); +H5_DLL herr_t H5O_reset(unsigned type_id, void *native); +H5_DLL void *H5O_free(unsigned type_id, void *mesg); +H5_DLL void *H5O_copy(unsigned type_id, const void *mesg, void *dst); +H5_DLL size_t H5O_raw_size(unsigned type_id, H5F_t *f, const void *mesg); +H5_DLL herr_t H5O_get_share(unsigned type_id, H5F_t *f, const void *mesg, H5O_shared_t *share); H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5O_get_info(H5G_entry_t *ent, H5O_stat_t *ostat, hid_t dxpl_id); H5_DLL herr_t H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth); diff --git a/src/H5private.h b/src/H5private.h index c37decd..71b09f6 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -434,6 +434,7 @@ #ifndef LLONG_MAX # define LLONG_MAX ((long_long)(((unsigned long_long)1 \ <<(8*sizeof(long_long)-1))-1)) +# define LLONG_MIN ((long_long)(-LLONG_MAX)-1) # define ULLONG_MAX ((unsigned long_long)((long_long)(-1))) #endif #ifndef SIZET_MAX @@ -450,15 +451,6 @@ #define HSSIZET_MIN (~(HSSIZET_MAX)) /* - * Some compilers have problems declaring auto variables that point - * to string constants. Use the CONSTR() macro so it's easy to fix - * those compilers. - */ -#ifndef CONSTR -# define CONSTR(VAR,STR) static const char VAR[]=STR -#endif - -/* * A macro to portably increment enumerated types. */ #ifndef H5_INC_ENUM @@ -489,16 +481,16 @@ * A macro for detecting over/under-flow when assigning between types */ #ifndef NDEBUG -#define H5_ASSIGN_OVERFLOW(var,expr,vartype,casttype) \ +#define H5_ASSIGN_OVERFLOW(var,expr,exprtype,vartype) \ { \ - vartype _tmp_overflow=(vartype)(expr); \ - casttype _tmp_overflow2=(casttype)(_tmp_overflow); \ - assert((casttype)_tmp_overflow==_tmp_overflow2); \ + exprtype _tmp_overflow=(exprtype)(expr); \ + vartype _tmp_overflow2=(vartype)(_tmp_overflow); \ + assert((vartype)_tmp_overflow==_tmp_overflow2); \ (var)=_tmp_overflow2; \ } #else /* NDEBUG */ -#define H5_ASSIGN_OVERFLOW(var,expr,vartype,casttype) \ - (var)=(casttype)(expr); +#define H5_ASSIGN_OVERFLOW(var,expr,exprtype,vartype) \ + (var)=(vartype)(expr); #endif /* NDEBUG */ /* @@ -578,6 +570,7 @@ H5_DLL void H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds); #endif /* __MWERKS __ */ #define HDexp(X) exp(X) #define HDfabs(X) fabs(X) +/* use ABS() because fabsf() fabsl() are not common yet. */ #define HDfabsf(X) ABS(X) #define HDfabsl(X) ABS(X) #define HDfclose(F) fclose(F) @@ -589,7 +582,11 @@ H5_DLL void H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds); #define HDfgetc(F) fgetc(F) #define HDfgetpos(F,P) fgetpos(F,P) #define HDfgets(S,N,F) fgets(S,N,F) +#ifdef WIN32 +#define HDfileno(F) _fileno(F) +#else /* WIN32 */ #define HDfileno(F) fileno(F) +#endif /* WIN32 */ #define HDfloor(X) floor(X) #define HDfmod(X,Y) fmod(X,Y) #define HDfopen(S,M) fopen(S,M) @@ -979,9 +976,13 @@ extern H5_debug_t H5_debug_g; #define H5TRACE9(R,T,A0,A1,A2,A3,A4,A5,A6,A7,A8) RTYPE=R; \ CALLTIME=H5_trace(NULL,FUNC,T,#A0,A0,#A1,A1,#A2,A2,#A3,A3, \ #A4,A4,#A5,A5,#A6,A6,#A7,A7,#A8,A8) -#define H5TRACE10(R,T,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9) RTYPE=R; \ +#define H5TRACE10(R,T,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9) RTYPE=R; \ CALLTIME=H5_trace(NULL,FUNC,T,#A0,A0,#A1,A1,#A2,A2,#A3,A3, \ #A4,A4,#A5,A5,#A6,A6,#A7,A7,#A8,A8,#A9,A9) +#define H5TRACE11(R,T,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) RTYPE=R; \ + CALLTIME=H5_trace(NULL,FUNC,T,#A0,A0,#A1,A1,#A2,A2,#A3,A3, \ + #A4,A4,#A5,A5,#A6,A6,#A7,A7,#A8,A8,#A9,A9, \ + #A10,A10) #define H5TRACE_RETURN(V) if (RTYPE) { \ H5_trace(&CALLTIME,FUNC,RTYPE,NULL,V); \ RTYPE=NULL; \ @@ -999,6 +1000,7 @@ extern H5_debug_t H5_debug_g; #define H5TRACE8(R,T,A0,A1,A2,A3,A4,A5,A6,A7) /*void*/ #define H5TRACE9(R,T,A0,A1,A2,A3,A4,A5,A6,A7,A8) /*void*/ #define H5TRACE10(R,T,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9) /*void*/ +#define H5TRACE11(R,T,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) /*void*/ #define H5TRACE_RETURN(V) /*void*/ #endif @@ -1024,37 +1026,6 @@ H5_DLL double H5_trace(double *calltime, const char *func, const char *type, ... * * Modifications: * - * Robb Matzke, 4 Aug 1997 - * The `interface_init_func' can be the null pointer. Changed - * HGOTO_ERROR() to HRETURN_ERROR() since no clean-up needs to occur - * when an error is detected at this point since this must be the - * first executable statement in a function. This allows functions - * to omit the `done:' label when convenient to do so. - * - * Robb Matzke, 4 Aug 1997 - * The pablo mask comes from the constant PABLO_MASK defined on - * a per-file basis. The `pablo_func_id' is generated from the - * `func_name' argument by prepending an `ID_' to the name. The - * pablo function identifier should be saved in a local variable - * so FUNC_LEAVE() can access it. - * - * Robb Matzke, 4 Aug 1997 - * It is safe to call this function even inside various library - * initializing functions. Infinite recursion is no longer a - * danger. - * - * Robb Matzke, 3 Dec 1997 - * The interface initialization function is no longer passed as an - * argument unless the `FUNC_ENTER_INIT' form is called. Instead, the - * function comes from the `INTERFACE_INIT' constant which must be - * defined in every source file. - * - * Robb Matzke, 17 Jun 1998 - * Added auto variable RTYPE which is initialized by the tracing macros. - * - * Quincey Koziol, 28 May 2002 - * Split FUNC_ENTER macro into FUNC_ENTER_API, FUNC_ENTER_NOAPI and - * FUNC_ENTER_NOAPI_NOINIT. *------------------------------------------------------------------------- */ @@ -1115,7 +1086,6 @@ extern H5_api_t H5_g; /* extern global variables */ extern hbool_t H5_libinit_g; /* Has the library been initialized? */ - /* Macros for accessing the global variables */ #define H5_INIT_GLOBAL H5_libinit_g @@ -1140,7 +1110,7 @@ extern hbool_t H5_MPEinit_g; /* Has the MPE Library been initialized? */ /* Check if the function name is correct (if the compiler supports __FUNCTION__) */ #ifdef H5_HAVE_FUNCTION #define H5_CHECK_FUNCNAME(func_name) \ - assert(func_name && !HDstrcmp(#func_name, __FUNCTION__)) + assert(!HDstrcmp(#func_name, __FUNCTION__)) #else /* H5_HAVE_FUNCTION */ #define H5_CHECK_FUNCNAME(func_name) \ assert(func_name) @@ -1159,8 +1129,8 @@ extern hbool_t H5_MPEinit_g; /* Has the MPE Library been initialized? */ PABLO_TRACE_ON (PABLO_MASK, pablo_func_id) #define FUNC_ENTER_COMMON(func_name,asrt) \ - CONSTR (FUNC, #func_name); \ - FUNC_ENTER_COMMON_NOFUNC(func_name,asrt); \ + static const char FUNC[]=#func_name; \ + FUNC_ENTER_COMMON_NOFUNC(func_name,asrt); /* Threadsafety initialization code for API routines */ #define FUNC_ENTER_API_THREADSAFE \ @@ -1267,7 +1237,7 @@ extern hbool_t H5_MPEinit_g; /* Has the MPE Library been initialized? */ H5_INIT_GLOBAL = TRUE; \ if (H5_init_library()<0) \ HGOTO_ERROR (H5E_FUNC, H5E_CANTINIT, err, \ - "library initialization failed"); \ + "library initialization failed") \ } \ \ /* Initialize this interface or bust */ \ |