From 35f98ad8b6612eb76e1f8d01ee42dd6527a82c48 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Thu, 5 Jul 2012 16:14:37 -0500 Subject: [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. --- src/H5HL.c | 62 ++++++++++++++++++++++ src/H5HLcache.c | 151 ++++++++++++++++++++++++++++++++++++++++++------------ src/H5HLint.c | 64 +++++++++++++++++++++++ src/H5HLpkg.h | 19 ++++--- src/H5HLprivate.h | 2 + 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, -- cgit v0.12