diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 160 | ||||
-rw-r--r-- | src/H5ACpkg.h | 14 | ||||
-rw-r--r-- | src/H5ACprivate.h | 4 | ||||
-rw-r--r-- | src/H5C.c | 97 | ||||
-rw-r--r-- | src/H5Cprivate.h | 19 |
5 files changed, 289 insertions, 5 deletions
@@ -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, @@ -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, |