summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2012-07-05 21:14:37 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2012-07-05 21:14:37 (GMT)
commit35f98ad8b6612eb76e1f8d01ee42dd6527a82c48 (patch)
tree1bd8aaaaaffe39feb38bae0c7363119c77e58b0a
parentce0496520836aef9fdea54fc01d5d92fe8f43b77 (diff)
downloadhdf5-35f98ad8b6612eb76e1f8d01ee42dd6527a82c48.zip
hdf5-35f98ad8b6612eb76e1f8d01ee42dd6527a82c48.tar.gz
hdf5-35f98ad8b6612eb76e1f8d01ee42dd6527a82c48.tar.bz2
[svn-r22518] Added flush dependencies for SWMR to the local heap code.
Tested on jam. This branch still has h5diff errors. The library tests all pass, though.
-rw-r--r--src/H5HL.c62
-rw-r--r--src/H5HLcache.c151
-rw-r--r--src/H5HLint.c64
-rw-r--r--src/H5HLpkg.h19
-rw-r--r--src/H5HLprivate.h2
5 files changed, 259 insertions, 39 deletions
diff --git a/src/H5HL.c b/src/H5HL.c
index 3f1047c..76a6499 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -1083,3 +1083,65 @@ CATCH
H5E_THROW(H5E_CANTUNPROTECT, "unable to release local heap prefix");
END_FUNC(PRIV) /* end H5HL_heapsize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_depend
+ *
+ * Purpose: Create a child flush dependency between the local heap
+ * and another piece of metadata in the file.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Dana Robinson
+ * derobins@hdfgroup.org
+ * Fall 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5HL_depend(H5AC_info_t *parent_entry, H5HL_t *heap))
+
+ /* Check arguments */
+ HDassert(heap);
+
+ /* Set up a flush dependency between the parent entry and the local heap */
+ if(FAIL == H5HL__create_flush_depend(parent_entry, (H5AC_info_t *)heap))
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency on file metadata");
+
+CATCH
+ /* No special processing on errors */
+END_FUNC(PRIV) /* end H5HL_depend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_undepend
+ *
+ * Purpose: Remove a child flush dependency between the local heap and
+ * another piece of metadata in the file.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Dana Robinson
+ * derobins@hdfgroup.org
+ * Fall 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5HL_undepend(H5AC_info_t *parent_entry, H5HL_t *heap))
+
+ /* Check arguments */
+ HDassert(heap);
+
+ /* Remove a flush dependency between the parent entry and the local heap */
+ if(FAIL == H5HL__destroy_flush_depend(parent_entry, (H5AC_info_t *)heap))
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency on file metadata");
+
+CATCH
+ /* No special processing on errors */
+END_FUNC(PRIV) /* end H5HL_undepend() */
diff --git a/src/H5HLcache.c b/src/H5HLcache.c
index a27e092..5576e6b 100644
--- a/src/H5HLcache.c
+++ b/src/H5HLcache.c
@@ -73,18 +73,20 @@
/* Local heap prefix */
static H5HL_prfx_t *H5HL__prefix_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
static herr_t H5HL__prefix_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
- void *thing, unsigned *flags_ptr);
-static herr_t H5HL__prefix_dest(H5F_t *f, void *thing);
-static herr_t H5HL__prefix_clear(H5F_t *f, void *thing, hbool_t destroy);
-static herr_t H5HL__prefix_size(const H5F_t *f, const void *thing, size_t *size_ptr);
+ H5HL_prfx_t *prfx, unsigned *flags_ptr);
+static herr_t H5HL__prefix_dest(H5F_t *f, H5HL_prfx_t *prfx);
+static herr_t H5HL__prefix_clear(H5F_t *f, H5HL_prfx_t *prfx, hbool_t destroy);
+static herr_t H5HL__prefix_notify(H5AC_notify_action_t action, H5HL_prfx_t *prfx);
+static herr_t H5HL__prefix_size(const H5F_t *f, H5HL_prfx_t *prfx, size_t *size_ptr);
/* Local heap data block */
static H5HL_dblk_t *H5HL__datablock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
static herr_t H5HL__datablock_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
- void *thing, unsigned *flags_ptr);
-static herr_t H5HL__datablock_dest(H5F_t *f, void *thing);
-static herr_t H5HL__datablock_clear(H5F_t *f, void *thing, hbool_t destroy);
-static herr_t H5HL__datablock_size(const H5F_t *f, const void *thing, size_t *size_ptr);
+ H5HL_dblk_t *dblk, unsigned *flags_ptr);
+static herr_t H5HL__datablock_dest(H5F_t *f, H5HL_dblk_t *dblk);
+static herr_t H5HL__datablock_clear(H5F_t *f, H5HL_dblk_t *dblk, hbool_t destroy);
+static herr_t H5HL__datablock_notify(H5AC_notify_action_t action, H5HL_dblk_t *dblk);
+static herr_t H5HL__datablock_size(const H5F_t *f, H5HL_dblk_t *dblk, size_t *size_ptr);
/* Free list de/serialization */
static herr_t H5HL__fl_deserialize(H5HL_t *heap);
@@ -101,7 +103,7 @@ const H5AC_class_t H5AC_LHEAP_PRFX[1] = {{
(H5AC_flush_func_t) H5HL__prefix_flush,
(H5AC_dest_func_t) H5HL__prefix_dest,
(H5AC_clear_func_t) H5HL__prefix_clear,
- (H5AC_notify_func_t) NULL,
+ (H5AC_notify_func_t) H5HL__prefix_notify,
(H5AC_size_func_t) H5HL__prefix_size,
}};
@@ -111,7 +113,7 @@ const H5AC_class_t H5AC_LHEAP_DBLK[1] = {{
(H5AC_flush_func_t) H5HL__datablock_flush,
(H5AC_dest_func_t) H5HL__datablock_dest,
(H5AC_clear_func_t) H5HL__datablock_clear,
- (H5AC_notify_func_t) NULL,
+ (H5AC_notify_func_t) H5HL__datablock_notify,
(H5AC_size_func_t) H5HL__datablock_size,
}};
@@ -391,9 +393,8 @@ END_FUNC(STATIC) /* end H5HL__prefix_load() */
BEGIN_FUNC(STATIC, ERR,
herr_t, SUCCEED, FAIL,
H5HL__prefix_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
- void *thing, unsigned UNUSED *flags_ptr))
+ H5HL_prfx_t *prfx, unsigned UNUSED *flags_ptr))
- H5HL_prfx_t *prfx = (H5HL_prfx_t *)thing; /* Local heap prefix to flush */
H5WB_t *wb = NULL; /* Wrapped buffer for heap data */
uint8_t heap_buf[H5HL_SPEC_READ_SIZE]; /* Buffer for heap */
@@ -493,9 +494,7 @@ END_FUNC(STATIC) /* end H5HL__prefix_flush() */
*/
BEGIN_FUNC(STATIC, ERR,
herr_t, SUCCEED, FAIL,
-H5HL__prefix_dest(H5F_t *f, void *thing))
-
- H5HL_prfx_t *prfx = (H5HL_prfx_t *)thing; /* Local heap prefix to destroy */
+H5HL__prefix_dest(H5F_t *f, H5HL_prfx_t *prfx))
/* check arguments */
HDassert(prfx);
@@ -549,9 +548,7 @@ END_FUNC(STATIC) /* end H5HL__prefix_dest() */
*/
BEGIN_FUNC(STATIC, ERR,
herr_t, SUCCEED, FAIL,
-H5HL__prefix_clear(H5F_t UNUSED *f, void *thing, hbool_t destroy))
-
- H5HL_prfx_t *prfx = (H5HL_prfx_t *)thing; /* The local heap prefix to operate on */
+H5HL__prefix_clear(H5F_t UNUSED *f, H5HL_prfx_t *prfx, hbool_t destroy))
/* check arguments */
HDassert(prfx);
@@ -570,6 +567,52 @@ END_FUNC(STATIC) /* end H5HL__prefix_clear() */
/*-------------------------------------------------------------------------
+ * Function: H5HL__prefix_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Dana Robinson
+ * derobins@hdfgroup.org
+ * Fall 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5HL__prefix_notify(H5AC_notify_action_t action, H5HL_prfx_t *prfx))
+
+ /* Sanity check */
+ HDassert(prfx);
+
+ /* Check if the file was opened with SWMR-write access */
+ if(prfx->heap->swmr_write) {
+ /* Determine which action to take */
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on child */
+ if(FAIL == H5HL__destroy_flush_depend((H5AC_info_t *)prfx, (H5AC_info_t *)prfx->heap->dblk))
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between prefix and data block, address of prefix = %llu", (unsigned long long)prfx->heap->prfx_addr);
+ break;
+
+ default:
+#ifdef NDEBUG
+ H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache");
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+ } /* end if */
+
+CATCH
+ /* No special processing on errors */
+
+END_FUNC(STATIC) /* end H5HL__prefix_notify() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HL__prefix_size
*
* Purpose: Compute the size in bytes of the heap prefix on disk,
@@ -586,9 +629,7 @@ END_FUNC(STATIC) /* end H5HL__prefix_clear() */
*/
BEGIN_FUNC(STATIC, NOERR,
herr_t, SUCCEED, -,
-H5HL__prefix_size(const H5F_t UNUSED *f, const void *thing, size_t *size_ptr))
-
- const H5HL_prfx_t *prfx = (const H5HL_prfx_t *)thing; /* Pointer to local heap prefix to query */
+H5HL__prefix_size(const H5F_t UNUSED *f, H5HL_prfx_t *prfx, size_t *size_ptr))
/* check arguments */
HDassert(prfx);
@@ -687,9 +728,7 @@ END_FUNC(STATIC) /* end H5HL__datablock_load() */
BEGIN_FUNC(STATIC, ERR,
herr_t, SUCCEED, FAIL,
H5HL__datablock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
- void *_thing, unsigned UNUSED * flags_ptr))
-
- H5HL_dblk_t *dblk = (H5HL_dblk_t *)_thing; /* Pointer to the local heap data block */
+ H5HL_dblk_t *dblk, unsigned UNUSED * flags_ptr))
/* check arguments */
HDassert(f);
@@ -741,9 +780,7 @@ END_FUNC(STATIC) /* end H5HL__datablock_flush() */
*/
BEGIN_FUNC(STATIC, ERR,
herr_t, SUCCEED, FAIL,
-H5HL__datablock_dest(H5F_t *f, void *_thing))
-
- H5HL_dblk_t *dblk = (H5HL_dblk_t *)_thing; /* Pointer to the local heap data block */
+H5HL__datablock_dest(H5F_t *f, H5HL_dblk_t *dblk))
/* check arguments */
HDassert(dblk);
@@ -791,9 +828,7 @@ END_FUNC(STATIC) /* end H5HL__datablock_dest() */
*/
BEGIN_FUNC(STATIC, ERR,
herr_t, SUCCEED, FAIL,
-H5HL__datablock_clear(H5F_t *f, void *_thing, hbool_t destroy))
-
- H5HL_dblk_t *dblk = (H5HL_dblk_t *)_thing; /* Pointer to the local heap data block */
+H5HL__datablock_clear(H5F_t *f, H5HL_dblk_t *dblk, hbool_t destroy))
/* check arguments */
HDassert(dblk);
@@ -811,6 +846,58 @@ END_FUNC(STATIC) /* end H5HL__datablock_clear() */
/*-------------------------------------------------------------------------
+ * Function: H5HL__datablock_notify
+ *
+ * Purpose: Handle cache action notifications
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Dana Robinson
+ * derobins@hdfgroup.org
+ * Fall 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5HL__datablock_notify(H5AC_notify_action_t action, H5HL_dblk_t *dblk))
+
+ /* Sanity check */
+ HDassert(dblk);
+
+ /* Check if the file was opened with SWMR-write access */
+ if(dblk->heap->swmr_write) {
+ /* Determine which action to take */
+ switch(action) {
+ case H5AC_NOTIFY_ACTION_AFTER_INSERT:
+ /* Create flush dependency on parent */
+ if(FAIL == H5HL__create_flush_depend((H5AC_info_t *)dblk->heap->prfx, (H5AC_info_t *)dblk))
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block and parent, address = %llu", (unsigned long long)dblk->heap->dblk_addr);
+ break;
+
+ case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
+ /* Destroy flush dependency on parent */
+ if(FAIL == H5HL__destroy_flush_depend((H5AC_info_t *)dblk->heap->prfx, (H5AC_info_t *)dblk))
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block and parent, address = %llu", (unsigned long long)dblk->heap->dblk_addr);
+ break;
+
+ default:
+#ifdef NDEBUG
+ H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache");
+#else /* NDEBUG */
+ HDassert(0 && "Unknown action?!?");
+#endif /* NDEBUG */
+ } /* end switch */
+ } /* end if */
+
+CATCH
+ /* No special processing on errors */
+
+END_FUNC(STATIC) /* end H5HL__datablock_notify() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HL__datablock_size
*
* Purpose: Compute the size in bytes of the local heap data block on disk,
@@ -827,9 +914,7 @@ END_FUNC(STATIC) /* end H5HL__datablock_clear() */
*/
BEGIN_FUNC(STATIC, NOERR,
herr_t, SUCCEED, -,
-H5HL__datablock_size(const H5F_t UNUSED *f, const void *_thing, size_t *size_ptr))
-
- const H5HL_dblk_t *dblk = (const H5HL_dblk_t *)_thing; /* Pointer to the local heap data block */
+H5HL__datablock_size(const H5F_t UNUSED *f, H5HL_dblk_t *dblk, size_t *size_ptr))
/* check arguments */
HDassert(dblk);
diff --git a/src/H5HLint.c b/src/H5HLint.c
index d5876f0..c2119d3 100644
--- a/src/H5HLint.c
+++ b/src/H5HLint.c
@@ -227,3 +227,67 @@ CATCH
H5E_THROW(H5E_CANTFREE, "unable to free local heap");
END_FUNC(PKG) /* end H5HL__dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL__create_flush_depend
+ *
+ * Purpose: Create a flush dependency between two data structure components
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Dana Robinson
+ * derobins@hdfgroup.org
+ * Fall 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5HL__create_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t *child_entry))
+
+ /* Sanity check */
+ HDassert(parent_entry);
+ HDassert(child_entry);
+
+ /* Create a flush dependency between parent and child entry */
+ if(FAIL == H5AC_create_flush_dependency(parent_entry, child_entry))
+ H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency");
+
+CATCH
+ /* No special processing on errors */
+
+END_FUNC(PKG) /* end H5HL__create_flush_depend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL__destroy_flush_depend
+ *
+ * Purpose: Destroy a flush dependency between two data structure components
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Dana Robinson
+ * derobins@hdfgroup.org
+ * Fall 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5HL__destroy_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t *child_entry))
+
+ /* Sanity check */
+ HDassert(parent_entry);
+ HDassert(child_entry);
+
+ /* Destroy a flush dependency between parent and child entry */
+ if(FAIL == H5AC_destroy_flush_dependency(parent_entry, child_entry))
+ H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency");
+
+CATCH
+ /* No special processing on errors */
+
+END_FUNC(PKG) /* end H5HL__destroy_flush_depend() */
diff --git a/src/H5HLpkg.h b/src/H5HLpkg.h
index 50f5797..2670b18 100644
--- a/src/H5HLpkg.h
+++ b/src/H5HLpkg.h
@@ -95,12 +95,13 @@ 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 */
+ hbool_t swmr_write; /* Flag indicating the file is opened with SWMR-write access */
+ H5HL_free_t *freelist; /* the free list */
/* Prefix-specific fields */
H5HL_prfx_t *prfx; /* The prefix object for the heap */
@@ -154,6 +155,12 @@ typedef struct H5HL_cache_dblk_ud_t {
/* Package Private Prototypes */
/******************************/
+/* Generic routines */
+H5_DLL herr_t H5HL__create_flush_depend(H5AC_info_t *parent_entry,
+ H5AC_info_t *child_entry);
+H5_DLL herr_t H5HL__destroy_flush_depend(H5AC_info_t *parent_entry,
+ H5AC_info_t *child_entry);
+
/* 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);
diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h
index d396a53..7ca54b0 100644
--- a/src/H5HLprivate.h
+++ b/src/H5HLprivate.h
@@ -69,6 +69,8 @@ H5_DLL H5HL_t *H5HL_protect(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5AC_protect_
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 herr_t H5HL_depend(H5AC_info_t *parent_entry, H5HL_t *heap);
+H5_DLL herr_t H5HL_undepend(H5AC_info_t *parent_entry, H5HL_t *heap);
/* 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,