diff options
author | Quincey Koziol <koziol@lbl.gov> | 2016-11-07 16:47:29 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@lbl.gov> | 2016-11-07 16:47:29 (GMT) |
commit | 21c68f439391b084ca63dbf401dcdf5179c035c1 (patch) | |
tree | 4778cce3b3f9362c7e467179b06a469d16d2e635 /src | |
parent | 9dc83a5f998edb1eddcaf75a0d51b104f6c4045c (diff) | |
parent | 9504d3f337c94c1a2d00bc5b05561e6ed1cee798 (diff) | |
download | hdf5-21c68f439391b084ca63dbf401dcdf5179c035c1.zip hdf5-21c68f439391b084ca63dbf401dcdf5179c035c1.tar.gz hdf5-21c68f439391b084ca63dbf401dcdf5179c035c1.tar.bz2 |
Merge pull request #140 in HDFFV/hdf5 from ~KOZIOL/hdf5:develop_merge_revise_chunks_02 to develop
* commit '9504d3f337c94c1a2d00bc5b05561e6ed1cee798':
Switch to new, more scalable, metadata cache entry tagging.
Remove routines not yet used in develop
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 35 | ||||
-rw-r--r-- | src/H5AClog.c | 140 | ||||
-rw-r--r-- | src/H5ACpkg.h | 1 | ||||
-rw-r--r-- | src/H5ACprivate.h | 16 | ||||
-rw-r--r-- | src/H5C.c | 213 | ||||
-rw-r--r-- | src/H5Cdbg.c | 8 | ||||
-rw-r--r-- | src/H5Cpkg.h | 16 | ||||
-rw-r--r-- | src/H5Cprivate.h | 31 | ||||
-rw-r--r-- | src/H5Cquery.c | 2 | ||||
-rw-r--r-- | src/H5Ctag.c | 339 | ||||
-rw-r--r-- | src/H5Ctest.c | 6 | ||||
-rw-r--r-- | src/H5Fpkg.h | 1 | ||||
-rw-r--r-- | src/H5Ftest.c | 34 | ||||
-rw-r--r-- | src/H5Pdxpl.c | 4 |
14 files changed, 381 insertions, 465 deletions
@@ -2269,7 +2269,6 @@ done: herr_t H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag) { - H5C_tag_t tag; /* Tag structure */ H5P_genplist_t *dxpl; /* Dataset transfer property list */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2281,32 +2280,16 @@ H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag) /* Get the current tag value and return that (if prev_tag is NOT null) */ if(prev_tag) { - if((H5P_get(dxpl, "H5C_tag", &tag)) < 0) + haddr_t tag; /* Tag value */ + + if((H5P_get(dxpl, H5AC_TAG_NAME, &tag)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query dxpl") - *prev_tag = tag.value; + *prev_tag = tag; } /* end if */ - /* Add metadata_tag to tag structure */ - tag.value = metadata_tag; - - /* Determine globality of tag */ - switch(metadata_tag) { - case H5AC__SUPERBLOCK_TAG: - case H5AC__SOHM_TAG: - case H5AC__GLOBALHEAP_TAG: - tag.globality = H5C_GLOBALITY_MAJOR; - break; - case H5AC__FREESPACE_TAG: - tag.globality = H5C_GLOBALITY_MINOR; - break; - default: - tag.globality = H5C_GLOBALITY_NONE; - break; - } /* end switch */ - /* Set the provided tag in the dxpl_id. */ - if(H5P_set(dxpl, "H5C_tag", &tag) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "can't set property in dxpl") + if(H5P_set(dxpl, H5AC_TAG_NAME, &metadata_tag) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "can't set tag in dxpl") done: FUNC_LEAVE_NOAPI(ret_value) @@ -2506,7 +2489,7 @@ static herr_t H5AC__verify_tag(hid_t dxpl_id, const H5AC_class_t *type) { H5P_genplist_t *dxpl; /* DXPL for operation */ - H5C_tag_t tag; /* Entry tag to validate */ + haddr_t tag; /* Entry tag to validate */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -2516,11 +2499,11 @@ H5AC__verify_tag(hid_t dxpl_id, const H5AC_class_t *type) 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") /* Verify legal tag value */ - if(H5C_verify_tag(type->id, tag.value, tag.globality) < 0) + if(H5C_verify_tag(type->id, tag) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "tag verification failed") done: diff --git a/src/H5AClog.c b/src/H5AClog.c index 1cdaa00..980b105 100644 --- a/src/H5AClog.c +++ b/src/H5AClog.c @@ -206,51 +206,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5AC__write_evict_cache_log_msg - * - * Purpose: Write a log message for eviction of cache entries. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Dana Robinson - * Sunday, March 16, 2014 - * - *------------------------------------------------------------------------- - */ -herr_t -H5AC__write_evict_cache_log_msg(const H5AC_t *cache, - herr_t fxn_ret_value) -{ - char msg[MSG_SIZE]; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity checks */ - HDassert(cache); - - /* Create the log message string */ - HDsnprintf(msg, MSG_SIZE, -"\ -{\ -\"timestamp\":%lld,\ -\"action\":\"evict\",\ -\"returned\":%d\ -},\n\ -" - , (long long)HDtime(NULL), (int)fxn_ret_value); - - /* Write the log message to the file */ - if(H5C_write_log_message(cache, msg) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5AC__write_evict_cache_log_msg() */ - - -/*------------------------------------------------------------------------- * Function: H5AC__write_expunge_entry_log_msg * * Purpose: Write a log message for expunge of cache entries. @@ -449,53 +404,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5AC__write_mark_clean_entry_log_msg - * - * Purpose: Write a log message for marking cache entries as clean. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * Saturday, July 23, 2016 - * - *------------------------------------------------------------------------- - */ -herr_t -H5AC__write_mark_clean_entry_log_msg(const H5AC_t *cache, const H5AC_info_t *entry, - herr_t fxn_ret_value) -{ - char msg[MSG_SIZE]; /* Log message buffer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity checks */ - HDassert(cache); - HDassert(entry); - - /* Create the log message string */ - HDsnprintf(msg, MSG_SIZE, -"\ -{\ -\"timestamp\":%lld,\ -\"action\":\"clean\",\ -\"address\":0x%lx,\ -\"returned\":%d\ -},\n\ -" - , (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value); - - /* Write the log message to the file */ - if(H5C_write_log_message(cache, msg) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5AC__write_mark_clean_entry_log_msg() */ - - -/*------------------------------------------------------------------------- * Function: H5AC__write_move_entry_log_msg * * Purpose: Write a log message for moving a cache entry. @@ -962,51 +870,3 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5AC__write_set_cache_config_log_msg() */ - -/*------------------------------------------------------------------------- - * Function: H5AC__write_remove_entry_log_msg - * - * Purpose: Write a log message for removing a cache entry. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * September 17, 2016 - * - *------------------------------------------------------------------------- - */ -herr_t -H5AC__write_remove_entry_log_msg(const H5AC_t *cache, const H5AC_info_t *entry, - herr_t fxn_ret_value) -{ - char msg[MSG_SIZE]; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity checks */ - HDassert(cache); - HDassert(entry); - - /* Create the log message string */ - HDsnprintf(msg, MSG_SIZE, -"\ -{\ -\"timestamp\":%lld,\ -\"action\":\"remove\",\ -\"address\":0x%lx,\ -\"returned\":%d\ -},\n\ -" - , (long long)HDtime(NULL), (unsigned long)entry->addr, - (int)fxn_ret_value); - - /* Write the log message to the file */ - if(H5C_write_log_message(cache, msg) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5AC__write_remove_entry_log_msg() */ - diff --git a/src/H5ACpkg.h b/src/H5ACpkg.h index a689ffd..a298f85 100644 --- a/src/H5ACpkg.h +++ b/src/H5ACpkg.h @@ -42,7 +42,6 @@ /* Get needed headers */ #include "H5Cprivate.h" /* Cache */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5SLprivate.h" /* Skip lists */ /*****************************/ /* Package Private Variables */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 739cbce..abd1af0 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -35,6 +35,7 @@ #include "H5Cprivate.h" /* Cache */ #include "H5Fprivate.h" /* File access */ #include "H5Pprivate.h" /* Property lists */ +#include "H5SLprivate.h" /* Skip lists */ #ifdef H5_METADATA_TRACE_FILE #define H5AC__TRACE_FILE_ENABLED 1 @@ -45,11 +46,16 @@ /* Global metadata tag values */ #define H5AC__INVALID_TAG (haddr_t)0 #define H5AC__IGNORE_TAG (haddr_t)1 -#define H5AC__SUPERBLOCK_TAG (haddr_t)2 -#define H5AC__FREESPACE_TAG (haddr_t)3 -#define H5AC__SOHM_TAG (haddr_t)4 -#define H5AC__GLOBALHEAP_TAG (haddr_t)5 -#define H5AC__COPIED_TAG (haddr_t)6 +#define H5AC__COPIED_TAG (haddr_t)2 +#define H5AC__SUPERBLOCK_TAG (haddr_t)3 +#define H5AC__FREESPACE_TAG (haddr_t)4 +#define H5AC__SOHM_TAG (haddr_t)5 +#define H5AC__GLOBALHEAP_TAG (haddr_t)6 + +/* Definitions for cache "tag" property */ +#define H5AC_TAG_NAME "H5AC_tag" +#define H5AC_TAG_SIZE sizeof(haddr_t) +#define H5AC_TAG_DEF (H5AC__INVALID_TAG) /* Types of metadata objects cached */ typedef enum { @@ -197,6 +197,9 @@ static void H5C__assert_flush_dep_nocycle(const H5C_cache_entry_t * entry, /* Package initialization variable */ hbool_t H5_PKG_INIT_VAR = FALSE; +/* Declare a free list to manage the tag info struct */ +H5FL_DEFINE(H5C_tag_info_t); + /*****************************/ /* Library Private Variables */ @@ -216,9 +219,6 @@ H5FL_BLK_DEFINE_STATIC(parent); /* Declare extern free list to manage the H5C_collective_write_t struct */ H5FL_EXTERN(H5C_collective_write_t); -/* Declare a free list to manage corked object addresses */ -H5FL_DEFINE_STATIC(haddr_t); - /*------------------------------------------------------------------------- @@ -280,8 +280,8 @@ H5C_create(size_t max_cache_size, if(NULL == (cache_ptr->slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL))) HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list.") - if ( (cache_ptr->cork_list_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL ) - HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list for corked object addresses.") + if(NULL == (cache_ptr->tag_list = H5SL_create(H5SL_TYPE_HADDR, NULL))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list for tagged entry addresses.") /* If we get this far, we should succeed. Go ahead and initialize all * the fields. @@ -457,8 +457,8 @@ done: if(cache_ptr->slist_ptr != NULL) H5SL_close(cache_ptr->slist_ptr); - if ( cache_ptr->cork_list_ptr != NULL ) - H5SL_close(cache_ptr->cork_list_ptr); + if(cache_ptr->tag_list != NULL) + H5SL_close(cache_ptr->tag_list); cache_ptr->magic = 0; cache_ptr = H5FL_FREE(H5C_t, cache_ptr); @@ -656,10 +656,9 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr, /*------------------------------------------------------------------------- - * Function: H5C_free_cork_list_cb + * Function: H5C_free_tag_list_cb * - * Purpose: Callback function to free the list of object addresses - * on the skip list. + * Purpose: Callback function to free tag nodes from the skip list. * * Return: Non-negative on success/Negative on failure * @@ -669,19 +668,19 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr, *------------------------------------------------------------------------- */ static herr_t -H5C_free_cork_list_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) +H5C_free_tag_list_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) { - haddr_t *addr = (haddr_t *)_item; + H5C_tag_info_t *tag_info = (H5C_tag_info_t *)_item; FUNC_ENTER_NOAPI_NOINIT_NOERR - HDassert(addr); + HDassert(tag_info); /* Release the item */ - addr = H5FL_FREE(haddr_t, addr); + tag_info = H5FL_FREE(H5C_tag_info_t, tag_info); FUNC_LEAVE_NOAPI(0) -} /* H5C_free_cork_list_cb() */ +} /* H5C_free_tag_list_cb() */ /*------------------------------------------------------------------------- @@ -729,9 +728,9 @@ H5C_dest(H5F_t * f, hid_t dxpl_id) cache_ptr->slist_ptr = NULL; } /* end if */ - if(cache_ptr->cork_list_ptr != NULL) { - H5SL_destroy(cache_ptr->cork_list_ptr, H5C_free_cork_list_cb, NULL); - cache_ptr->cork_list_ptr = NULL; + if(cache_ptr->tag_list != NULL) { + H5SL_destroy(cache_ptr->tag_list, H5C_free_tag_list_cb, NULL); + cache_ptr->tag_list = NULL; } /* end if */ #ifndef NDEBUG @@ -1284,14 +1283,6 @@ H5C_insert_entry(H5F_t * f, entry_ptr->image_ptr = NULL; entry_ptr->image_up_to_date = FALSE; - /* Apply tag to newly inserted entry */ - if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot tag metadata entry") - - /* Set the entry's cork status */ - if(H5C_cork(cache_ptr, entry_ptr->tag, H5C__GET_CORKED, &entry_ptr->is_corked) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Cannot retrieve entry's cork status") - entry_ptr->is_protected = FALSE; entry_ptr->is_read_only = FALSE; entry_ptr->ro_ref_count = 0; @@ -1359,6 +1350,10 @@ H5C_insert_entry(H5F_t * f, entry_ptr->coll_prev = NULL; #endif /* H5_HAVE_PARALLEL */ + /* Apply tag to newly inserted entry */ + if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot tag metadata entry") + H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) if(cache_ptr->flash_size_increase_possible && @@ -1858,8 +1853,9 @@ H5C_resize_entry(void *thing, size_t new_size) if(!entry_ptr->in_slist) H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL) - if(entry_ptr->is_pinned) + if(entry_ptr->is_pinned) { H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) + } /* end if */ } /* end if */ done: @@ -2190,22 +2186,21 @@ H5C_protect(H5F_t * f, #if H5C_DO_TAGGING_SANITY_CHECKS { - H5C_tag_t tag; /* Tag structure */ + /* Verify tag value */ + if(cache_ptr->ignore_tags != TRUE) { + haddr_t tag; /* Tag value */ - /* The entry is already in the cache, but make sure that the tag value - being passed in via dxpl is still legal. This will ensure that had - the entry NOT been in the cache, tagging was still set up correctly - and it would have received a legal tag value after getting loaded - from disk. */ + /* The entry is already in the cache, but make sure that the tag value + being passed in via dxpl is still legal. This will ensure that had + the entry NOT been in the cache, tagging was still set up correctly + and it would have received a legal tag value after getting loaded + from disk. */ - /* Get the tag from the DXPL */ - if((H5P_get(dxpl, "H5C_tag", &tag)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to query property value"); + /* Get the tag from the DXPL */ + if((H5P_get(dxpl, H5AC_TAG_NAME, &tag)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to query property value"); - /* Verify tag value */ - if(cache_ptr->ignore_tags != TRUE) { - /* Verify legal tag value */ - if(H5C_verify_tag(entry_ptr->type->id, tag.value, tag.globality) < 0) + if(H5C_verify_tag(entry_ptr->type->id, tag) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "tag verification failed") } /* end if */ } @@ -2238,10 +2233,6 @@ H5C_protect(H5F_t * f, if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, NULL, "Cannot tag metadata entry") - /* Set the entry's cork status */ - if(H5C_cork(cache_ptr, entry_ptr->tag, H5C__GET_CORKED, &entry_ptr->is_corked) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "Cannot retrieve entry's cork status") - /* If the entry is very large, and we are configured to allow it, * we may wish to perform a flash cache size increase. */ @@ -4342,31 +4333,30 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f, if(prev_ptr != NULL) prev_is_dirty = prev_ptr->is_dirty; - /* dirty corked entry is skipped */ - if(entry_ptr->is_corked && entry_ptr->is_dirty) - corked = TRUE; - else if ( entry_ptr->is_dirty ) { - - /* reset entries_removed_counter and - * last_entry_removed_ptr prior to the call to - * H5C__flush_single_entry() so that we can spot - * unexpected removals of entries from the cache, - * and set the restart_scan flag if proceeding - * would be likely to cause us to scan an entry - * that is no longer in the cache. - */ - cache_ptr->entries_removed_counter = 0; - cache_ptr->last_entry_removed_ptr = NULL; - - if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, H5C__NO_FLAGS_SET, NULL, NULL) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush entry") - - if ( ( cache_ptr->entries_removed_counter > 1 ) || - ( cache_ptr->last_entry_removed_ptr == prev_ptr ) ) + if(entry_ptr->is_dirty ) { + /* dirty corked entry is skipped */ + if(entry_ptr->tag_info && entry_ptr->tag_info->corked) + corked = TRUE; + else { + /* reset entries_removed_counter and + * last_entry_removed_ptr prior to the call to + * H5C__flush_single_entry() so that we can spot + * unexpected removals of entries from the cache, + * and set the restart_scan flag if proceeding + * would be likely to cause us to scan an entry + * that is no longer in the cache. + */ + cache_ptr->entries_removed_counter = 0; + cache_ptr->last_entry_removed_ptr = NULL; - restart_scan = TRUE; + if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, H5C__NO_FLAGS_SET, NULL, NULL) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush entry") - } else { + if(cache_ptr->entries_removed_counter > 1 || cache_ptr->last_entry_removed_ptr == prev_ptr) + restart_scan = TRUE; + } /* end else */ + } /* end if */ + else { bytes_evicted += entry_ptr->size; @@ -6143,6 +6133,8 @@ H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ * * 3) Update the replacement policy for eviction * + * 4) Remove it from the tag list for this object + * * Finally, if the destroy_entry flag is set, discard the * entry. */ @@ -6154,6 +6146,10 @@ H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ H5C__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, FAIL) + /* Remove entry from tag list */ + if(H5C__untag_entry(cache_ptr, entry_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "can't remove entry from tag list") + /* verify that the entry is no longer part of any flush dependencies */ HDassert(entry_ptr->flush_dep_nparents == 0); HDassert(entry_ptr->flush_dep_nchildren == 0); @@ -6890,7 +6886,8 @@ H5C_make_space_in_cache(H5F_t * f, if(prev_ptr != NULL) prev_is_dirty = prev_ptr->is_dirty; - if (entry_ptr->is_corked && entry_ptr->is_dirty) { + if(entry_ptr->is_dirty && + (entry_ptr->tag_info && entry_ptr->tag_info->corked)) { /* Skip "dirty" corked entries. */ ++num_corked_entries; @@ -7615,8 +7612,8 @@ done: herr_t H5C_cork(H5C_t *cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked) { - haddr_t *ptr; /* Points to an address */ - herr_t ret_value = SUCCEED; /* Return value */ + H5C_tag_info_t *tag_info; /* Points to a tag info struct */ + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -7626,61 +7623,69 @@ H5C_cork(H5C_t *cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked) HDassert(action == H5C__SET_CORK || action == H5C__UNCORK || action == H5C__GET_CORKED); /* Search the list of corked object addresses in the cache */ - ptr = (haddr_t *)H5SL_search(cache_ptr->cork_list_ptr, &obj_addr); + tag_info = (H5C_tag_info_t *)H5SL_search(cache_ptr->tag_list, &obj_addr); if(H5C__GET_CORKED == action) { HDassert(corked); - if(ptr != NULL && *ptr == obj_addr) + if(tag_info != NULL && tag_info->corked) *corked = TRUE; else *corked = FALSE; } /* end if */ else { - hbool_t is_corked; /* Cork status for an entry */ - /* Sanity check */ HDassert(H5C__SET_CORK == action || H5C__UNCORK == action); /* Perform appropriate action */ if(H5C__SET_CORK == action) { - haddr_t *addr_ptr = NULL; /* Points to an address */ - - if(ptr != NULL && *ptr == obj_addr) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't cork an already corked object") - - /* Allocate address */ - if(NULL == (addr_ptr = H5FL_MALLOC(haddr_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Insert into the list */ - *addr_ptr = obj_addr; - if(H5SL_insert(cache_ptr->cork_list_ptr, addr_ptr, addr_ptr) < 0) { - addr_ptr = H5FL_FREE(haddr_t, addr_ptr); - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't insert address into cork list") + /* 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 = obj_addr; + + /* Insert tag info into skip list */ + if(H5SL_insert(cache_ptr->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 { + /* Check for object already corked */ + if(tag_info->corked) + HGOTO_ERROR(H5E_CACHE, H5E_CANTCORK, FAIL, "object already corked") + HDassert(tag_info->entry_cnt > 0 && tag_info->head); + } /* end else */ - /* Set the entry's cork status */ - is_corked = TRUE; + /* Set the corked status for the entire object */ + tag_info->corked = TRUE; } /* end if */ else { - if(ptr == NULL) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't uncork an object that is not corked ") + /* Sanity check */ + HDassert(tag_info); - /* Remove the object address from the list */ - ptr = (haddr_t *)H5SL_remove(cache_ptr->cork_list_ptr, &obj_addr); - if(ptr == NULL || *ptr != obj_addr) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't remove address from list") + /* Check for already uncorked */ + if(!tag_info->corked) + HGOTO_ERROR(H5E_CACHE, H5E_CANTUNCORK, FAIL, "object already uncorked") - /* Free address */ - ptr = H5FL_FREE(haddr_t, ptr); + /* Set the corked status for the entire object */ + tag_info->corked = FALSE; - /* Set the entry's cork status */ - is_corked = FALSE; - } /* end else */ + /* Remove the tag info from the tag list, if there's no more entries with this tag */ + if(0 == tag_info->entry_cnt) { + /* Sanity check */ + HDassert(NULL == tag_info->head); + + if(H5SL_remove(cache_ptr->tag_list, &(tag_info->tag)) != tag_info) + HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "can't remove tag info from list") - /* Mark existing cache entries with tag (obj_addr) to the cork status */ - if(H5C__mark_tagged_entries_cork(cache_ptr, obj_addr, is_corked) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't mark cork status on entry") + /* Release the tag info */ + tag_info = H5FL_FREE(H5C_tag_info_t, tag_info); + } /* end if */ + else + HDassert(NULL != tag_info->head); + } /* end else */ } /* end else */ done: diff --git a/src/H5Cdbg.c b/src/H5Cdbg.c index 08a7068..3961aa4 100644 --- a/src/H5Cdbg.c +++ b/src/H5Cdbg.c @@ -923,7 +923,7 @@ H5C__dump_children_cb(H5C_cache_entry_t *entry_ptr, void *_ctx) { H5C__dump_child_ctx_t *ctx = (H5C__dump_child_ctx_t *)_ctx; - if(entry_ptr->tag != entry_ptr->addr) { + if(entry_ptr->tag_info->tag != entry_ptr->addr) { unsigned u; HDassert(entry_ptr->flush_dep_nparents); @@ -941,12 +941,14 @@ H5C__dump_children(H5C_t *cache_ptr, const H5C_cache_entry_t *entry_ptr, { H5C__dump_child_ctx_t ctx; + HDassert(entry_ptr->tag_info); + ctx.cache_ptr = cache_ptr; ctx.parent = entry_ptr; ctx.dump_parents = dump_parents; ctx.prefix = prefix; ctx.indent = indent; - H5C__iter_tagged_entries(cache_ptr, entry_ptr->tag, FALSE, H5C__dump_children_cb, &ctx); + H5C__iter_tagged_entries(cache_ptr, entry_ptr->tag_info->tag, FALSE, H5C__dump_children_cb, &ctx); } void @@ -956,7 +958,7 @@ H5C__dump_entry(H5C_t *cache_ptr, const H5C_cache_entry_t *entry_ptr, HDassert(cache_ptr); HDassert(entry_ptr); - HDfprintf(stderr, "%*s%s: entry_ptr = (%a, '%s', %a, %t, %u, %u/%u)\n", indent, "", prefix, entry_ptr->addr, entry_ptr->type->name, entry_ptr->tag, entry_ptr->is_dirty, entry_ptr->flush_dep_nparents, entry_ptr->flush_dep_nchildren, entry_ptr->flush_dep_ndirty_children); + HDfprintf(stderr, "%*s%s: entry_ptr = (%a, '%s', %a, %t, %u, %u/%u)\n", indent, "", prefix, entry_ptr->addr, entry_ptr->type->name, entry_ptr->tag_info ? entry_ptr->tag_info->tag : HADDR_UNDEF, entry_ptr->is_dirty, entry_ptr->flush_dep_nparents, entry_ptr->flush_dep_nchildren, entry_ptr->flush_dep_ndirty_children); if(dump_parents && entry_ptr->flush_dep_nparents) H5C__dump_parents(cache_ptr, entry_ptr, "Parent", indent); if(entry_ptr->flush_dep_nchildren) diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index c8f5c00..2967361 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -3112,6 +3112,14 @@ if ( ( (entry_ptr) == NULL ) || \ /* Package Private Typedefs */ /****************************/ +/* Info about each set of tagged entries */ +typedef struct H5C_tag_info_t { + haddr_t tag; /* Tag (address) of the entries (must be first, for skiplist) */ + H5C_cache_entry_t *head; /* Head of the list of entries for this tag */ + size_t entry_cnt; /* Number of entries on list */ + hbool_t corked; /* Whether this object is corked */ +} H5C_tag_info_t; + /**************************************************************************** * * structure H5C_t @@ -4096,7 +4104,8 @@ struct H5C_t { int64_t slist_size_increase; #endif /* H5C_DO_SANITY_CHECKS */ - H5SL_t * cork_list_ptr; /* list of corked object addresses */ + /* Fields for maintaining list of tagged entries */ + H5SL_t * tag_list; /* Fields for tracking protected entries */ int32_t pl_len; @@ -4263,14 +4272,13 @@ H5_DLLVAR const H5C_class_t H5C__epoch_marker_class; H5_DLL herr_t H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr, unsigned flags, int64_t *entry_size_change_ptr, H5SL_t *collective_write_list); H5_DLL herr_t H5C__flush_marked_entries(H5F_t * f, hid_t dxpl_id); -H5_DLL int H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global, +H5_DLL 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); /* Routines for operating on entry tags */ H5_DLL herr_t H5C__tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr, hid_t dxpl_id); -H5_DLL herr_t H5C__mark_tagged_entries_cork(H5C_t *cache_ptr, haddr_t obj_addr, - hbool_t val); +H5_DLL herr_t H5C__untag_entry(H5C_t *cache, H5C_cache_entry_t *entry); /* Testing functions */ #ifdef H5C_TESTING diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 9b0dbd4..294d3a0b 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -204,11 +204,6 @@ #define H5C__EVICT_ALLOW_LAST_PINS_FLAG 0x4000 #define H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG 0x8000 -/* Definitions for cache "tag" property */ -#define H5C_TAG_NAME "H5C_tag" -#define H5C_TAG_SIZE sizeof(H5C_tag_t) -#define H5C_TAG_DEF {(haddr_t)0, H5C_GLOBALITY_NONE} - /* Debugging/sanity checking/statistics settings */ #ifndef NDEBUG #define H5C_DO_SANITY_CHECKS 1 @@ -271,19 +266,6 @@ /* Typedef for the main structure for the cache (defined in H5Cpkg.h) */ typedef struct H5C_t H5C_t; -/* Define enum for cache entry tag 'globality' value */ -typedef enum { - H5C_GLOBALITY_NONE=0, /* Non-global tag */ - H5C_GLOBALITY_MINOR, /* global, not flushed during single object flush */ - H5C_GLOBALITY_MAJOR /* global, needs flushed during single obect flush */ -} H5C_tag_globality_t; - -/* Cache entry tag structure */ -typedef struct H5C_tag_t { - haddr_t value; - H5C_tag_globality_t globality; -} H5C_tag_t; - /* * * Struct H5C_class_t @@ -1288,9 +1270,6 @@ typedef int H5C_ring_t; * The name is not particularly descriptive, but is retained * to avoid changes in existing code. * - * is_corked: Boolean flag indicating whether the cache entry associated - * with an object is corked or not corked. - * * is_dirty: Boolean flag indicating whether the contents of the cache * entry has been modified since the last time it was written * to disk. @@ -1609,9 +1588,6 @@ typedef struct H5C_cache_entry_t { void * image_ptr; hbool_t image_up_to_date; const H5C_class_t * type; - haddr_t tag; - H5C_tag_globality_t globality; - hbool_t is_corked; hbool_t is_dirty; hbool_t dirtied; hbool_t is_protected; @@ -1655,6 +1631,11 @@ typedef struct H5C_cache_entry_t { struct H5C_cache_entry_t * coll_prev; #endif /* H5_HAVE_PARALLEL */ + /* fields supporting tag lists */ + struct H5C_cache_entry_t * tl_next; + struct H5C_cache_entry_t * tl_prev; + struct H5C_tag_info_t * tag_info; + #if H5C_COLLECT_CACHE_ENTRY_STATS /* cache entry stats fields */ int32_t accesses; @@ -1980,7 +1961,7 @@ H5_DLL herr_t H5C_flush_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag); H5_DLL herr_t H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag, hbool_t match_global); H5_DLL herr_t H5C_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id, unsigned flags); #if H5C_DO_TAGGING_SANITY_CHECKS -herr_t H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality); +herr_t H5C_verify_tag(int id, haddr_t tag); #endif H5_DLL herr_t H5C_flush_to_min_clean(H5F_t *f, hid_t dxpl_id); H5_DLL herr_t H5C_get_cache_auto_resize_config(const H5C_t *cache_ptr, diff --git a/src/H5Cquery.c b/src/H5Cquery.c index 874b12f..be0d4fa 100644 --- a/src/H5Cquery.c +++ b/src/H5Cquery.c @@ -275,7 +275,7 @@ H5C_get_entry_status(const H5F_t *f, if(is_pinned_ptr != NULL) *is_pinned_ptr = entry_ptr->is_pinned; if(is_corked_ptr != NULL) - *is_corked_ptr = entry_ptr->is_corked; + *is_corked_ptr = entry_ptr->tag_info ? entry_ptr->tag_info->corked : FALSE; if(is_flush_dep_parent_ptr != NULL) *is_flush_dep_parent_ptr = (entry_ptr->flush_dep_nchildren > 0); if(is_flush_dep_child_ptr != NULL) 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() */ - diff --git a/src/H5Ctest.c b/src/H5Ctest.c index b049a75..876b63a 100644 --- a/src/H5Ctest.c +++ b/src/H5Ctest.c @@ -97,6 +97,7 @@ static int H5C__verify_cork_tag_test_cb(H5C_cache_entry_t *entry, void *_ctx) { H5C_tag_iter_vct_ctx_t *ctx = (H5C_tag_iter_vct_ctx_t *)_ctx; /* Get pointer to iterator context */ + hbool_t is_corked; /* Corked status for entry */ int ret_value = H5_ITER_CONT; /* Return value */ /* Function enter macro */ @@ -106,8 +107,11 @@ H5C__verify_cork_tag_test_cb(H5C_cache_entry_t *entry, void *_ctx) HDassert(entry); HDassert(ctx); + /* Retrieve corked status for entry */ + is_corked = entry->tag_info ? entry->tag_info->corked : FALSE; + /* Verify corked status for entry */ - if(entry->is_corked != ctx->status) + if(is_corked != ctx->status) HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, H5_ITER_ERROR, "bad cork status") done: diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 4d324d1..8d7dcbd 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -404,6 +404,7 @@ H5_DLL herr_t H5F_get_sohm_mesg_count_test(hid_t fid, unsigned type_id, size_t *mesg_count); H5_DLL herr_t H5F_check_cached_stab_test(hid_t file_id); H5_DLL herr_t H5F_get_maxaddr_test(hid_t file_id, haddr_t *maxaddr); +H5_DLL herr_t H5F_get_sbe_addr_test(hid_t file_id, haddr_t *sbe_addr); #endif /* H5F_TESTING */ #endif /* _H5Fpkg_H */ diff --git a/src/H5Ftest.c b/src/H5Ftest.c index 344d7c1..e3760b7 100644 --- a/src/H5Ftest.c +++ b/src/H5Ftest.c @@ -186,3 +186,37 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_maxaddr_test() */ + +/*------------------------------------------------------------------------- + * Function: H5F_get_sbe_addr_test + * + * Purpose: Retrieve the address of a superblock extension's object header + * for a file + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Jul 10, 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_sbe_addr_test(hid_t file_id, haddr_t *sbe_addr) +{ + H5F_t *file; /* File info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check arguments */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + + /* Retrieve maxaddr for file */ + *sbe_addr = file->shared->sblock->ext_addr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_sbe_addr_test() */ + diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index e685c65..c094c20 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -273,7 +273,7 @@ static const void *H5D_def_vlen_alloc_info_g = H5D_XFER_VLEN_ALLOC_INFO_DEF; / static const H5MM_free_t H5D_def_vlen_free_g = H5D_XFER_VLEN_FREE_DEF; /* Default value for vlen free function */ static const void *H5D_def_vlen_free_info_g = H5D_XFER_VLEN_FREE_INFO_DEF; /* Default value for vlen free information */ static const size_t H5D_def_hyp_vec_size_g = H5D_XFER_HYPER_VECTOR_SIZE_DEF; /* Default value for vector size */ -static const H5C_tag_t H5D_def_tag_g = H5C_TAG_DEF; /* Default value for cache entry tag */ +static const haddr_t H5D_def_tag_g = H5AC_TAG_DEF; /* Default value for cache entry tag */ static const H5FD_mpio_xfer_t H5D_def_io_xfer_mode_g = H5D_XFER_IO_XFER_MODE_DEF; /* Default value for I/O transfer mode */ static const H5FD_mpio_chunk_opt_t H5D_def_mpio_chunk_opt_mode_g = H5D_XFER_MPIO_CHUNK_OPT_HARD_DEF; static const H5FD_mpio_collective_opt_t H5D_def_mpio_collective_opt_mode_g = H5D_XFER_MPIO_COLLECTIVE_OPT_DEF; @@ -326,7 +326,7 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the cache tag property */ - if(H5P_register_real(pclass, H5C_TAG_NAME, H5C_TAG_SIZE, &H5D_def_tag_g, + if(H5P_register_real(pclass, H5AC_TAG_NAME, H5AC_TAG_SIZE, &H5D_def_tag_g, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") |