diff options
Diffstat (limited to 'src/H5FS.c')
-rw-r--r-- | src/H5FS.c | 197 |
1 files changed, 184 insertions, 13 deletions
@@ -55,6 +55,8 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5FS_sinfo_free_sect_cb(void *item, void *key, void *op_data); +static herr_t H5FS_sinfo_free_node_cb(void *item, void *key, void *op_data); /*********************/ @@ -156,7 +158,8 @@ HDfprintf(stderr, "%s: fspace = %p, fspace->addr = %a\n", FUNC, fspace, fspace-> done: if(!ret_value && fspace) - (void)H5FS_cache_hdr_dest(f, fspace); + if(H5FS_hdr_dest(fspace) < 0) + HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, NULL, "unable to destroy free space header") #ifdef H5FS_DEBUG HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value); @@ -220,7 +223,7 @@ HDfprintf(stderr, "%s: fspace->rc = %u\n", FUNC, fspace->rc); /* Increment the reference count on the free space manager header */ HDassert(fspace->rc <= 1); - if(H5FS_incr(f, fspace) < 0) + if(H5FS_incr(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTINC, NULL, "unable to increment ref. count on free space header") fspace->alignment = alignment; @@ -465,7 +468,7 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC); } /* end else */ /* Destroy section info */ - if(H5FS_cache_sinfo_dest(f, fspace->sinfo) < 0) + if(H5FS_sinfo_dest(fspace->sinfo) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space section info") } /* end else */ @@ -480,7 +483,7 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC); } /* end else */ /* Decrement the reference count on the free space manager header */ - if(H5FS_decr(f, fspace) < 0) + if(H5FS_decr(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header") done: @@ -616,7 +619,7 @@ H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size) *------------------------------------------------------------------------- */ herr_t -H5FS_incr(H5F_t *f, H5FS_t *fspace) +H5FS_incr(H5FS_t *fspace) { herr_t ret_value = SUCCEED; /* Return value */ @@ -628,7 +631,6 @@ HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fsp /* * Check arguments. */ - HDassert(f); HDassert(fspace); /* Check if we should pin the header in the cache */ @@ -658,7 +660,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5FS_decr(H5F_t *f, H5FS_t *fspace) +H5FS_decr(H5FS_t *fspace) { herr_t ret_value = SUCCEED; /* Return value */ @@ -670,7 +672,6 @@ HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fsp /* * Check arguments. */ - HDassert(f); HDassert(fspace); /* Decrement reference count on header */ @@ -683,7 +684,7 @@ HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fsp HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header") } /* end if */ else { - if(H5FS_cache_hdr_dest(f, fspace) < 0) + if(H5FS_hdr_dest(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space header") } /* end else */ } /* end if */ @@ -707,7 +708,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5FS_dirty(H5F_t *f, H5FS_t *fspace) +H5FS_dirty(H5FS_t *fspace) { herr_t ret_value = SUCCEED; /* Return value */ @@ -717,7 +718,6 @@ HDfprintf(stderr, "%s: Marking free space header as dirty\n", FUNC); #endif /* QAK */ /* Sanity check */ - HDassert(f); HDassert(fspace); /* Check if the free space manager is persistant */ @@ -802,7 +802,7 @@ H5FS_alloc_sect(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) fspace->alloc_sect_size = fspace->sect_size; /* Mark free-space header as dirty */ - if(H5FS_dirty(f, fspace) < 0) + if(H5FS_dirty(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") /* Cache the free-space section info */ @@ -873,7 +873,7 @@ H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections") /* Mark free-space manager header as dirty */ - if(H5FS_dirty(f, fspace) < 0) + if(H5FS_dirty(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") } @@ -907,6 +907,177 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5FS_free() */ + +/*------------------------------------------------------------------------- + * Function: H5FS_hdr_dest + * + * Purpose: Destroys a free space header in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * May 2 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_hdr_dest(H5FS_t *fspace) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FS_hdr_dest) + + /* + * Check arguments. + */ + HDassert(fspace); + + /* Terminate the section classes for this free space list */ + for(u = 0; u < fspace->nclasses ; u++) { + /* Call the class termination routine, if there is one */ + if(fspace->sect_cls[u].term_cls) + if((fspace->sect_cls[u].term_cls)(&fspace->sect_cls[u]) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "unable to finalize section class") + } /* end for */ + + /* Release the memory for the free space section classes */ + if(fspace->sect_cls) + fspace->sect_cls = (H5FS_section_class_t *)H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls); + + /* Free free space info */ + fspace = H5FL_FREE(H5FS_t, fspace); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FS_hdr_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_sinfo_free_sect_cb + * + * Purpose: Free a size-tracking node for a bin + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, March 11, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FS_sinfo_free_sect_cb(void *_sect, void UNUSED *key, void *op_data) +{ + H5FS_section_info_t *sect = (H5FS_section_info_t *)_sect; /* Section to free */ + const H5FS_sinfo_t *sinfo = (const H5FS_sinfo_t *)op_data; /* Free space manager for section */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_sect_cb) + + HDassert(sect); + HDassert(sinfo); + + /* Call the section's class 'free' method on the section */ + (*sinfo->fspace->sect_cls[sect->type].free)(sect); + + FUNC_LEAVE_NOAPI(0) +} /* H5FS_sinfo_free_sect_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_sinfo_free_node_cb + * + * Purpose: Free a size-tracking node for a bin + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, March 11, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data) +{ + H5FS_node_t *fspace_node = (H5FS_node_t *)item; /* Temporary pointer to free space list node */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_node_cb) + + HDassert(fspace_node); + HDassert(op_data); + + /* Release the skip list for sections of this size */ + H5SL_destroy(fspace_node->sect_list, H5FS_sinfo_free_sect_cb, op_data); + + /* Release free space list node */ + fspace_node = H5FL_FREE(H5FS_node_t, fspace_node); + + FUNC_LEAVE_NOAPI(0) +} /* H5FS_sinfo_free_node_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_sinfo_dest + * + * Purpose: Destroys a free space section info in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * July 31 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_sinfo_dest(H5FS_sinfo_t *sinfo) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_dest) + + /* + * Check arguments. + */ + HDassert(sinfo); + HDassert(sinfo->fspace); + HDassert(sinfo->bins); + + /* Clear out lists of nodes */ + for(u = 0; u < sinfo->nbins; u++) + if(sinfo->bins[u].bin_list) { + H5SL_destroy(sinfo->bins[u].bin_list, H5FS_sinfo_free_node_cb, sinfo); + sinfo->bins[u].bin_list = NULL; + } /* end if */ + + /* Release bins for skip lists */ + sinfo->bins = H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins); + + /* Release skip list for merging sections */ + if(sinfo->merge_list) + if(H5SL_close(sinfo->merge_list) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "can't destroy section merging skip list") + + /* Decrement the reference count on free space header */ + /* (make certain this is last action with section info, to allow for header + * disappearing immediately) + */ + sinfo->fspace->sinfo = NULL; + if(H5FS_decr(sinfo->fspace) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header") + sinfo->fspace = NULL; + + /* Release free space section info */ + sinfo = H5FL_FREE(H5FS_sinfo_t, sinfo); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FS_sinfo_dest() */ + #ifdef H5FS_DEBUG_ASSERT /*------------------------------------------------------------------------- |