[svn-r30053] Description:

Create iterator routine for tagged entries and refactor current routines
to use it.

Tested on:
    MacOSX/64 10.11.5 (amazon) w/serial, parallel & production
    (h5committest forthcoming)
This commit is contained in:
Quincey Koziol 2016-06-07 19:50:46 -05:00
parent aee288c19d
commit 2e6ccbfff8
3 changed files with 222 additions and 70 deletions

View File

@ -2418,17 +2418,21 @@ done:
herr_t
H5AC_retag_copied_metadata(const H5F_t *f, haddr_t metadata_tag)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity checks */
HDassert(f);
HDassert(f->shared);
/* Call cache-level function to re-tag entries with the COPIED tag */
H5C_retag_entries(f->shared->cache, H5AC__COPIED_TAG, metadata_tag);
if(H5C_retag_entries(f->shared->cache, H5AC__COPIED_TAG, metadata_tag) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "Can't retag metadata")
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5AC_retag_copied_metadata */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_retag_copied_metadata() */
/*------------------------------------------------------------------------------

View File

@ -2016,7 +2016,7 @@ H5_DLL herr_t H5C_validate_resize_config(H5C_auto_size_ctl_t *config_ptr,
unsigned int tests);
H5_DLL herr_t H5C_ignore_tags(H5C_t *cache_ptr);
H5_DLL hbool_t H5C_get_ignore_tags(const H5C_t *cache_ptr);
H5_DLL void H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag);
H5_DLL herr_t H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag);
H5_DLL herr_t H5C_get_entry_ring(const H5F_t *f, haddr_t addr, H5C_ring_t *ring);
#ifdef H5_HAVE_PARALLEL

View File

@ -54,11 +54,29 @@
/* Local Typedefs */
/******************/
/* Define cache entry iteration callback type */
typedef int (*H5C_tag_iter_cb_t)(H5C_cache_entry_t *entry, void *ctx);
/* Typedef for tagged entry iterator callback context - retag tagged entries */
typedef struct {
haddr_t dest_tag; /* New tag value for matching entries */
} H5C_tag_iter_retag_ctx_t;
/* Typedef for tagged entry iterator callback context - expunge tag type metadata */
typedef struct {
H5F_t * f; /* File pointer for evicting entry */
hid_t dxpl_id; /* DXPL for evicting entry */
int type_id; /* Cache entry type to expunge */
unsigned flags; /* Flags for expunging entry */
} H5C_tag_iter_ettm_ctx_t;
/********************/
/* Local Prototypes */
/********************/
static herr_t H5C__mark_tagged_entries(H5C_t *cache_ptr, haddr_t tag);
static int H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global,
H5C_tag_iter_cb_t cb, void *cb_ctx);
/*********************/
@ -212,6 +230,89 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__tag_entry */
/*-------------------------------------------------------------------------
*
* Function: H5C_iter_tagged_entries
*
* Purpose: Iterate over tagged entries, making a callback for matches
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: Quincey Koziol
* June 7, 2016
*
*-------------------------------------------------------------------------
*/
static int
H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global,
H5C_tag_iter_cb_t cb, void *cb_ctx)
{
unsigned u; /* Local index variable */
int ret_value = H5_ITER_CONT; /* Return value */
/* Function enter macro */
FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(cache != NULL);
HDassert(cache->magic == H5C__H5C_T_MAGIC);
/* Iterate through entries in the index. */
for(u = 0; u < H5C__HASH_TABLE_LEN; u++) {
H5C_cache_entry_t *entry; /* Pointer to current entry */
H5C_cache_entry_t *next_entry; /* Pointer to next entry in hash bucket chain */
next_entry = cache->index[u];
while(next_entry != NULL) {
/* Acquire pointer to current entry and to next entry */
entry = next_entry;
next_entry = entry->ht_next;
/* Check for entry matching tag and/or globality */
if((entry->tag == tag) || (match_global && entry->globality == H5C_GLOBALITY_MAJOR)) {
/* Make callback for entry */
if((ret_value = (cb)(entry, cb_ctx)) != H5_ITER_CONT)
HGOTO_ERROR(H5E_CACHE, H5E_BADITER, H5_ITER_ERROR, "Iteration of tagged entries failed")
} /* end if */
} /* end while */
} /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__iter_tagged_entries() */
/*-------------------------------------------------------------------------
*
* Function: H5C__mark_tagged_entries_cb
*
* Purpose: Callback to set the flush marker on dirty entries in the cache
*
* Return: H5_ITER_CONT (can't fail)
*
* Programmer: Mike McGreevy
* September 9, 2010
*
*-------------------------------------------------------------------------
*/
static int
H5C__mark_tagged_entries_cb(H5C_cache_entry_t *entry, void H5_ATTR_UNUSED *_ctx)
{
/* Function enter macro */
FUNC_ENTER_STATIC_NOERR
/* Sanity checks */
HDassert(entry);
/* We only want to set the flush marker on entries that
* actually need flushed (i.e., dirty ones) */
if(entry->is_dirty)
entry->flush_marker = TRUE;
FUNC_LEAVE_NOAPI(H5_ITER_CONT)
} /* H5C__mark_tagged_entries_cb() */
/*-------------------------------------------------------------------------
*
@ -228,37 +329,26 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5C__mark_tagged_entries(H5C_t * cache_ptr, haddr_t tag)
H5C__mark_tagged_entries(H5C_t *cache, haddr_t tag)
{
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC_NOERR
/* Function enter macro */
FUNC_ENTER_STATIC
/* Sanity check */
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(cache);
HDassert(cache->magic == H5C__H5C_T_MAGIC);
/* Iterate through hash table entries, marking those with specified tag, as
* well as any major global entries which should always be flushed
* when flushing based on tag value */
for(u = 0; u < H5C__HASH_TABLE_LEN; u++) {
H5C_cache_entry_t *entry_ptr; /* Entry pointer */
if(H5C__iter_tagged_entries(cache, tag, TRUE, H5C__mark_tagged_entries_cb, NULL) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iteration of tagged entries failed")
entry_ptr = cache_ptr->index[u];
while(entry_ptr != NULL) {
if((entry_ptr->tag == tag) || (entry_ptr->globality == H5C_GLOBALITY_MAJOR)) {
/* We only want to set the flush marker on entries that
* actually need flushed (i.e., dirty ones) */
if(entry_ptr->is_dirty)
entry_ptr->flush_marker = TRUE;
} /* end if */
entry_ptr = entry_ptr->ht_next;
} /* end while */
} /* end for */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5C__mark_tagged_entries */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__mark_tagged_entries() */
#if H5C_DO_TAGGING_SANITY_CHECKS
@ -386,6 +476,37 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_flush_tagged_entries */
/*-------------------------------------------------------------------------
*
* Function: H5C__retag_entries_cb
*
* Purpose: Change tag for entries that match current tag
*
* Return: H5_ITER_CONT (can't fail)
*
* Programmer: Mike McGreevy
* March 17, 2010
*
*-------------------------------------------------------------------------
*/
static int
H5C__retag_entries_cb(H5C_cache_entry_t *entry, void *_ctx)
{
H5C_tag_iter_retag_ctx_t *ctx = (H5C_tag_iter_retag_ctx_t *)_ctx; /* Get pointer to iterator context */
/* Function enter macro */
FUNC_ENTER_STATIC_NOERR
/* Santify checks */
HDassert(entry);
HDassert(ctx);
entry->tag = ctx->dest_tag;
FUNC_LEAVE_NOAPI(H5_ITER_CONT)
} /* H5C_retag_entries_cb() */
/*-------------------------------------------------------------------------
*
@ -402,30 +523,65 @@ done:
*
*-------------------------------------------------------------------------
*/
void
H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag)
herr_t
H5C_retag_entries(H5C_t *cache, haddr_t src_tag, haddr_t dest_tag)
{
unsigned u; /* Local index variable */
H5C_tag_iter_retag_ctx_t ctx; /* Iterator callback context */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Function enter macro */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
HDassert(cache_ptr);
HDassert(cache);
/* Construct context for iterator callbacks */
ctx.dest_tag = dest_tag;
/* Iterate through entries, retagging those with the src_tag tag */
for(u = 0; u < H5C__HASH_TABLE_LEN; u++) {
H5C_cache_entry_t *entry_ptr; /* entry pointer */
if(H5C__iter_tagged_entries(cache, src_tag, FALSE, H5C__retag_entries_cb, &ctx) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iteration of tagged entries failed")
entry_ptr = cache_ptr->index[u];
while(entry_ptr) {
if(entry_ptr->tag == src_tag)
entry_ptr->tag = dest_tag;
entry_ptr = entry_ptr->ht_next;
} /* end while */
} /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_retag_entries() */
FUNC_LEAVE_NOAPI_VOID
} /* H5C_retag_entries */
/*-------------------------------------------------------------------------
*
* Function: H5C__expunge_tag_type_metadata_cb
*
* Purpose: Expunge from the cache entries associated
* with 'tag' and type id.
*
* Return: H5_ITER_ERROR if error is detected, H5_ITER_CONT otherwise.
*
* Programmer: Vailin Choi
* May 2016
*
*-------------------------------------------------------------------------
*/
static int
H5C__expunge_tag_type_metadata_cb(H5C_cache_entry_t *entry, void *_ctx)
{
H5C_tag_iter_ettm_ctx_t *ctx = (H5C_tag_iter_ettm_ctx_t *)_ctx; /* Get pointer to iterator context */
int ret_value = H5_ITER_CONT; /* Return value */
/* Function enter macro */
FUNC_ENTER_STATIC
/* Santify checks */
HDassert(entry);
HDassert(ctx);
/* Found one with the same tag and type id */
if(entry->type->id == ctx->type_id)
if(H5C_expunge_entry(ctx->f, ctx->dxpl_id, entry->type, entry->addr, ctx->flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, H5_ITER_ERROR, "can't expunge entry")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__expunge_tag_type_metadata_cb() */
/*-------------------------------------------------------------------------
@ -437,48 +593,40 @@ H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag)
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: Vailin Choi; May 2016
* Programmer: Vailin Choi
* May 2016
*
*-------------------------------------------------------------------------
*/
herr_t
H5C_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id, unsigned flags)
H5C_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id,
unsigned flags)
{
unsigned u; /* Local index variable */
H5C_t *cache_ptr = NULL;
H5C_t *cache; /* Pointer to cache structure */
H5C_tag_iter_ettm_ctx_t ctx; /* Context for iterator callback */
herr_t ret_value = SUCCEED; /* Return value */
/* Function enter macro */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
/* Sanity checks */
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->cache);
HDassert(f->shared->cache->magic == H5C__H5C_T_MAGIC);
cache = f->shared->cache; /* Get cache pointer */
HDassert(cache != NULL);
HDassert(cache->magic == H5C__H5C_T_MAGIC);
/* Get cache pointer */
cache_ptr = f->shared->cache;
/* Construct context for iterator callbacks */
ctx.f = f;
ctx.dxpl_id = dxpl_id;
ctx.type_id = type_id;
ctx.flags = flags;
/* Iterate through hash table entries, expunge those with specified tag and type id */
for(u = 0; u < H5C__HASH_TABLE_LEN; u++) {
H5C_cache_entry_t *entry_ptr; /* Entry pointer */
entry_ptr = cache_ptr->index[u];
while(entry_ptr != NULL) {
H5C_cache_entry_t *next_entry_ptr = entry_ptr->ht_next;
/* Found one with the same tag and type id */
if(entry_ptr->tag == tag && entry_ptr->type->id == type_id) {
if(H5C_expunge_entry(f, dxpl_id, entry_ptr->type, entry_ptr->addr, flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "H5C_expunge_entry() failed.")
} /* end if */
entry_ptr = next_entry_ptr;
} /* end while */
} /* end for */
if(H5C__iter_tagged_entries(cache, tag, FALSE, H5C__expunge_tag_type_metadata_cb, &ctx) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iteration of tagged entries failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_expunge_tag_type_metadata */
} /* H5C_expunge_tag_type_metadata() */