summaryrefslogtreecommitdiffstats
path: root/src/H5Ctag.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2016-11-07 07:14:10 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2016-11-07 07:14:10 (GMT)
commit9504d3f337c94c1a2d00bc5b05561e6ed1cee798 (patch)
tree4778cce3b3f9362c7e467179b06a469d16d2e635 /src/H5Ctag.c
parent323ae135906c4a0adb11ad2ee87b4a9814035ac3 (diff)
downloadhdf5-9504d3f337c94c1a2d00bc5b05561e6ed1cee798.zip
hdf5-9504d3f337c94c1a2d00bc5b05561e6ed1cee798.tar.gz
hdf5-9504d3f337c94c1a2d00bc5b05561e6ed1cee798.tar.bz2
Switch to new, more scalable, metadata cache entry tagging.
Diffstat (limited to 'src/H5Ctag.c')
-rw-r--r--src/H5Ctag.c339
1 files changed, 186 insertions, 153 deletions
diff --git a/src/H5Ctag.c b/src/H5Ctag.c
index 8ee287c..b03d2a6 100644
--- a/src/H5Ctag.c
+++ b/src/H5Ctag.c
@@ -62,11 +62,6 @@ typedef struct {
hbool_t pinned_entries_need_evicted; /* Flag to indicate that a pinned entry was attempted to be evicted */
} H5C_tag_iter_evict_ctx_t;
-/* 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 */
@@ -91,6 +86,9 @@ static herr_t H5C__mark_tagged_entries(H5C_t *cache_ptr, haddr_t tag);
/* Package Variables */
/*********************/
+/* Declare extern free list to manage the tag info struct */
+H5FL_EXTERN(H5C_tag_info_t);
+
/*****************************/
/* Library Private Variables */
@@ -188,7 +186,8 @@ herr_t
H5C__tag_entry(H5C_t *cache, H5C_cache_entry_t *entry, hid_t dxpl_id)
{
H5P_genplist_t *dxpl; /* dataset transfer property list */
- H5C_tag_t tag; /* Tag structure */
+ H5C_tag_info_t *tag_info; /* Points to a tag info struct */
+ haddr_t tag; /* Tag value */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -203,7 +202,7 @@ H5C__tag_entry(H5C_t *cache, H5C_cache_entry_t *entry, hid_t dxpl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Get the tag from the DXPL */
- if((H5P_get(dxpl, "H5C_tag", &tag)) < 0)
+ if((H5P_get(dxpl, H5AC_TAG_NAME, &tag)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value")
if(cache->ignore_tags) {
@@ -214,24 +213,48 @@ H5C__tag_entry(H5C_t *cache, H5C_cache_entry_t *entry, hid_t dxpl_id)
arbitrarily set it to something for the sake of passing the tests.
If the tag value is set, then we'll just let it get assigned without
additional checking for correctness. */
- if(!tag.value) {
- tag.value = H5AC__IGNORE_TAG;
- tag.globality = H5C_GLOBALITY_NONE;
- } /* end if */
+ if(!H5F_addr_defined(tag))
+ tag = H5AC__IGNORE_TAG;
} /* end if */
#if H5C_DO_TAGGING_SANITY_CHECKS
else {
/* Perform some sanity checks to ensure that a correct tag is being applied */
- if(H5C_verify_tag(entry->type->id, tag.value, tag.globality) < 0)
+ if(H5C_verify_tag(entry->type->id, tag) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "tag verification failed")
} /* end else */
#endif
- /* Apply the tag to the entry */
- entry->tag = tag.value;
+ /* Search the list of tagged object addresses in the cache */
+ tag_info = (H5C_tag_info_t *)H5SL_search(cache->tag_list, &tag);
+
+ /* Check if this is the first entry for this tagged object */
+ if(NULL == tag_info) {
+ /* Allocate new tag info struct */
+ if(NULL == (tag_info = H5FL_CALLOC(H5C_tag_info_t)))
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "can't allocate tag info for cache entry")
+
+ /* Set the tag for all entries */
+ tag_info->tag = tag;
+
+ /* Insert tag info into skip list */
+ if(H5SL_insert(cache->tag_list, tag_info, &(tag_info->tag)) < 0 )
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, "can't insert tag info in skip list")
+ } /* end if */
+ else
+ HDassert(tag_info->corked || (tag_info->entry_cnt > 0 && tag_info->head));
+
+ /* Sanity check entry, to avoid double insertions, etc */
+ HDassert(entry->tl_next == NULL);
+ HDassert(entry->tl_prev == NULL);
+ HDassert(entry->tag_info == NULL);
- /* Apply the tag globality to the entry */
- entry->globality = tag.globality;
+ /* Add the entry to the list for the tagged object */
+ entry->tl_next = tag_info->head;
+ entry->tag_info = tag_info;
+ if(tag_info->head)
+ tag_info->head->tl_prev = entry;
+ tag_info->head = entry;
+ tag_info->entry_cnt++;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -240,7 +263,70 @@ done:
/*-------------------------------------------------------------------------
*
- * Function: H5C_iter_tagged_entries
+ * Function: H5C__untag_entry
+ *
+ * Purpose: Removes an entry from a tag list, possibly removing the tag
+ * info from the list of tagged objects with entries.
+ *
+ * Return: FAIL if error is detected, SUCCEED otherwise.
+ *
+ * Programmer: Quincey Koziol
+ * July 8, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C__untag_entry(H5C_t *cache, H5C_cache_entry_t *entry)
+{
+ H5C_tag_info_t *tag_info; /* Points to a tag info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Assertions */
+ HDassert(cache != NULL);
+ HDassert(entry != NULL);
+ HDassert(cache->magic == H5C__H5C_T_MAGIC);
+
+ /* Get the entry's tag info struct */
+ if(NULL != (tag_info = entry->tag_info)) {
+ /* Remove the entry from the list */
+ if(entry->tl_next)
+ entry->tl_next->tl_prev = entry->tl_prev;
+ if(entry->tl_prev)
+ entry->tl_prev->tl_next = entry->tl_next;
+ if(tag_info->head == entry)
+ tag_info->head = entry->tl_next;
+ tag_info->entry_cnt--;
+
+ /* Reset pointers, to avoid confusion */
+ entry->tl_next = NULL;
+ entry->tl_prev = NULL;
+ entry->tag_info = NULL;
+
+ /* Remove the tag info from the tag list, if there's no more entries with this tag */
+ if(!tag_info->corked && 0 == tag_info->entry_cnt) {
+ /* Sanity check */
+ HDassert(NULL == tag_info->head);
+
+ if(H5SL_remove(cache->tag_list, &(tag_info->tag)) != tag_info)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "can't remove tag info from list")
+
+ /* Release the tag info */
+ tag_info = H5FL_FREE(H5C_tag_info_t, tag_info);
+ } /* end if */
+ else
+ HDassert(tag_info->corked || NULL != tag_info->head);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C__untag_entry */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5C__iter_tagged_entries_real
*
* Purpose: Iterate over tagged entries, making a callback for matches
*
@@ -251,39 +337,92 @@ done:
*
*-------------------------------------------------------------------------
*/
-int
-H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global,
- H5C_tag_iter_cb_t cb, void *cb_ctx)
+static herr_t
+H5C__iter_tagged_entries_real(H5C_t *cache, haddr_t tag, H5C_tag_iter_cb_t cb,
+ void *cb_ctx)
{
- unsigned u; /* Local index variable */
- int ret_value = H5_ITER_CONT; /* Return value */
+ H5C_tag_info_t *tag_info; /* Points to a tag info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
/* Function enter macro */
- FUNC_ENTER_PACKAGE
+ 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++) {
+ /* Search the list of tagged object addresses in the cache */
+ tag_info = (H5C_tag_info_t *)H5SL_search(cache->tag_list, &tag);
+
+ /* If there's any entries for this tag, iterate over them */
+ if(tag_info) {
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 */
+ /* Sanity check */
+ HDassert(tag_info->head);
+ HDassert(tag_info->entry_cnt > 0);
+
+ /* Iterate over the entries for this tag */
+ entry = tag_info->head;
+ while(entry) {
+ /* Acquire pointer to next entry */
+ next_entry = entry->tl_next;
+
+ /* Make callback for entry */
+ if((cb)(entry, cb_ctx) != H5_ITER_CONT)
+ HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "tagged entry iteration callback failed")
+
+ /* Advance 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 */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C__iter_tagged_entries_real() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * 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
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global,
+ H5C_tag_iter_cb_t cb, void *cb_ctx)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ /* Function enter macro */
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(cache != NULL);
+ HDassert(cache->magic == H5C__H5C_T_MAGIC);
+
+ /* Iterate over the entries for this tag */
+ if(H5C__iter_tagged_entries_real(cache, tag, cb, cb_ctx) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "iteration of tagged entries failed")
+
+ /* Check for iterating over global metadata */
+ if(match_global) {
+ /* Iterate over the entries for SOHM entries */
+ if(H5C__iter_tagged_entries_real(cache, H5AC__SOHM_TAG, cb, cb_ctx) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "iteration of tagged entries failed")
+
+ /* Iterate over the entries for global heap entries */
+ if(H5C__iter_tagged_entries_real(cache, H5AC__GLOBALHEAP_TAG, cb, cb_ctx) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "iteration of tagged entries failed")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -476,7 +615,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality)
+H5C_verify_tag(int id, haddr_t tag)
{
herr_t ret_value = SUCCEED;
@@ -498,8 +637,6 @@ H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality)
if((id == H5AC_SUPERBLOCK_ID) || (id == H5AC_DRVRINFO_ID)) {
if(tag != H5AC__SUPERBLOCK_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "superblock not tagged with H5AC__SUPERBLOCK_TAG")
- if(globality != H5C_GLOBALITY_MAJOR)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "superblock/driver-info globality not marked with H5C_GLOBALITY_MAJOR")
} /* end if */
else {
if(tag == H5AC__SUPERBLOCK_TAG)
@@ -510,8 +647,6 @@ H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality)
if((id == H5AC_FSPACE_HDR_ID) || (id == H5AC_FSPACE_SINFO_ID)) {
if(tag != H5AC__FREESPACE_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "freespace entry not tagged with H5AC__FREESPACE_TAG")
- if(globality != H5C_GLOBALITY_MINOR)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "freespace entry globality not marked with H5C_GLOBALITY_MINOR")
} /* end if */
else {
if(tag == H5AC__FREESPACE_TAG)
@@ -522,16 +657,12 @@ H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality)
if((id == H5AC_SOHM_TABLE_ID) || (id == H5AC_SOHM_LIST_ID)) {
if(tag != H5AC__SOHM_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "sohm entry not tagged with H5AC__SOHM_TAG")
- if(globality != H5C_GLOBALITY_MAJOR)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "sohm entry globality not marked with H5C_GLOBALITY_MAJOR")
} /* end if */
/* Global Heap */
if(id == H5AC_GHEAP_ID) {
if(tag != H5AC__GLOBALHEAP_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "global heap not tagged with H5AC__GLOBALHEAP_TAG")
- if(globality != H5C_GLOBALITY_MAJOR)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "global heap entry globality not marked with H5C_GLOBALITY_MAJOR")
} /* end if */
else {
if(tag == H5AC__GLOBALHEAP_TAG)
@@ -589,37 +720,6 @@ 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
@@ -636,7 +736,7 @@ H5C__retag_entries_cb(H5C_cache_entry_t *entry, void *_ctx)
herr_t
H5C_retag_entries(H5C_t *cache, haddr_t src_tag, haddr_t dest_tag)
{
- H5C_tag_iter_retag_ctx_t ctx; /* Iterator callback context */
+ H5C_tag_info_t *tag_info; /* Points to a tag info struct */
herr_t ret_value = SUCCEED; /* Return value */
/* Function enter macro */
@@ -645,12 +745,15 @@ H5C_retag_entries(H5C_t *cache, haddr_t src_tag, haddr_t dest_tag)
/* Sanity check */
HDassert(cache);
- /* Construct context for iterator callbacks */
- ctx.dest_tag = dest_tag;
+ /* Remove tag info from tag list */
+ if(NULL != (tag_info = (H5C_tag_info_t *)H5SL_remove(cache->tag_list, &src_tag))) {
+ /* Change to new tag */
+ tag_info->tag = dest_tag;
- /* Iterate through entries, retagging those with the src_tag tag */
- 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")
+ /* Re-insert tag info into skip list */
+ if(H5SL_insert(cache->tag_list, tag_info, &(tag_info->tag)) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, "can't insert tag info in skip list")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -740,73 +843,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_expunge_tag_type_metadata() */
-
-/*-------------------------------------------------------------------------
- * Function: H5C__mark_tagged_entries_cork_cb
- *
- * Purpose: The "is_corked" field to "val" for en entry
- *
- * Return: H5_ITER_ERROR if error is detected, H5_ITER_CONT otherwise.
- *
- * Programmer: Vailin Choi
- * January 2014
- *
- *-------------------------------------------------------------------------
- */
-static int
-H5C__mark_tagged_entries_cork_cb(H5C_cache_entry_t *entry, void *_ctx)
-{
- H5C_tag_iter_cork_ctx_t *ctx = (H5C_tag_iter_cork_ctx_t *)_ctx; /* Get pointer to iterator context */
-
- /* Function enter macro */
- FUNC_ENTER_STATIC_NOERR
-
- /* Santify checks */
- HDassert(entry);
- HDassert(ctx);
-
- /* Set the entry's "corked" field to "val" */
- entry->is_corked = ctx->cork_val;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5C__mark_tagged_entries_cork_cb() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5C__mark_tagged_entries_cork
- *
- * Purpose: To set the "is_corked" field to "val" for entries in cache
- * with the entry's tag equals to "obj_addr".
- *
- * Return: FAIL if error is detected, SUCCEED otherwise.
- *
- * Programmer: Vailin Choi
- * January 2014
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5C__mark_tagged_entries_cork(H5C_t *cache, haddr_t obj_addr, hbool_t val)
-{
- H5C_tag_iter_cork_ctx_t ctx; /* Context for iterator callback */
- herr_t ret_value = SUCCEED; /* Return value */
-
- /* Function enter macro */
- FUNC_ENTER_PACKAGE
-
- /* Sanity checks */
- HDassert(cache);
- HDassert(cache->magic == H5C__H5C_T_MAGIC);
-
- /* Construct context for iterator callbacks */
- ctx.cork_val = val;
-
- /* Iterate through entries, find each entry with the specified tag */
- /* and set the entry's "corked" field to "val" */
- if(H5C__iter_tagged_entries(cache, obj_addr, FALSE, H5C__mark_tagged_entries_cork_cb, &ctx) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iteration of tagged entries failed")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__mark_tagged_entries_cork() */
-