diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/H5HL.c | 870 | ||||
-rw-r--r-- | src/H5HLcache.c | 96 | ||||
-rw-r--r-- | src/H5HLdbg.c | 72 | ||||
-rw-r--r-- | src/H5HLdblk.c | 282 | ||||
-rw-r--r-- | src/H5HLint.c | 317 | ||||
-rw-r--r-- | src/H5HLpkg.h | 98 | ||||
-rw-r--r-- | src/H5HLprfx.c | 166 | ||||
-rw-r--r-- | src/H5HLprivate.h | 45 | ||||
-rw-r--r-- | src/H5HLpublic.h | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 |
11 files changed, 1028 insertions, 924 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 59be2dd..2c9ca8a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -338,7 +338,9 @@ set (H5HL_SRCS ${HDF5_SRC_DIR}/H5HL.c ${HDF5_SRC_DIR}/H5HLcache.c ${HDF5_SRC_DIR}/H5HLdbg.c + ${HDF5_SRC_DIR}/H5HLdblk.c ${HDF5_SRC_DIR}/H5HLint.c + ${HDF5_SRC_DIR}/H5HLprfx.c ) set (H5HL_HDRS @@ -15,12 +15,12 @@ /*------------------------------------------------------------------------- * - * Created: H5HL.c - * Jul 16 1997 - * Robb Matzke <matzke@llnl.gov> + * Created: H5HL.c + * Jul 16 1997 + * Robb Matzke <matzke@llnl.gov> * - * Purpose: Heap functions for the local heaps used by symbol - * tables to store names (among other things). + * Purpose: Heap functions for the local heaps used by symbol + * tables to store names (among other things). * *------------------------------------------------------------------------- */ @@ -35,18 +35,18 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5HLpkg.h" /* Local Heaps */ -#include "H5MFprivate.h" /* File memory management */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5HLpkg.h" /* Local Heaps */ +#include "H5MFprivate.h" /* File memory management */ /****************/ /* Local Macros */ /****************/ -#define H5HL_MIN_HEAP 128 /* Minimum size to reduce heap buffer to */ +#define H5HL_MIN_HEAP 128 /* Minimum size to reduce heap buffer to */ /******************/ @@ -63,8 +63,9 @@ /* Local Prototypes */ /********************/ -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); +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); +static herr_t H5HL__dirty(H5HL_t *heap); /*********************/ @@ -93,7 +94,7 @@ H5FL_BLK_DEFINE(lheap_chunk); /*------------------------------------------------------------------------- - * Function: H5HL_create + * Function: H5HL_create * * Purpose: Creates a new heap data structure on disk and caches it * in memory. SIZE_HINT is a hint for the initial size of the @@ -102,26 +103,22 @@ H5FL_BLK_DEFINE(lheap_chunk); * If the heap ever has to grow, then REALLOC_HINT is the * minimum amount by which the heap will grow. * - * Return: Success: Non-negative. The file address of new heap is - * returned through the ADDR argument. + * Return: Success: SUCCEED. The file address of new heap is + * returned through the ADDR argument. + * Failure: FAIL. addr_p will be HADDR_UNDEF. * - * Failure: Negative - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Robb Matzke + * Jul 16 1997 * *------------------------------------------------------------------------- */ -herr_t -H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/) -{ - H5HL_t *heap = NULL; /* Heap created */ - H5HL_prfx_t *prfx = NULL; /* Heap prefix */ - hsize_t total_size = 0; /* Total heap size on disk */ - herr_t ret_value = SUCCEED; /* Return value */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/)) - FUNC_ENTER_NOAPI(FAIL) + H5HL_t *heap = NULL; /* Heap created */ + H5HL_prfx_t *prfx = NULL; /* Heap prefix */ + hsize_t total_size = 0; /* Total heap size on disk */ /* check arguments */ HDassert(f); @@ -129,17 +126,17 @@ H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/) /* Adjust size hint as necessary */ if(size_hint && size_hint < H5HL_SIZEOF_FREE(f)) - size_hint = H5HL_SIZEOF_FREE(f); + size_hint = H5HL_SIZEOF_FREE(f); size_hint = H5HL_ALIGN(size_hint); /* Allocate new heap structure */ - if(NULL == (heap = H5HL_new(H5F_SIZEOF_SIZE(f), H5F_SIZEOF_ADDR(f), H5HL_SIZEOF_HDR(f)))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate new heap struct") + if(NULL == (heap = H5HL__new(H5F_SIZEOF_SIZE(f), H5F_SIZEOF_ADDR(f), H5HL_SIZEOF_HDR(f)))) + H5E_THROW(H5E_CANTALLOC, "can't allocate new heap struct"); /* Allocate file space */ total_size = heap->prfx_size + size_hint; if(HADDR_UNDEF == (heap->prfx_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, total_size))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "unable to allocate file memory") + H5E_THROW(H5E_CANTALLOC, "unable to allocate file memory"); /* Initialize info */ heap->single_cache_obj = TRUE; @@ -147,188 +144,72 @@ H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/) heap->dblk_size = size_hint; if(size_hint) if(NULL == (heap->dblk_image = H5FL_BLK_CALLOC(lheap_chunk, size_hint))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); /* free list */ if(size_hint) { - if(NULL == (heap->freelist = H5FL_MALLOC(H5HL_free_t))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") - heap->freelist->offset = 0; - heap->freelist->size = size_hint; - heap->freelist->prev = heap->freelist->next = NULL; + if(NULL == (heap->freelist = H5FL_MALLOC(H5HL_free_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); + heap->freelist->offset = 0; + heap->freelist->size = size_hint; + heap->freelist->prev = heap->freelist->next = NULL; heap->free_block = 0; } /* end if */ else { - heap->freelist = NULL; + heap->freelist = NULL; heap->free_block = H5HL_FREE_NULL; } /* end else */ /* Allocate the heap prefix */ - if(NULL == (prfx = H5HL_prfx_new(heap))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") + if(NULL == (prfx = H5HL__prfx_new(heap))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); /* Add to cache */ - if(H5AC_insert_entry(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to cache local heap prefix") + if(FAIL == H5AC_insert_entry(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, H5AC__NO_FLAGS_SET)) + H5E_THROW(H5E_CANTINIT, "unable to cache local heap prefix"); /* Set address to return */ *addr_p = heap->prfx_addr; -done: +CATCH if(ret_value < 0) { + *addr_p = HADDR_UNDEF; if(prfx) { - if(H5HL_prfx_dest(prfx) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap prefix") + if(FAIL == H5HL__prfx_dest(prfx)) + H5E_THROW(H5E_CANTFREE, "unable to destroy local heap prefix"); } /* end if */ else { if(heap) { if(H5F_addr_defined(heap->prfx_addr)) - if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->prfx_addr, total_size) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "can't release heap data?") - if(H5HL_dest(heap) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap") + if(FAIL == H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->prfx_addr, total_size)) + H5E_THROW(H5E_CANTFREE, "can't release heap data?"); + if(FAIL == H5HL__dest(heap)) + H5E_THROW(H5E_CANTFREE, "unable to destroy local heap"); } /* end if */ } /* end else */ } /* end if */ - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_create() */ - - -/*------------------------------------------------------------------------- - * Function: H5HL_dblk_realloc - * - * Purpose: Reallocate data block for heap - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HL_dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size) -{ - H5HL_dblk_t *dblk; /* Local heap data block */ - haddr_t old_addr; /* Old location of heap data block */ - haddr_t new_addr; /* New location of heap data block */ - size_t old_heap_size; /* Old size of heap data block */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* check arguments */ - HDassert(heap); - HDassert(new_heap_size > 0); - - /* Release old space on disk */ - old_addr = heap->dblk_addr; - old_heap_size = heap->dblk_size; - H5_CHECK_OVERFLOW(old_heap_size, size_t, hsize_t); - if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)old_heap_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "can't release old heap data?") - - /* Allocate new space on disk */ - H5_CHECK_OVERFLOW(new_heap_size, size_t, hsize_t); - if(HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_size))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "unable to allocate file space for heap") - - /* Update heap info*/ - heap->dblk_addr = new_addr; - heap->dblk_size = new_heap_size; - - /* Check if heap data block actually moved in the file */ - if(H5F_addr_eq(old_addr, new_addr)) { - /* Check if heap data block is contiguous w/prefix */ - if(heap->single_cache_obj) { - /* Sanity check */ - HDassert(H5F_addr_eq(heap->prfx_addr + heap->prfx_size, old_addr)); - HDassert(heap->prfx); - - /* Resize the heap prefix in the cache */ - if(H5AC_resize_entry(heap->prfx, (size_t)(heap->prfx_size + new_heap_size)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to resize heap in cache") - } /* end if */ - else { - /* Sanity check */ - HDassert(H5F_addr_ne(heap->prfx_addr + heap->prfx_size, old_addr)); - HDassert(heap->dblk); - - /* Resize the heap data block in the cache */ - if(H5AC_resize_entry(heap->dblk, (size_t)new_heap_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to resize heap in cache") - } /* end else */ - } /* end if */ - else { - /* Check if heap data block was contiguous w/prefix previously */ - if(heap->single_cache_obj) { - /* Create new heap data block */ - if(NULL == (dblk = H5HL_dblk_new(heap))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "unable to allocate local heap data block") - - /* Resize current heap prefix */ - heap->prfx_size = H5HL_SIZEOF_HDR(f); - if(H5AC_resize_entry(heap->prfx, (size_t)heap->prfx_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to resize heap prefix in cache") - - /* Insert data block into cache (pinned) */ - if(H5AC_insert_entry(f, dxpl_id, H5AC_LHEAP_DBLK, new_addr, dblk, H5AC__PIN_ENTRY_FLAG) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to cache local heap data block") - dblk = NULL; - - /* Reset 'single cache object' flag */ - heap->single_cache_obj = FALSE; - } /* end if */ - else { - /* Resize the heap data block in the cache */ - /* (ignore [unlikely] case where heap data block ends up - * contiguous w/heap prefix again. - */ - if(H5AC_resize_entry(heap->dblk, (size_t)new_heap_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to resize heap data block in cache") - - /* Relocate the heap data block in the cache */ - if(H5AC_move_entry(f, H5AC_LHEAP_DBLK, old_addr, new_addr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTMOVE, FAIL, "unable to move heap data block in cache") - } /* end else */ - } /* end else */ - -done: - if(ret_value < 0) { - /* Restore old heap address & size */ - heap->dblk_addr = old_addr; - heap->dblk_size = old_heap_size; - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_dblk_realloc() */ +END_FUNC(PRIV) /* end H5HL_create() */ /*------------------------------------------------------------------------- - * Function: H5HL_minimize_heap_space + * 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 + * Return: SUCCEED/FAIL * * Programmer: Bill Wendling - * wendling@ncsa.uiuc.edu * Sept. 16, 2003 * *------------------------------------------------------------------------- */ -static herr_t -H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap) -{ - size_t new_heap_size = heap->dblk_size; /* New size of heap */ - herr_t ret_value = SUCCEED; /* Return value */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5HL__minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)) - FUNC_ENTER_NOAPI(FAIL) + size_t new_heap_size = heap->dblk_size; /* New size of heap */ /* check args */ HDassert(f); @@ -393,7 +274,7 @@ H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap) new_heap_size = last_fl->offset; /* Eliminate the free block from the list */ - last_fl = H5HL_remove_free(heap, last_fl); + last_fl = H5HL__remove_free(heap, last_fl); } /* end else */ } /* end if */ else { @@ -413,20 +294,21 @@ H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap) * storage. */ if(new_heap_size != heap->dblk_size) { - HDassert(new_heap_size < heap->dblk_size); + HDassert(new_heap_size < heap->dblk_size); /* Resize the memory buffer */ if(NULL == (heap->dblk_image = H5FL_BLK_REALLOC(lheap_chunk, heap->dblk_image, new_heap_size))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); /* Reallocate data block in file */ - if(H5HL_dblk_realloc(f, dxpl_id, heap, new_heap_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "reallocating data block failed") + if(FAIL == H5HL__dblk_realloc(f, dxpl_id, heap, new_heap_size)) + H5E_THROW(H5E_CANTRESIZE, "reallocating data block failed"); } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5HL_minimize_heap_space() */ +CATCH + /* No special processing on errors */ + +END_FUNC(STATIC) /* H5HL__minimize_heap_space() */ /*------------------------------------------------------------------------- @@ -438,23 +320,20 @@ done: * Failure: NULL * * Programmer: Bill Wendling - * wendling@ncsa.uiuc.edu * Sept. 17, 2003 * *------------------------------------------------------------------------- */ -H5HL_t * -H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, unsigned flags) -{ - H5HL_cache_prfx_ud_t prfx_udata; /* User data for protecting local heap prefix */ - H5HL_prfx_t *prfx = NULL; /* Local heap prefix */ - H5HL_dblk_t *dblk = NULL; /* Local heap data block */ - H5HL_t *heap = NULL; /* Heap data structure */ - unsigned prfx_cache_flags = H5AC__NO_FLAGS_SET; /* Cache flags for unprotecting prefix entry */ - unsigned dblk_cache_flags = H5AC__NO_FLAGS_SET; /* Cache flags for unprotecting data block entry */ - H5HL_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) +BEGIN_FUNC(PRIV, ERR, +H5HL_t *, NULL, NULL, +H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, unsigned flags)) + + H5HL_cache_prfx_ud_t prfx_udata; /* User data for protecting local heap prefix */ + H5HL_prfx_t *prfx = NULL; /* Local heap prefix */ + H5HL_dblk_t *dblk = NULL; /* Local heap data block */ + H5HL_t *heap = NULL; /* Heap data structure */ + unsigned prfx_cache_flags = H5AC__NO_FLAGS_SET; /* Cache flags for unprotecting prefix entry */ + unsigned dblk_cache_flags = H5AC__NO_FLAGS_SET; /* Cache flags for unprotecting data block entry */ /* check arguments */ HDassert(f); @@ -473,7 +352,7 @@ H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, unsigned flags) /* Protect the local heap prefix */ if(NULL == (prfx = (H5HL_prfx_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP_PRFX, addr, &prfx_udata, flags))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to load heap prefix") + H5E_THROW(H5E_CANTPROTECT, "unable to load heap prefix"); /* Get the pointer to the heap */ heap = prfx->heap; @@ -495,7 +374,7 @@ H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, unsigned flags) /* Protect the local heap data block */ if(NULL == (dblk = (H5HL_dblk_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP_DBLK, heap->dblk_addr, &dblk_udata, flags))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to load heap data block") + H5E_THROW(H5E_CANTPROTECT, "unable to load heap data block"); /* Pin the prefix, if the data block was loaded from file */ if(dblk_udata.loaded) @@ -512,49 +391,43 @@ H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, unsigned flags) /* Set return value */ ret_value = heap; -done: +CATCH /* Release the prefix from the cache, now pinned */ if(prfx && heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, prfx_cache_flags) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release local heap prefix") + H5E_THROW(H5E_CANTUNPROTECT, "unable to release local heap prefix"); /* Release the data block from the cache, now pinned */ if(dblk && heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_DBLK, heap->dblk_addr, dblk, dblk_cache_flags) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release local heap data block") + H5E_THROW(H5E_CANTUNPROTECT, "unable to release local heap data block"); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_protect() */ +END_FUNC(PRIV) /* end H5HL_protect() */ /*------------------------------------------------------------------------- * Function: H5HL_offset_into * * Purpose: Called directly after the call to H5HL_protect so that - * a pointer to the object in the heap can be got. + * a pointer to the object in the heap can be obtained. * * Return: Success: Valid pointer. - * Failure: NULL + * Failure: Can't fail * * Programmer: Bill Wendling - * wendling@ncsa.uiuc.edu * Sept. 17, 2003 * *------------------------------------------------------------------------- */ -void * -H5HL_offset_into(const H5HL_t *heap, size_t offset) -{ - /* - * 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_NOERR +BEGIN_FUNC(PRIV, NOERR, +void *, NULL, -, +H5HL_offset_into(const H5HL_t *heap, size_t offset)) /* Sanity check */ HDassert(heap); HDassert(offset < heap->dblk_size); - FUNC_LEAVE_NOAPI(heap->dblk_image + offset) -} /* end H5HL_offset_into() */ + ret_value = heap->dblk_image + offset; + +END_FUNC(PRIV) /* end H5HL_offset_into() */ /*------------------------------------------------------------------------- @@ -562,21 +435,16 @@ H5HL_offset_into(const H5HL_t *heap, size_t offset) * * Purpose: Unprotect the data retrieved by the H5HL_protect call. * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: SUCCEED/FAIL * * Programmer: Bill Wendling - * wendling@ncsa.uiuc.edu * Sept. 17, 2003 * *------------------------------------------------------------------------- */ -herr_t -H5HL_unprotect(H5HL_t *heap) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5HL_unprotect(H5HL_t *heap)) /* check arguments */ HDassert(heap); @@ -589,8 +457,8 @@ H5HL_unprotect(H5HL_t *heap) /* Check for separate heap data block */ if(heap->single_cache_obj) { /* Mark local heap prefix as evictable again */ - if(H5AC_unpin_entry(heap->prfx) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin local heap data block") + if(FAIL == H5AC_unpin_entry(heap->prfx)) + H5E_THROW(H5E_CANTUNPIN, "unable to unpin local heap data block"); } /* end if */ else { /* Sanity check */ @@ -598,34 +466,33 @@ H5HL_unprotect(H5HL_t *heap) /* Mark local heap data block as evictable again */ /* (data block still pins prefix) */ - if(H5AC_unpin_entry(heap->dblk) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin local heap data block") + if(FAIL == H5AC_unpin_entry(heap->dblk)) + H5E_THROW(H5E_CANTUNPIN, "unable to unpin local heap data block"); } /* end else */ } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_unprotect() */ +CATCH + /* No special processing on errors */ + +END_FUNC(PRIV) /* end H5HL_unprotect() */ /*------------------------------------------------------------------------- - * Function: H5HL_remove_free + * Function: H5HL__remove_free * - * Purpose: Removes free list element FL from the specified heap and - * frees it. + * Purpose: Removes free list element FL from the specified heap and + * frees it. * - * Return: NULL + * Return: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 17 1997 + * Programmer: Robb Matzke + * Jul 17 1997 * *------------------------------------------------------------------------- */ -static H5HL_free_t * -H5HL_remove_free(H5HL_t *heap, H5HL_free_t *fl) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR +BEGIN_FUNC(STATIC, NOERR, +H5HL_free_t *, NULL, -, +H5HL__remove_free(H5HL_t *heap, H5HL_free_t *fl)) if(fl->prev) fl->prev->next = fl->next; @@ -635,30 +502,27 @@ H5HL_remove_free(H5HL_t *heap, H5HL_free_t *fl) if(!fl->prev) heap->freelist = fl->next; - FUNC_LEAVE_NOAPI((H5HL_free_t *)H5FL_FREE(H5HL_free_t, fl)) -} /* end H5HL_remove_free() */ + /* H5FL_FREE always returns NULL so we can't check for errors */ + ret_value = (H5HL_free_t *)H5FL_FREE(H5HL_free_t, fl); + +END_FUNC(STATIC) /* end H5HL__remove_free() */ /*------------------------------------------------------------------------- - * Function: H5HL_dirty + * Function: H5HL__dirty * - * Purpose: Mark heap as dirty + * Purpose: Mark heap as dirty * - * Return: Success: Non-negative - * Failure: Negative + * Return: SUCCEED/FAIL * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 + * Programmer: Quincey Koziol + * Oct 12 2008 * *------------------------------------------------------------------------- */ -static herr_t -H5HL_dirty(H5HL_t *heap) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5HL__dirty(H5HL_t *heap)) /* check arguments */ HDassert(heap); @@ -669,43 +533,41 @@ H5HL_dirty(H5HL_t *heap) /* Sanity check */ HDassert(heap->dblk); - if(H5AC_mark_entry_dirty(heap->dblk) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark heap data block as dirty") + if(FAIL == H5AC_mark_entry_dirty(heap->dblk)) + H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark heap data block as dirty"); } /* end if */ /* Mark heap prefix as dirty */ - if(H5AC_mark_entry_dirty(heap->prfx) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark heap prefix as dirty") + if(FAIL == H5AC_mark_entry_dirty(heap->prfx)) + H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark heap prefix as dirty"); -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_dirty() */ +CATCH + /* No special processing on errors */ + +END_FUNC(STATIC) /* end H5HL__dirty() */ /*------------------------------------------------------------------------- - * Function: H5HL_insert + * Function: H5HL_insert * - * Purpose: Inserts a new item into the heap. + * Purpose: Inserts a new item into the heap. * - * Return: Success: Offset of new item within heap. - * Failure: UFAIL + * Return: Success: Offset of new item within heap. + * Failure: UFAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 17 1997 + * Programmer: Robb Matzke + * Jul 17 1997 * *------------------------------------------------------------------------- */ -size_t -H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void *buf) -{ - H5HL_free_t *fl = NULL, *last_fl = NULL; - size_t offset = 0; - size_t need_size; - hbool_t found; - size_t ret_value = 0; /* Return value */ +BEGIN_FUNC(PRIV, ERR, +size_t, UFAIL, UFAIL, +H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void *buf)) - FUNC_ENTER_NOAPI(UFAIL) + H5HL_free_t *fl = NULL, *last_fl = NULL; + size_t offset = 0; + size_t need_size; + hbool_t found; /* check arguments */ HDassert(f); @@ -719,8 +581,8 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void * * so we just accept that an extra flush of the heap info could occur * if an error occurs -QAK) */ - if(H5HL_dirty(heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, UFAIL, "unable to mark heap as dirty") + if(FAIL == H5HL__dirty(heap)) + H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark heap as dirty"); /* * In order to keep the free list descriptors aligned on word boundaries, @@ -734,26 +596,25 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void * * leave zero or at least H5G_SIZEOF_FREE bytes left over. */ for(fl = heap->freelist, found = FALSE; fl; fl = fl->next) { - if(fl->size > need_size && - fl->size - need_size >= H5HL_SIZEOF_FREE(f)) { - /* a big enough free block was found */ - offset = fl->offset; - fl->offset += need_size; - fl->size -= need_size; - HDassert(fl->offset == H5HL_ALIGN(fl->offset)); - HDassert(fl->size == H5HL_ALIGN(fl->size)); - found = TRUE; - break; - } else if(fl->size == need_size) { - /* free block of exact size found */ - offset = fl->offset; - fl = H5HL_remove_free(heap, fl); - found = TRUE; - break; - } else if(!last_fl || last_fl->offset < fl->offset) { - /* track free space that's closest to end of heap */ - last_fl = fl; - } + if(fl->size > need_size && fl->size - need_size >= H5HL_SIZEOF_FREE(f)) { + /* a big enough free block was found */ + offset = fl->offset; + fl->offset += need_size; + fl->size -= need_size; + HDassert(fl->offset == H5HL_ALIGN(fl->offset)); + HDassert(fl->size == H5HL_ALIGN(fl->size)); + found = TRUE; + break; + } else if(fl->size == need_size) { + /* free block of exact size found */ + offset = fl->offset; + fl = H5HL__remove_free(heap, fl); + found = TRUE; + break; + } else if(!last_fl || last_fl->offset < fl->offset) { + /* track free space that's closest to end of heap */ + last_fl = fl; + } } /* end for */ /* @@ -770,7 +631,7 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void * /* At least double the heap's size, making certain there's enough room * for the new object */ - need_more = MAX(need_size, heap->dblk_size); + need_more = MAX(need_size, heap->dblk_size); /* If there is no last free block or it's not at the end of the heap, * and the amount of space to allocate is not big enough to include at @@ -778,106 +639,104 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void * * space requested to just the amount of space needed. (Generally * speaking, this only occurs when the heap is small -QAK) */ - if(!(last_fl && last_fl->offset + last_fl->size == heap->dblk_size) + if(!(last_fl && last_fl->offset + last_fl->size == heap->dblk_size) && (need_more < (need_size + H5HL_SIZEOF_FREE(f)))) need_more = need_size; - new_dblk_size = heap->dblk_size + need_more; - HDassert(heap->dblk_size < new_dblk_size); + new_dblk_size = heap->dblk_size + need_more; + HDassert(heap->dblk_size < new_dblk_size); old_dblk_size = heap->dblk_size; - H5_CHECK_OVERFLOW(heap->dblk_size, size_t, hsize_t); - H5_CHECK_OVERFLOW(new_dblk_size, size_t, hsize_t); + H5_CHECK_OVERFLOW(heap->dblk_size, size_t, hsize_t); + H5_CHECK_OVERFLOW(new_dblk_size, size_t, hsize_t); /* Extend current heap if possible */ - was_extended = H5MF_try_extend(f, dxpl_id, H5FD_MEM_LHEAP, heap->dblk_addr, (hsize_t)(heap->dblk_size), (hsize_t)need_more); - if(was_extended < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, UFAIL, "error trying to extend heap") + was_extended = H5MF_try_extend(f, dxpl_id, H5FD_MEM_LHEAP, heap->dblk_addr, (hsize_t)(heap->dblk_size), (hsize_t)need_more); + if(FAIL == was_extended) + H5E_THROW(H5E_CANTEXTEND, "error trying to extend heap"); /* Check if we extended the heap data block in file */ if(was_extended == TRUE) { /* Check for prefix & data block contiguous */ if(heap->single_cache_obj) { /* Resize prefix+data block */ - if(H5AC_resize_entry(heap->prfx, (size_t)(heap->prfx_size + new_dblk_size)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, UFAIL, "unable to resize heap prefix in cache") + if(FAIL == H5AC_resize_entry(heap->prfx, (size_t)(heap->prfx_size + new_dblk_size))) + H5E_THROW(H5E_CANTRESIZE, "unable to resize heap prefix in cache"); } /* end if */ else { /* Resize 'standalone' data block */ - if(H5AC_resize_entry(heap->dblk, (size_t)new_dblk_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, UFAIL, "unable to resize heap data block in cache") + if(FAIL == H5AC_resize_entry(heap->dblk, (size_t)new_dblk_size)) + H5E_THROW(H5E_CANTRESIZE, "unable to resize heap data block in cache"); } /* end else */ /* Note new size */ heap->dblk_size = new_dblk_size; - } /* end if */ + } /* end if */ else { /* ...if we can't, allocate a new chunk & release the old */ /* Reallocate data block in file */ - if(H5HL_dblk_realloc(f, dxpl_id, heap, new_dblk_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, UFAIL, "reallocating data block failed") - } /* end if */ + if(FAIL == H5HL__dblk_realloc(f, dxpl_id, heap, new_dblk_size)) + H5E_THROW(H5E_CANTRESIZE, "reallocating data block failed"); + } /* end if */ /* If the last free list in the heap is at the end of the heap, extend it */ - if(last_fl && last_fl->offset + last_fl->size == old_dblk_size) { - /* - * Increase the size of the last free block. - */ - offset = last_fl->offset; - last_fl->offset += need_size; - last_fl->size += need_more - need_size; - HDassert(last_fl->offset == H5HL_ALIGN(last_fl->offset)); - HDassert(last_fl->size == H5HL_ALIGN(last_fl->size)); - - if (last_fl->size < H5HL_SIZEOF_FREE(f)) { + if(last_fl && last_fl->offset + last_fl->size == old_dblk_size) { + /* + * Increase the size of the last free block. + */ + offset = last_fl->offset; + last_fl->offset += need_size; + last_fl->size += need_more - need_size; + HDassert(last_fl->offset == H5HL_ALIGN(last_fl->offset)); + HDassert(last_fl->size == H5HL_ALIGN(last_fl->size)); + + if (last_fl->size < H5HL_SIZEOF_FREE(f)) { #ifdef H5HL_DEBUG - if (H5DEBUG(HL) && last_fl->size) { - fprintf(H5DEBUG(HL), "H5HL: lost %lu bytes at line %d\n", - (unsigned long)(last_fl->size), __LINE__); - } + if (H5DEBUG(HL) && last_fl->size) { + HDfprintf(H5DEBUG(HL), "H5HL: lost %lu bytes at line %d\n", + (unsigned long)(last_fl->size), __LINE__); + } #endif - last_fl = H5HL_remove_free(heap, last_fl); - } - } /* end if */ + last_fl = H5HL__remove_free(heap, last_fl); + } + } /* end if */ else { - /* - * Create a new free list element large enough that we can - * take some space out of it right away. - */ - offset = old_dblk_size; - if(need_more - need_size >= H5HL_SIZEOF_FREE(f)) { - if(NULL == (fl = H5FL_MALLOC(H5HL_free_t))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, UFAIL, "memory allocation failed") - fl->offset = old_dblk_size + need_size; - fl->size = need_more - need_size; - HDassert(fl->offset == H5HL_ALIGN(fl->offset)); - HDassert(fl->size == H5HL_ALIGN(fl->size)); - fl->prev = NULL; - fl->next = heap->freelist; - if(heap->freelist) + /* + * Create a new free list element large enough that we can + * take some space out of it right away. + */ + offset = old_dblk_size; + if(need_more - need_size >= H5HL_SIZEOF_FREE(f)) { + if(NULL == (fl = H5FL_MALLOC(H5HL_free_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); + fl->offset = old_dblk_size + need_size; + fl->size = need_more - need_size; + HDassert(fl->offset == H5HL_ALIGN(fl->offset)); + HDassert(fl->size == H5HL_ALIGN(fl->size)); + fl->prev = NULL; + fl->next = heap->freelist; + if(heap->freelist) heap->freelist->prev = fl; - heap->freelist = fl; + heap->freelist = fl; #ifdef H5HL_DEBUG - } else if (H5DEBUG(HL) && need_more > need_size) { - fprintf(H5DEBUG(HL), - "H5HL_insert: lost %lu bytes at line %d\n", - (unsigned long)(need_more - need_size), __LINE__); + } else if (H5DEBUG(HL) && need_more > need_size) { + HDfprintf(H5DEBUG(HL), "H5HL_insert: lost %lu bytes at line %d\n", + (unsigned long)(need_more - need_size), __LINE__); #endif - } - } /* end else */ + } + } /* end else */ #ifdef H5HL_DEBUG - if (H5DEBUG(HL)) { - fprintf(H5DEBUG(HL), - "H5HL: resize mem buf from %lu to %lu bytes\n", - (unsigned long)(old_dblk_size), - (unsigned long)(old_dblk_size + need_more)); - } + if (H5DEBUG(HL)) { + HDfprintf(H5DEBUG(HL), "H5HL: resize mem buf from %lu to %lu bytes\n", + (unsigned long)(old_dblk_size), + (unsigned long)(old_dblk_size + need_more)); + } #endif - if(NULL == (heap->dblk_image = H5FL_BLK_REALLOC(lheap_chunk, heap->dblk_image, heap->dblk_size))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, UFAIL, "memory allocation failed") + if(NULL == (heap->dblk_image = H5FL_BLK_REALLOC(lheap_chunk, heap->dblk_image, heap->dblk_size))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); - /* Clear new section so junk doesn't appear in the file */ + /* Clear new section so junk doesn't appear in the file */ /* (Avoid clearing section which will be overwritten with newly inserted data) */ - HDmemset(heap->dblk_image + offset + buf_size, 0, (new_dblk_size - (offset + buf_size))); + HDmemset(heap->dblk_image + offset + buf_size, 0, (new_dblk_size - (offset + buf_size))); } /* end if */ /* Copy the data into the heap */ @@ -886,42 +745,40 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void * /* Set return value */ ret_value = offset; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5HL_insert() */ +CATCH + /* No special processing on errors */ + +END_FUNC(PRIV) /* H5HL_insert() */ /*------------------------------------------------------------------------- - * Function: H5HL_remove + * Function: H5HL_remove * - * Purpose: Removes an object or part of an object from the heap at - * address ADDR of file F. The object (or part) to remove - * begins at byte OFFSET from the beginning of the heap and - * continues for SIZE bytes. + * Purpose: Removes an object or part of an object from the heap at + * address ADDR of file F. The object (or part) to remove + * begins at byte OFFSET from the beginning of the heap and + * continues for SIZE bytes. * - * Once part of an object is removed, one must not attempt - * to access that part. Removing the beginning of an object - * results in the object OFFSET increasing by the amount - * truncated. Removing the end of an object results in - * object truncation. Removing the middle of an object results - * in two separate objects, one at the original offset and - * one at the first offset past the removed portion. + * Once part of an object is removed, one must not attempt + * to access that part. Removing the beginning of an object + * results in the object OFFSET increasing by the amount + * truncated. Removing the end of an object results in + * object truncation. Removing the middle of an object results + * in two separate objects, one at the original offset and + * one at the first offset past the removed portion. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 16 1997 + * Programmer: Robb Matzke + * Jul 16 1997 * *------------------------------------------------------------------------- */ -herr_t -H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size) -{ - H5HL_free_t *fl = NULL; - herr_t ret_value = SUCCEED; /* Return value */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size)) - FUNC_ENTER_NOAPI(FAIL) + H5HL_free_t *fl = NULL; /* check arguments */ HDassert(f); @@ -940,8 +797,8 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size) * so we just accept that an extra flush of the heap info could occur * if an error occurs -QAK) */ - if(H5HL_dirty(heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark heap as dirty") + if(FAIL == H5HL__dirty(heap)) + H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark heap as dirty"); /* * Check if this chunk can be prepended or appended to an already @@ -952,60 +809,60 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size) while(fl) { H5HL_free_t *fl2 = NULL; - if((offset + size) == fl->offset) { - fl->offset = offset; - fl->size += size; - HDassert(fl->offset == H5HL_ALIGN(fl->offset)); - HDassert(fl->size == H5HL_ALIGN(fl->size)); - fl2 = fl->next; - while(fl2) { - if((fl2->offset + fl2->size) == fl->offset) { - fl->offset = fl2->offset; - fl->size += fl2->size; - HDassert(fl->offset == H5HL_ALIGN(fl->offset)); - HDassert(fl->size == H5HL_ALIGN(fl->size)); - fl2 = H5HL_remove_free(heap, fl2); - if(((fl->offset + fl->size) == heap->dblk_size) && + if((offset + size) == fl->offset) { + fl->offset = offset; + fl->size += size; + HDassert(fl->offset == H5HL_ALIGN(fl->offset)); + HDassert(fl->size == H5HL_ALIGN(fl->size)); + fl2 = fl->next; + while(fl2) { + if((fl2->offset + fl2->size) == fl->offset) { + fl->offset = fl2->offset; + fl->size += fl2->size; + HDassert(fl->offset == H5HL_ALIGN(fl->offset)); + HDassert(fl->size == H5HL_ALIGN(fl->size)); + fl2 = H5HL__remove_free(heap, fl2); + if(((fl->offset + fl->size) == heap->dblk_size) && ((2 * fl->size) > heap->dblk_size)) { - if(H5HL_minimize_heap_space(f, dxpl_id, heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "heap size minimization failed") + if(FAIL == H5HL__minimize_heap_space(f, dxpl_id, heap)) + H5E_THROW(H5E_CANTFREE, "heap size minimization failed"); } - HGOTO_DONE(SUCCEED); - } - fl2 = fl2->next; - } - if(((fl->offset + fl->size) == heap->dblk_size) && + H5_LEAVE(SUCCEED); + } + fl2 = fl2->next; + } + if(((fl->offset + fl->size) == heap->dblk_size) && ((2 * fl->size) > heap->dblk_size)) { - if(H5HL_minimize_heap_space(f, dxpl_id, heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "heap size minimization failed") + if(FAIL == H5HL__minimize_heap_space(f, dxpl_id, heap)) + H5E_THROW(H5E_CANTFREE, "heap size minimization failed"); } - HGOTO_DONE(SUCCEED); - } else if(fl->offset + fl->size == offset) { - fl->size += size; - fl2 = fl->next; - HDassert(fl->size == H5HL_ALIGN(fl->size)); - while(fl2) { - if(fl->offset + fl->size == fl2->offset) { - fl->size += fl2->size; - HDassert(fl->size == H5HL_ALIGN(fl->size)); - fl2 = H5HL_remove_free(heap, fl2); - if(((fl->offset + fl->size) == heap->dblk_size) && - ((2 * fl->size) > heap->dblk_size)) { - if(H5HL_minimize_heap_space(f, dxpl_id, heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "heap size minimization failed") + H5_LEAVE(SUCCEED); + } else if(fl->offset + fl->size == offset) { + fl->size += size; + fl2 = fl->next; + HDassert(fl->size == H5HL_ALIGN(fl->size)); + while(fl2) { + if(fl->offset + fl->size == fl2->offset) { + fl->size += fl2->size; + HDassert(fl->size == H5HL_ALIGN(fl->size)); + fl2 = H5HL__remove_free(heap, fl2); + if(((fl->offset + fl->size) == heap->dblk_size) && + ((2 * fl->size) > heap->dblk_size)) { + if(FAIL == H5HL__minimize_heap_space(f, dxpl_id, heap)) + H5E_THROW(H5E_CANTFREE, "heap size minimization failed"); } /* end if */ - HGOTO_DONE(SUCCEED); - } /* end if */ - fl2 = fl2->next; - } /* end while */ - if(((fl->offset + fl->size) == heap->dblk_size) && + H5_LEAVE(SUCCEED); + } /* end if */ + fl2 = fl2->next; + } /* end while */ + if(((fl->offset + fl->size) == heap->dblk_size) && ((2 * fl->size) > heap->dblk_size)) { - if(H5HL_minimize_heap_space(f, dxpl_id, heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "heap size minimization failed") + if(FAIL == H5HL__minimize_heap_space(f, dxpl_id, heap)) + H5E_THROW(H5E_CANTFREE, "heap size minimization failed"); } /* end if */ - HGOTO_DONE(SUCCEED); - } /* end if */ - fl = fl->next; + H5_LEAVE(SUCCEED); + } /* end if */ + fl = fl->next; } /* end while */ /* @@ -1015,19 +872,18 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size) */ if(size < H5HL_SIZEOF_FREE(f)) { #ifdef H5HL_DEBUG - if(H5DEBUG(HL)) { - fprintf(H5DEBUG(HL), "H5HL: lost %lu bytes\n", - (unsigned long) size); - } + if(H5DEBUG(HL)) { + HDfprintf(H5DEBUG(HL), "H5HL: lost %lu bytes\n", (unsigned long) size); + } #endif - HGOTO_DONE(SUCCEED); + H5_LEAVE(SUCCEED); } /* end if */ /* * Add an entry to the free list. */ if(NULL == (fl = H5FL_MALLOC(H5HL_free_t))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); fl->offset = offset; fl->size = size; HDassert(fl->offset == H5HL_ALIGN(fl->offset)); @@ -1040,39 +896,37 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size) if(((fl->offset + fl->size) == heap->dblk_size) && ((2 * fl->size) > heap->dblk_size)) { - if(H5HL_minimize_heap_space(f, dxpl_id, heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "heap size minimization failed") + if(FAIL == H5HL__minimize_heap_space(f, dxpl_id, heap)) + H5E_THROW(H5E_CANTFREE, "heap size minimization failed"); } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_remove() */ +CATCH + /* No special processing on exit */ + +END_FUNC(PRIV) /* end H5HL_remove() */ /*------------------------------------------------------------------------- - * Function: H5HL_delete + * Function: H5HL_delete * - * Purpose: Deletes a local heap from disk, freeing disk space used. + * Purpose: Deletes a local heap from disk, freeing disk space used. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 22 2003 + * Programmer: Quincey Koziol + * Mar 22 2003 * *------------------------------------------------------------------------- */ -herr_t -H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) -{ - H5HL_t *heap = NULL; /* Local heap to delete */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)) + + H5HL_t *heap = NULL; /* Local heap to delete */ H5HL_cache_prfx_ud_t prfx_udata; /* User data for protecting local heap prefix */ H5HL_prfx_t *prfx = NULL; /* Local heap prefix */ H5HL_dblk_t *dblk = NULL; /* Local heap data block */ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) /* check arguments */ HDassert(f); @@ -1088,7 +942,7 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) /* Protect the local heap prefix */ if(NULL == (prfx = (H5HL_prfx_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP_PRFX, addr, &prfx_udata, H5AC__NO_FLAGS_SET))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load heap prefix") + H5E_THROW(H5E_CANTPROTECT, "unable to load heap prefix"); /* Get the pointer to the heap */ heap = prfx->heap; @@ -1103,53 +957,49 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) /* Protect the local heap data block */ if(NULL == (dblk = (H5HL_dblk_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP_DBLK, heap->dblk_addr, &dblk_udata, H5AC__NO_FLAGS_SET))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load heap data block") + H5E_THROW(H5E_CANTPROTECT, "unable to load heap data block"); /* Pin the prefix, if the data block was loaded from file */ if(dblk_udata.loaded) { - if(H5AC_pin_protected_entry(prfx) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPIN, FAIL, "unable to pin local heap prefix") + if(FAIL == H5AC_pin_protected_entry(prfx)) + H5E_THROW(H5E_CANTPIN, "unable to pin local heap prefix"); } /* end if */ } /* end if */ /* Set the flags for releasing the prefix and data block */ cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; -done: +CATCH /* Release the data block from the cache, now deleted */ if(dblk && heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_DBLK, heap->dblk_addr, dblk, cache_flags) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release local heap data block") + H5E_THROW(H5E_CANTUNPROTECT, "unable to release local heap data block"); /* Release the prefix from the cache, now deleted */ if(prfx && heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, cache_flags) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release local heap prefix") + H5E_THROW(H5E_CANTUNPROTECT, "unable to release local heap prefix"); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_delete() */ +END_FUNC(PRIV) /* end H5HL_delete() */ /*------------------------------------------------------------------------- - * Function: H5HL_get_size + * Function: H5HL_get_size * - * Purpose: Retrieves the current size of a heap + * Purpose: Retrieves the current size of a heap * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Nov 7 2005 + * Programmer: Quincey Koziol + * Nov 7 2005 * *------------------------------------------------------------------------- */ -herr_t -H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size) -{ - H5HL_cache_prfx_ud_t prfx_udata; /* User data for protecting local heap prefix */ - H5HL_prfx_t *prfx = NULL; /* Local heap prefix */ - H5HL_t *heap; /* Heap data structure */ - herr_t ret_value = SUCCEED; /* Return value */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size)) - FUNC_ENTER_NOAPI(FAIL) + H5HL_cache_prfx_ud_t prfx_udata; /* User data for protecting local heap prefix */ + H5HL_prfx_t *prfx = NULL; /* Local heap prefix */ + H5HL_t *heap; /* Heap data structure */ /* check arguments */ HDassert(f); @@ -1166,7 +1016,7 @@ H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size) /* Protect the local heap prefix */ if(NULL == (prfx = (H5HL_prfx_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP_PRFX, addr, &prfx_udata, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load heap prefix") + H5E_THROW(H5E_CANTPROTECT, "unable to load heap prefix"); /* Get the pointer to the heap */ heap = prfx->heap; @@ -1174,12 +1024,11 @@ H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size) /* Set the size to return */ *size = heap->dblk_size; -done: - if(prfx && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release local heap prefix") +CATCH + if(prfx && FAIL == H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, H5AC__NO_FLAGS_SET)) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release local heap prefix"); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_get_size() */ +END_FUNC(PRIV) /* end H5HL_get_size() */ /*------------------------------------------------------------------------- @@ -1188,22 +1037,20 @@ done: * Purpose: Compute the size in bytes of the specified instance of * H5HL_t via H5HL_size() * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * * Programmer: Vailin Choi * June 19 2007 * *------------------------------------------------------------------------- */ -herr_t -H5HL_heapsize(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t *heap_size) -{ - H5HL_cache_prfx_ud_t prfx_udata; /* User data for protecting local heap prefix */ - H5HL_prfx_t *prfx = NULL; /* Local heap prefix */ - H5HL_t *heap; /* Heap data structure */ - herr_t ret_value = SUCCEED; /* Return value */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5HL_heapsize(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t *heap_size)) - FUNC_ENTER_NOAPI(FAIL) + H5HL_cache_prfx_ud_t prfx_udata; /* User data for protecting local heap prefix */ + H5HL_prfx_t *prfx = NULL; /* Local heap prefix */ + H5HL_t *heap; /* Heap data structure */ /* check arguments */ HDassert(f); @@ -1220,7 +1067,7 @@ H5HL_heapsize(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t *heap_size) /* Protect the local heap prefix */ if(NULL == (prfx = (H5HL_prfx_t *)H5AC_protect(f, dxpl_id, H5AC_LHEAP_PRFX, addr, &prfx_udata, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load heap prefix") + H5E_THROW(H5E_CANTPROTECT, "unable to load heap prefix"); /* Get the pointer to the heap */ heap = prfx->heap; @@ -1228,10 +1075,9 @@ H5HL_heapsize(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t *heap_size) /* Accumulate the size of the local heap */ *heap_size += (hsize_t)(heap->prfx_size + heap->dblk_size); -done: - if(prfx && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release local heap prefix") +CATCH + if(prfx && FAIL == H5AC_unprotect(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, H5AC__NO_FLAGS_SET)) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release local heap prefix"); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_heapsize() */ +END_FUNC(PRIV) /* end H5HL_heapsize() */ diff --git a/src/H5HLcache.c b/src/H5HLcache.c index 42fe1c7..1133dd3 100644 --- a/src/H5HLcache.c +++ b/src/H5HLcache.c @@ -15,11 +15,11 @@ /*------------------------------------------------------------------------- * - * Created: H5HLcache.c - * Feb 5 2008 - * Quincey Koziol <koziol@hdfgroup.org> + * Created: H5HLcache.c + * Feb 5 2008 + * Quincey Koziol <koziol@hdfgroup.org> * - * Purpose: Implement local heap metadata cache methods. + * Purpose: Implement local heap metadata cache methods. * *------------------------------------------------------------------------- */ @@ -34,24 +34,25 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5HLpkg.h" /* Local Heaps */ -#include "H5MFprivate.h" /* File memory management */ -#include "H5WBprivate.h" /* Wrapped Buffers */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5HLpkg.h" /* Local Heaps */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5WBprivate.h" /* Wrapped Buffers */ /****************/ /* Local Macros */ /****************/ -#define H5HL_VERSION 0 /* Local heap collection version */ +#define H5HL_VERSION 0 /* Local heap collection version */ -/* Set the local heap size to speculatively read in */ -/* (needs to be more than the local heap prefix size to work at all and +/* Set the local heap size to speculatively read in + * (needs to be more than the local heap prefix size to work at all and * should be larger than the default local heap size to save the - * extra I/O operations) */ -#define H5HL_SPEC_READ_SIZE 512 + * extra I/O operations) + */ +#define H5HL_SPEC_READ_SIZE 512 /******************/ @@ -69,6 +70,7 @@ /********************/ /* Metadata cache callbacks */ +/* Local heap prefix */ static herr_t H5HL__cache_prefix_get_load_size(const void *udata, size_t *image_len); static void *H5HL__cache_prefix_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); @@ -79,6 +81,7 @@ static herr_t H5HL__cache_prefix_serialize(const H5F_t *f, void *image, size_t len, void *thing); static herr_t H5HL__cache_prefix_free_icr(void *thing); +/* Local heap data block */ static herr_t H5HL__cache_datablock_get_load_size(const void *udata, size_t *image_len); static void *H5HL__cache_datablock_deserialize(const void *image, size_t len, @@ -141,15 +144,14 @@ const H5AC_class_t H5AC_LHEAP_DBLK[1] = {{ /*------------------------------------------------------------------------- - * Function: H5HL__fl_deserialize + * Function: H5HL__fl_deserialize * - * Purpose: Deserialize the free list for a heap data block + * Purpose: Deserialize the free list for a heap data block * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 + * Programmer: Quincey Koziol + * Oct 12 2008 * *------------------------------------------------------------------------- */ @@ -185,7 +187,7 @@ H5HL__fl_deserialize(H5HL_t *heap) /* Decode offset of next free block */ image = heap->dblk_image + free_block; H5F_DECODE_LENGTH_LEN(image, free_block, heap->sizeof_size); - if(free_block == 0) + if(0 == free_block) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "free block size is zero?") /* Decode length of this free block */ @@ -205,6 +207,7 @@ H5HL__fl_deserialize(H5HL_t *heap) done: if(ret_value < 0) if(fl) + /* H5FL_FREE always returns NULL so we can't check for errors */ fl = H5FL_FREE(H5HL_free_t, fl); FUNC_LEAVE_NOAPI(ret_value) @@ -212,23 +215,21 @@ done: /*------------------------------------------------------------------------- - * Function: H5HL__fl_serialize + * Function: H5HL__fl_serialize * - * Purpose: Serialize the free list for a heap data block + * Purpose: Serialize the free list for a heap data block * - * Return: Success: SUCCESS - * Failure: FAIL + * Return: Nothing (void) * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 + * Programmer: Quincey Koziol + * Oct 12 2008 * *------------------------------------------------------------------------- */ static void H5HL__fl_serialize(const H5HL_t *heap) { - H5HL_free_t *fl; /* Pointer to heap free list node */ + H5HL_free_t *fl; /* Pointer to heap free list node */ FUNC_ENTER_STATIC_NOERR @@ -251,6 +252,7 @@ H5HL__fl_serialize(const H5HL_t *heap) } /* end for */ FUNC_LEAVE_NOAPI_VOID + } /* end H5HL__fl_serialize() */ @@ -338,12 +340,12 @@ H5HL__cache_prefix_deserialize(const void *_image, size_t len, void *_udata, image += 3; /* Allocate space in memory for the heap */ - if(NULL == (heap = H5HL_new(udata->sizeof_size, udata->sizeof_addr, udata->sizeof_prfx))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate local heap structure") + if(NULL == (heap = H5HL__new(udata->sizeof_size, udata->sizeof_addr, udata->sizeof_prfx))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate local heap structure"); /* Allocate the heap prefix */ - if(NULL == (prfx = H5HL_prfx_new(heap))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate local heap prefix") + if(NULL == (prfx = H5HL__prfx_new(heap))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate local heap prefix"); /* Store the prefix's address & length */ heap->prfx_addr = udata->prfx_addr; @@ -422,12 +424,12 @@ done: /* Release the [possibly partially initialized] local heap on errors */ if(!ret_value) { if(prfx) { - if(H5HL_prfx_dest(prfx) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to destroy local heap prefix") + if(FAIL == H5HL__prfx_dest(prfx)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to destroy local heap prefix"); } /* end if */ else { - if(heap && H5HL_dest(heap) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to destroy local heap") + if(heap && FAIL == H5HL__dest(heap)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to destroy local heap"); } /* end else */ } /* end if */ @@ -472,7 +474,6 @@ H5HL__cache_prefix_image_len(const void *_thing, size_t *image_len, if(prfx->heap->single_cache_obj) *image_len += prfx->heap->dblk_size; - FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HL__cache_prefix_image_len() */ @@ -619,7 +620,7 @@ H5HL__cache_prefix_free_icr(void *_thing) HDassert(H5F_addr_eq(prfx->cache_info.addr, prfx->heap->prfx_addr)); /* Destroy local heap prefix */ - if(H5HL_prfx_dest(prfx) < 0) + if(H5HL__prfx_dest(prfx) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't destroy local heap prefix") done: @@ -697,21 +698,21 @@ H5HL__cache_datablock_deserialize(const void *image, size_t len, void *_udata, HDassert(dirty); /* Allocate space in memory for the heap data block */ - if(NULL == (dblk = H5HL_dblk_new(udata->heap))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed") + if(NULL == (dblk = H5HL__dblk_new(udata->heap))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed"); /* Check for heap still retaining image */ if(NULL == udata->heap->dblk_image) { /* Allocate space for the heap data image */ if(NULL == (udata->heap->dblk_image = H5FL_BLK_MALLOC(lheap_chunk, udata->heap->dblk_size))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate data block image buffer") + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate data block image buffer"); /* copy the datablock from the read buffer */ HDmemcpy(udata->heap->dblk_image, image, len); /* Build free list */ - if(H5HL__fl_deserialize(udata->heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't initialize free list") + if(FAIL == H5HL__fl_deserialize(udata->heap)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't initialize free list"); } /* end if */ /* Set flag to indicate data block from loaded from file */ @@ -723,8 +724,8 @@ H5HL__cache_datablock_deserialize(const void *image, size_t len, void *_udata, done: /* Release the [possibly partially initialized] local heap on errors */ if(!ret_value && dblk) - if(H5HL_dblk_dest(dblk) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to destroy local heap data block") + if(FAIL == H5HL__dblk_dest(dblk)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to destroy local heap data block"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HL__cache_datablock_deserialize() */ @@ -851,10 +852,9 @@ H5HL__cache_datablock_free_icr(void *_thing) HDassert(dblk->cache_info.type == H5AC_LHEAP_DBLK); /* Destroy the data block */ - if(H5HL_dblk_dest(dblk) < 0) + if(H5HL__dblk_dest(dblk) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap data block") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HL__cache_datablock_free_icr() */ - diff --git a/src/H5HLdbg.c b/src/H5HLdbg.c index 3620511..fc8f5d3 100644 --- a/src/H5HLdbg.c +++ b/src/H5HLdbg.c @@ -13,55 +13,49 @@ * access to either file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> +/* Programmer: Quincey Koziol <koziol@hdfgroup.org> * Wednesday, July 9, 2003 * - * Purpose: Local Heap object debugging functions. + * Purpose: Local Heap object debugging functions. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5HLmodule.h" /* This source code file is part of the H5HL module */ +/***********/ +/* Headers */ +/***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5HLpkg.h" /* Local heaps */ -#include "H5Iprivate.h" /* ID Functions */ -#include "H5MMprivate.h" /* Memory management */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5HLpkg.h" /* Local heaps */ +#include "H5MMprivate.h" /* Memory management */ /*------------------------------------------------------------------------- - * Function: H5HL_debug - * - * Purpose: Prints debugging information about a heap. - * - * Return: Non-negative on success/Negative on failure + * Function: H5HL_debug * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 1 1997 + * Purpose: Prints debugging information about a heap. * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. + * Return: SUCCEED/FAIL * - * John Mainzer, 6/17/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. + * Programmer: Robb Matzke + * Aug 1 1997 * *------------------------------------------------------------------------- */ -herr_t -H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth) -{ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth)) + H5HL_t *h = NULL; int free_block; H5HL_free_t *freelist; uint8_t *marker = NULL; size_t amount_free = 0; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) /* check arguments */ HDassert(f); @@ -71,17 +65,17 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int HDassert(fwidth >= 0); if(NULL == (h = (H5HL_t *)H5HL_protect(f, dxpl_id, addr, H5AC__READ_ONLY_FLAG))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap") + H5E_THROW(H5E_CANTPROTECT, "unable to load/protect local heap"); HDfprintf(stream, "%*sLocal Heap...\n", indent, ""); HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, "Header size (in bytes):", (unsigned long)h->prfx_size); HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, - "Address of heap data:", - h->dblk_addr); + "Address of heap data:", + h->dblk_addr); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, - "Data bytes allocated for heap:", + "Data bytes allocated for heap:", h->dblk_size); /* @@ -89,7 +83,7 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int * the heap and that no two free blocks point to the same region of * the heap. */ if(NULL == (marker = (uint8_t *)H5MM_calloc(h->dblk_size))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); HDfprintf(stream, "%*sFree Blocks (offset, size):\n", indent, ""); for(free_block = 0, freelist = h->freelist; freelist; freelist = freelist->next, free_block++) { @@ -127,11 +121,11 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int */ H5_buffer_dump(stream, indent, h->dblk_image, marker, (size_t)0, h->dblk_size); -done: - if(h && H5HL_unprotect(h) < 0) - HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") - H5MM_xfree(marker); +CATCH + if(h && FAIL == H5HL_unprotect(h)) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release/unprotect local heap"); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_debug() */ + if(marker && NULL != (marker = (uint8_t *)H5MM_xfree(marker))) + H5E_THROW(H5E_CANTFREE, "can't free marker buffer"); +END_FUNC(PRIV) /* end H5HL_debug() */ diff --git a/src/H5HLdblk.c b/src/H5HLdblk.c new file mode 100644 index 0000000..6a4d8ce --- /dev/null +++ b/src/H5HLdblk.c @@ -0,0 +1,282 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5HLdblk.c + * Summer 2012 + * Dana Robinson <derobins@hdfgroup.org> + * + * Purpose: Data block routines for local heaps. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5HLmodule.h" /* This source code file is part of the H5HL module */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5HLpkg.h" /* Local Heaps */ +#include "H5MFprivate.h" /* File memory management */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5HL_dblk_t struct */ +H5FL_DEFINE_STATIC(H5HL_dblk_t); + + + +/*------------------------------------------------------------------------- + * Function: H5HL__dblk_new + * + * Purpose: Create a new local heap data block object + * + * Return: Success: non-NULL pointer to new local heap data block + * Failure: NULL + * + * Programmer: Quincey Koziol + * Oct 12 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5HL_dblk_t *, NULL, NULL, +H5HL__dblk_new(H5HL_t *heap)) + + H5HL_dblk_t *dblk = NULL; /* New local heap data block */ + + /* check arguments */ + HDassert(heap); + + /* Allocate new local heap data block */ + if(NULL == (dblk = H5FL_CALLOC(H5HL_dblk_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for local heap data block") + + /* Increment ref. count on heap data structure */ + if(FAIL == H5HL__inc_rc(heap)) + H5E_THROW(H5E_CANTINC, "can't increment heap ref. count") + + /* Link the heap & the data block */ + dblk->heap = heap; + heap->dblk = dblk; + + /* Set the return value */ + ret_value = dblk; + +CATCH + /* Ensure that the data block memory is deallocated on errors */ + if(!ret_value && dblk != NULL) { + /* H5FL_FREE always returns NULL so we can't check for errors */ + dblk = H5FL_FREE(H5HL_dblk_t, dblk); + } + +END_FUNC(PKG) /* end H5HL__dblk_new() */ + + +/*------------------------------------------------------------------------- + * Function: H5HL__dblk_dest + * + * Purpose: Destroy a local heap data block object + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Oct 12 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5HL__dblk_dest(H5HL_dblk_t *dblk)) + + /* check arguments */ + HDassert(dblk); + + /* Check if data block was initialized */ + if(dblk->heap) { + /* Unlink data block from heap */ + dblk->heap->dblk = NULL; + + /* Unpin the local heap prefix */ + if(FAIL == H5AC_unpin_entry(dblk->heap->prfx)) + H5E_THROW(H5E_CANTUNPIN, "can't unpin local heap prefix") + + /* Decrement ref. count on heap data structure */ + if(FAIL == H5HL__dec_rc(dblk->heap)) + H5E_THROW(H5E_CANTDEC, "can't decrement heap ref. count") + + /* Unlink heap from data block */ + dblk->heap = NULL; + } /* end if */ + +CATCH + /* Free local heap data block */ + /* H5FL_FREE always returns NULL so we can't check for errors */ + dblk = H5FL_FREE(H5HL_dblk_t, dblk); + +END_FUNC(PKG) /* end H5HL__dblk_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5HL__dblk_realloc + * + * Purpose: Reallocate data block for heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Oct 12 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5HL__dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size)) + + H5HL_dblk_t *dblk; /* Local heap data block */ + haddr_t old_addr; /* Old location of heap data block */ + haddr_t new_addr; /* New location of heap data block */ + size_t old_heap_size; /* Old size of heap data block */ + + /* check arguments */ + HDassert(heap); + HDassert(new_heap_size > 0); + + /* Release old space on disk */ + old_addr = heap->dblk_addr; + old_heap_size = heap->dblk_size; + H5_CHECK_OVERFLOW(old_heap_size, size_t, hsize_t); + if(FAIL == H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)old_heap_size)) + H5E_THROW(H5E_CANTFREE, "can't free old local heap data"); + + /* Allocate new space on disk */ + H5_CHECK_OVERFLOW(new_heap_size, size_t, hsize_t); + if(HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_size))) + H5E_THROW(H5E_CANTALLOC, "unable to allocate file space for local heap"); + + /* Update heap info*/ + heap->dblk_addr = new_addr; + heap->dblk_size = new_heap_size; + + /* Check if heap data block actually moved in the file */ + if(H5F_addr_eq(old_addr, new_addr)) { + /* Check if heap data block is contiguous w/prefix */ + if(heap->single_cache_obj) { + /* Sanity check */ + HDassert(H5F_addr_eq(heap->prfx_addr + heap->prfx_size, old_addr)); + HDassert(heap->prfx); + + /* Resize the heap prefix in the cache */ + if(FAIL == H5AC_resize_entry(heap->prfx, (size_t)(heap->prfx_size + new_heap_size))) + H5E_THROW(H5E_CANTRESIZE, "unable to resize heap in cache"); + + } /* end if */ + else { + /* Sanity check */ + HDassert(H5F_addr_ne(heap->prfx_addr + heap->prfx_size, old_addr)); + HDassert(heap->dblk); + + /* Resize the heap data block in the cache */ + if(H5AC_resize_entry(heap->dblk, (size_t)new_heap_size) < 0) + H5E_THROW(H5E_CANTRESIZE, "unable to resize heap (data block) in cache"); + + } /* end else */ + } /* end if */ + else { + /* Check if heap data block was contiguous w/prefix previously */ + if(heap->single_cache_obj) { + /* Create new heap data block */ + if(NULL == (dblk = H5HL__dblk_new(heap))) + H5E_THROW(H5E_CANTALLOC, "unable to allocate local heap data block"); + + /* Resize current heap prefix */ + heap->prfx_size = H5HL_SIZEOF_HDR(f); + if(FAIL == H5AC_resize_entry(heap->prfx, (size_t)heap->prfx_size)) + H5E_THROW(H5E_CANTRESIZE, "unable to resize heap prefix in cache"); + + /* Insert data block into cache (pinned) */ + if(FAIL == H5AC_insert_entry(f, dxpl_id, H5AC_LHEAP_DBLK, new_addr, dblk, H5AC__PIN_ENTRY_FLAG)) + H5E_THROW(H5E_CANTINIT, "unable to cache local heap data block"); + + dblk = NULL; + + /* Reset 'single cache object' flag */ + heap->single_cache_obj = FALSE; + } /* end if */ + else { + /* Resize the heap data block in the cache */ + /* (ignore [unlikely] case where heap data block ends up + * contiguous w/heap prefix again. + */ + if(FAIL == H5AC_resize_entry(heap->dblk, (size_t)new_heap_size)) + H5E_THROW(H5E_CANTRESIZE, "unable to resize heap data block in cache"); + + /* Relocate the heap data block in the cache */ + if(FAIL == H5AC_move_entry(f, H5AC_LHEAP_DBLK, old_addr, new_addr)) + H5E_THROW(H5E_CANTMOVE, "unable to move heap data block in cache"); + + } /* end else */ + } /* end else */ + +CATCH + /* Restore old heap address & size on errors */ + if(FAIL == ret_value) { + heap->dblk_addr = old_addr; + heap->dblk_size = old_heap_size; + } /* end if */ + +END_FUNC(PKG) /* end H5HL__dblk_realloc() */ diff --git a/src/H5HLint.c b/src/H5HLint.c index bbf579d..5b547cf 100644 --- a/src/H5HLint.c +++ b/src/H5HLint.c @@ -15,11 +15,11 @@ /*------------------------------------------------------------------------- * - * Created: H5HLint.c - * Oct 12 2008 - * Quincey Koziol <koziol@hdfgroup.org> + * Created: H5HLint.c + * Oct 12 2008 + * Quincey Koziol <koziol@hdfgroup.org> * - * Purpose: Local heap internal routines. + * Purpose: Local heap internal routines. * *------------------------------------------------------------------------- */ @@ -34,9 +34,10 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5HLpkg.h" /* Local Heaps */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5HLpkg.h" /* Local Heaps */ /****************/ @@ -76,35 +77,26 @@ /* Declare a free list to manage the H5HL_t struct */ H5FL_DEFINE_STATIC(H5HL_t); -/* Declare a free list to manage the H5HL_dblk_t struct */ -H5FL_DEFINE_STATIC(H5HL_dblk_t); - -/* Declare a free list to manage the H5HL_prfx_t struct */ -H5FL_DEFINE_STATIC(H5HL_prfx_t); - /*------------------------------------------------------------------------- - * Function: H5HL_new + * Function: H5HL__new * - * Purpose: Create a new local heap object + * Purpose: Create a new local heap object * - * Return: Success: non-NULL pointer to new local heap - * Failure: NULL + * Return: Success: non-NULL pointer to new local heap + * Failure: NULL * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Jan 5 2010 + * Programmer: Quincey Koziol + * Jan 5 2010 * *------------------------------------------------------------------------- */ -H5HL_t * -H5HL_new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size) -{ - H5HL_t *heap = NULL; /* New local heap */ - H5HL_t *ret_value = NULL; /* Return value */ +BEGIN_FUNC(PKG, ERR, +H5HL_t *, NULL, NULL, +H5HL__new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size)) - FUNC_ENTER_NOAPI(NULL) + H5HL_t *heap = NULL; /* New local heap */ /* check arguments */ HDassert(sizeof_size > 0); @@ -113,7 +105,7 @@ H5HL_new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size) /* Allocate new local heap structure */ if(NULL == (heap = H5FL_CALLOC(H5HL_t))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed") + H5E_THROW(H5E_CANTALLOC, "memory allocation failed"); /* Initialize non-zero fields */ heap->sizeof_size = sizeof_size; @@ -123,29 +115,29 @@ H5HL_new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size) /* Set the return value */ ret_value = heap; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_new() */ +CATCH + if(!ret_value && heap != NULL) + if (NULL == (heap = H5FL_FREE(H5HL_t, heap))) + H5E_THROW(H5E_CANTFREE, "can't free heap memory"); + +END_FUNC(PKG) /* end H5HL__new() */ /*------------------------------------------------------------------------- * Function: H5HL__inc_rc * - * Purpose: Increment ref. count on heap + * Purpose: Increment ref. count on heap * - * Return: Success: Non-negative - * Failure: Negative + * Return: SUCCEED (Can't fail) * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 + * Programmer: Quincey Koziol + * Oct 12 2008 * *------------------------------------------------------------------------- */ -static herr_t -H5HL__inc_rc(H5HL_t *heap) -{ - FUNC_ENTER_STATIC_NOERR +BEGIN_FUNC(PKG, NOERR, +herr_t, SUCCEED, -, +H5HL__inc_rc(H5HL_t *heap)) /* check arguments */ HDassert(heap); @@ -153,28 +145,24 @@ H5HL__inc_rc(H5HL_t *heap) /* Increment heap's ref. count */ heap->rc++; - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HL__inc_rc() */ +END_FUNC(PKG) /* end H5HL__inc_rc() */ /*------------------------------------------------------------------------- * Function: H5HL__dec_rc * - * Purpose: Decrement ref. count on heap + * Purpose: Decrement ref. count on heap * - * Return: Success: Non-negative - * Failure: Negative + * Return: SUCCEED/FAIL * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 + * Programmer: Quincey Koziol + * Oct 12 2008 * *------------------------------------------------------------------------- */ -static herr_t -H5HL__dec_rc(H5HL_t *heap) -{ - FUNC_ENTER_STATIC_NOERR +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5HL__dec_rc(H5HL_t *heap)) /* check arguments */ HDassert(heap); @@ -182,31 +170,29 @@ H5HL__dec_rc(H5HL_t *heap) /* Decrement heap's ref. count */ heap->rc--; +CATCH /* Check if we should destroy the heap */ - if(heap->rc == 0) - H5HL_dest(heap); + if(heap->rc == 0 && FAIL == H5HL__dest(heap)) + H5E_THROW(H5E_CANTFREE, "unable to destroy local heap"); - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HL__dec_rc() */ +END_FUNC(PKG) /* end H5HL__dec_rc() */ /*------------------------------------------------------------------------- - * Function: H5HL_dest + * Function: H5HL__dest * - * Purpose: Destroys a heap in memory. + * Purpose: Destroys a heap in memory. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jan 15 2003 + * Programmer: Quincey Koziol + * Jan 15 2003 * *------------------------------------------------------------------------- */ -herr_t -H5HL_dest(H5HL_t *heap) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5HL__dest(H5HL_t *heap)) /* check arguments */ HDassert(heap); @@ -217,201 +203,20 @@ H5HL_dest(H5HL_t *heap) HDassert(heap->prfx == NULL); HDassert(heap->dblk == NULL); +CATCH if(heap->dblk_image) - heap->dblk_image = H5FL_BLK_FREE(lheap_chunk, heap->dblk_image); + if(NULL != (heap->dblk_image = H5FL_BLK_FREE(lheap_chunk, heap->dblk_image))) + H5E_THROW(H5E_CANTFREE, "unable to free local heap data block image"); while(heap->freelist) { H5HL_free_t *fl; fl = heap->freelist; heap->freelist = fl->next; - fl = H5FL_FREE(H5HL_free_t, fl); + if(NULL != (fl = H5FL_FREE(H5HL_free_t, fl))) + H5E_THROW(H5E_CANTFREE, "unable to free local heap free list"); } /* end while */ - heap = H5FL_FREE(H5HL_t, heap); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HL_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5HL_prfx_new - * - * Purpose: Create a new local heap prefix object - * - * Return: Success: non-NULL pointer to new local heap prefix - * Failure: NULL - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 - * - *------------------------------------------------------------------------- - */ -H5HL_prfx_t * -H5HL_prfx_new(H5HL_t *heap) -{ - H5HL_prfx_t *prfx = NULL; /* New local heap prefix */ - H5HL_prfx_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* check arguments */ - HDassert(heap); - - /* Allocate new local heap prefix */ - if(NULL == (prfx = H5FL_CALLOC(H5HL_prfx_t))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed") - - /* Increment ref. count on heap data structure */ - if(H5HL__inc_rc(heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment heap ref. count") - - /* Link the heap & the prefix */ - prfx->heap = heap; - heap->prfx = prfx; - - /* Set the return value */ - ret_value = prfx; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_prfx_new() */ - - -/*------------------------------------------------------------------------- - * Function: H5HL_prfx_dest - * - * Purpose: Destroy a local heap prefix object - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 - * - *------------------------------------------------------------------------- - */ -herr_t -H5HL_prfx_dest(H5HL_prfx_t *prfx) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* check arguments */ - HDassert(prfx); - - /* Check if prefix was initialized */ - if(prfx->heap) { - /* Unlink prefix from heap */ - prfx->heap->prfx = NULL; - - /* Decrement ref. count on heap data structure */ - if(H5HL__dec_rc(prfx->heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement heap ref. count") - - /* Unlink heap from prefix */ - prfx->heap = NULL; - } /* end if */ - - /* Free local heap prefix */ - prfx = H5FL_FREE(H5HL_prfx_t, prfx); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_prfx_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5HL_dblk_new - * - * Purpose: Create a new local heap data block object - * - * Return: Success: non-NULL pointer to new local heap data block - * Failure: NULL - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 - * - *------------------------------------------------------------------------- - */ -H5HL_dblk_t * -H5HL_dblk_new(H5HL_t *heap) -{ - H5HL_dblk_t *dblk = NULL; /* New local heap data block */ - H5HL_dblk_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* check arguments */ - HDassert(heap); - - /* Allocate new local heap data block */ - if(NULL == (dblk = H5FL_CALLOC(H5HL_dblk_t))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed") - - /* Increment ref. count on heap data structure */ - if(H5HL__inc_rc(heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment heap ref. count") - - /* Link the heap & the data block */ - dblk->heap = heap; - heap->dblk = dblk; - - /* Set the return value */ - ret_value = dblk; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_dblk_new() */ - - -/*------------------------------------------------------------------------- - * Function: H5HL_dblk_dest - * - * Purpose: Destroy a local heap data block object - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 12 2008 - * - *------------------------------------------------------------------------- - */ -herr_t -H5HL_dblk_dest(H5HL_dblk_t *dblk) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* check arguments */ - HDassert(dblk); - - /* Check if data block was initialized */ - if(dblk->heap) { - /* Unlink data block from heap */ - dblk->heap->dblk = NULL; - - /* Unpin the local heap prefix */ - if(H5AC_unpin_entry(dblk->heap->prfx) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "can't unpin local heap prefix") - - /* Decrement ref. count on heap data structure */ - if(H5HL__dec_rc(dblk->heap) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement heap ref. count") - - /* Unlink heap from data block */ - dblk->heap = NULL; - } /* end if */ - - /* Free local heap data block */ - dblk = H5FL_FREE(H5HL_dblk_t, dblk); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HL_dblk_dest() */ + + if(NULL != (heap = H5FL_FREE(H5HL_t, heap))) + H5E_THROW(H5E_CANTFREE, "unable to free local heap"); +END_FUNC(PKG) /* end H5HL__dest() */ diff --git a/src/H5HLpkg.h b/src/H5HLpkg.h index 6e35add..fb8667b 100644 --- a/src/H5HLpkg.h +++ b/src/H5HLpkg.h @@ -14,7 +14,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * Programmer: Quincey Koziol <koziol@hdfgroup.org> * Wednesday, July 9, 2003 * * Purpose: This file contains declarations which are visible @@ -32,7 +32,7 @@ #include "H5HLprivate.h" /* Other private headers needed by this file */ -#include "H5FLprivate.h" /* Free lists */ +#include "H5FLprivate.h" /* Free lists */ /*****************************/ @@ -56,16 +56,26 @@ H5FL_BLK_EXTERN(lheap_chunk); /* Package Private Macros */ /**************************/ -#define H5HL_SIZEOF_HDR(F) \ - H5HL_ALIGN(H5_SIZEOF_MAGIC + /*heap signature */ \ - 1 + /*version */ \ - 3 + /*reserved */ \ - H5F_SIZEOF_SIZE(F) + /*data size */ \ - H5F_SIZEOF_SIZE(F) + /*free list head */ \ - H5F_SIZEOF_ADDR(F)) /*data address */ +/* If this package header is being included in one of the H5HL source files, + * define the proper control macros for the generic FUNC_ENTER/LEAVE and + * error reporting macros. + */ +#ifdef H5HL_PACKAGE +#define H5_MY_PKG H5HL +#define H5_MY_PKG_ERR H5E_HEAP +#define H5_MY_PKG_INIT NO +#endif /* H5HL_PACKAGE */ + +#define H5HL_SIZEOF_HDR(F) \ + H5HL_ALIGN(H5_SIZEOF_MAGIC + /* heap signature */ \ + 1 + /* version */ \ + 3 + /* reserved */ \ + H5F_SIZEOF_SIZE(F) + /* data size */ \ + H5F_SIZEOF_SIZE(F) + /* free list head */ \ + H5F_SIZEOF_ADDR(F)) /* data address */ /* Value indicating end of free list on disk */ -#define H5HL_FREE_NULL 1 +#define H5HL_FREE_NULL 1 /****************************/ @@ -73,10 +83,10 @@ H5FL_BLK_EXTERN(lheap_chunk); /****************************/ typedef struct H5HL_free_t { - size_t offset; /*offset of free block */ - size_t size; /*size of free block */ - struct H5HL_free_t *prev; /*previous entry in free list */ - struct H5HL_free_t *next; /*next entry in free list */ + size_t offset; /* offset of free block */ + size_t size; /* size of free block */ + struct H5HL_free_t *prev; /* previous entry in free list */ + struct H5HL_free_t *next; /* next entry in free list */ } H5HL_free_t; /* Forward declarations */ @@ -85,38 +95,38 @@ typedef struct H5HL_prfx_t H5HL_prfx_t; struct H5HL_t { /* General heap-management fields */ - size_t rc; /* Ref. count for prefix & data block using this struct */ - size_t prots; /* # of times the heap has been protected */ - size_t sizeof_size; /* Size of file sizes */ - size_t sizeof_addr; /* Size of file addresses */ - hbool_t single_cache_obj; /* Indicate if the heap is a single object in the cache */ - H5HL_free_t *freelist; /*the free list */ + size_t rc; /* Ref. count for prefix & data block using this struct */ + size_t prots; /* # of times the heap has been protected */ + size_t sizeof_size; /* Size of file sizes */ + size_t sizeof_addr; /* Size of file addresses */ + hbool_t single_cache_obj; /* Indicate if the heap is a single object in the cache */ + H5HL_free_t *freelist; /* the free list */ /* Prefix-specific fields */ - H5HL_prfx_t *prfx; /* The prefix object for the heap */ - haddr_t prfx_addr; /* address of heap prefix */ - size_t prfx_size; /* size of heap prefix */ - hsize_t free_block; /* Address of first free block */ + H5HL_prfx_t *prfx; /* The prefix object for the heap */ + haddr_t prfx_addr; /* address of heap prefix */ + size_t prfx_size; /* size of heap prefix */ + hsize_t free_block; /* Address of first free block */ /* Data block-specific fields */ - H5HL_dblk_t *dblk; /* The data block object for the heap */ - haddr_t dblk_addr; /* address of data block */ - size_t dblk_size; /* size of heap data block on disk and in mem */ - uint8_t *dblk_image; /* The data block image */ + H5HL_dblk_t *dblk; /* The data block object for the heap */ + haddr_t dblk_addr; /* address of data block */ + size_t dblk_size; /* size of heap data block on disk and in mem */ + uint8_t *dblk_image; /* The data block image */ }; /* Struct for heap data block */ struct H5HL_dblk_t { - H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ - /* first field in structure */ - H5HL_t *heap; /* Pointer to heap for data block */ + H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ + /* first field in structure */ + H5HL_t *heap; /* Pointer to heap for data block */ }; /* Struct for heap prefix */ struct H5HL_prfx_t { - H5AC_info_t cache_info; /* Information for H5AC cache functions, */ - /* _must_ be first field in structure */ - H5HL_t *heap; /* Pointer to heap for prefix */ + H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ + /* first field in structure */ + H5HL_t *heap; /* Pointer to heap for prefix */ }; /* Callback information for loading local heap prefix from disk */ @@ -137,10 +147,10 @@ typedef struct H5HL_cache_prfx_ud_t { /* Callback information for loading local heap data block from disk */ typedef struct H5HL_cache_dblk_ud_t { /* Downwards */ - H5HL_t *heap; /* Local heap */ + H5HL_t *heap; /* Local heap */ /* Upwards */ - hbool_t loaded; /* Whether data block was loaded from file */ + hbool_t loaded; /* Whether data block was loaded from file */ } H5HL_cache_dblk_ud_t; @@ -149,16 +159,18 @@ typedef struct H5HL_cache_dblk_ud_t { /******************************/ /* Heap routines */ -H5_DLL H5HL_t *H5HL_new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size); -H5_DLL herr_t H5HL_dest(H5HL_t *heap); +H5_DLL H5HL_t *H5HL__new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size); +H5_DLL herr_t H5HL__dest(H5HL_t *heap); +H5_DLL herr_t H5HL__inc_rc(H5HL_t *heap); +H5_DLL herr_t H5HL__dec_rc(H5HL_t *heap); /* Heap prefix routines */ -H5_DLL H5HL_prfx_t *H5HL_prfx_new(H5HL_t *heap); -H5_DLL herr_t H5HL_prfx_dest(H5HL_prfx_t *prfx); +H5_DLL H5HL_prfx_t *H5HL__prfx_new(H5HL_t *heap); +H5_DLL herr_t H5HL__prfx_dest(H5HL_prfx_t *prfx); /* Heap data block routines */ -H5_DLL H5HL_dblk_t *H5HL_dblk_new(H5HL_t *heap); -H5_DLL herr_t H5HL_dblk_dest(H5HL_dblk_t *dblk); +H5_DLL H5HL_dblk_t *H5HL__dblk_new(H5HL_t *heap); +H5_DLL herr_t H5HL__dblk_dest(H5HL_dblk_t *dblk); +H5_DLL herr_t H5HL__dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size); #endif /* _H5HLpkg_H */ - diff --git a/src/H5HLprfx.c b/src/H5HLprfx.c new file mode 100644 index 0000000..66c4dad --- /dev/null +++ b/src/H5HLprfx.c @@ -0,0 +1,166 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5HLprfx.c + * Summer 2012 + * Dana Robinson <derobins@hdfgroup.org> + * + * Purpose: Prefix routines for local heaps. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5HLmodule.h" /* This source code file is part of the H5HL module */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5HLpkg.h" /* Local Heaps */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5HL_prfx_t struct */ +H5FL_DEFINE_STATIC(H5HL_prfx_t); + + + +/*------------------------------------------------------------------------- + * Function: H5HL__prfx_new + * + * Purpose: Create a new local heap prefix object + * + * Return: Success: non-NULL pointer to new local heap prefix + * Failure: NULL + * + * Programmer: Quincey Koziol + * Oct 12 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5HL_prfx_t *, NULL, NULL, +H5HL__prfx_new(H5HL_t *heap)) + + H5HL_prfx_t *prfx = NULL; /* New local heap prefix */ + + /* check arguments */ + HDassert(heap); + + /* Allocate new local heap prefix */ + if(NULL == (prfx = H5FL_CALLOC(H5HL_prfx_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for local heap prefix") + + /* Increment ref. count on heap data structure */ + if(FAIL == H5HL__inc_rc(heap)) + H5E_THROW(H5E_CANTINC, "can't increment heap ref. count") + + /* Link the heap & the prefix */ + prfx->heap = heap; + heap->prfx = prfx; + + /* Set the return value */ + ret_value = prfx; + +CATCH + /* Ensure that the prefix memory is deallocated on errors */ + if(!ret_value && prfx != NULL) { + /* H5FL_FREE always returns NULL so we can't check for errors */ + prfx = H5FL_FREE(H5HL_prfx_t, prfx); + } + +END_FUNC(PKG) /* end H5HL__prfx_new() */ + + +/*------------------------------------------------------------------------- + * Function: H5HL__prfx_dest + * + * Purpose: Destroy a local heap prefix object + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Oct 12 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5HL__prfx_dest(H5HL_prfx_t *prfx)) + + /* check arguments */ + HDassert(prfx); + + /* Check if prefix was initialized */ + if(prfx->heap) { + /* Unlink prefix from heap */ + prfx->heap->prfx = NULL; + + /* Decrement ref. count on heap data structure */ + if(FAIL == H5HL__dec_rc(prfx->heap)) + H5E_THROW(H5E_CANTDEC, "can't decrement heap ref. count") + + /* Unlink heap from prefix */ + prfx->heap = NULL; + } /* end if */ + +CATCH + /* Free prefix memory */ + /* H5FL_FREE always returns NULL so we can't check for errors */ + prfx = H5FL_FREE(H5HL_prfx_t, prfx); + +END_FUNC(PKG) /* end H5HL__prfx_dest() */ diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h index 3035689..e2bf29c 100644 --- a/src/H5HLprivate.h +++ b/src/H5HLprivate.h @@ -15,13 +15,11 @@ /*------------------------------------------------------------------------- * - * Created: H5HLprivate.h - * Jul 16 1997 - * Robb Matzke <matzke@llnl.gov> + * Created: H5HLprivate.h + * Jul 16 1997 + * Robb Matzke <matzke@llnl.gov> * - * Purpose: - * - * Modifications: + * Purpose: Private declarations for the H5HL (local heap) package. * *------------------------------------------------------------------------- */ @@ -32,23 +30,23 @@ #include "H5HLpublic.h" /* Private headers needed by this file. */ -#include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ -#include "H5Fprivate.h" /* File access */ +#include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5Fprivate.h" /* File access */ /* * Feature: Define H5HL_DEBUG on the compiler command line if you want to - * diagnostic messages from this layer. + * enable diagnostic messages from this layer. */ #ifdef NDEBUG # undef H5HL_DEBUG #endif -#define H5HL_ALIGN(X) ((((unsigned)X)+7)&(unsigned)(~0x07)) /*align on 8-byte boundary */ +#define H5HL_ALIGN(X) ((((unsigned)X)+7)&(unsigned)(~0x07)) /* align on 8-byte boundary */ -#define H5HL_SIZEOF_FREE(F) \ - H5HL_ALIGN(H5F_SIZEOF_SIZE (F) + /*ptr to next free block */ \ - H5F_SIZEOF_SIZE (F)) /*size of this free block */ +#define H5HL_SIZEOF_FREE(F) \ + H5HL_ALIGN(H5F_SIZEOF_SIZE (F) + /* ptr to next free block */ \ + H5F_SIZEOF_SIZE (F)) /* size of this free block */ /****************************/ /* Library Private Typedefs */ @@ -58,22 +56,23 @@ typedef struct H5HL_t H5HL_t; /* - * Library prototypes... + * 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 H5HL_t *H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, unsigned flags); +H5_DLL herr_t H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); +H5_DLL herr_t H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size); +H5_DLL herr_t H5HL_heapsize(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t *heap_size); +H5_DLL size_t H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t size, + const void *buf); H5_DLL void *H5HL_offset_into(const H5HL_t *heap, size_t offset); +H5_DLL H5HL_t *H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, unsigned flags); H5_DLL herr_t H5HL_remove(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t offset, size_t size); H5_DLL herr_t H5HL_unprotect(H5HL_t *heap); -H5_DLL size_t H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t size, - const void *buf); -H5_DLL herr_t H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); -H5_DLL herr_t H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size); -H5_DLL herr_t H5HL_heapsize(H5F_t *f, hid_t dxpl_id, haddr_t addr, hsize_t *heap_size); -/* Debugging functions */ +/* Debugging routines for dumping file structures */ H5_DLL herr_t H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, - int fwidth); + int fwidth); + #endif diff --git a/src/H5HLpublic.h b/src/H5HLpublic.h index db00f51..6dc1828 100644 --- a/src/H5HLpublic.h +++ b/src/H5HLpublic.h @@ -21,8 +21,6 @@ * * Purpose: Public declarations for the H5HL (local heap) package. * - * Modifications: - * *------------------------------------------------------------------------- */ #ifndef _H5HLpublic_H diff --git a/src/Makefile.am b/src/Makefile.am index 86dad23..d6a5909 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -73,7 +73,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ H5HG.c H5HGcache.c H5HGdbg.c H5HGquery.c \ - H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c \ + H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c H5HLprfx.c H5HLdblk.c\ H5HP.c H5I.c H5Itest.c H5L.c H5Lexternal.c H5lib_settings.c \ H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \ H5MM.c H5MP.c H5MPtest.c \ |