summaryrefslogtreecommitdiffstats
path: root/src/H5HLcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5HLcache.c')
-rw-r--r--src/H5HLcache.c648
1 files changed, 648 insertions, 0 deletions
diff --git a/src/H5HLcache.c b/src/H5HLcache.c
new file mode 100644
index 0000000..fef4340
--- /dev/null
+++ b/src/H5HLcache.c
@@ -0,0 +1,648 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5HLcache.c
+ * Jul 23 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Local heap metadata cache callbacks.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5HL_PACKAGE /* Suppress error about including H5HLpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5HLpkg.h" /* Local Heaps */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Local heap format version */
+#define H5HL_VERSION 0
+
+/* Value indicating end of free list on disk */
+#define H5HL_FREE_NULL 1
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Metadata cache callbacks */
+static void *H5HL_prfx_deserialize(haddr_t addr, size_t len, const void *image,
+ void *udata, hbool_t *dirty);
+static herr_t H5HL_prfx_image_len(const void *thing, size_t *image_len_ptr);
+static herr_t H5HL_prfx_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len,
+ void *image, void *thing, unsigned *flags, haddr_t *new_addr,
+ size_t *new_len, void **new_image);
+static herr_t H5HL_prfx_free_icr(haddr_t addr, size_t len, void *thing);
+
+static void *H5HL_dblk_deserialize(haddr_t addr, size_t len, const void *image,
+ void *udata, hbool_t *dirty);
+static herr_t H5HL_dblk_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len,
+ void *image, void *thing, unsigned *flags, haddr_t *new_addr,
+ size_t *new_len, void **new_image);
+static herr_t H5HL_dblk_free_icr(haddr_t addr, size_t len, void *thing);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*
+ * H5HL prefix inherits cache-like properties from H5AC2
+ */
+const H5AC2_class_t H5AC2_LHEAP_PRFX[1] = {{
+ H5AC2_LHEAP_PRFX_ID,
+ "local heap prefix",
+ H5FD_MEM_LHEAP,
+ H5HL_prfx_deserialize,
+ H5HL_prfx_image_len,
+ H5HL_prfx_serialize,
+ H5HL_prfx_free_icr,
+ NULL,
+}};
+
+/*
+ * H5HL data block inherits cache-like properties from H5AC2
+ */
+const H5AC2_class_t H5AC2_LHEAP_DBLK[1] = {{
+ H5AC2_LHEAP_DBLK_ID,
+ "local heap data block",
+ H5FD_MEM_LHEAP,
+ H5HL_dblk_deserialize,
+ NULL,
+ H5HL_dblk_serialize,
+ H5HL_dblk_free_icr,
+ NULL,
+}};
+
+/* Declare a free list to manage the H5HL_free_t struct */
+H5FL_EXTERN(H5HL_free_t);
+
+/* Declare a free list to manage the H5HL_t struct */
+H5FL_EXTERN(H5HL_t);
+
+/* Declare a PQ free list to manage the heap chunk information */
+H5FL_BLK_EXTERN(lheap_chunk);
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_fl_deserialize
+ *
+ * Purpose: Deserialize the free list for a heap data block
+ *
+ * Return: Success: SUCCESS
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 12 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_fl_deserialize(const H5F_t *f, H5HL_t *heap, hsize_t free_block)
+{
+ H5HL_free_t *fl, *tail = NULL; /* Heap free block nodes */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HL_fl_deserialize)
+
+ /* check arguments */
+ HDassert(heap);
+
+ /* Build free list */
+ while(H5HL_FREE_NULL != free_block) {
+ const uint8_t *p; /* Pointer into image buffer */
+
+ /* Sanity check */
+ if(free_block >= heap->dblk_size)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "bad heap free list")
+
+ /* Allocate & initialize free list node */
+ if(NULL == (fl = H5FL_MALLOC(H5HL_free_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ fl->offset = (size_t)free_block;
+ fl->prev = tail;
+ fl->next = NULL;
+
+ /* Insert node into list */
+ if(tail)
+ tail->next = fl;
+ tail = fl;
+ if(!heap->freelist)
+ heap->freelist = fl;
+
+ /* Decode offset of next free block */
+ p = heap->image + free_block;
+ H5F_DECODE_LENGTH(f, p, free_block);
+ if(free_block == 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "free block size is zero?")
+
+ /* Decode length of this free block */
+ H5F_DECODE_LENGTH(f, p, fl->size);
+ if(fl->offset + fl->size > heap->dblk_size)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "bad heap free list")
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_fl_deserialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_fl_serialize
+ *
+ * Purpose: Serialize the free list for a heap data block
+ *
+ * Return: Success: SUCCESS
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 12 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+H5HL_fl_serialize(const H5F_t *f, H5HL_t *heap)
+{
+ H5HL_free_t *fl; /* Pointer to heap free list node */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_fl_serialize)
+
+ /* check arguments */
+ HDassert(heap);
+
+ /* Serialize the free list into the heap data's image */
+ for(fl = heap->freelist; fl; fl = fl->next) {
+ uint8_t *p; /* Pointer into raw data buffer */
+
+ HDassert(fl->offset == H5HL_ALIGN(fl->offset));
+ p = heap->image + fl->offset;
+
+ if(fl->next)
+ H5F_ENCODE_LENGTH(f, p, fl->next->offset)
+ else
+ H5F_ENCODE_LENGTH(f, p, H5HL_FREE_NULL)
+
+ H5F_ENCODE_LENGTH(f, p, fl->size);
+ } /* end for */
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5HL_fl_serialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_prfx_deserialize
+ *
+ * Purpose: Deserialize the data structure from disk.
+ *
+ * Return: Success: SUCCESS
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5HL_prfx_deserialize(haddr_t addr, size_t len, const void *image,
+ void *_udata, hbool_t UNUSED *dirty)
+{
+ H5HL_t *heap = NULL; /* Local heap */
+ H5HL_prfx_t *prfx = NULL; /* Heap prefix deserialized */
+ H5HL_cache_prfx_ud_t *udata = (H5HL_cache_prfx_ud_t *)_udata; /* User data for callback */
+ const uint8_t *p; /* Pointer into image buffer */
+ H5HL_prfx_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HL_prfx_deserialize)
+
+ /* check arguments */
+ HDassert(H5F_addr_defined(addr));
+ HDassert(len > 0);
+ HDassert(image);
+ HDassert(udata);
+ HDassert(udata->f);
+
+ /* Point to beginning of image buffer */
+ p = (const uint8_t *)image;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5HL_MAGIC, (size_t)H5HL_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad local heap signature")
+ p += H5HL_SIZEOF_MAGIC;
+
+ /* Version */
+ if(H5HL_VERSION != *p++)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in local heap")
+
+ /* Reserved */
+ p += 3;
+
+ /* Allocate space in memory for the heap */
+ if(NULL == (heap = H5FL_CALLOC(H5HL_t)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed")
+
+ /* Allocate the heap prefix */
+ if(NULL == (prfx = H5HL_prfx_new(heap)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed")
+
+ /* Store the prefix's address & length */
+ heap->prfx_addr = addr;
+ heap->prfx_size = H5HL_SIZEOF_HDR(udata->f);
+
+ /* Heap data size */
+ H5F_DECODE_LENGTH(udata->f, p, heap->dblk_size);
+
+ /* Free list head */
+ H5F_DECODE_LENGTH(udata->f, p, udata->free_block);
+ if(udata->free_block != H5HL_FREE_NULL && udata->free_block >= heap->dblk_size)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
+
+ /* Heap data address */
+ H5F_addr_decode(udata->f, &p, &(heap->dblk_addr));
+
+ /* Check if heap block exists */
+ if(heap->dblk_size) {
+ /* Check if heap data block is contiguous with header */
+ if(H5F_addr_eq((heap->prfx_addr + heap->prfx_size), heap->dblk_addr)) {
+ /* Note that the heap should be a single object in the cache */
+ heap->single_cache_obj = TRUE;
+
+ /* Check if the current image from the cache is big enough to hold the heap data */
+ if(len >= (heap->prfx_size + heap->dblk_size)) {
+ /* Allocate space for the heap data image */
+ if(NULL == (heap->image = H5FL_BLK_MALLOC(lheap_chunk, heap->dblk_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed")
+
+ /* Copy the heap data from the image */
+ HDmemcpy(heap->image, p, heap->dblk_size);
+
+ /* Build free list */
+ if(H5HL_fl_deserialize(udata->f, heap, udata->free_block) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't initialize free list")
+ } /* end if */
+ else
+ /* Make certain the length was OK on the retry */
+ HDassert(!udata->made_attempt);
+
+ /* Note that we've made one attempt at decoding the local heap already */
+ /* (useful when the length is incorrect and the cache will retry with a larger one) */
+ udata->made_attempt = TRUE;
+ } /* end if */
+ else
+ /* Note that the heap should _NOT_ be a single object in the cache */
+ heap->single_cache_obj = FALSE;
+ } /* end if */
+
+ /* Set flag to indicate prefix from loaded from file */
+ udata->loaded = TRUE;
+
+ /* Set return value */
+ ret_value = prfx;
+
+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")
+ } /* end if */
+ else {
+ if(heap && H5HL_dest(heap) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to destroy local heap")
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_prfx_deserialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_prfx_image_len
+ *
+ * Purpose: Tell the metadata cache about the actual size of the object
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_prfx_image_len(const void *thing, size_t *image_len_ptr)
+{
+ const H5HL_prfx_t *prfx = (const H5HL_prfx_t *)thing; /* The local heap prefix */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_prfx_image_len)
+
+ /* Check arguments */
+ HDassert(prfx);
+ HDassert(prfx->heap);
+ HDassert(image_len_ptr);
+
+ /* Report the local heap's size, including the data block, if it's contiguous w/prefix */
+ if(prfx->heap->single_cache_obj)
+ *image_len_ptr = prfx->heap->prfx_size + prfx->heap->dblk_size;
+ else
+ *image_len_ptr = prfx->heap->prfx_size;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HL_prfx_image_len() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_prfx_serialize
+ *
+ * Purpose: Serializes a 'in core' representation of data structure
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_prfx_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr,
+ size_t UNUSED len, void *image, void *_thing, unsigned *flags,
+ haddr_t UNUSED *new_addr, size_t UNUSED *new_len, void UNUSED **new_image)
+{
+ H5HL_prfx_t *prfx = (H5HL_prfx_t *)_thing; /* Pointer to the local heap prefix */
+ H5HL_t *heap; /* Pointer to the local heap */
+ uint8_t *p; /* Pointer into raw data buffer */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_prfx_serialize)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(image);
+ HDassert(prfx);
+ HDassert(prfx->heap);
+ HDassert(flags);
+
+ /* Get the pointer to the heap */
+ heap = prfx->heap;
+
+ /* Point to the cache image */
+ p = (uint8_t *)image;
+
+ /* Serialize the header */
+ HDmemcpy(p, H5HL_MAGIC, (size_t)H5HL_SIZEOF_MAGIC);
+ p += H5HL_SIZEOF_MAGIC;
+ *p++ = H5HL_VERSION;
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+ H5F_ENCODE_LENGTH(f, p, heap->dblk_size);
+ H5F_ENCODE_LENGTH(f, p, heap->freelist ? heap->freelist->offset : H5HL_FREE_NULL);
+ H5F_addr_encode(f, &p, heap->dblk_addr);
+
+ /* Check if the local heap is a single object in cache */
+ if(heap->single_cache_obj) {
+ /* Serialize the free list into the heap data's image */
+ H5HL_fl_serialize(f, heap);
+
+ /* Copy the heap data block into the cache image */
+ HDmemcpy(p, heap->image, heap->dblk_size);
+ } /* end if */
+
+ /* Reset the cache flags for this operation */
+ *flags = 0;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5HL_prfx_serialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_prfx_free_icr
+ *
+ * Purpose: Destroy/release an "in core representation" of a data
+ * structure
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * October 11, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_prfx_free_icr(haddr_t UNUSED addr, size_t UNUSED len, void *thing)
+{
+ H5HL_prfx_t *prfx = (H5HL_prfx_t *)thing; /* Local heap prefix to destroy */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HL_prfx_free_icr)
+
+ /* Check arguments */
+ HDassert(prfx);
+
+ /* Destroy local heap prefix */
+ if(H5HL_prfx_dest(prfx) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't destroy local heap prefix")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HL_prfx_free_icr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_dblk_deserialize
+ *
+ * Purpose: Deserialize the data structure from disk.
+ *
+ * Return: Success: SUCCESS
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 12 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5HL_dblk_deserialize(haddr_t UNUSED addr, size_t UNUSED len, const void *image,
+ void *_udata, hbool_t UNUSED *dirty)
+{
+ H5HL_dblk_t *dblk = NULL; /* Local heap data block deserialized */
+ H5HL_cache_dblk_ud_t *udata = (H5HL_cache_dblk_ud_t *)_udata; /* User data for callback */
+ H5HL_dblk_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HL_dblk_deserialize)
+
+ /* check arguments */
+ HDassert(image);
+ HDassert(udata);
+ HDassert(udata->f);
+ HDassert(udata->heap);
+ HDassert(!udata->heap->single_cache_obj);
+ HDassert(NULL == udata->heap->dblk);
+
+ /* 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")
+
+ /* Check for heap still retaining image */
+ if(NULL == udata->heap->image) {
+ /* Allocate space for the heap data image */
+ if(NULL == (udata->heap->image = H5FL_BLK_MALLOC(lheap_chunk, udata->heap->dblk_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed")
+
+ /* Copy the cache image into the heap's data image */
+ HDmemcpy(udata->heap->image, image, udata->heap->dblk_size);
+
+ /* Build free list */
+ if(H5HL_fl_deserialize(udata->f, udata->heap, udata->free_block) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't initialize free list")
+ } /* end if */
+
+ /* Set flag to indicate data block from loaded from file */
+ udata->loaded = TRUE;
+
+ /* Set return value */
+ ret_value = dblk;
+
+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")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_dblk_deserialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_dblk_serialize
+ *
+ * Purpose: Serializes a 'in core' representation of data structure
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 12 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_dblk_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr,
+ size_t UNUSED len, void *image, void *_thing, unsigned *flags,
+ haddr_t UNUSED *new_addr, size_t UNUSED *new_len, void UNUSED **new_image)
+{
+ H5HL_dblk_t *dblk = (H5HL_dblk_t *)_thing; /* Pointer to the local heap data block */
+ H5HL_t *heap; /* Pointer to the local heap */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_dblk_serialize)
+
+ /* check arguments */
+ HDassert(image);
+ HDassert(dblk);
+ HDassert(flags);
+
+ /* Get the pointer to the heap */
+ heap = dblk->heap;
+
+ /* Serialize the free list into the heap data's image */
+ H5HL_fl_serialize(f, heap);
+
+ /* Copy the heap's data block into the cache's image */
+ HDmemcpy(image, heap->image, heap->dblk_size);
+
+ /* Reset the cache flags for this operation */
+ *flags = 0;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5HL_dblk_serialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_dblk_free_icr
+ *
+ * Purpose: Destroy/release an "in core representation" of a data
+ * structure
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * October 12, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HL_dblk_free_icr(haddr_t UNUSED addr, size_t UNUSED len, void *thing)
+{
+ H5HL_dblk_t *dblk = (H5HL_dblk_t *)thing; /* Local heap data block to destroy */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HL_dblk_free_icr)
+
+ /* Check arguments */
+ HDassert(dblk);
+
+ /* Destroy local heap data block */
+ if(H5HL_dblk_dest(dblk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "unable to destroy local heap data block")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HL_dblk_free_icr() */
+