diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2012-04-01 23:53:17 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2012-04-01 23:53:17 (GMT) |
commit | 42306f8ed4ade51a8629b9c5a159d1afac5f617f (patch) | |
tree | a503b4e463f3888709d893eae564898d899135bb /src/H5HFspace.c | |
parent | 982f1ff8ff1687cc62e310c991c0d56929b271fd (diff) | |
download | hdf5-42306f8ed4ade51a8629b9c5a159d1afac5f617f.zip hdf5-42306f8ed4ade51a8629b9c5a159d1afac5f617f.tar.gz hdf5-42306f8ed4ade51a8629b9c5a159d1afac5f617f.tar.bz2 |
[svn-r22233] Description:
Correct several errors in fractal heap code: root indirect block was
getting pinned/protected more than once, "single" free space sections weren't
getting "re-parented" correctly when the heap transitioned between having a
root indirect block and a root direct block, and several related issues. Also
cleaned up some warnings in library/tests.
Tested on:
FreeBSD/32 8.2 (loyalty) w/gcc4.6, w/C++ & FORTRAN, in debug mode
FreeBSD/64 8.2 (freedom) w/gcc4.6, w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
w/C++ & FORTRAN, w/threadsafe, in debug mode
Linux/64-amd64 2.6 (koala) w/Intel compilers, w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Mac OSX/64 10.7.3 (amazon) w/debug
Diffstat (limited to 'src/H5HFspace.c')
-rw-r--r-- | src/H5HFspace.c | 181 |
1 files changed, 180 insertions, 1 deletions
diff --git a/src/H5HFspace.c b/src/H5HFspace.c index cec9b3a..01330d3 100644 --- a/src/H5HFspace.c +++ b/src/H5HFspace.c @@ -168,7 +168,7 @@ herr_t H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node, unsigned flags) { - H5HF_sect_add_ud1_t udata; /* User data for free space manager 'add' */ + H5HF_sect_add_ud_t udata; /* User data for free space manager 'add' */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -246,6 +246,185 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_space_revert_root_cb + * + * Purpose: Callback routine from iterator, to reset 'parent' pointers in + * sections, when the heap is changing from having a root indirect + * block to a direct block. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Feb 24 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_space_revert_root_cb(H5FS_section_info_t *_sect, void UNUSED *_udata) +{ + H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* + * Check arguments. + */ + HDassert(sect); + + /* Only modify "live" single blocks... */ + if(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE && sect->sect_info.state == H5FS_SECT_LIVE) { + /* Release hold on previous indirect block (we must have one) */ + HDassert(sect->u.single.parent); + if(H5HF_iblock_decr(sect->u.single.parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block") + + /* Reset parent information */ + sect->u.single.parent = NULL; + sect->u.single.par_entry = 0; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_space_revert_root_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_space_revert_root + * + * Purpose: Reset 'parent' pointers in sections, when the heap is + * changing from having a root indirect block to a direct block. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Feb 23 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_space_revert_root(const H5HF_hdr_t *hdr, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* + * Check arguments. + */ + HDassert(hdr); + + /* Only need to scan the sections if the free space has been initialized */ + if(hdr->fspace) { + /* Iterate over all sections, reseting the parent pointers in 'single' sections */ + if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_revert_root_cb, NULL) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to reset parent pointers") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_space_revert_root() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_space_create_root_cb + * + * Purpose: Callback routine from iterator, to set 'parent' pointers in + * sections to newly created root indirect block, when the heap + * is changing from having a root direct block to an indirect block. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Feb 24 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_space_create_root_cb(H5FS_section_info_t *_sect, void *_udata) +{ + H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */ + H5HF_indirect_t *root_iblock = (H5HF_indirect_t *)_udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* + * Check arguments. + */ + HDassert(sect); + HDassert(root_iblock); + + /* Sanity check sections */ + /* (If we are switching from a direct block for the root block of the heap, */ + /* there should only be 'single' type sections. -QAK) */ + HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE); + + /* Increment ref. count on new root indirect block */ + if(H5HF_iblock_incr(root_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on section's indirect block") + + /* Set parent info ("live" section must _NOT_ have a parent right now) */ + if(sect->sect_info.state == H5FS_SECT_SERIALIZED) + sect->sect_info.state = H5FS_SECT_LIVE; /* Mark "live" now */ + else + HDassert(!sect->u.single.parent); + sect->u.single.parent = root_iblock; + sect->u.single.par_entry = 0; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_space_create_root_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_space_create_root + * + * Purpose: Set 'parent' pointers in sections to new indirect block, when + * the heap is changing from having a root direct block to a + * indirect block. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Feb 24 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_space_create_root(const H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *root_iblock) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(root_iblock); + + /* Only need to scan the sections if the free space has been initialized */ + if(hdr->fspace) { + /* Iterate over all sections, seting the parent pointers in 'single' sections to the new indirect block */ + if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_create_root_cb, root_iblock) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to set parent pointers") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_space_create_root() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_space_size * * Purpose: Query the size of the heap's free space info on disk |