summaryrefslogtreecommitdiffstats
path: root/src/H5Distore.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-07-09 02:06:29 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-07-09 02:06:29 (GMT)
commitfe76fb1b580aa99fa26ccb26da88ce7e16b35a84 (patch)
treeb90b9832ec612a2d7efead8c6bea6c767edc5b15 /src/H5Distore.c
parentd5c705a642a1ed06fa8dcaa25b61aa75687799d2 (diff)
downloadhdf5-fe76fb1b580aa99fa26ccb26da88ce7e16b35a84.zip
hdf5-fe76fb1b580aa99fa26ccb26da88ce7e16b35a84.tar.gz
hdf5-fe76fb1b580aa99fa26ccb26da88ce7e16b35a84.tar.bz2
[svn-r8844] Purpose:
Bug fix Description: The "shared" raw B-tree node can get freed before all the B-tree nodes had been flushed out to disk and released by the cache. Solution: Implement a simple reference counting wrapper for objects in the library and use it to hold the shared raw B-tree nodes so they aren't freed before all references to them in memory are released. Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.10 (sleipnir) IRIX64 6.5 (modei4)
Diffstat (limited to 'src/H5Distore.c')
-rw-r--r--src/H5Distore.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 0bab89d..09c025c 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -146,6 +146,7 @@ static haddr_t H5D_istore_get_addr(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *
const hssize_t offset[], H5D_istore_ud1_t *_udata);
static void *H5D_istore_chunk_alloc(size_t size, const H5O_pline_t *pline);
static void *H5D_istore_chunk_xfree(void *chk, const H5O_pline_t *pline);
+static herr_t H5D_istore_page_free (void *page);
/* B-tree iterator callbacks */
static int H5D_istore_iter_allocated(H5F_t *f, hid_t dxpl_id, void *left_key, haddr_t addr,
@@ -278,9 +279,13 @@ H5D_istore_get_page(H5F_t UNUSED *f, const void *_udata)
assert(udata);
assert(udata->mesg);
- assert(udata->mesg->u.chunk.raw_page);
+ assert(udata->mesg->u.chunk.rc_page);
- FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.raw_page);
+ /* Increment reference count on B-tree node */
+ H5RC_INC(udata->mesg->u.chunk.rc_page);
+
+ /* Get the pointer to the ref-count object */
+ FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.rc_page);
} /* end H5D_istore_get_page() */
@@ -898,6 +903,7 @@ H5D_istore_init (H5F_t *f, H5D_t *dset)
size_t sizeof_rkey; /* Single raw key size */
size_t size; /* Raw B-tree node size */
H5D_rdcc_t *rdcc = &(dset->cache.chunk);
+ void *page; /* Buffer for raw B-tree node */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_init, FAIL);
@@ -919,9 +925,13 @@ H5D_istore_init (H5F_t *f, H5D_t *dset)
assert(sizeof_rkey);
size = H5B_nodesize(f, H5B_ISTORE, NULL, sizeof_rkey);
assert(size);
- if(NULL==(dset->layout.u.chunk.raw_page=H5FL_BLK_MALLOC(chunk_page,size)))
+ if(NULL==(page=H5FL_BLK_MALLOC(chunk_page,size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page")
+ /* Make page buffer reference counted */
+ if(NULL==(dset->layout.u.chunk.rc_page=H5RC_create(page,H5D_istore_page_free)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for page")
+
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_istore_init() */
@@ -1217,7 +1227,8 @@ H5D_istore_dest (H5F_t *f, hid_t dxpl_id, H5D_t *dset)
HDmemset (rdcc, 0, sizeof(H5D_rdcc_t));
/* Free the raw B-tree node buffer */
- H5FL_BLK_FREE(chunk_page,dset->layout.u.chunk.raw_page);
+ if(H5RC_DEC(dset->layout.u.chunk.rc_page)<0)
+ HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page");
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1225,6 +1236,31 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_page_free
+ *
+ * Purpose: Free a B-tree node
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, July 8, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_istore_page_free (void *page)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_page_free)
+
+ H5FL_BLK_FREE(chunk_page,page);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5D_istore_page_free() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_prune
*
* Purpose: Prune the cache by preempting some things until the cache has