summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVailin Choi <vchoi@hdfgroup.org>2014-01-29 22:54:07 (GMT)
committerVailin Choi <vchoi@hdfgroup.org>2014-01-29 22:54:07 (GMT)
commit3d7d7f3f24384dc38c54e51c9033ce07ee4e5152 (patch)
tree823127dc6675e9267f6eff76c4a97d3ce8152db9 /src
parente1d277b660e0fc572fb768fc954316bc9170a4dd (diff)
downloadhdf5-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.c37
-rw-r--r--src/H5ACprivate.h8
-rw-r--r--src/H5C.c241
-rw-r--r--src/H5Cpkg.h7
-rw-r--r--src/H5Cprivate.h12
-rw-r--r--src/H5O.c128
-rw-r--r--src/H5Oflush.c11
-rw-r--r--src/H5Opublic.h6
8 files changed, 434 insertions, 16 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index 18da8de..3f5fc83 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -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 */
diff --git a/src/H5C.c b/src/H5C.c
index cd2345c..87a100a 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -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 */
diff --git a/src/H5O.c b/src/H5O.c
index aaa3211..e39b63f 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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.
*