summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5AC.c897
-rw-r--r--src/H5ACprivate.h20
-rw-r--r--src/H5ACpublic.h87
-rw-r--r--src/H5C.c383
-rw-r--r--src/H5Cpkg.h14
-rw-r--r--src/H5Cprivate.h18
-rw-r--r--src/H5Edefin.h4
-rw-r--r--src/H5Einit.h10
-rw-r--r--src/H5Epubgen.h6
-rw-r--r--src/H5Eterm.h272
-rw-r--r--src/H5config.h.in3
-rw-r--r--src/H5err.txt2
12 files changed, 1534 insertions, 182 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index cf794c6..a7ae790 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -742,6 +742,10 @@ done:
* Added code to free the auxiliary structure and its
* associated slist if present.
* JRM - 6/28/05
+ *
+ * Added code to close the trace file if it is present.
+ *
+ * JRM - 6/8/06
*
*-------------------------------------------------------------------------
*/
@@ -768,6 +772,14 @@ H5AC_dest(H5F_t *f, hid_t dxpl_id)
}
#endif /* H5_HAVE_PARALLEL */
+#if H5AC__TRACE_FILE_ENABLED
+ if ( H5AC_close_trace_file(cache) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5AC_close_trace_file() failed.")
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
if ( H5C_dest(f, dxpl_id, H5AC_noblock_dxpl_id, cache) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache")
@@ -802,6 +814,92 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5AC_expunge_entry
+ *
+ * Purpose: Expunge the target entry from the cache without writing it
+ * to disk even if it is dirty. The entry must not be either
+ * pinned or protected.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 6/30/06
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC_expunge_entry(H5F_t *f,
+ hid_t dxpl_id,
+ const H5AC_class_t *type,
+ haddr_t addr)
+{
+ herr_t result;
+ herr_t ret_value=SUCCEED; /* Return value */
+ H5AC_t * cache_ptr = NULL;
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ FUNC_ENTER_NOAPI(H5AC_expunge_entry, FAIL)
+
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->cache);
+ HDassert(type);
+ HDassert(type->clear);
+ HDassert(type->dest);
+ HDassert(H5F_addr_defined(addr));
+
+ cache_ptr = f->shared->cache;
+
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the expunge entry call, only the addr, and type id are really
+ * necessary in the trace file. Write the return value to catch occult
+ * errors.
+ */
+ if ( ( cache_ptr != NULL ) &&
+ ( H5C_get_trace_file_ptr(cache_ptr, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_expunge_entry %lx %d",
+ (unsigned long)addr,
+ (int)(type->id));
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ result = H5C_expunge_entry(f,
+ dxpl_id,
+ H5AC_noblock_dxpl_id,
+ cache_ptr,
+ type,
+ addr);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \
+ "H5C_expunge_entry() failed.")
+ }
+
+done:
+
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_expunge_entry() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5AC_flush
*
* Purpose: Flush (and possibly destroy) the metadata cache associated
@@ -871,6 +969,9 @@ done:
* JRM -- 5/11/06
* Added call to the write_done callback.
*
+ * JRM -- 6/6/06
+ * Added trace file support.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -882,6 +983,10 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags)
H5AC_aux_t * aux_ptr = NULL;
int mpi_code;
#endif /* H5_HAVE_PARALLEL */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_flush, FAIL)
@@ -889,6 +994,20 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags)
HDassert(f);
HDassert(f->shared->cache);
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the flush, only the flags are really necessary in the trace file.
+ * Write the result to catch occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_flush 0x%x", flags);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
#ifdef H5_HAVE_PARALLEL
aux_ptr = f->shared->cache->aux_ptr;
@@ -972,6 +1091,13 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags)
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_flush() */
@@ -1118,6 +1244,9 @@ done:
* the PHDF5 case. It should have no effect on either the
* serial or FPHSD5 cases.
*
+ * JRM - 6/6/06
+ * Added trace file support.
+ *
*-------------------------------------------------------------------------
*/
@@ -1131,6 +1260,11 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *
#ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ size_t trace_entry_size = 0;
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_set, FAIL)
@@ -1142,6 +1276,27 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *
HDassert(H5F_addr_defined(addr));
HDassert(thing);
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the insert, only the addr, size, type id and flags are really
+ * necessary in the trace file. Write the result to catch occult
+ * errors.
+ *
+ * Note that some data is not available right now -- put what we can
+ * in the trace buffer now, and fill in the rest at the end.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_set 0x%lx %d 0x%x",
+ (unsigned long)addr,
+ type->id,
+ flags);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
/* Get local copy of this information */
cache = f->shared->cache;
info = (H5AC_info_t *)thing;
@@ -1181,6 +1336,14 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *
HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C_insert_entry() failed")
}
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ /* make note of the entry size */
+ trace_entry_size = ((H5C_cache_entry_t *)thing)->size;
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
#ifdef H5_HAVE_PARALLEL
if ( ( aux_ptr != NULL ) &&
( aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold ) ) {
@@ -1199,6 +1362,15 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d %d\n", trace,
+ (int)trace_entry_size,
+ (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_set() */
@@ -1220,7 +1392,7 @@ done:
*
* Modifications:
*
- * None
+ * Added trace file support. JRM -- 6/6/06
*
*-------------------------------------------------------------------------
*/
@@ -1233,9 +1405,31 @@ H5AC_mark_pinned_entry_dirty(H5F_t * f,
H5C_t *cache_ptr = f->shared->cache;
herr_t result;
herr_t ret_value = SUCCEED; /* Return value */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_mark_pinned_entry_dirty, FAIL)
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the mark pinned entry dirty call, only the addr, size_changed,
+ * and new_size are really necessary in the trace file. Write the result
+ * to catch occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_mark_pinned_entry_dirty 0x%lx %d %d",
+ (unsigned long)(((H5C_cache_entry_t *)thing)->addr),
+ (int)size_changed,
+ (int)new_size);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
#ifdef H5_HAVE_PARALLEL
HDassert( cache_ptr );
@@ -1290,6 +1484,13 @@ H5AC_mark_pinned_entry_dirty(H5F_t * f,
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_mark_pinned_entry_dirty() */
@@ -1311,7 +1512,7 @@ done:
*
* Modifications:
*
- * None
+ * Added trace file support. JRM -- 6/6/06
*
*-------------------------------------------------------------------------
*/
@@ -1325,9 +1526,29 @@ H5AC_mark_pinned_or_protected_entry_dirty(H5F_t * f,
#endif /* H5_HAVE_PARALLEL */
herr_t result;
herr_t ret_value = SUCCEED; /* Return value */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_mark_pinned_or_protected_entry_dirty, FAIL)
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the mark pinned or protected entry dirty call, only the addr
+ * is really necessary in the trace file. Write the result to catch
+ * occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_mark_pinned_or_protected_entry_dirty %lx",
+ (unsigned long)(((H5C_cache_entry_t *)thing)->addr));
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
#ifdef H5_HAVE_PARALLEL
HDassert( cache_ptr );
@@ -1366,6 +1587,13 @@ H5AC_mark_pinned_or_protected_entry_dirty(H5F_t * f,
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_mark_pinned_entry_dirty() */
@@ -1411,6 +1639,9 @@ done:
* To maintain this invarient, only rename entries immediately
* after you unprotect them.
*
+ * JRM - 6/6/06
+ * Added trace file support.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1421,6 +1652,10 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad
#ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_rename, FAIL)
@@ -1431,6 +1666,24 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad
HDassert(H5F_addr_defined(new_addr));
HDassert(H5F_addr_ne(old_addr, new_addr));
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the rename call, only the old addr and new addr are really
+ * necessary in the trace file. Include the type id so we don't have to
+ * look it up. Also write the result to catch occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_rename %lx %lx %d",
+ (unsigned long)old_addr,
+ (unsigned long)new_addr,
+ (int)(type->id));
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
#ifdef H5_HAVE_PARALLEL
if ( NULL != (aux_ptr = f->shared->cache->aux_ptr) ) {
@@ -1475,6 +1728,13 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_rename() */
@@ -1493,7 +1753,7 @@ done:
*
* Modifications:
*
- * None.
+ * Added trace file support. 6/6/06
*
*-------------------------------------------------------------------------
*/
@@ -1504,9 +1764,28 @@ H5AC_pin_protected_entry(H5F_t * f,
H5C_t *cache_ptr = f->shared->cache;
herr_t result;
herr_t ret_value = SUCCEED; /* Return value */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_pin_protected_entry, FAIL)
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the pin protected entry call, only the addr is really necessary
+ * in the trace file. Also write the result to catch occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_pin_protected_entry %lx",
+ (unsigned long)(((H5C_cache_entry_t *)thing)->addr));
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
result = H5C_pin_protected_entry(cache_ptr, thing);
if ( result < 0 ) {
@@ -1517,6 +1796,13 @@ H5AC_pin_protected_entry(H5F_t * f,
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_pin_protected_entry() */
@@ -1579,6 +1865,9 @@ done:
* in H5C.c, and then re-wrote the function as a wrapper for
* H5C_protect().
*
+ * JRM - 6/6/06
+ * Added trace file support.
+ *
*-------------------------------------------------------------------------
*/
void *
@@ -1590,8 +1879,14 @@ H5AC_protect(H5F_t *f,
void *udata2,
H5AC_protect_t UNUSED rw)
{
- void * thing = NULL;
+ /* char * fcn_name = "H5AC_protect"; */
+ void * thing = (void *)NULL;
void * ret_value; /* Return value */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ size_t trace_entry_size = 0;
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_protect, NULL)
@@ -1603,6 +1898,24 @@ H5AC_protect(H5F_t *f,
HDassert(type->load);
HDassert(H5F_addr_defined(addr));
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the protect call, only the addr and type id is really necessary
+ * in the trace file. Include the size of the entry protected as a
+ * sanity check. Also indicate whether the call was successful to
+ * catch occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_protect %lx %d",
+ (unsigned long)addr,
+ (int)(type->id));
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
thing = H5C_protect(f,
dxpl_id,
H5AC_noblock_dxpl_id,
@@ -1617,17 +1930,146 @@ H5AC_protect(H5F_t *f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C_protect() failed.")
}
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ /* make note of the entry size */
+ trace_entry_size = ((H5C_cache_entry_t *)thing)->size;
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
/* Set return value */
ret_value = thing;
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d %d\n", trace,
+ (int)trace_entry_size,
+ (int)(ret_value != NULL));
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_protect() */
/*-------------------------------------------------------------------------
+ * Function: H5AC_resize_pinned_entry
+ *
+ * Purpose: Resize a pinned entry. The target entry MUST be
+ * be pinned, and MUST not be unprotected.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 7/5/06
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC_resize_pinned_entry(H5F_t * f,
+ void * thing,
+ size_t new_size)
+{
+ H5C_t *cache_ptr = f->shared->cache;
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ FUNC_ENTER_NOAPI(H5AC_resize_pinned_entry, FAIL)
+
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the resize pinned entry call, only the addr, and new_size are
+ * really necessary in the trace file. Write the result to catch
+ * occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_resize_pinned_entry 0x%lx %d %d",
+ (unsigned long)(((H5C_cache_entry_t *)thing)->addr),
+ (int)new_size);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+#ifdef H5_HAVE_PARALLEL
+
+ HDassert( cache_ptr );
+ HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( thing );
+
+ if ( ( ((H5AC_info_t *)thing)->is_dirty == FALSE ) &&
+ ( NULL != cache_ptr->aux_ptr) ) {
+
+ H5AC_info_t * entry_ptr;
+
+ entry_ptr = (H5AC_info_t *)thing;
+
+ if ( ! ( entry_ptr->is_pinned ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \
+ "Entry isn't pinned??")
+ }
+
+ if ( entry_ptr->is_protected ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \
+ "Entry is protected??")
+ }
+
+ result = H5AC_log_dirtied_entry(cache_ptr,
+ entry_ptr,
+ entry_ptr->addr,
+ TRUE,
+ new_size);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, \
+ "H5AC_log_dirtied_entry() failed.")
+ }
+ }
+#endif /* H5_HAVE_PARALLEL */
+
+ result = H5C_resize_pinned_entry(cache_ptr,
+ thing,
+ new_size);
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \
+ "H5C_resize_pinned_entry() failed.")
+
+ }
+
+done:
+
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_resize_pinned_entry() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5AC_unpin_entry()
*
* Purpose: Unpin a cache entry. The entry must be unprotected at
@@ -1640,7 +2082,7 @@ done:
*
* Modifications:
*
- * None.
+ * Added code supporting the trace file. JRM -- 6/7/06
*
*-------------------------------------------------------------------------
*/
@@ -1651,9 +2093,28 @@ H5AC_unpin_entry(H5F_t * f,
H5C_t *cache_ptr = f->shared->cache;
herr_t result;
herr_t ret_value = SUCCEED; /* Return value */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_unpin_entry, FAIL)
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the unpin entry call, only the addr is really necessary
+ * in the trace file. Also write the result to catch occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_unpin_entry %lx",
+ (unsigned long)(((H5C_cache_entry_t *)thing)->addr));
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
result = H5C_unpin_entry(cache_ptr, thing);
if ( result < 0 ) {
@@ -1663,6 +2124,13 @@ H5AC_unpin_entry(H5F_t * f,
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_unpin_entry() */
@@ -1756,6 +2224,9 @@ done:
* H5C_cache_entry_t in the test to see if the entry has
* been dirtied.
*
+ * JRM - 6/7/06
+ * Added support for the trace file.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1770,6 +2241,12 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
#ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
+#if H5AC__TRACE_FILE_ENABLED
+ char trace[128] = "";
+ size_t trace_new_size = 0;
+ unsigned trace_flags = 0;
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_unprotect, FAIL)
@@ -1783,6 +2260,25 @@ 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 );
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the unprotect call, only the addr, type id, flags, and possible
+ * new size are really necessary in the trace file. Write the return
+ * value to catch occult errors.
+ */
+ if ( ( f != NULL ) &&
+ ( f->shared != NULL ) &&
+ ( f->shared->cache != NULL ) &&
+ ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ sprintf(trace, "H5AC_protect %lx %d",
+ (unsigned long)addr,
+ (int)(type->id));
+
+ trace_flags = flags;
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
dirtied = ( ( (flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG ) ||
( ((H5AC_info_t *)thing)->dirtied ) );
@@ -1798,6 +2294,10 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
size_changed = TRUE;
flags = flags | H5AC__SIZE_CHANGED_FLAG;
+#if H5AC__TRACE_FILE_ENABLED
+ trace_flags = flags;
+ trace_new_size = new_size;
+#endif /* H5AC__TRACE_FILE_ENABLED */
}
}
@@ -1870,6 +2370,17 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
done:
+#if H5AC__TRACE_FILE_ENABLED
+ if ( trace_file_ptr != NULL ) {
+
+ HDfprintf(trace_file_ptr, "%s %d %x %d\n",
+ trace,
+ (int)trace_new_size,
+ (unsigned)trace_flags,
+ (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_unprotect() */
@@ -1983,6 +2494,9 @@ done:
* Added support for the new dirty_bytes_threshold field of
* both H5AC_cache_config_t and H5AC_aux_t.
*
+ * JRM - 6/8/06
+ * Added support for the new trace file related fields.
+ *
*-------------------------------------------------------------------------
*/
@@ -2036,6 +2550,9 @@ H5AC_get_cache_auto_resize_config(H5AC_t * cache_ptr,
config_ptr->rpt_fcn_enabled = TRUE;
}
+ config_ptr->open_trace_file = FALSE;
+ config_ptr->close_trace_file = FALSE;
+ config_ptr->trace_file_name[0] = '\0';
config_ptr->set_initial_size = internal_config.set_initial_size;
config_ptr->initial_size = internal_config.initial_size;
config_ptr->min_clean_fraction = internal_config.min_clean_fraction;
@@ -2224,10 +2741,13 @@ done:
* John Mainzer -- 4/6/05
* Updated for the addition of H5AC_cache_config_t.
*
- * John Mainzer -- 1025/05
- * Added support for the new dirty_bytes_threshold field of
+ * John Mainzer -- 10/25/05
+ * Added support for the new dirty_bytes_threshold field of
* both H5AC_cache_config_t and H5AC_aux_t.
*
+ * John Mainzer -- 6/7/06
+ * Added trace file support.
+ *
*-------------------------------------------------------------------------
*/
@@ -2235,12 +2755,29 @@ herr_t
H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
H5AC_cache_config_t *config_ptr)
{
- herr_t result;
- herr_t ret_value = SUCCEED; /* Return value */
+ /* const char * fcn_name = "H5AC_set_cache_auto_resize_config"; */
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+ int name_len;
H5C_auto_size_ctl_t internal_config;
+#if H5AC__TRACE_FILE_ENABLED
+ H5AC_cache_config_t trace_config = H5AC__DEFAULT_CACHE_CONFIG;
+ FILE * trace_file_ptr = NULL;
+#endif /* H5AC__TRACE_FILE_ENABLED */
FUNC_ENTER_NOAPI(H5AC_set_cache_auto_resize_config, FAIL)
+#if H5AC__TRACE_FILE_ENABLED
+ /* Make note of the new configuration. Don't look up the trace file
+ * pointer, as that may change before we use it.
+ */
+ if ( config_ptr != NULL ) {
+
+ trace_config = *config_ptr;
+
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
if ( ( cache_ptr == NULL )
#ifdef H5_HAVE_PARALLEL
||
@@ -2271,10 +2808,63 @@ H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
if ( ( config_ptr->rpt_fcn_enabled != TRUE ) &&
( config_ptr->rpt_fcn_enabled != FALSE ) ) {
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
"config_ptr->rpt_fcn_enabled must be either TRUE or FALSE.")
}
+ if ( ( config_ptr->open_trace_file != TRUE ) &&
+ ( config_ptr->open_trace_file != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->open_trace_file must be either TRUE or FALSE.")
+ }
+
+ if ( ( config_ptr->close_trace_file != TRUE ) &&
+ ( config_ptr->close_trace_file != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->close_trace_file must be either TRUE or FALSE.")
+ }
+
+ /* don't bother to test trace_file_name unless open_trace_file is TRUE */
+ if ( config_ptr->open_trace_file ) {
+
+ /* Can't really test the trace_file_name field without trying to
+ * open the file, so we will content ourselves with a couple of
+ * sanity checks on the length of the file name.
+ */
+ name_len = HDstrlen(config_ptr->trace_file_name);
+
+ if ( name_len <= 0 ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->trace_file_name is empty.")
+
+ } else if ( name_len > H5AC__MAX_TRACE_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->trace_file_name too long.")
+ }
+ }
+
+ if ( config_ptr->open_trace_file ) {
+
+ FILE * file_ptr = NULL;
+
+ if ( H5C_get_trace_file_ptr(cache_ptr, &file_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_get_trace_file_ptr() failed.")
+ }
+
+ if ( ( ! ( config_ptr->close_trace_file ) ) &&
+ ( file_ptr != NULL ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "Trace file already open.")
+ }
+ }
+
if (
(
config_ptr->dirty_bytes_threshold
@@ -2293,6 +2883,25 @@ H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
"config_ptr->dirty_bytes_threshold out of range.")
}
+ if ( config_ptr->close_trace_file ) {
+
+ if ( H5AC_close_trace_file(cache_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5AC_close_trace_file() failed.")
+ }
+ }
+
+ if ( config_ptr->open_trace_file ) {
+
+ if ( H5AC_open_trace_file(cache_ptr, config_ptr->trace_file_name) < 0 )
+ {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "H5AC_open_trace_file() failed.")
+ }
+ }
+
if ( H5AC_ext_config_2_int_config(config_ptr, &internal_config) !=
SUCCEED ) {
@@ -2318,6 +2927,47 @@ H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
done:
+#if H5AC__TRACE_FILE_ENABLED
+ /* For the set cache auto resize config call, only the contents
+ * of the config is necessary in the trace file. Write the return
+ * value to catch occult errors.
+ */
+ if ( ( cache_ptr != NULL ) &&
+ ( H5C_get_trace_file_ptr(cache_ptr, &trace_file_ptr) >= 0 ) &&
+ ( trace_file_ptr != NULL ) ) {
+
+ HDfprintf(trace_file_ptr,
+ "%s %d %d %d %d \"%s\" %d %d %f %d %d %ld %d %f %f %d %d %d %f %f %d %d %d %d %f %d %d\n",
+ "H5AC_set_cache_auto_resize_config",
+ trace_config.version,
+ (int)(trace_config.rpt_fcn_enabled),
+ (int)(trace_config.open_trace_file),
+ (int)(trace_config.close_trace_file),
+ trace_config.trace_file_name,
+ (int)(trace_config.set_initial_size),
+ (int)(trace_config.initial_size),
+ trace_config.min_clean_fraction,
+ (int)(trace_config.max_size),
+ (int)(trace_config.min_size),
+ trace_config.epoch_length,
+ (int)(trace_config.incr_mode),
+ trace_config.lower_hr_threshold,
+ trace_config.increment,
+ (int)(trace_config.apply_max_increment),
+ (int)(trace_config.max_increment),
+ (int)(trace_config.decr_mode),
+ trace_config.upper_hr_threshold,
+ trace_config.decrement,
+ (int)(trace_config.apply_max_decrement),
+ (int)(trace_config.max_decrement),
+ trace_config.epochs_before_eviction,
+ (int)(trace_config.apply_empty_reserve),
+ trace_config.empty_reserve,
+ trace_config.dirty_bytes_threshold,
+ (int)ret_value);
+ }
+#endif /* H5AC__TRACE_FILE_ENABLED */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_set_cache_auto_resize_config() */
@@ -2345,7 +2995,11 @@ done:
*
* Modifications:
*
- * None.
+ * - Added code testing the trace file configuration fields.
+ * These tests are not comprehensive, as many errors cannot
+ * be caught until the directives contained in these fields
+ * are applied.
+ * JRM - 5/15/06
*
*-------------------------------------------------------------------------
*/
@@ -2354,8 +3008,9 @@ herr_t
H5AC_validate_config(H5AC_cache_config_t * config_ptr)
{
- herr_t result;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+ int name_len;
H5C_auto_size_ctl_t internal_config;
FUNC_ENTER_NOAPI(H5AC_validate_config, FAIL)
@@ -2377,6 +3032,41 @@ H5AC_validate_config(H5AC_cache_config_t * config_ptr)
"config_ptr->rpt_fcn_enabled must be either TRUE or FALSE.")
}
+ if ( ( config_ptr->open_trace_file != TRUE ) &&
+ ( config_ptr->open_trace_file != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->open_trace_file must be either TRUE or FALSE.")
+ }
+
+ if ( ( config_ptr->close_trace_file != TRUE ) &&
+ ( config_ptr->close_trace_file != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->close_trace_file must be either TRUE or FALSE.")
+ }
+
+ /* don't bother to test trace_file_name unless open_trace_file is TRUE */
+ if ( config_ptr->open_trace_file ) {
+
+ /* Can't really test the trace_file_name field without trying to
+ * open the file, so we will content ourselves with a couple of
+ * sanity checks on the length of the file name.
+ */
+ name_len = HDstrlen(config_ptr->trace_file_name);
+
+ if ( name_len <= 0 ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->trace_file_name is empty.")
+
+ } else if ( name_len > H5AC__MAX_TRACE_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->trace_file_name too long.")
+ }
+ }
+
if ( config_ptr->dirty_bytes_threshold < H5AC__MIN_DIRTY_BYTES_THRESHOLD ) {
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
@@ -2410,6 +3100,185 @@ done:
} /* H5AC_validate_config() */
+/*-------------------------------------------------------------------------
+ * Function: H5AC_close_trace_file()
+ *
+ * Purpose: If a trace file is open, stop logging calls to the cache,
+ * and close the file.
+ *
+ * Note that the function does nothing if there is no trace
+ * file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 6/2/06
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_close_trace_file(H5AC_t * cache_ptr)
+
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ FILE * trace_file_ptr = NULL;
+
+ FUNC_ENTER_NOAPI(H5AC_close_trace_file, FAIL)
+
+ if ( cache_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL cache_ptr on entry.")
+ }
+
+ if ( H5C_get_trace_file_ptr(cache_ptr, &trace_file_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_get_trace_file_ptr() failed.")
+ }
+
+ if ( trace_file_ptr != NULL ) {
+
+ if ( H5C_set_trace_file_ptr(cache_ptr, NULL) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_set_trace_file_ptr() failed.")
+ }
+
+ if ( HDfclose(trace_file_ptr) != 0 ) {
+
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, \
+ "can't close metadata cache trace file")
+ }
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_close_trace_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AC_open_trace_file()
+ *
+ * Purpose: Open a trace file, and start logging calls to the cache.
+ *
+ * This logging is done at the H5C level, and will only take
+ * place if H5C_TRACE_FILE_ENABLED (defined in H5Cprivate.h)
+ * is TRUE.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 6/1/06
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_open_trace_file(H5AC_t * cache_ptr,
+ const char * trace_file_name)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ char file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 2];
+ FILE * file_ptr = NULL;
+#ifdef H5_HAVE_PARALLEL
+ H5AC_aux_t * aux_ptr = NULL;
+#endif /* H5_HAVE_PARALLEL */
+
+ FUNC_ENTER_NOAPI(H5AC_open_trace_file, FAIL)
+
+ HDassert(cache_ptr);
+
+ if ( cache_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr NULL on entry.")
+ }
+
+ if ( trace_file_name == NULL ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "NULL trace_file_name on entry.")
+ }
+
+ if ( HDstrlen(trace_file_name) > H5AC__MAX_TRACE_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "trace file name too long.")
+ }
+
+ if ( H5C_get_trace_file_ptr(cache_ptr, &file_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_get_trace_file_ptr() failed.")
+ }
+
+ if ( file_ptr != NULL ) {
+
+ HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "trace file already open.")
+ }
+
+#ifdef H5_HAVE_PARALLEL
+
+ aux_ptr = (H5AC_aux_t *)(cache_ptr->aux_ptr);
+
+ if ( cache_ptr->aux_ptr == NULL ) {
+
+ sprintf(file_name, "%s", trace_file_name);
+
+ } else {
+
+ if ( aux_ptr->magic != H5AC__H5AC_AUX_T_MAGIC ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad aux_ptr->magic.")
+ }
+
+ sprintf(file_name, "%s.%d", trace_file_name, aux_ptr->mpi_rank);
+
+ }
+
+ if ( HDstrlen(file_name) >
+ H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 1 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "cooked trace file name too long.")
+ }
+
+#else /* H5_HAVE_PARALLEL */
+
+ sprintf(file_name, "%s", trace_file_name);
+
+#endif /* H5_HAVE_PARALLEL */
+
+ if ( (file_ptr = HDfopen(file_name, "w")) == NULL ) {
+
+ /* trace file open failed */
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "trace file open failed.")
+ }
+
+ HDfprintf(file_ptr, "### HDF5 metadata cache trace file version 1 ###\n");
+
+ if ( H5C_set_trace_file_ptr(cache_ptr, file_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_set_trace_file_ptr() failed.")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_open_trace_file() */
+
+
/*************************************************************************/
/**************************** Private Functions: *************************/
/*************************************************************************/
@@ -3063,7 +3932,7 @@ H5AC_log_flushed_entry(H5C_t * cache_ptr,
haddr_t addr,
hbool_t was_dirty,
unsigned flags,
- UNUSED int type_id)
+ int UNUSED type_id)
{
herr_t ret_value = SUCCEED; /* Return value */
hbool_t cleared;
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index c3433be..2cbda20 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -38,6 +38,11 @@
#include "H5Fprivate.h" /* File access */
#include "H5Cprivate.h" /* cache */
+#ifdef H5_METADATA_TRACE_FILE
+#define H5AC__TRACE_FILE_ENABLED 1
+#else /* H5_METADATA_TRACE_FILE */
+#define H5AC__TRACE_FILE_ENABLED 0
+#endif /* H5_METADATA_TRACE_FILE */
/* Types of metadata objects cached */
typedef enum {
@@ -185,6 +190,9 @@ extern hid_t H5AC_ind_dxpl_id;
{ \
/* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, \
/* hbool_t rpt_fcn_enabled = */ FALSE, \
+ /* hbool_t open_trace_file = */ FALSE, \
+ /* hbool_t close_trace_file = */ FALSE, \
+ /* char trace_file_name[] = */ "", \
/* hbool_t set_initial_size = */ TRUE, \
/* size_t initial_size = */ ( 1 * 1024 * 1024), \
/* double min_clean_fraction = */ 0.5, \
@@ -251,6 +259,9 @@ H5_DLL herr_t H5AC_pin_protected_entry(H5F_t * f, void * thing);
H5_DLL void * H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
haddr_t addr, const void *udata1, void *udata2,
H5AC_protect_t rw);
+H5_DLL herr_t H5AC_resize_pinned_entry(H5F_t * f,
+ void * thing,
+ size_t new_size);
H5_DLL herr_t H5AC_unpin_entry(H5F_t * f,
void * thing);
H5_DLL herr_t H5AC_unprotect(H5F_t *f, hid_t dxpl_id,
@@ -267,6 +278,10 @@ 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_expunge_entry(H5F_t *f, hid_t dxpl_id,
+ const H5AC_class_t *type, haddr_t addr);
+
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);
@@ -290,5 +305,10 @@ H5_DLL herr_t H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
H5_DLL herr_t H5AC_validate_config(H5AC_cache_config_t * config_ptr);
+H5_DLL herr_t H5AC_close_trace_file( H5AC_t * cache_ptr);
+
+H5_DLL herr_t H5AC_open_trace_file(H5AC_t * cache_ptr,
+ const char * trace_file_name);
+
#endif /* !_H5ACprivate_H */
diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h
index 81d3319..a050a03 100644
--- a/src/H5ACpublic.h
+++ b/src/H5ACpublic.h
@@ -35,6 +35,8 @@
extern "C" {
#endif
+#define H5AC__MAX_TRACE_FILE_NAME_LEN 1024
+
/****************************************************************************
*
* structure H5AC_cache_config_t
@@ -53,6 +55,11 @@ extern "C" {
* considerable interaction between this value and the other fields in this
* structure.
*
+ * Similarly, the open_trace_file, close_trace_file, and trace_file_name
+ * fields do not appear in H5C_auto_size_ctl_t, as most trace file
+ * issues are handled at the H5AC level. The one exception is storage of
+ * the pointer to the trace file, which is handled by H5C.
+ *
* The structure is in H5ACpublic.h as we may wish to allow different
* configuration options for metadata and raw data caches.
*
@@ -69,6 +76,36 @@ extern "C" {
*
* This is a debugging function, and should normally be turned off.
*
+ * open_trace_file: Boolean field indicating whether the trace_file_name
+ * field should be used to open a trace file for the cache.
+ *
+ * The trace file is a debuging feature that allow the capture of
+ * top level metadata cache requests for purposes of debugging and/or
+ * optimization. This field should normally be set to FALSE, as
+ * trace file collection imposes considerable overhead.
+ *
+ * This field should only be set to TRUE when the trace_file_name
+ * contains the full path of the desired trace file, and either
+ * there is no open trace file on the cache, or the close_trace_file
+ * field is also TRUE.
+ *
+ * close_trace_file: Boolean field indicating whether the current trace
+ * file (if any) should be closed.
+ *
+ * See the above comments on the open_trace_file field. This field
+ * should be set to FALSE unless there is an open trace file on the
+ * cache that you wish to close.
+ *
+ * trace_file_name: Full path of the trace file to be opened if the
+ * open_trace_file field is TRUE.
+ *
+ * In the parallel case, an ascii representation of the mpi rank of
+ * the process will be appended to the file name to yield a unique
+ * trace file name for each process.
+ *
+ * The length of the path must not exceed H5AC__MAX_TRACE_FILE_NAME_LEN
+ * characters.
+ *
* set_initial_size: Boolean flag indicating whether the size of the
* initial size of the cache is to be set to the value given in
* the initial_size field. If set_initial_size is FALSE, the
@@ -265,55 +302,59 @@ extern "C" {
*
****************************************************************************/
-#define H5AC__CURR_CACHE_CONFIG_VERSION 1
+#define H5AC__CURR_CACHE_CONFIG_VERSION 1
typedef struct H5AC_cache_config_t
{
/* general configuration fields: */
- int version;
+ int version;
+
+ hbool_t rpt_fcn_enabled;
- hbool_t rpt_fcn_enabled;
+ hbool_t open_trace_file;
+ hbool_t close_trace_file;
+ char trace_file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + 1];
- hbool_t set_initial_size;
- size_t initial_size;
+ hbool_t set_initial_size;
+ size_t initial_size;
- double min_clean_fraction;
+ double min_clean_fraction;
- size_t max_size;
- size_t min_size;
+ size_t max_size;
+ size_t min_size;
- long int epoch_length;
+ long int epoch_length;
/* size increase control fields: */
- enum H5C_cache_incr_mode incr_mode;
+ enum H5C_cache_incr_mode incr_mode;
- double lower_hr_threshold;
+ double lower_hr_threshold;
- double increment;
+ double increment;
- hbool_t apply_max_increment;
- size_t max_increment;
+ hbool_t apply_max_increment;
+ size_t max_increment;
/* size decrease control fields: */
- enum H5C_cache_decr_mode decr_mode;
+ enum H5C_cache_decr_mode decr_mode;
- double upper_hr_threshold;
+ double upper_hr_threshold;
- double decrement;
+ double decrement;
- hbool_t apply_max_decrement;
- size_t max_decrement;
+ hbool_t apply_max_decrement;
+ size_t max_decrement;
- int epochs_before_eviction;
+ int epochs_before_eviction;
- hbool_t apply_empty_reserve;
- double empty_reserve;
+ hbool_t apply_empty_reserve;
+ double empty_reserve;
/* parallel configuration fields: */
- int dirty_bytes_threshold;
+ int dirty_bytes_threshold;
} H5AC_cache_config_t;
diff --git a/src/H5C.c b/src/H5C.c
index dd0d56d..8283d77 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -1043,10 +1043,13 @@ if ( ( (cache_ptr) == NULL ) || \
* QAK -- 11/27/04
* Switched over to using skip list routines.
*
+ * JRM -- 6/27/06
+ * Added fail_val parameter.
+ *
*-------------------------------------------------------------------------
*/
-#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr) \
+#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \
{ \
HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
@@ -1057,7 +1060,7 @@ if ( ( (cache_ptr) == NULL ) || \
\
if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &(entry_ptr)->addr) \
< 0 ) \
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), \
"Can't insert entry in skip list") \
\
(entry_ptr)->in_slist = TRUE; \
@@ -2459,6 +2462,9 @@ done:
* JRM -- 3/16/06
* Added initialization for the pinned entry related fields.
*
+ * JRM -- 5/31/06
+ * Added initialization for the trace_file_ptr field.
+ *
*-------------------------------------------------------------------------
*/
@@ -2513,6 +2519,8 @@ H5C_create(size_t max_cache_size,
cache_ptr->magic = H5C__H5C_T_MAGIC;
+ cache_ptr->trace_file_ptr = NULL;
+
cache_ptr->aux_ptr = aux_ptr;
cache_ptr->max_type_id = max_type_id;
@@ -2690,7 +2698,11 @@ done:
*/
void
H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr,
+#ifndef NDEBUG
int32_t version,
+#else /* NDEBUG */
+ UNUSED int32_t version,
+#endif /* NDEBUG */
double hit_rate,
enum H5C_resize_status status,
size_t old_max_cache_size,
@@ -2951,6 +2963,116 @@ done:
/*-------------------------------------------------------------------------
+ *
+ * Function: H5C_expunge_entry
+ *
+ * Purpose: Use this function to tell the cache to expunge an entry
+ * from the cache without writing it to disk even if it is
+ * dirty. The entry may not be either pinned or protected.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 6/29/06
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5C_expunge_entry(H5F_t * f,
+ hid_t primary_dxpl_id,
+ hid_t secondary_dxpl_id,
+ H5C_t * cache_ptr,
+ const H5C_class_t * type,
+ haddr_t addr)
+{
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t first_flush = TRUE;
+ H5C_cache_entry_t * entry_ptr = NULL;
+
+ FUNC_ENTER_NOAPI(H5C_expunge_entry, FAIL)
+
+ HDassert( H5F_addr_defined(addr) );
+ HDassert( cache_ptr );
+ HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( type );
+ HDassert( type->clear );
+ HDassert( type->dest );
+
+#if H5C_DO_EXTREME_SANITY_CHECKS
+ if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "LRU sanity check failed.\n");
+ }
+#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
+
+ H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
+
+ if ( ( entry_ptr == NULL ) || ( entry_ptr->type != type ) ) {
+
+ /* the target doesn't exist in the cache, so we are done. */
+ HGOTO_DONE(SUCCEED)
+ }
+
+ HDassert( entry_ptr->addr == addr );
+ HDassert( entry_ptr->type == type );
+
+ if ( entry_ptr->is_protected ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \
+ "Target entry is protected.")
+ }
+
+ if ( entry_ptr->is_pinned ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \
+ "Target entry is pinned.")
+ }
+
+ /* If we get this far, call H5C_flush_single_entry() with the
+ * H5C__FLUSH_INVALIDATE_FLAG and the H5C__FLUSH_CLEAR_ONLY_FLAG.
+ * This will clear the entry, and then delete it from the cache.
+ */
+
+ result = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ entry_ptr->type,
+ entry_ptr->addr,
+ H5C__FLUSH_INVALIDATE_FLAG |
+ H5C__FLUSH_CLEAR_ONLY_FLAG,
+ &first_flush,
+ TRUE);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \
+ "H5C_flush_single_entry() failed.")
+ }
+
+done:
+
+#if H5C_DO_EXTREME_SANITY_CHECKS
+ if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "LRU sanity check failed.\n");
+ }
+#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5C_expunge_entry() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5C_flush_cache
*
* Purpose: Flush (and possibly destroy) the entries contained in the
@@ -3180,6 +3302,7 @@ H5C_flush_cache(H5F_t * f,
done:
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_flush_cache() */
@@ -3678,6 +3801,54 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5C_get_trace_file_ptr
+ *
+ * Purpose: Get the trace_file_ptr field from the cache.
+ *
+ * This field will either be NULL (which indicates that trace
+ * file logging is turned off), or contain a pointer to the
+ * open file to which trace file data is to be written.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 1/20/06
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5C_get_trace_file_ptr(H5C_t * cache_ptr,
+ FILE ** trace_file_ptr_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C_get_trace_file_ptr, 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")
+ }
+
+ if ( trace_file_ptr_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "NULL trace_file_ptr_ptr")
+ }
+
+ *trace_file_ptr_ptr = cache_ptr->trace_file_ptr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5C_get_trace_file_ptr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5C_insert_entry
*
* Purpose: Adds the specified thing to the cache. The thing need not
@@ -3932,7 +4103,7 @@ H5C_insert_entry(H5F_t * f,
if ( entry_ptr->is_dirty ) {
entry_ptr->flush_marker = set_flush_marker;
- H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr)
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
} else {
@@ -4359,7 +4530,7 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr,
if ( ! (entry_ptr->in_slist) ) {
- H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr)
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
}
H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr)
@@ -4426,7 +4597,7 @@ H5C_mark_pinned_or_protected_entry_dirty(H5C_t * cache_ptr,
if ( ! (entry_ptr->in_slist) ) {
- H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr)
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
}
H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr)
@@ -4565,7 +4736,7 @@ H5C_rename_entry(H5C_t * cache_ptr,
H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL)
- H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr)
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
H5C__UPDATE_RP_FOR_RENAME(cache_ptr, entry_ptr, was_dirty, FAIL)
@@ -4587,6 +4758,107 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5C_resize_pinned_entry
+ *
+ * Purpose: Resize a pinned entry. The target entry MUST be
+ * be pinned, and MUST not be unprotected.
+ *
+ * Resizing an entry dirties it, so 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
+ * 7/5/06
+ *
+ * Modifications:
+ *
+ * None
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_resize_pinned_entry(H5C_t * cache_ptr,
+ void * thing,
+ size_t new_size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5C_cache_entry_t * entry_ptr;
+
+ FUNC_ENTER_NOAPI(H5C_resize_pinned_entry, FAIL)
+
+ HDassert( cache_ptr );
+ HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( thing );
+
+ entry_ptr = (H5C_cache_entry_t *)thing;
+
+ if ( new_size <= 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \
+ "New size is non-positive.")
+ }
+
+ if ( ! ( entry_ptr->is_pinned ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \
+ "Entry isn't pinned??")
+ }
+
+ if ( entry_ptr->is_protected ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \
+ "Entry is protected??")
+ }
+
+ /* resizing dirties entries -- mark the entry as dirty if it
+ * isn't already
+ */
+ entry_ptr->is_dirty = TRUE;
+
+ /* update for change in entry size if necessary */
+ if ( entry_ptr->size != new_size ) {
+
+ /* update the protected entry list */
+ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr->pel_len), \
+ (cache_ptr->pel_size), \
+ (entry_ptr->size), (new_size));
+
+ /* update the hash table */
+ H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), (entry_ptr->size),\
+ (new_size));
+
+ /* if the entry is in the skip list, update that too */
+ if ( entry_ptr->in_slist ) {
+
+ H5C__UPDATE_SLIST_FOR_SIZE_CHANGE((cache_ptr), (entry_ptr->size),\
+ (new_size));
+ }
+
+ /* update statistics just before changing the entry size */
+ H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE((cache_ptr), (entry_ptr), \
+ (new_size));
+
+ /* finally, update the entry size proper */
+ entry_ptr->size = new_size;
+ }
+
+ if ( ! (entry_ptr->in_slist) ) {
+
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
+ }
+
+ H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr)
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5C_resize_pinned_entry() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5C_pin_protected_entry()
*
* Purpose: Pin a protected cache entry. The entry must be protected
@@ -4706,6 +4978,11 @@ done:
* Added code to set the new dirtied field in
* H5C_cache_entry_t to FALSE prior to return.
*
+ * JRM -- 6/23/06
+ * Modified code to allow dirty entries to be loaded from
+ * disk. This is necessary as a bug fix in the object
+ * header code requires us to modify a header as it is read.
+ *
*-------------------------------------------------------------------------
*/
@@ -4852,9 +5129,17 @@ H5C_protect(H5F_t * f,
/* Insert the entry in the hash table. It can't be dirty yet, so
* we don't even check to see if it should go in the skip list.
+ *
+ * This is no longer true -- due to a bug fix, we may modify
+ * data on load to repair a file.
*/
H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, NULL)
+ if ( ( entry_ptr->is_dirty ) && ( ! (entry_ptr->in_slist) ) ) {
+
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, NULL)
+ }
+
/* insert the entry in the data structures used by the replacement
* policy. We are just going to take it out again when we update
* the replacement policy for a protect, but this simplifies the
@@ -5359,6 +5644,49 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5C_set_trace_file_ptr
+ *
+ * Purpose: Set the trace_file_ptr field for the cache.
+ *
+ * This field must either be NULL (which turns of trace
+ * file logging), or be a pointer to an open file to which
+ * trace file data is to be written.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 1/20/06
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5C_set_trace_file_ptr(H5C_t * cache_ptr,
+ FILE * trace_file_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C_set_trace_file_ptr, 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")
+ }
+
+ cache_ptr->trace_file_ptr = trace_file_ptr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5C_set_trace_file_ptr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5C_stats
*
* Purpose: Prints statistics about the cache.
@@ -5984,6 +6312,12 @@ H5C_unprotect(H5F_t * f,
pin_entry = ( (flags & H5C__PIN_ENTRY_FLAG) != 0 );
unpin_entry = ( (flags & H5C__UNPIN_ENTRY_FLAG) != 0 );
+ /* Changing the size of an entry dirties it. Thus, set the
+ * dirtied flag if the size_changed flag is set.
+ */
+
+ dirtied |= size_changed;
+
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( cache_ptr->skip_file_checks || f );
@@ -6120,7 +6454,7 @@ H5C_unprotect(H5F_t * f,
if ( ! (entry_ptr->in_slist) ) {
- H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr)
+ H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
}
}
@@ -8272,6 +8606,12 @@ done:
* JRM - 7/21/04
* Updated function for the addition of the hash table.
*
+ * JRM - 6/23/06
+ * Deleted assertion that verified that a newly loaded
+ * entry is clean. Due to a bug fix, this need not be
+ * the case, as our code will attempt to repair errors
+ * on load.
+ *
*-------------------------------------------------------------------------
*/
@@ -8282,7 +8622,11 @@ H5C_load_entry(H5F_t * f,
haddr_t addr,
const void * udata1,
void * udata2,
+#ifndef NDEBUG
hbool_t skip_file_checks)
+#else /* NDEBUG */
+ UNUSED hbool_t skip_file_checks)
+#endif /* NDEBUG */
{
void * thing = NULL;
void * ret_value = NULL;
@@ -8304,7 +8648,30 @@ H5C_load_entry(H5F_t * f,
entry_ptr = (H5C_cache_entry_t *)thing;
- HDassert( entry_ptr->is_dirty == FALSE );
+ /* In general, an entry should be clean just after it is loaded.
+ *
+ * However, when this code is used in the metadata cache, it is
+ * possible that object headers will be dirty at this point, as
+ * the load function will alter object headers if necessary to
+ * fix an old bug.
+ *
+ * To support this bug fix, I have replace the old assert:
+ *
+ * HDassert( entry_ptr->is_dirty == FALSE );
+ *
+ * with:
+ *
+ * HDassert( ( entry_ptr->is_dirty == FALSE ) || ( type->id == 4 ) );
+ *
+ * Note that type id 4 is associated with object headers in the metadata
+ * cache.
+ *
+ * When we get to using H5C for other purposes, we may wish to
+ * tighten up the assert so that the loophole only applies to the
+ * metadata cache.
+ */
+
+ HDassert( ( entry_ptr->is_dirty == FALSE ) || ( type->id == 4 ) );
entry_ptr->addr = addr;
entry_ptr->type = type;
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index 16c27de..1a32f0a 100644
--- a/src/H5Cpkg.h
+++ b/src/H5Cpkg.h
@@ -87,6 +87,18 @@
* magic: Unsigned 32 bit integer always set to H5C__H5C_T_MAGIC. This
* field is used to validate pointers to instances of H5C_t.
*
+ * trace_file_ptr: File pointer pointing to the trace file, which is used
+ * to record cache operations for use in simulations and design
+ * studies. This field will usually be NULL, indicating that
+ * no trace file should be recorded.
+ *
+ * Since much of the code supporting the parallel metadata
+ * cache is in H5AC, we don't write the trace file from
+ * H5C. Instead, H5AC reads the trace_file_ptr as needed.
+ *
+ * When we get to using H5C in other places, we may add
+ * code to write trace file data at the H5C level as well.
+ *
* aux_ptr: Pointer to void used to allow wrapper code to associate
* its data with an instance of H5C_t. The H5C cache code
* sets this field to NULL, and otherwise leaves it alone.
@@ -702,6 +714,8 @@ struct H5C_t
{
uint32_t magic;
+ FILE * trace_file_ptr;
+
void * aux_ptr;
int32_t max_type_id;
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index fd54d69..ac8851a 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -35,6 +35,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Fprivate.h" /* File access */
+
#define H5C_DO_SANITY_CHECKS 0
#define H5C_DO_EXTREME_SANITY_CHECKS 0
@@ -799,6 +800,13 @@ H5_DLL herr_t H5C_dest(H5F_t * f,
H5_DLL herr_t H5C_dest_empty(H5C_t * cache_ptr);
+H5_DLL herr_t H5C_expunge_entry(H5F_t * f,
+ hid_t primary_dxpl_id,
+ hid_t secondary_dxpl_id,
+ H5C_t * cache_ptr,
+ const H5C_class_t * type,
+ haddr_t addr);
+
H5_DLL herr_t H5C_flush_cache(H5F_t * f,
hid_t primary_dxpl_id,
hid_t secondary_dxpl_id,
@@ -830,6 +838,9 @@ H5_DLL herr_t H5C_get_entry_status(H5C_t * cache_ptr,
hbool_t * is_protected_ptr,
hbool_t * is_pinned_ptr);
+H5_DLL herr_t H5C_get_trace_file_ptr(H5C_t * cache_ptr,
+ FILE ** trace_file_ptr_ptr);
+
H5_DLL herr_t H5C_insert_entry(H5F_t * f,
hid_t primary_dxpl_id,
hid_t secondary_dxpl_id,
@@ -873,6 +884,10 @@ H5_DLL void * H5C_protect(H5F_t * f,
H5_DLL herr_t H5C_reset_cache_hit_rate_stats(H5C_t * cache_ptr);
+H5_DLL herr_t H5C_resize_pinned_entry(H5C_t * cache_ptr,
+ void * thing,
+ size_t new_size);
+
H5_DLL herr_t H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
H5C_auto_size_ctl_t *config_ptr);
@@ -882,6 +897,9 @@ H5_DLL herr_t H5C_set_skip_flags(H5C_t * cache_ptr,
hbool_t skip_file_checks,
hbool_t skip_dxpl_id_checks);
+H5_DLL herr_t H5C_set_trace_file_ptr(H5C_t * cache_ptr,
+ FILE * trace_file_ptr);
+
H5_DLL herr_t H5C_stats(H5C_t * cache_ptr,
const char * cache_name,
hbool_t display_detailed_stats);
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 8602aca..229a67f 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -115,7 +115,7 @@ hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoding disabled
hid_t H5E_CANTOPENOBJ_g = FAIL; /* Can't open object */
hid_t H5E_CANTCLOSEOBJ_g = FAIL; /* Can't close object */
hid_t H5E_COMPLEN_g = FAIL; /* Name component is too long */
-hid_t H5E_LINK_g = FAIL; /* Link-related failure */
+hid_t H5E_LINK_g = FAIL; /* Link failure */
hid_t H5E_SLINK_g = FAIL; /* Symbolic link error */
hid_t H5E_PATH_g = FAIL; /* Problem with path to object */
@@ -156,6 +156,8 @@ hid_t H5E_CANTPIN_g = FAIL; /* Unable to pin cache entry */
hid_t H5E_CANTUNPIN_g = FAIL; /* Unable to un-pin cache entry */
hid_t H5E_CANTMARKDIRTY_g = FAIL; /* Unable to mark a pinned entry as dirty */
hid_t H5E_CANTDIRTY_g = FAIL; /* Unable to mark metadata as dirty */
+hid_t H5E_CANTEXPUNGE_g = FAIL; /* Unable to expunge a metadata cache entry */
+hid_t H5E_CANTRESIZE_g = FAIL; /* Unable to resize a metadata cache entry */
/* Parallel MPI errors */
hid_t H5E_MPI_g = FAIL; /* Some MPI function failed */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index 5f95ca8..a5a3f18 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -586,6 +586,16 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to mark metadata as dirty"))==N
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_CANTDIRTY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTEXPUNGE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to expunge a metadata cache entry"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTEXPUNGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTRESIZE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to resize a metadata cache entry"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTRESIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Parallel MPI errors */
assert(H5E_MPI_g==(-1));
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index b989db7..70334fa 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -196,7 +196,7 @@ H5_DLLVAR hid_t H5E_NOENCODER_g; /* Filter present but encoding disabled */
H5_DLLVAR hid_t H5E_CANTOPENOBJ_g; /* Can't open object */
H5_DLLVAR hid_t H5E_CANTCLOSEOBJ_g; /* Can't close object */
H5_DLLVAR hid_t H5E_COMPLEN_g; /* Name component is too long */
-H5_DLLVAR hid_t H5E_LINK_g; /* Link count failure */
+H5_DLLVAR hid_t H5E_LINK_g; /* Link failure */
H5_DLLVAR hid_t H5E_SLINK_g; /* Symbolic link error */
H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */
@@ -253,6 +253,8 @@ H5_DLLVAR hid_t H5E_NOIDS_g; /* Out of IDs for group */
#define H5E_CANTUNPIN (H5OPEN H5E_CANTUNPIN_g)
#define H5E_CANTMARKDIRTY (H5OPEN H5E_CANTMARKDIRTY_g)
#define H5E_CANTDIRTY (H5OPEN H5E_CANTDIRTY_g)
+#define H5E_CANTEXPUNGE (H5OPEN H5E_CANTEXPUNGE_g)
+#define H5E_CANTRESIZE (H5OPEN H5E_CANTRESIZE_g)
H5_DLLVAR hid_t H5E_CANTFLUSH_g; /* Unable to flush data from cache */
H5_DLLVAR hid_t H5E_CANTSERIALIZE_g; /* Unable to serialize data from cache */
H5_DLLVAR hid_t H5E_CANTLOAD_g; /* Unable to load metadata into cache */
@@ -267,6 +269,8 @@ H5_DLLVAR hid_t H5E_CANTPIN_g; /* Unable to pin cache entry */
H5_DLLVAR hid_t H5E_CANTUNPIN_g; /* Unable to un-pin cache entry */
H5_DLLVAR hid_t H5E_CANTMARKDIRTY_g; /* Unable to mark a pinned entry as dirty */
H5_DLLVAR hid_t H5E_CANTDIRTY_g; /* Unable to mark metadata as dirty */
+H5_DLLVAR hid_t H5E_CANTEXPUNGE_g; /* Unable to expunge a metadata cache entry */
+H5_DLLVAR hid_t H5E_CANTRESIZE_g; /* Unable to resize a metadata cache entry */
/* Parallel MPI errors */
#define H5E_MPI (H5OPEN H5E_MPI_g)
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index 0b3a85e..c0d6f56 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -20,180 +20,182 @@
#define _H5Eterm_H
/* Reset major error IDs */
-
-H5E_DATASET_g=
-H5E_FUNC_g=
-H5E_STORAGE_g=
-H5E_FILE_g=
-H5E_SYM_g=
-H5E_VFL_g=
-H5E_INTERNAL_g=
-H5E_BTREE_g=
-H5E_REFERENCE_g=
-H5E_DATASPACE_g=
-H5E_RESOURCE_g=
-H5E_PLIST_g=
-H5E_DATATYPE_g=
-H5E_RS_g=
-H5E_HEAP_g=
-H5E_OHDR_g=
-H5E_ATOM_g=
-H5E_ATTR_g=
-H5E_NONE_MAJOR_g=
-H5E_IO_g=
-H5E_SLIST_g=
-H5E_EFL_g=
-H5E_TST_g=
-H5E_ARGS_g=
-H5E_ERROR_g=
-H5E_PLINE_g=
-H5E_FSPACE_g=
+
+H5E_DATASET_g=
+H5E_FUNC_g=
+H5E_STORAGE_g=
+H5E_FILE_g=
+H5E_SYM_g=
+H5E_VFL_g=
+H5E_INTERNAL_g=
+H5E_BTREE_g=
+H5E_REFERENCE_g=
+H5E_DATASPACE_g=
+H5E_RESOURCE_g=
+H5E_PLIST_g=
+H5E_DATATYPE_g=
+H5E_RS_g=
+H5E_HEAP_g=
+H5E_OHDR_g=
+H5E_ATOM_g=
+H5E_ATTR_g=
+H5E_NONE_MAJOR_g=
+H5E_IO_g=
+H5E_SLIST_g=
+H5E_EFL_g=
+H5E_TST_g=
+H5E_ARGS_g=
+H5E_ERROR_g=
+H5E_PLINE_g=
+H5E_FSPACE_g=
H5E_CACHE_g= (-1);
/* Reset minor error IDs */
-/* Generic low-level file I/O errors */
-H5E_SEEKERROR_g=
-H5E_READERROR_g=
-H5E_WRITEERROR_g=
-H5E_CLOSEERROR_g=
-H5E_OVERFLOW_g=
+/* Generic low-level file I/O errors */
+H5E_SEEKERROR_g=
+H5E_READERROR_g=
+H5E_WRITEERROR_g=
+H5E_CLOSEERROR_g=
+H5E_OVERFLOW_g=
H5E_FCNTL_g=
-/* Resource errors */
-H5E_NOSPACE_g=
-H5E_CANTALLOC_g=
-H5E_CANTCOPY_g=
-H5E_CANTFREE_g=
-H5E_ALREADYEXISTS_g=
-H5E_CANTLOCK_g=
-H5E_CANTUNLOCK_g=
-H5E_CANTGC_g=
+/* Resource errors */
+H5E_NOSPACE_g=
+H5E_CANTALLOC_g=
+H5E_CANTCOPY_g=
+H5E_CANTFREE_g=
+H5E_ALREADYEXISTS_g=
+H5E_CANTLOCK_g=
+H5E_CANTUNLOCK_g=
+H5E_CANTGC_g=
H5E_CANTGETSIZE_g=
-/* Heap errors */
-H5E_CANTRESTORE_g=
-H5E_CANTCOMPUTE_g=
-H5E_CANTEXTEND_g=
-H5E_CANTATTACH_g=
+/* Heap errors */
+H5E_CANTRESTORE_g=
+H5E_CANTCOMPUTE_g=
+H5E_CANTEXTEND_g=
+H5E_CANTATTACH_g=
H5E_CANTUPDATE_g=
-/* Function entry/exit interface errors */
-H5E_CANTINIT_g=
-H5E_ALREADYINIT_g=
+/* Function entry/exit interface errors */
+H5E_CANTINIT_g=
+H5E_ALREADYINIT_g=
H5E_CANTRELEASE_g=
-/* Property list errors */
-H5E_CANTGET_g=
-H5E_CANTSET_g=
+/* Property list errors */
+H5E_CANTGET_g=
+H5E_CANTSET_g=
H5E_DUPCLASS_g=
-/* Free space errors */
-H5E_CANTMERGE_g=
-H5E_CANTREVIVE_g=
+/* Free space errors */
+H5E_CANTMERGE_g=
+H5E_CANTREVIVE_g=
H5E_CANTSHRINK_g=
-/* Object header related errors */
-H5E_LINKCOUNT_g=
-H5E_VERSION_g=
-H5E_ALIGNMENT_g=
-H5E_BADMESG_g=
-H5E_CANTDELETE_g=
-H5E_BADITER_g=
+/* Object header related errors */
+H5E_LINKCOUNT_g=
+H5E_VERSION_g=
+H5E_ALIGNMENT_g=
+H5E_BADMESG_g=
+H5E_CANTDELETE_g=
+H5E_BADITER_g=
H5E_CANTPACK_g=
-/* System level errors */
+/* System level errors */
H5E_SYSERRSTR_g=
-/* I/O pipeline errors */
-H5E_NOFILTER_g=
-H5E_CALLBACK_g=
-H5E_CANAPPLY_g=
-H5E_SETLOCAL_g=
+/* I/O pipeline errors */
+H5E_NOFILTER_g=
+H5E_CALLBACK_g=
+H5E_CANAPPLY_g=
+H5E_SETLOCAL_g=
H5E_NOENCODER_g=
-/* Group related errors */
-H5E_CANTOPENOBJ_g=
-H5E_CANTCLOSEOBJ_g=
-H5E_COMPLEN_g=
-H5E_LINK_g=
-H5E_SLINK_g=
+/* Group related errors */
+H5E_CANTOPENOBJ_g=
+H5E_CANTCLOSEOBJ_g=
+H5E_COMPLEN_g=
+H5E_LINK_g=
+H5E_SLINK_g=
H5E_PATH_g=
-/* No error */
+/* No error */
H5E_NONE_MINOR_g=
-/* File accessability errors */
-H5E_FILEEXISTS_g=
-H5E_FILEOPEN_g=
-H5E_CANTCREATE_g=
-H5E_CANTOPENFILE_g=
-H5E_CANTCLOSEFILE_g=
-H5E_NOTHDF5_g=
-H5E_BADFILE_g=
-H5E_TRUNCATED_g=
+/* File accessability errors */
+H5E_FILEEXISTS_g=
+H5E_FILEOPEN_g=
+H5E_CANTCREATE_g=
+H5E_CANTOPENFILE_g=
+H5E_CANTCLOSEFILE_g=
+H5E_NOTHDF5_g=
+H5E_BADFILE_g=
+H5E_TRUNCATED_g=
H5E_MOUNT_g=
-/* Object atom related errors */
-H5E_BADATOM_g=
-H5E_BADGROUP_g=
-H5E_CANTREGISTER_g=
-H5E_CANTINC_g=
-H5E_CANTDEC_g=
+/* Object atom related errors */
+H5E_BADATOM_g=
+H5E_BADGROUP_g=
+H5E_CANTREGISTER_g=
+H5E_CANTINC_g=
+H5E_CANTDEC_g=
H5E_NOIDS_g=
-/* Cache related errors */
-H5E_CANTFLUSH_g=
-H5E_CANTSERIALIZE_g=
-H5E_CANTLOAD_g=
-H5E_PROTECT_g=
-H5E_NOTCACHED_g=
-H5E_SYSTEM_g=
-H5E_CANTINS_g=
-H5E_CANTRENAME_g=
-H5E_CANTPROTECT_g=
-H5E_CANTUNPROTECT_g=
-H5E_CANTPIN_g=
-H5E_CANTUNPIN_g=
-H5E_CANTMARKDIRTY_g=
-H5E_CANTDIRTY_g=
-
-/* Parallel MPI errors */
-H5E_MPI_g=
-H5E_MPIERRSTR_g=
+/* Cache related errors */
+H5E_CANTFLUSH_g=
+H5E_CANTSERIALIZE_g=
+H5E_CANTLOAD_g=
+H5E_PROTECT_g=
+H5E_NOTCACHED_g=
+H5E_SYSTEM_g=
+H5E_CANTINS_g=
+H5E_CANTRENAME_g=
+H5E_CANTPROTECT_g=
+H5E_CANTUNPROTECT_g=
+H5E_CANTPIN_g=
+H5E_CANTUNPIN_g=
+H5E_CANTMARKDIRTY_g=
+H5E_CANTDIRTY_g=
+H5E_CANTEXPUNGE_g=
+H5E_CANTRESIZE_g=
+
+/* Parallel MPI errors */
+H5E_MPI_g=
+H5E_MPIERRSTR_g=
H5E_CANTRECV_g=
-/* Dataspace errors */
-H5E_CANTCLIP_g=
-H5E_CANTCOUNT_g=
-H5E_CANTSELECT_g=
-H5E_CANTNEXT_g=
-H5E_BADSELECT_g=
+/* Dataspace errors */
+H5E_CANTCLIP_g=
+H5E_CANTCOUNT_g=
+H5E_CANTSELECT_g=
+H5E_CANTNEXT_g=
+H5E_BADSELECT_g=
H5E_CANTCOMPARE_g=
-/* B-tree related errors */
-H5E_NOTFOUND_g=
-H5E_EXISTS_g=
-H5E_CANTENCODE_g=
-H5E_CANTDECODE_g=
-H5E_CANTSPLIT_g=
-H5E_CANTREDISTRIBUTE_g=
-H5E_CANTSWAP_g=
-H5E_CANTINSERT_g=
-H5E_CANTLIST_g=
-H5E_CANTMODIFY_g=
+/* B-tree related errors */
+H5E_NOTFOUND_g=
+H5E_EXISTS_g=
+H5E_CANTENCODE_g=
+H5E_CANTDECODE_g=
+H5E_CANTSPLIT_g=
+H5E_CANTREDISTRIBUTE_g=
+H5E_CANTSWAP_g=
+H5E_CANTINSERT_g=
+H5E_CANTLIST_g=
+H5E_CANTMODIFY_g=
H5E_CANTREMOVE_g=
-/* Argument errors */
-H5E_UNINITIALIZED_g=
-H5E_UNSUPPORTED_g=
-H5E_BADTYPE_g=
-H5E_BADRANGE_g=
+/* Argument errors */
+H5E_UNINITIALIZED_g=
+H5E_UNSUPPORTED_g=
+H5E_BADTYPE_g=
+H5E_BADRANGE_g=
H5E_BADVALUE_g=
-/* Datatype conversion errors */
-H5E_CANTCONVERT_g=
+/* Datatype conversion errors */
+H5E_CANTCONVERT_g=
H5E_BADSIZE_g= (-1);
#endif /* H5Eterm_H */
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 86e30f2..9022204 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -398,6 +398,9 @@
values correctly. */
#undef LLONG_TO_LDOUBLE_CORRECT
+/* Define if the metadata trace file code is to be compiled in */
+#undef METADATA_TRACE_FILE
+
/* Define if your system can handle complicated MPI derived datatype
correctly. */
#undef MPI_COMPLEX_DERIVED_DATATYPE_WORKS
diff --git a/src/H5err.txt b/src/H5err.txt
index 7cc1c15..25accb7 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -161,6 +161,8 @@ MINOR, CACHE, H5E_CANTPIN, Unable to pin cache entry
MINOR, CACHE, H5E_CANTUNPIN, Unable to un-pin cache entry
MINOR, CACHE, H5E_CANTMARKDIRTY, Unable to mark a pinned entry as dirty
MINOR, CACHE, H5E_CANTDIRTY, Unable to mark metadata as dirty
+MINOR, CACHE, H5E_CANTEXPUNGE, Unable to expunge a metadata cache entry
+MINOR, CACHE, H5E_CANTRESIZE, Unable to resize a metadata cache entry
# B-tree related errors
MINOR, BTREE, H5E_NOTFOUND, Object not found