summaryrefslogtreecommitdiffstats
path: root/src/H5C.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5C.c')
-rw-r--r--src/H5C.c278
1 files changed, 262 insertions, 16 deletions
diff --git a/src/H5C.c b/src/H5C.c
index 37c833e..4adee6d 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -308,6 +308,7 @@ H5C_create(size_t max_cache_size,
cache_ptr->log_flush = log_flush;
cache_ptr->evictions_enabled = TRUE;
+ cache_ptr->close_warning_received = FALSE;
cache_ptr->index_len = 0;
cache_ptr->index_size = (size_t)0;
@@ -1439,6 +1440,7 @@ H5C_insert_entry(H5F_t * f,
entry_ptr->flush_dep_parent_nalloc = 0;
entry_ptr->flush_dep_nchildren = 0;
entry_ptr->flush_dep_ndirty_children = 0;
+ entry_ptr->flush_dep_nunser_children = 0;
entry_ptr->ht_next = NULL;
entry_ptr->ht_prev = NULL;
@@ -1645,12 +1647,25 @@ H5C_mark_entry_dirty(void *thing)
/* set the dirtied flag */
entry_ptr->dirtied = TRUE;
- } else if ( entry_ptr->is_pinned ) {
+ /* reset image_up_to_date */
+ if(entry_ptr->image_up_to_date) {
+ entry_ptr->image_up_to_date = FALSE;
+
+ if(entry_ptr->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_unserialized(entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "Can't propagate serialization status to fd parents")
+ }/* end if */
+ } /* end if */
+ else if ( entry_ptr->is_pinned ) {
hbool_t was_clean; /* Whether the entry was previously clean */
+ hbool_t image_was_up_to_date;
/* Remember previous dirty status */
was_clean = !entry_ptr->is_dirty;
+ /* Check if image is up to date */
+ image_was_up_to_date = entry_ptr->image_up_to_date;
+
/* Mark the entry as dirty if it isn't already */
entry_ptr->is_dirty = TRUE;
entry_ptr->image_up_to_date = FALSE;
@@ -1678,6 +1693,10 @@ H5C_mark_entry_dirty(void *thing)
if(H5C__mark_flush_dep_dirty(entry_ptr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "Can't propagate flush dep dirty flag")
} /* end if */
+ if(image_was_up_to_date)
+ if(entry_ptr->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_unserialized(entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "Can't propagate serialization status to fd parents")
} /* end if */
else
HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "Entry is neither pinned nor protected??")
@@ -1767,6 +1786,99 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5C_mark_entry_unserialized
+ *
+ * Purpose: Mark a pinned or protected entry as unserialized. The target
+ * entry MUST be either pinned or protected, and MAY be both.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 12/23/16
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_mark_entry_unserialized(void *thing)
+{
+ H5C_cache_entry_t *entry = (H5C_cache_entry_t *)thing;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(entry);
+ HDassert(H5F_addr_defined(entry->addr));
+
+ if(entry->is_protected || entry->is_pinned) {
+ HDassert(!entry->is_read_only);
+
+ /* Reset image_up_to_date */
+ if(entry->image_up_to_date) {
+ entry->image_up_to_date = FALSE;
+
+ if(entry->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_unserialized(entry) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "Can't propagate serialization status to fd parents")
+ }/* end if */
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKUNSERIALIZED, FAIL, "Entry to unserialize is neither pinned nor protected??")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_mark_entry_unserialized() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_mark_entry_serialized
+ *
+ * Purpose: Mark a pinned entry as serialized. The target entry MUST be
+ * pinned.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 12/23/16
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_mark_entry_serialized(void *_thing)
+{
+ H5C_cache_entry_t *entry = (H5C_cache_entry_t *)_thing;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(entry);
+ HDassert(H5F_addr_defined(entry->addr));
+
+ /* Operate on pinned entry */
+ if(entry->is_protected)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKSERIALIZED, FAIL, "entry is protected")
+ else if(entry->is_pinned) {
+ /* Check for entry changing status and do notifications, etc. */
+ if(!entry->image_up_to_date) {
+ /* Set the image_up_to_date flag */
+ entry->image_up_to_date = TRUE;
+
+ /* Propagate the serialize up the flush dependency chain, if appropriate */
+ if(entry->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_serialized(entry) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKSERIALIZED, FAIL, "Can't propagate flush dep serialize")
+ } /* end if */
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKSERIALIZED, FAIL, "Entry is not pinned??")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_mark_entry_serialized() */
+
+
+/*-------------------------------------------------------------------------
*
* Function: H5C_move_entry
*
@@ -1867,7 +1979,12 @@ H5C_move_entry(H5C_t * cache_ptr,
entry_ptr->is_dirty = TRUE;
/* This shouldn't be needed, but it keeps the test code happy */
- entry_ptr->image_up_to_date = FALSE;
+ if(entry_ptr->image_up_to_date) {
+ entry_ptr->image_up_to_date = FALSE;
+ if(entry_ptr->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_unserialized(entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "Can't propagate serialization status to fd parents")
+ } /* end if */
/* Modify cache data structures */
H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL)
@@ -1965,7 +2082,14 @@ H5C_resize_entry(void *thing, size_t new_size)
/* mark the entry as dirty if it isn't already */
entry_ptr->is_dirty = TRUE;
- entry_ptr->image_up_to_date = FALSE;
+
+ /* Reset the image up-to-date status */
+ if(entry_ptr->image_up_to_date) {
+ entry_ptr->image_up_to_date = FALSE;
+ if(entry_ptr->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_unserialized(entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "Can't propagate serialization status to fd parents")
+ } /* end if */
/* Release the current image */
if(entry_ptr->image_ptr)
@@ -3229,18 +3353,13 @@ H5C_unprotect(H5F_t * f,
/* Mark the entry as dirty if appropriate */
entry_ptr->is_dirty = (entry_ptr->is_dirty || dirtied);
- /* the image_up_to_date field was introduced to support
- * journaling. Until we re-introduce journaling, this
- * field should be equal to !entry_ptr->is_dirty.
- *
- * When journaling is re-enabled it should be set
- * to FALSE if dirtied is TRUE.
- */
-#if 1 /* JRM */
- entry_ptr->image_up_to_date = FALSE;
-#else /* JRM */
- entry_ptr->image_up_to_date = !entry_ptr->is_dirty;
-#endif /* JRM */
+ if(dirtied)
+ if(entry_ptr->image_up_to_date) {
+ entry_ptr->image_up_to_date = FALSE;
+ if(entry_ptr->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_unserialized(entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "Can't propagate serialization status to fd parents")
+ } /* end if */
/* Check for newly dirtied entry */
if(was_clean && entry_ptr->is_dirty) {
@@ -3782,6 +3901,20 @@ H5C_create_flush_dependency(void * parent_thing, void * child_thing)
HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify parent about child entry dirty flag set")
} /* end if */
+ /* adjust the parent's number of unserialized children. Note
+ * that it is possible for and entry to be clean and unserialized.
+ */
+ if(!child_entry->image_up_to_date) {
+ HDassert(parent_entry->flush_dep_nunser_children < parent_entry->flush_dep_nchildren);
+
+ parent_entry->flush_dep_nunser_children++;
+
+ /* If the parent has a 'notify' callback, send a 'child entry unserialized' notice */
+ if(parent_entry->type->notify &&
+ (parent_entry->type->notify)(H5C_NOTIFY_ACTION_CHILD_UNSERIALIZED, parent_entry) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify parent about child entry serialized flag reset")
+ } /* end if */
+
/* Post-conditions, for successful operation */
HDassert(parent_entry->is_pinned);
HDassert(parent_entry->flush_dep_nchildren > 0);
@@ -3893,6 +4026,18 @@ H5C_destroy_flush_dependency(void *parent_thing, void * child_thing)
HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify parent about child entry dirty flag reset")
} /* end if */
+ /* adjust parent entry's number of unserialized children */
+ if(!child_entry->image_up_to_date) {
+ HDassert(parent_entry->flush_dep_nunser_children > 0);
+
+ parent_entry->flush_dep_nunser_children--;
+
+ /* If the parent has a 'notify' callback, send a 'child entry serialized' notice */
+ if(parent_entry->type->notify &&
+ (parent_entry->type->notify)(H5C_NOTIFY_ACTION_CHILD_SERIALIZED, parent_entry) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify parent about child entry serialized flag set")
+ } /* end if */
+
/* Shrink or free the parent array if apporpriate */
if(child_entry->flush_dep_nparents == 0) {
child_entry->flush_dep_parent = (H5C_cache_entry_t **)H5FL_BLK_FREE(parent, child_entry->flush_dep_parent);
@@ -5950,6 +6095,9 @@ H5C_flush_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring, unsigned flags)
&& (entry_ptr->flush_dep_nchildren == 0
|| entry_ptr->flush_dep_ndirty_children == 0)
&& entry_ptr->ring == ring) {
+
+ HDassert(entry_ptr->flush_dep_nunser_children == 0);
+
if(entry_ptr->is_protected) {
/* we probably have major problems -- but lets
* flush everything we can before we decide
@@ -6811,6 +6959,7 @@ H5C_load_entry(H5F_t * f,
entry->flush_dep_parent_nalloc = 0;
entry->flush_dep_nchildren = 0;
entry->flush_dep_ndirty_children = 0;
+ entry->flush_dep_nunser_children = 0;
entry->ht_next = NULL;
entry->ht_prev = NULL;
entry->il_next = NULL;
@@ -7882,9 +8031,102 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__mark_flush_dep_clean() */
-#ifndef NDEBUG
/*-------------------------------------------------------------------------
+ * Function: H5C__mark_flush_dep_serialized()
+ *
+ * Purpose: Decrement the flush_dep_nunser_children fields of all the
+ * target entry's flush dependency parents in response to
+ * the target entry becoming serialized.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 8/30/16
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C__mark_flush_dep_serialized(H5C_cache_entry_t * entry_ptr)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(entry_ptr);
+
+ /* Iterate over the parent entries, if any */
+ for(u = 0; u < entry_ptr->flush_dep_nparents; u++) {
+
+ HDassert(entry_ptr->flush_dep_parent);
+ HDassert(entry_ptr->flush_dep_parent[u]->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(entry_ptr->flush_dep_parent[u]->flush_dep_nunser_children > 0);
+
+ /* decrement the parents number of unserialized children */
+ entry_ptr->flush_dep_parent[u]->flush_dep_nunser_children--;
+
+ /* If the parent has a 'notify' callback, send a 'child entry serialized' notice */
+ if(entry_ptr->flush_dep_parent[u]->type->notify &&
+ (entry_ptr->flush_dep_parent[u]->type->notify)(H5C_NOTIFY_ACTION_CHILD_SERIALIZED, entry_ptr->flush_dep_parent[u]) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify parent about child entry serialized flag set")
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C__mark_flush_dep_serialized() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5C__mark_flush_dep_unserialized()
+ *
+ * Purpose: Decrement the flush_dep_nunser_children fields of all the
+ * target entry's flush dependency parents in response to
+ * the target entry becoming unserialized.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 8/30/16
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C__mark_flush_dep_unserialized(H5C_cache_entry_t * entry_ptr)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(entry_ptr);
+
+ /* Iterate over the parent entries, if any */
+ for(u = 0; u < entry_ptr->flush_dep_nparents; u++) {
+ /* Sanity check */
+ HDassert(entry_ptr->flush_dep_parent);
+ HDassert(entry_ptr->flush_dep_parent[u]->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(entry_ptr->flush_dep_parent[u]->flush_dep_nunser_children <
+ entry_ptr->flush_dep_parent[u]->flush_dep_nchildren);
+
+ /* increment parents number of usserialized children */
+ entry_ptr->flush_dep_parent[u]->flush_dep_nunser_children++;
+
+ /* If the parent has a 'notify' callback, send a 'child entry unserialized' notice */
+ if(entry_ptr->flush_dep_parent[u]->type->notify &&
+ (entry_ptr->flush_dep_parent[u]->type->notify)(H5C_NOTIFY_ACTION_CHILD_UNSERIALIZED, entry_ptr->flush_dep_parent[u]) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "can't notify parent about child entry serialized flag reset")
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C__mark_flush_dep_unserialized() */
+
+
+#ifndef NDEBUG
+/*-------------------------------------------------------------------------
* Function: H5C__assert_flush_dep_nocycle()
*
* Purpose: Assert recursively that base_entry is not the same as
@@ -8074,6 +8316,10 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
#endif /* H5C_DO_MEMORY_SANITY_CHECKS */
entry_ptr->image_up_to_date = TRUE;
+ if(entry_ptr->flush_dep_nparents > 0)
+ if(H5C__mark_flush_dep_serialized(entry_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "Can't propagate serialization status to fd parents")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__generate_image */