From 2e6ccbfff807fa986a1a8b22ef7fe172ffa7802f Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 7 Jun 2016 19:50:46 -0500 Subject: [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) --- src/H5AC.c | 12 ++- src/H5Cprivate.h | 2 +- src/H5Ctag.c | 280 ++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 223 insertions(+), 71 deletions(-) diff --git a/src/H5AC.c b/src/H5AC.c index cb587df..9ab1a14 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -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() */ /*------------------------------------------------------------------------------ diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index fb04d84..e077cc0 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -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 diff --git a/src/H5Ctag.c b/src/H5Ctag.c index 5a5b197..6c26796 100644 --- a/src/H5Ctag.c +++ b/src/H5Ctag.c @@ -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); /*********************/ @@ -215,6 +233,89 @@ done: /*------------------------------------------------------------------------- * + * 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() */ + + +/*------------------------------------------------------------------------- + * * Function: H5C__mark_tagged_entries * * Purpose: Set the flush marker on dirty entries in the cache that have @@ -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 */ - - 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 */ + 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") - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5C__mark_tagged_entries */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C__mark_tagged_entries() */ #if H5C_DO_TAGGING_SANITY_CHECKS @@ -389,6 +479,37 @@ done: /*------------------------------------------------------------------------- * + * 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() */ + + +/*------------------------------------------------------------------------- + * * Function: H5C_retag_entries * * Purpose: Searches through cache index for all entries with the @@ -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 */ - - 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 */ + 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") - FUNC_LEAVE_NOAPI_VOID -} /* H5C_retag_entries */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* 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() */ -- cgit v0.12