diff options
Diffstat (limited to 'src/H5Ctag.c')
-rw-r--r-- | src/H5Ctag.c | 339 |
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() */ - |