summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5AC.c160
-rw-r--r--src/H5ACpkg.h14
-rw-r--r--src/H5ACprivate.h4
-rw-r--r--src/H5C.c97
-rw-r--r--src/H5Cprivate.h19
5 files changed, 289 insertions, 5 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index d08c7df..798c0b5 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -465,6 +465,10 @@ H5AC_term_interface(void)
* Added code to set the prefix if required.
*
* JRM - 1/20/06
+ *
+ * Added code to initialize the new write_done field.
+ *
+ * JRM - 5/11/06
*
*-------------------------------------------------------------------------
*/
@@ -568,6 +572,7 @@ H5AC_create(const H5F_t *f,
aux_ptr->d_slist_len = 0;
aux_ptr->c_slist_ptr = NULL;
aux_ptr->c_slist_len = 0;
+ aux_ptr->write_done = NULL;
sprintf(prefix, "%d:", mpi_rank);
}
@@ -863,6 +868,9 @@ done:
* bug in PHDF5. See the header comments on the H5AC_aux_t
* structure for details.
*
+ * JRM -- 5/11/06
+ * Added call to the write_done callback.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -936,6 +944,12 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
}
+
+ if ( aux_ptr->write_done != NULL ) {
+
+ (aux_ptr->write_done)();
+ }
+
} /* end if ( aux_ptr->mpi_rank == 0 ) */
status = H5AC_propagate_flushed_and_still_clean_entries_list(f,
@@ -1199,9 +1213,6 @@ done:
* If the entry has changed size, the function updates
* data structures for the size change.
*
- * If the entry is not already dirty, the function places
- * the entry on the skip list.
- *
* Return: Non-negative on success/Negative on failure
*
* Programmer: John Mainzer
@@ -1260,7 +1271,7 @@ H5AC_mark_pinned_entry_dirty(H5F_t * f,
if ( result < 0 ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, \
"H5AC_log_dirtied_entry() failed.")
}
}
@@ -1285,6 +1296,82 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5AC_mark_pinned_or_protected_entry_dirty
+ *
+ * Purpose: Mark a pinned or protected entry as dirty. The target
+ * entry MUST be either pinned, protected, or both.
+ *
+ * Unlike H5AC_mark_pinned_entry_dirty(), this function does
+ * not support size changes.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 5/16/06
+ *
+ * Modifications:
+ *
+ * None
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC_mark_pinned_or_protected_entry_dirty(H5F_t * f,
+ void * thing)
+{
+ H5C_t * cache_ptr = f->shared->cache;
+#ifdef H5_HAVE_PARALLEL
+ H5AC_info_t * info_ptr;
+#endif /* H5_HAVE_PARALLEL */
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5AC_mark_pinned_or_protected_entry_dirty, FAIL)
+
+#ifdef H5_HAVE_PARALLEL
+
+ HDassert( cache_ptr );
+ HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( thing );
+
+ info_ptr = (H5AC_info_t *)thing;
+
+ if ( ( info_ptr->is_dirty == FALSE ) &&
+ ( ! ( info_ptr->is_protected ) ) &&
+ ( info_ptr->is_pinned ) &&
+ ( NULL != cache_ptr->aux_ptr) ) {
+
+ result = H5AC_log_dirtied_entry(cache_ptr,
+ info_ptr,
+ info_ptr->addr,
+ FALSE,
+ 0);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, \
+ "H5AC_log_dirtied_entry() failed.")
+ }
+ }
+#endif /* H5_HAVE_PARALLEL */
+
+ result = H5C_mark_pinned_or_protected_entry_dirty(cache_ptr, thing);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, \
+ "H5C_mark_pinned_entry_dirty() failed.")
+
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_mark_pinned_entry_dirty() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5AC_rename
*
* Purpose: Use this function to notify the cache that an object's
@@ -1664,6 +1751,11 @@ done:
* as it can effect dirty byte creation counts, thereby
* throwing the caches out of sync in the PHDF5 case.
*
+ * JRM - 5/16/06
+ * Added code to use the new dirtied field in
+ * H5C_cache_entry_t in the test to see if the entry has
+ * been dirtied.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1691,7 +1783,8 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
HDassert( ((H5AC_info_t *)thing)->addr == addr );
HDassert( ((H5AC_info_t *)thing)->type == type );
- dirtied = ((flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG );
+ dirtied = ( ( (flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG ) ||
+ ( ((H5AC_info_t *)thing)->dirtied ) );
if ( dirtied ) {
@@ -1783,6 +1876,55 @@ done:
/*-------------------------------------------------------------------------
+ * Function: HA5C_set_write_done_callback
+ *
+ * Purpose: Set the value of the write_done callback. This callback
+ * is used to improve performance of the parallel test bed
+ * for the cache.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 5/11/06
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifdef H5_HAVE_PARALLEL
+herr_t
+H5AC_set_write_done_callback(H5C_t * cache_ptr,
+ void (* write_done)(void))
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5AC_aux_t * aux_ptr = NULL;
+
+ FUNC_ENTER_NOAPI(H5AC_set_write_done_callback, FAIL)
+
+ /* This would normally be an assert, but we need to use an HGOTO_ERROR
+ * call to shut up the compiler.
+ */
+ if ( ( ! cache_ptr ) || ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr")
+ }
+
+ aux_ptr = cache_ptr->aux_ptr;
+
+ HDassert( aux_ptr != NULL );
+ HDassert( aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC );
+
+ aux_ptr->write_done = write_done;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_set_write_done_callback() */
+#endif /* H5_HAVE_PARALLEL */
+
+
+/*-------------------------------------------------------------------------
* Function: H5AC_stats
*
* Purpose: Prints statistics about the cache.
@@ -3410,6 +3552,9 @@ done:
*
* Modifications:
*
+ * JRM -- 5/11/06
+ * Added code to call the write_done callback.
+ *
*-------------------------------------------------------------------------
*/
@@ -3476,6 +3621,11 @@ H5AC_propagate_flushed_and_still_clean_entries_list(H5F_t * f,
"H5C_flush_to_min_clean() failed.")
}
+ if ( aux_ptr->write_done != NULL ) {
+
+ (aux_ptr->write_done)();
+ }
+
if ( H5AC_broadcast_clean_list(cache_ptr) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
diff --git a/src/H5ACpkg.h b/src/H5ACpkg.h
index 903eca3..e31f245 100644
--- a/src/H5ACpkg.h
+++ b/src/H5ACpkg.h
@@ -263,6 +263,18 @@
* contain the value 0 on all processes other than process 0.
* It exists primarily for sanity checking.
*
+ * write_done: In the parallel test bed, it is necessary to ensure that
+ * all writes to the server process from cache 0 complete
+ * before it enters the barrier call with the other caches.
+ *
+ * The write_done callback allows t_cache to do this without
+ * requiring an ACK on each write. Since these ACKs greatly
+ * increase the run time on some platforms, this is a
+ * significant optimization.
+ *
+ * This field must be set to NULL when the callback is not
+ * needed.
+ *
****************************************************************************/
#ifdef H5_HAVE_PARALLEL
@@ -308,6 +320,8 @@ typedef struct H5AC_aux_t
int32_t c_slist_len;
+ void (* write_done)(void);
+
} H5AC_aux_t; /* struct H5AC_aux_t */
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index 6638be4..6dcd88c 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -261,10 +261,14 @@ H5_DLL herr_t H5AC_mark_pinned_entry_dirty(H5F_t * f,
void * thing,
hbool_t size_changed,
size_t new_size);
+H5_DLL herr_t H5AC_mark_pinned_or_protected_entry_dirty(H5F_t * f,
+ void * thing);
H5_DLL herr_t H5AC_rename(H5F_t *f, const H5AC_class_t *type,
haddr_t old_addr, haddr_t new_addr);
H5_DLL herr_t H5AC_dest(H5F_t *f, hid_t dxpl_id);
+H5_DLL herr_t H5AC_set_write_done_callback(H5C_t * cache_ptr,
+ void (* write_done)(void));
H5_DLL herr_t H5AC_stats(const H5F_t *f);
H5_DLL herr_t H5AC_get_cache_auto_resize_config(H5AC_t * cache_ptr,
diff --git a/src/H5C.c b/src/H5C.c
index fcc9e49..15fc671 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -2607,6 +2607,7 @@ H5C_create(size_t max_cache_size,
((cache_ptr->epoch_markers)[i]).size = (size_t)0;
((cache_ptr->epoch_markers)[i]).type = &epoch_marker_class;
((cache_ptr->epoch_markers)[i]).is_dirty = FALSE;
+ ((cache_ptr->epoch_markers)[i]).dirtied = FALSE;
((cache_ptr->epoch_markers)[i]).is_protected = FALSE;
((cache_ptr->epoch_markers)[i]).is_pinned = FALSE;
((cache_ptr->epoch_markers)[i]).in_slist = FALSE;
@@ -3732,6 +3733,10 @@ done:
* Added initialization for the new is_pinned field of the
* H5C_cache_entry_t structure.
*
+ * JRM -- 5/3/06
+ * Added initialization for the new dirtied field of the
+ * H5C_cache_entry_t structure.
+ *
*-------------------------------------------------------------------------
*/
@@ -3789,6 +3794,9 @@ H5C_insert_entry(H5F_t * f,
/* newly inserted entries are assumed to be dirty */
entry_ptr->is_dirty = TRUE;
+ /* not protected, so can't be dirtied */
+ entry_ptr->dirtied = FALSE;
+
if ( (type->size)(f, thing, &(entry_ptr->size)) < 0 ) {
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, \
@@ -4364,6 +4372,79 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5C_mark_pinned_or_protected_entry_dirty
+ *
+ * Purpose: Mark a pinned or protected entry as dirty. The target entry
+ * MUST be either pinned or protected, and MAY be both.
+ *
+ * At present, this funtion does not support size change.
+ *
+ * In the protected case, this call is the functional
+ * equivalent of setting the H5C__DIRTIED_FLAG on an unprotect
+ * call.
+ *
+ * In the pinned but not protected case, if the entry is not
+ * already dirty, the function places function marks the entry
+ * dirty and places it on the skip list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 5/15/06
+ *
+ * Modifications:
+ *
+ * None
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_mark_pinned_or_protected_entry_dirty(H5C_t * cache_ptr,
+ void * thing)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5C_cache_entry_t * entry_ptr;
+
+ FUNC_ENTER_NOAPI(H5C_mark_pinned_or_protected_entry_dirty, FAIL)
+
+ HDassert( cache_ptr );
+ HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( thing );
+
+ entry_ptr = (H5C_cache_entry_t *)thing;
+
+ if ( entry_ptr->is_protected ) {
+
+ /* set the dirtied flag */
+ entry_ptr->dirtied = TRUE;
+
+ } else if ( entry_ptr->is_pinned ) {
+
+ /* mark the entry as dirty if it isn't already */
+ entry_ptr->is_dirty = TRUE;
+
+
+ if ( ! (entry_ptr->in_slist) ) {
+
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr)
+ }
+
+ H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr)
+
+ } else {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, \
+ "Entry is neither pinned nor protected??")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5C_mark_pinned_or_protected_entry_dirty() */
+
+
+/*-------------------------------------------------------------------------
*
* Function: H5C_rename_entry
*
@@ -4621,6 +4702,10 @@ done:
* JRM -- 10/22/05
* Hand optimizations.
*
+ * JRM -- 5/3/06
+ * Added code to set the new dirtied field in
+ * H5C_cache_entry_t to FALSE prior to return.
+ *
*-------------------------------------------------------------------------
*/
@@ -4791,6 +4876,8 @@ H5C_protect(H5F_t * f,
entry_ptr->is_protected = TRUE;
+ entry_ptr->dirtied = FALSE;
+
ret_value = thing;
H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit)
@@ -5857,6 +5944,11 @@ done:
* Unpdated function to pin and unpin entries as directed via
* the new H5C__PIN_ENTRY_FLAG and H5C__UNPIN_ENTRY_FLAG flags.
*
+ * JRM -- 5/3/06
+ * Added code to make use of the new dirtied field in
+ * H5C_cache_entry_t. If this field is TRUE, it is the
+ * equivalent of setting the H5C__DIRTIED_FLAG.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -5910,6 +6002,11 @@ H5C_unprotect(H5F_t * f,
HDassert( entry_ptr->addr == addr );
HDassert( entry_ptr->type == type );
+ /* also set the dirtied variable if the dirtied field is set in
+ * the entry.
+ */
+ dirtied |= entry_ptr->dirtied;
+
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index 43a93b3..bdcf501 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -234,6 +234,21 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr,
* modules using the cache. These still clear the
* is_dirty field as before. -- JRM 7/5/05
*
+ * dirtied: Boolean flag used to indicate that the entry has been
+ * dirtied while protected.
+ *
+ * This field is set to FALSE in the protect call, and may
+ * be set to TRUE by the
+ * H5C_mark_pinned_or_protected_entry_dirty()
+ * call at an time prior to the unprotect call.
+ *
+ * The H5C_mark_pinned_or_protected_entry_dirty() call exists
+ * as a convenience function for the fractal heap code which
+ * may not know if an entry is protected or pinned, but knows
+ * that is either protected or pinned. The dirtied field was
+ * added as in the parallel case, it is necessary to know
+ * whether a protected entry was dirty prior to the protect call.
+ *
* is_protected: Boolean flag indicating whether this entry is protected
* (or locked, to use more conventional terms). When it is
* protected, the entry cannot be flushed or accessed until
@@ -401,6 +416,7 @@ typedef struct H5C_cache_entry_t
size_t size;
const H5C_class_t * type;
hbool_t is_dirty;
+ hbool_t dirtied;
hbool_t is_protected;
hbool_t is_pinned;
hbool_t in_slist;
@@ -835,6 +851,9 @@ H5_DLL herr_t H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr,
hbool_t size_changed,
size_t new_size);
+H5_DLL herr_t H5C_mark_pinned_or_protected_entry_dirty(H5C_t * cache_ptr,
+ void * thing);
+
H5_DLL herr_t H5C_rename_entry(H5C_t * cache_ptr,
const H5C_class_t * type,
haddr_t old_addr,