diff options
author | Vailin Choi <vchoi@hdfgroup.org> | 2014-01-29 22:54:07 (GMT) |
---|---|---|
committer | Vailin Choi <vchoi@hdfgroup.org> | 2014-01-29 22:54:07 (GMT) |
commit | 3d7d7f3f24384dc38c54e51c9033ce07ee4e5152 (patch) | |
tree | 823127dc6675e9267f6eff76c4a97d3ce8152db9 /src | |
parent | e1d277b660e0fc572fb768fc954316bc9170a4dd (diff) | |
download | hdf5-3d7d7f3f24384dc38c54e51c9033ce07ee4e5152.zip hdf5-3d7d7f3f24384dc38c54e51c9033ce07ee4e5152.tar.gz hdf5-3d7d7f3f24384dc38c54e51c9033ce07ee4e5152.tar.bz2 |
[svn-r24663] Implementation for H5Ocork, H5Ouncork, H5Ois_corked public routines.
Tested on jam, koala, ostrich, platypus.
PENDING:
(1) Code review.
(2) More work on tests, comments, cache related work.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 37 | ||||
-rw-r--r-- | src/H5ACprivate.h | 8 | ||||
-rw-r--r-- | src/H5C.c | 241 | ||||
-rw-r--r-- | src/H5Cpkg.h | 7 | ||||
-rw-r--r-- | src/H5Cprivate.h | 12 | ||||
-rw-r--r-- | src/H5O.c | 128 | ||||
-rw-r--r-- | src/H5Oflush.c | 11 | ||||
-rw-r--r-- | src/H5Opublic.h | 6 |
8 files changed, 434 insertions, 16 deletions
@@ -912,6 +912,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_flush() */ + /*------------------------------------------------------------------------- * Function: H5AC_get_entry_status @@ -5445,6 +5446,42 @@ done: } /* H5AC_evict_tagged_metadata */ + +/*------------------------------------------------------------------------- + * Function: H5AC_cork + * + * Purpose: To cork/uncork/get cork status for an object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_cork(H5F_t *f, haddr_t obj_addr, unsigned action, hbool_t *corked) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->cache); + HDassert(H5F_addr_defined(obj_addr)); + HDassert(action == H5AC__SET_CORK || action == H5AC__UNCORK || action == H5AC__GET_CORKED); + + if(action == H5AC__GET_CORKED) + HDassert(corked); + + if(H5C_cork(f->shared->cache, obj_addr, action, corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Cannot perform the cork action") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC_cork() */ + #if H5AC_DO_TAGGING_SANITY_CHECKS /*------------------------------------------------------------------------- diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index acb3adc..2fa8277 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -148,6 +148,12 @@ typedef enum { #define H5AC_CALLBACK__SIZE_CHANGED_FLAG H5C_CALLBACK__SIZE_CHANGED_FLAG #define H5AC_CALLBACK__MOVED_FLAG H5C_CALLBACK__MOVED_FLAG + +/* Cork actions: cork/uncork/get cork status of an object */ +#define H5AC__SET_CORK H5C__SET_CORK +#define H5AC__UNCORK H5C__UNCORK +#define H5AC__GET_CORKED H5C__GET_CORKED + /* Aliases for 'notify action' type & values */ typedef H5C_notify_action_t H5AC_notify_action_t; #define H5AC_NOTIFY_ACTION_AFTER_INSERT H5C_NOTIFY_ACTION_AFTER_INSERT @@ -421,6 +427,8 @@ H5_DLL herr_t H5AC_flush_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t H5_DLL herr_t H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id); +H5_DLL herr_t H5AC_cork(H5F_t *f, haddr_t obj_addr, unsigned action, hbool_t *corked); + #ifdef H5_HAVE_PARALLEL H5_DLL herr_t H5AC_add_candidate(H5AC_t * cache_ptr, haddr_t addr); #endif /* H5_HAVE_PARALLEL */ @@ -100,6 +100,9 @@ H5FL_DEFINE_STATIC(H5C_t); /* Declare a free list to manage flush dependency arrays */ H5FL_BLK_DEFINE_STATIC(parent); +/* Declare a free list to manage corked object addresses */ +H5FL_DEFINE_STATIC(haddr_t); + /* * Private file-scope function declarations: @@ -172,6 +175,9 @@ static herr_t H5C_tag_entry(H5C_t * cache_ptr, static herr_t H5C_mark_tagged_entries(H5C_t * cache_ptr, haddr_t tag, hbool_t mark_clean); +static herr_t H5C_mark_tagged_entries_cork(H5C_t *cache_ptr, + haddr_t obj_addr, + hbool_t val); static herr_t H5C_flush_marked_entries(H5F_t * f, hid_t primary_dxpl_id, @@ -1152,6 +1158,11 @@ H5C_create(size_t max_cache_size, 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 we get this far, we should succeed. Go ahead and initialize all * the fields. */ @@ -1305,6 +1316,9 @@ 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); + cache_ptr->magic = 0; cache_ptr = H5FL_FREE(H5C_t, cache_ptr); @@ -1504,6 +1518,35 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr, /*------------------------------------------------------------------------- + * Function: H5C_free_cork_list_cb + * + * Purpose: Callback function to free the list of object addresses + * on the skip list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5C_free_cork_list_cb(void *_item, void UNUSED *key, void UNUSED *op_data) +{ + haddr_t *addr = (haddr_t *)_item; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(addr); + + /* Release the item */ + addr = H5FL_FREE(haddr_t, addr); + + FUNC_LEAVE_NOAPI(0) +} /* H5C_free_cork_list_cb() */ + + + +/*------------------------------------------------------------------------- * Function: H5C_dest * * Purpose: Flush all data to disk and destroy the cache. @@ -1551,6 +1594,11 @@ H5C_dest(H5F_t * f, 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; + } /* end if */ + cache_ptr->magic = 0; cache_ptr = H5FL_FREE(H5C_t, cache_ptr); @@ -2724,6 +2772,10 @@ H5C_insert_entry(H5F_t * f, if(H5C_tag_entry(cache_ptr, entry_ptr, primary_dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot tag 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; @@ -3848,6 +3900,10 @@ H5C_protect(H5F_t * f, if(H5C_tag_entry(cache_ptr, entry_ptr, primary_dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, NULL, "Cannot tag 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") + /* If the entry is very large, and we are configured to allow it, * we may wish to perform a flash cache size increase. */ @@ -5241,7 +5297,7 @@ H5C_dump_cache(H5C_t * cache_ptr, HDfprintf(stdout, "\n\nDump of metadata cache \"%s\".\n", cache_name); HDfprintf(stdout, - "Num: Addr: Len: Type: Prot: Pinned: Dirty:\n"); + "Num: Addr: Tag: Len: Type: Prot: Pinned: Dirty: Corked:\n"); i = 0; @@ -5261,14 +5317,16 @@ H5C_dump_cache(H5C_t * cache_ptr, HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ); HDfprintf(stdout, - "%s%d 0x%08llx 0x%3llx %2d %d %d %d\n", + "%s%d 0x%16llx 0x%3llx 0x%3llx %2d %d %d %d %d\n", cache_ptr->prefix, i, (long long)(entry_ptr->addr), + (long long)(entry_ptr->tag), (long long)(entry_ptr->size), (int)(entry_ptr->type->id), (int)(entry_ptr->is_protected), (int)(entry_ptr->is_pinned), - (int)(entry_ptr->is_dirty)); + (int)(entry_ptr->is_dirty), + (int)(entry_ptr->is_corked)); /* increment node_ptr before we delete its target */ node_ptr = H5SL_next(node_ptr); @@ -8723,6 +8781,7 @@ H5C_make_space_in_cache(H5F_t * f, H5C_cache_entry_t * entry_ptr; H5C_cache_entry_t * prev_ptr; H5C_cache_entry_t * next_ptr; + int32_t num_corked_entries = 0; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -8751,7 +8810,7 @@ H5C_make_space_in_cache(H5F_t * f, } - while ( ( ( (cache_ptr->index_size + space_needed) + while ( ( ( (cache_ptr->index_size + space_needed) > cache_ptr->max_cache_size ) @@ -8768,7 +8827,7 @@ H5C_make_space_in_cache(H5F_t * f, ( entry_ptr != NULL ) ) { - HDassert( ! (entry_ptr->is_protected) ); + HDassert( !(entry_ptr->is_protected) ); HDassert( ! (entry_ptr->is_read_only) ); HDassert( (entry_ptr->ro_ref_count) == 0 ); @@ -8779,8 +8838,21 @@ H5C_make_space_in_cache(H5F_t * f, prev_is_dirty = prev_ptr->is_dirty; } + if ( (entry_ptr->type)->id == H5C__EPOCH_MARKER_TYPE) { - if ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) { + /* Skip epoch markers. Set result to SUCCEED to avoid + * triggering the error code below. + */ + didnt_flush_entry = TRUE; + result = SUCCEED; + } else if (entry_ptr->is_corked && entry_ptr->is_dirty) { + /* Skip "dirty" corked entries. Set result to SUCCEED to avoid + * triggering the error code below. + */ + ++num_corked_entries; + didnt_flush_entry = TRUE; + result = SUCCEED; + } else { didnt_flush_entry = FALSE; @@ -8836,14 +8908,7 @@ H5C_make_space_in_cache(H5F_t * f, #endif /* H5C_COLLECT_CACHE_STATS */ - } else { - - /* Skip epoch markers. Set result to SUCCEED to avoid - * triggering the error code below. - */ - didnt_flush_entry = TRUE; - result = SUCCEED; - } + } if ( result < 0 ) { @@ -8930,12 +8995,14 @@ H5C_make_space_in_cache(H5F_t * f, } #endif /* H5C_COLLECT_CACHE_STATS */ + + /* NEED: work on a better assert for corked entries */ HDassert( ( entries_examined > (2 * initial_list_len) ) || ( (cache_ptr->pl_size + cache_ptr->pel_size + cache_ptr->min_clean_size) > cache_ptr->max_cache_size ) || ( ( cache_ptr->clean_index_size + empty_space ) - >= cache_ptr->min_clean_size ) ); - + >= cache_ptr->min_clean_size ) || + ( ( num_corked_entries ))); #if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS HDassert( ( entries_examined > (2 * initial_list_len) ) || @@ -9608,6 +9675,148 @@ H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag) /*------------------------------------------------------------------------- + * + * Function: H5C_cork + * + * Purpose: To cork/uncork/get cork status of an object depending on "action": + * H5C__SET_CORK: + * To cork the object + * Return error if the object is already corked + * H5C__UNCORK: + * To uncork the obejct + * Return error if the object is not corked + * H5C__GET_CORKED: + * To retrieve the cork status of an object in + * the parameter "corked" + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_cork(H5C_t * cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked) +{ + haddr_t *ptr; /* Points to an address */ + haddr_t *addr_ptr = NULL; /* Points to an address */ + hbool_t is_corked; /* Cork status for an entry */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Assertions */ + HDassert(cache_ptr != NULL); + HDassert(H5F_addr_defined(obj_addr)); + 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); + + switch(action) { + case H5C__SET_CORK: + 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) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't insert address into cork list") + + /* Set the entry's cork status */ + is_corked = TRUE; + + break; + + case H5C__UNCORK: + if(ptr == NULL) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't uncork an object that is not corked ") + + /* 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") + + /* Set the entry's cork status */ + is_corked = FALSE; + break; + + case H5C__GET_CORKED: + HDassert(corked); + if(ptr != NULL && *ptr == obj_addr) + *corked = TRUE; + else + *corked = FALSE; + break; + + default: /* should be unreachable */ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown cork action") + break; + } /* end switch */ + + if(action != H5C__GET_CORKED) + /* 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, "Unknown cork action") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_cork() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_mark_tagged_entries_cork + * + * NEED: work to combine with H5C_mark_tagged_entries()-- + * probably an action (FLUSH or CORK) with hbool_t clean_or_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 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5C_mark_tagged_entries_cork(H5C_t *cache_ptr, haddr_t obj_addr, hbool_t val) +{ + /* Variable Declarations */ + int u; /* Iterator */ + H5C_cache_entry_t *entry_ptr = NULL; /* entry pointer */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Assertions */ + HDassert(cache_ptr != NULL); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Iterate through entries, find each entry with the specified tag */ + /* and set the entry's "corked" field to "val" */ + for(u = 0; u < H5C__HASH_TABLE_LEN; u++) { + + entry_ptr = cache_ptr->index[u]; + + while(entry_ptr != NULL) { + + if(entry_ptr->tag == obj_addr) + entry_ptr->is_corked = val; + + entry_ptr = entry_ptr->ht_next; + } /* end while */ + } /* end for */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5C_mark_tagged_entries_cork */ + + +/*------------------------------------------------------------------------- * Function: H5C__mark_flush_dep_dirty() * * Purpose: Recursively propagate the flush_dep_ndirty_children flag diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 57197be..4e2cd76 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -292,6 +292,11 @@ * to the slist since the last time this field was set to * zero. * + * cork_list_ptr: A skip list to track object addresses that are corked. + * When an entry is inserted or protected in the cache, + * the entry's associated object address (tag field) is + * checked against this skip list. If found, the entry + * is corked. * * When a cache entry is protected, it must be removed from the LRU * list(s) as it cannot be either flushed or evicted until it is unprotected. @@ -881,6 +886,8 @@ struct H5C_t int64_t slist_size_increase; #endif /* H5C_DO_SANITY_CHECKS */ + H5SL_t * cork_list_ptr; /* list of corked object addresses */ + int32_t pl_len; size_t pl_size; H5C_cache_entry_t * pl_head_ptr; diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 581e89d..3ee74ea 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -141,6 +141,12 @@ typedef enum { #define H5C_CALLBACK__SIZE_CHANGED_FLAG 0x1 #define H5C_CALLBACK__MOVED_FLAG 0x2 +/* Cork actions: cork/uncork/get cork status of an object */ +#define H5C__SET_CORK 0x1 +#define H5C__UNCORK 0x2 +#define H5C__GET_CORKED 0x4 + + /* Actions that can be reported to 'notify' client callback */ typedef enum H5C_notify_action_t { H5C_NOTIFY_ACTION_AFTER_INSERT, /* Entry has been added to the cache */ @@ -275,6 +281,9 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr, * 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. @@ -600,6 +609,7 @@ typedef struct H5C_cache_entry_t const H5C_class_t * type; haddr_t tag; int globality; + hbool_t is_corked; hbool_t is_dirty; hbool_t dirtied; hbool_t is_protected; @@ -1243,5 +1253,7 @@ H5_DLL herr_t H5C_ignore_tags(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_cork(H5C_t *cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked); + #endif /* !_H5Cprivate_H */ @@ -1087,6 +1087,116 @@ done: /*------------------------------------------------------------------------- + * Function: H5Ocork + * + * Purpose: To "cork" an object: + * --keep dirty entries assoicated with the object in the metadata cache + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ocork(hid_t object_id) +{ + H5O_loc_t *oloc; /* Object location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", object_id); + + /* Get the object's oloc */ + if((oloc = H5O_get_loc(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + if(H5AC_cork(oloc->file, oloc->addr, H5AC__SET_CORK, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to cork an object") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Ocork() */ + + +/*------------------------------------------------------------------------- + * Function: H5Ouncork + * + * Purpose: To "uncork" an object + * --release keeping dirty entries associated with the object + * in the metadata cache + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ouncork(hid_t object_id) +{ + H5O_loc_t *oloc; /* Object location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", object_id); + + /* Get the object's oloc */ + if((oloc = H5O_get_loc(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + /* Set the value */ + if(H5AC_cork(oloc->file, oloc->addr, H5AC__UNCORK, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to uncork an object") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Ouncork() */ + +/*------------------------------------------------------------------------- + * Function: H5Ois_corked + * + * Purpose: Retrieve the object's "cork" status in the parameter "corked": + * TRUE if the object is "corked" + * FALSE if the object is not "corked" + * Return error if the parameter "corked" is not supplied + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ois_corked(hid_t object_id, hbool_t *corked) +{ + H5O_loc_t *oloc; /* Object location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*b", object_id, corked); + + /* Check args */ + + /* Get the object's oloc */ + if((oloc = H5O_get_loc(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + if(!corked) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + /* Get the cork status */ + if(H5AC_cork(oloc->file, oloc->addr, H5AC__GET_CORKED, corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to retrieve an object's cork status") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Ois_corked() */ + + +/*------------------------------------------------------------------------- * Function: H5O_create * * Purpose: Creates a new object header. Allocates space for it and @@ -1439,6 +1549,7 @@ done: herr_t H5O_close(H5O_loc_t *loc) { + hbool_t corked; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1462,6 +1573,14 @@ H5O_close(H5O_loc_t *loc) } /* end if */ #endif + /* Uncork cache entries with tag: addr */ + if(H5AC_cork(loc->file, loc->addr, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to retrieve an object's cork status") + else if(corked) { + if(H5AC_cork(loc->file, loc->addr, H5AC__UNCORK, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "unable to uncork an object") + } + /* * If the file open object count has reached the number of open mount points * (each of which has a group open in the file) attempt to close the file. @@ -2207,6 +2326,7 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) H5O_t *oh = NULL; /* Object header information */ H5O_loc_t loc; /* Object location for object to delete */ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting object header */ + hbool_t corked; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_TAG(dxpl_id, addr, FAIL) @@ -2228,6 +2348,14 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) if(H5O_delete_oh(f, dxpl_id, oh) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file") + /* Uncork cache entries with tag: addr */ + if(H5AC_cork(f, addr, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to retrieve an object's cork status") + else if(corked) { + if(H5AC_cork(f, addr, H5AC__UNCORK, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "unable to uncork an object") + } + /* Mark object header as deleted */ oh_flags = H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 489afb2..e30094e 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -236,6 +236,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) H5G_loc_t tmp_loc; H5G_name_t obj_path; H5O_loc_t obj_oloc; + hbool_t corked; hid_t ret_value = SUCCEED; H5I_type_t type; @@ -266,6 +267,10 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) /* Reset object header pointer */ oh = NULL; + /* Get cork status of the object with tag */ + if(H5AC_cork(oloc.file, tag, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to retrieve an object's cork status") + /* Close the object */ if(H5I_dec_ref(oid) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to close object") @@ -278,6 +283,12 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) if(H5F_evict_tagged_metadata(oloc.file, tag, dxpl_id)<0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict metadata") + /* Re-cork object with tag */ + if(corked) { + if(H5AC_cork(oloc.file, tag, H5AC__SET_CORK, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to cork the object") + } + switch (type) { case(H5I_GROUP): diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 4fee641..12d0780 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -184,6 +184,12 @@ H5_DLL herr_t H5Ovisit_by_name(hid_t loc_id, const char *obj_name, H5_DLL herr_t H5Oclose(hid_t object_id); H5_DLL herr_t H5Oflush(hid_t obj_id); H5_DLL herr_t H5Orefresh(hid_t oid); +H5_DLL herr_t H5Ocork(hid_t object_id); +H5_DLL herr_t H5Ouncork(hid_t object_id); +H5_DLL herr_t H5Ois_corked(hid_t object_id, hbool_t *corked); + + + /* Symbols defined for compatibility with previous versions of the HDF5 API. * |