summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Mainzer <mainzer@hdfgroup.org>2008-05-20 20:43:50 (GMT)
committerJohn Mainzer <mainzer@hdfgroup.org>2008-05-20 20:43:50 (GMT)
commitf9857027e327cac5b356da2c6c3ac94e3a773b29 (patch)
tree8c93fd6a30f34c9b2d63acdcf429e1f9a3bf5378 /src
parent2c84019fcaca9a1cb2a415564d8b88e3dd88479d (diff)
downloadhdf5-f9857027e327cac5b356da2c6c3ac94e3a773b29.zip
hdf5-f9857027e327cac5b356da2c6c3ac94e3a773b29.tar.gz
hdf5-f9857027e327cac5b356da2c6c3ac94e3a773b29.tar.bz2
[svn-r15049] This is an interrim commit of metadata cache journaling mods.
I now have substantial tests for this code -- enough (I hope) for Mike M. to get started. However, the code is my no means fully tested. I don't expect any obvious problems, but there are probably quite a few relatively subtle bugs remaining. I'll be chasing these in the next week. For an example of setting up the cache to journal, see setup_cache_for_journaling() in test/cache2_journal.c Warnings: 1) For now, only enable journaling at file creation time -- code to do this after the file is opened exists, but it hasn't been tested. 2) Right now the journal logging code is very inefficient, so expect things to run slowly until Mike M. checks in his changes to address this problem. 3) I have not checked in exemplar journal output files pending a fix another minor bug in the journal logging code. Until then, the journal tests create exemplars and then test against them -- a poor way to find errors. 4) The USE_CORE_DRIVER has been moved to cache2_common.h. 5) When USE_CORE_DRIVER is FALSE, cache2_journal runs VERY slowly on some system (i.e. 4 hours on Phoenix) -- but it runs fast on Kagiso (~10 minutes). Don't know why, but would guess that the quantity of RAM on the system has much to do with it. Tested serial debug on Phonenix, and parallel debug on Kagiso
Diffstat (limited to 'src')
-rw-r--r--src/H5AC2.c3
-rw-r--r--src/H5C2.c511
-rw-r--r--src/H5C2journal.c570
-rw-r--r--src/H5C2pkg.h200
-rw-r--r--src/H5C2private.h14
5 files changed, 1009 insertions, 289 deletions
diff --git a/src/H5AC2.c b/src/H5AC2.c
index adda9b1..bf5400e 100644
--- a/src/H5AC2.c
+++ b/src/H5AC2.c
@@ -3003,6 +3003,7 @@ H5AC2_get_cache_auto_resize_config(H5AC2_t * cache_ptr,
config_ptr->jbrb_human_readable = FALSE;
result = H5C2_get_journal_config(cache_ptr,
+ NULL,
&(config_ptr->enable_journaling),
&(config_ptr->journal_file_path[0]),
&(config_ptr->jbrb_buf_size),
@@ -3345,7 +3346,7 @@ H5AC2_set_cache_auto_resize_config(const H5F_t * f,
}
result = H5C2_get_journal_config((H5C2_t *)cache_ptr, &mdj_enabled,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL, NULL);
if ( result < 0 ) {
diff --git a/src/H5C2.c b/src/H5C2.c
index 02b2a1d..4ea6158 100644
--- a/src/H5C2.c
+++ b/src/H5C2.c
@@ -601,6 +601,8 @@ H5C2_create(H5F_t * f,
#endif /* NDEBUG */
((cache_ptr->epoch_markers)[i]).addr = (haddr_t)i;
((cache_ptr->epoch_markers)[i]).size = (size_t)0;
+ ((cache_ptr->epoch_markers)[i]).image_ptr = NULL;
+ ((cache_ptr->epoch_markers)[i]).image_up_to_date = FALSE;
((cache_ptr->epoch_markers)[i]).type = &epoch_marker_class_2;
((cache_ptr->epoch_markers)[i]).is_dirty = FALSE;
((cache_ptr->epoch_markers)[i]).dirtied = FALSE;
@@ -644,6 +646,15 @@ H5C2_create(H5F_t * f,
cache_ptr->jwipl_head_ptr = NULL;
cache_ptr->jwipl_tail_ptr = NULL;
+ cache_ptr->mdj_startup_pending = FALSE;
+ cache_ptr->mdj_startup_f = NULL;
+ cache_ptr->mdj_startup_dxpl_id = -1;
+ cache_ptr->mdj_startup_jrnl_file_name = NULL;
+ cache_ptr->mdj_startup_buf_size = 0;
+ cache_ptr->mdj_startup_num_bufs = 0;
+ cache_ptr->mdj_startup_use_aio = FALSE;
+ cache_ptr->mdj_startup_human_readable = FALSE;
+
if ( H5C2_reset_cache_hit_rate_stats(cache_ptr) != SUCCEED ) {
@@ -1032,9 +1043,12 @@ done:
* *cache_ptr), and one of the dxpl ids.
*
* JRM -- 4/3/08
- * I don't think we need to do anything on an expunge
- * vis-a-vis journaling. Comment is here just to make
- * note of the fact that I have reviewed this function.
+ * Added code to test to see if journaling is enabled, and
+ * if it is, test to see if entry_ptr->last_trans > zero.
+ * If so, must remove the entry from the transaction list
+ * (if it is present), remove the entry from the journal
+ * write in progress list, and set entry_ptr->last_trans to
+ * zero before calling H5C2_flush_single_entry().
*
*-------------------------------------------------------------------------
*/
@@ -1083,17 +1097,43 @@ H5C2_expunge_entry(H5F_t * f,
HDassert( entry_ptr->type == type );
if ( entry_ptr->is_protected ) {
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: Target entry is protected.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \
"Target entry is protected.")
}
if ( entry_ptr->is_pinned ) {
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: Target entry is pinned.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \
"Target entry is pinned.")
}
+ /* H5C2_flush_single_entry() will choke if the last_trans field
+ * of the entry isn't zero, or if the entry is on the transaction
+ * list, or on the transaction write in progress list. Must tend
+ * to this before we we make the call.
+ */
+ if ( cache_ptr->mdj_enabled ) {
+
+ if ( cache_ptr->trans_num > 0 ) {
+
+ /* remove the entry from the transaction list if it is there */
+ H5C2__TRANS_DLL_REMOVE(entry_ptr, cache_ptr->tl_head_ptr, \
+ cache_ptr->tl_tail_ptr, cache_ptr->tl_len, \
+ cache_ptr->tl_size, FAIL);
+
+ entry_ptr->last_trans = (uint64_t)0;
+
+ H5C2__UPDATE_RP_FOR_JOURNAL_WRITE_COMPLETE(cache_ptr, \
+ entry_ptr, \
+ FAIL)
+ }
+ }
+
/* If we get this far, call H5C2_flush_single_entry() with the
* H5C2__FLUSH_INVALIDATE_FLAG and the H5C2__FLUSH_CLEAR_ONLY_FLAG.
* This will clear the entry, and then delete it from the cache.
@@ -1109,7 +1149,9 @@ H5C2_expunge_entry(H5F_t * f,
TRUE);
if ( result < 0 ) {
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_flush_single_entry() failed.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \
"H5C2_flush_single_entry() failed.")
}
@@ -2385,6 +2427,9 @@ H5C2_insert_entry(H5F_t * f,
entry_ptr->addr = addr;
entry_ptr->type = type;
+ entry_ptr->image_ptr = NULL;
+ entry_ptr->image_up_to_date = FALSE;
+
/* newly inserted entries are assumed to be dirty */
entry_ptr->is_dirty = TRUE;
@@ -2427,6 +2472,10 @@ H5C2_insert_entry(H5F_t * f,
if ( result < 0 ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2__flash_increase_cache_size failed.\n",
+ FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
"H5C2__flash_increase_cache_size failed.")
}
@@ -2448,6 +2497,9 @@ H5C2_insert_entry(H5F_t * f,
if ( result < 0 ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: Can't get write_permitted.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
"Can't get write_permitted")
}
@@ -2498,6 +2550,9 @@ H5C2_insert_entry(H5F_t * f,
if ( result < 0 ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_make_space_in_cache() failed.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
"H5C2_make_space_in_cache failed.")
}
@@ -2513,6 +2568,9 @@ H5C2_insert_entry(H5F_t * f,
if ( test_entry_ptr == entry_ptr ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: entry already in cache.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \
"entry already in cache.")
@@ -2985,6 +3043,7 @@ H5C2_mark_pinned_entry_dirty(H5F_t * f,
/* mark the entry as dirty if it isn't already */
entry_ptr->is_dirty = TRUE;
+ entry_ptr->image_up_to_date = FALSE;
/* update for change in entry size if necessary */
if ( ( size_changed ) && ( entry_ptr->size != new_size ) ) {
@@ -3136,6 +3195,7 @@ H5C2_mark_pinned_or_protected_entry_dirty(H5F_t * f,
/* mark the entry as dirty if it isn't already */
entry_ptr->is_dirty = TRUE;
+ entry_ptr->image_up_to_date = FALSE;
/* If journaling is enabled, must add the entry to the transaction
* list, if it is not there already.
@@ -3342,6 +3402,8 @@ H5C2_rename_entry(H5C2_t * cache_ptr,
if ( ! ( entry_ptr->flush_in_progress ) ) {
entry_ptr->is_dirty = TRUE;
+ /* This shouldn't be needed, but it keeps the test code happy */
+ entry_ptr->image_up_to_date = FALSE;
}
H5C2__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL)
@@ -3471,6 +3533,7 @@ H5C2_resize_pinned_entry(H5F_t * f,
* isn't already
*/
entry_ptr->is_dirty = TRUE;
+ entry_ptr->image_up_to_date = FALSE;
/* update for change in entry size if necessary */
if ( entry_ptr->size != new_size ) {
@@ -3514,6 +3577,13 @@ H5C2_resize_pinned_entry(H5F_t * f,
(new_size));
}
+ /* if journaling is enabled, and the entry is already in the
+ * transaction list, update that list for the size change as well.
+ */
+ H5C2__UPDATE_TL_FOR_ENTRY_SIZE_CHANGE((cache_ptr), (entry_ptr), \
+ (entry_ptr->size), (new_size));
+
+
/* update statistics just before changing the entry size */
H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE((cache_ptr), (entry_ptr), \
(new_size));
@@ -3527,6 +3597,12 @@ H5C2_resize_pinned_entry(H5F_t * f,
H5C2__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL)
}
+ /* if journaling is enabled, check to see if the entry is in the
+ * transaction list. If it isn't, insert it. If it is, move it to
+ * the head of the list.
+ */
+ H5C2__UPDATE_TL_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr, FAIL)
+
H5C2__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr)
done:
@@ -3562,17 +3638,16 @@ done:
* H5C2__UPDATE_STATS_FOR_UNPIN to call to
* H5C2__UPDATE_STATS_FOR_PIN.
*
+ * JRM -- 5/16/08
+ * Undid change of 2/16/08, as we can use the f parameter
+ * in production mode.
+ *
*-------------------------------------------------------------------------
*/
-#ifndef NDEBUG
+
herr_t
H5C2_pin_protected_entry(H5F_t * f,
void * thing)
-#else
-herr_t
-H5C2_pin_protected_entry(H5F_t UNUSED * f,
- void * thing)
-#endif
{
H5C2_t * cache_ptr;
herr_t ret_value = SUCCEED; /* Return value */
@@ -3788,6 +3863,9 @@ H5C2_protect(H5F_t * f,
if ( thing == NULL ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s can't load entry.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "can't load entry")
}
@@ -3804,6 +3882,10 @@ H5C2_protect(H5F_t * f,
if ( result < 0 ) {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s H5C2__flash_increase_cache_size failed.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
"H5C2__flash_increase_cache_size failed.")
}
@@ -3828,6 +3910,10 @@ H5C2_protect(H5F_t * f,
if ( result < 0 ) {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s Can't get write_permitted 1.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
"Can't get write_permitted 1")
@@ -3889,6 +3975,10 @@ H5C2_protect(H5F_t * f,
if ( result < 0 ) {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s H5C2_make_space_in_cache failed 1.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
"H5C2_make_space_in_cache failed 1.")
}
@@ -3917,12 +4007,18 @@ H5C2_protect(H5F_t * f,
H5C2__INSERT_ENTRY_IN_TL(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
- * code. If we do this often enough, we may want to optimize this.
- */
- H5C2__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, NULL)
+ /* load the entry into 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
+ * code. If we do this often enough, we may want to optimize this.
+ *
+ * Note that we used to do an update for insertion here, but
+ * that confused the journaling code -- the update for load is
+ * just a simplified version of update for insertion that
+ * avoids the problem.
+ */
+
+ H5C2__UPDATE_RP_FOR_LOAD(cache_ptr, entry_ptr, NULL)
}
HDassert( entry_ptr->addr == addr );
@@ -3938,6 +4034,10 @@ H5C2_protect(H5F_t * f,
} else {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s Target already protected & not read only?!?\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
"Target already protected & not read only?!?.")
}
@@ -4007,6 +4107,10 @@ H5C2_protect(H5F_t * f,
write_permitted);
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s Cache auto-resize failed.?!?\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
"Cache auto-resize failed.")
}
@@ -4032,6 +4136,10 @@ H5C2_protect(H5F_t * f,
if ( result < 0 ) {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s H5C2_make_space_in_cache failed 2.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
"H5C2_make_space_in_cache failed 2.")
}
@@ -4044,7 +4152,6 @@ done:
#if H5C2_DO_EXTREME_SANITY_CHECKS
if ( H5C2_validate_lru_list(cache_ptr) < 0 ) {
- HDassert(0);
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, \
"LRU sanity check failed.\n");
}
@@ -5484,7 +5591,13 @@ H5C2_unprotect(H5F_t * f,
}
/* mark the entry as dirty if appropriate */
- entry_ptr->is_dirty = ( (entry_ptr->is_dirty) || dirtied );
+ if ( dirtied ) {
+
+ entry_ptr->is_dirty = ( (entry_ptr->is_dirty) || dirtied );
+ entry_ptr->image_up_to_date = FALSE;
+
+ H5C2__UPDATE_TL_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr, FAIL)
+ }
/* update for change in entry size if necessary */
if ( ( size_changed ) && ( entry_ptr->size != new_size ) ) {
@@ -5529,6 +5642,13 @@ H5C2_unprotect(H5F_t * f,
(new_size));
}
+ /* if journaling is enabled, and the entry is on the transaction
+ * list, update that list for the size changed.
+ */
+ H5C2__UPDATE_TL_FOR_ENTRY_SIZE_CHANGE((cache_ptr), (entry_ptr), \
+ (entry_ptr->size), \
+ (new_size));
+
/* update statistics just before changing the entry size */
H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE((cache_ptr), (entry_ptr), \
(new_size));
@@ -5621,6 +5741,9 @@ H5C2_unprotect(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "Can't flush.")
}
+
+ /* delete the entry from the transaction list if appropriate */
+ H5C2__UPDATE_TL_FOR_ENTRY_CLEAR((cache_ptr), (entry_ptr), FAIL)
}
#ifdef H5_HAVE_PARALLEL
else if ( clear_entry ) {
@@ -5650,6 +5773,9 @@ H5C2_unprotect(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "Can't clear.")
}
+
+ /* delete the entry from the transaction list if appropriate */
+ H5C2__UPDATE_TL_FOR_ENTRY_CLEAR((cache_ptr), (entry_ptr), FAIL)
}
#endif /* H5_HAVE_PARALLEL */
}
@@ -8001,7 +8127,7 @@ H5C2_flush_single_entry(H5F_t * f,
}
}
}
-#if 1
+#if 0
/* this should be useful for debugging from time to time.
* lets leave it in for now. -- JRM 12/15/04
*/
@@ -8016,6 +8142,7 @@ H5C2_flush_single_entry(H5F_t * f,
if ( ( entry_ptr != NULL ) && ( entry_ptr->is_protected ) )
{
+
/* Attempt to flush a protected entry -- scream and die. */
HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, FAIL, \
"Attempt to flush a protected entry.")
@@ -8245,6 +8372,7 @@ H5C2_flush_single_entry(H5F_t * f,
H5C2__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, FAIL)
} else {
+
/* If journaling is enabled, the target entry is being cleared,
* and it is on the transaction list, remove it from the transaction
* list and set its last_trans field to zero.
@@ -8273,6 +8401,7 @@ H5C2_flush_single_entry(H5F_t * f,
}
}
+
/* Clear the dirty flag only, if requested */
if ( clear_only )
{
@@ -8329,172 +8458,184 @@ H5C2_flush_single_entry(H5F_t * f,
}
}
- if ( entry_ptr->type->serialize(entry_ptr->addr,
- entry_ptr->size,
- entry_ptr->image_ptr,
- (void *)entry_ptr,
- &serialize_flags,
- &new_addr,
- &new_len,
- &new_image_ptr) != SUCCEED )
- {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "unable to serialize entry")
- }
+ if ( ! ( entry_ptr->image_up_to_date ) ) {
- if ( serialize_flags != 0 )
- {
- if ( destroy )
- {
- if ( cache_ptr->mdj_enabled ) {
+ if ( entry_ptr->type->serialize(entry_ptr->addr,
+ entry_ptr->size,
+ entry_ptr->image_ptr,
+ (void *)entry_ptr,
+ &serialize_flags,
+ &new_addr,
+ &new_len,
+ &new_image_ptr) != SUCCEED )
+ {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "rename/resize on destroy when journaling enabled.");
- }
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "unable to serialize entry")
+ }
- /* We have already removed the entry from the
- * cache's data structures, so no need to update
- * them for the re-size and/or rename. All we need
- * to do is update the cache entry so we will have
- * the correct values when we actually write the
- * image of the entry to disk.
- *
- * Note that if the serialize function changes the
- * size of the disk image of the entry, it must
- * deallocate the old image, and allocate a new.
- */
+ if ( serialize_flags != 0 )
+ {
+ if ( destroy )
+ {
+ if ( cache_ptr->mdj_enabled ) {
- switch ( serialize_flags )
- {
- case H5C2__SERIALIZE_RESIZED_FLAG:
- H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr,
- entry_ptr,
- new_len)
- entry_ptr->size = new_len;
- entry_ptr->image_ptr = new_image_ptr;
- break;
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "rename/resize on destroy when journaling enabled.");
+ }
+
+ /* We have already removed the entry from the
+ * cache's data structures, so no need to update
+ * them for the re-size and/or rename. All we need
+ * to do is update the cache entry so we will have
+ * the correct values when we actually write the
+ * image of the entry to disk.
+ *
+ * Note that if the serialize function changes the
+ * size of the disk image of the entry, it must
+ * deallocate the old image, and allocate a new.
+ */
+
+ switch ( serialize_flags )
+ {
+ case H5C2__SERIALIZE_RESIZED_FLAG:
+ H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE( \
+ cache_ptr, \
+ entry_ptr, \
+ new_len)
+ entry_ptr->size = new_len;
+ entry_ptr->image_ptr = new_image_ptr;
+ break;
- case (H5C2__SERIALIZE_RESIZED_FLAG |
- H5C2__SERIALIZE_RENAMED_FLAG):
- H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr,
- entry_ptr,
- new_len)
- entry_ptr->addr = new_addr;
- entry_ptr->size = new_len;
- entry_ptr->image_ptr = new_image_ptr;
- break;
+ case (H5C2__SERIALIZE_RESIZED_FLAG |
+ H5C2__SERIALIZE_RENAMED_FLAG):
+ H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE( \
+ cache_ptr, \
+ entry_ptr, \
+ new_len)
+ entry_ptr->addr = new_addr;
+ entry_ptr->size = new_len;
+ entry_ptr->image_ptr = new_image_ptr;
+ break;
- default:
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "unexpected serialize flag(s)")
- break;
+ default:
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "unexpected serialize flag(s)")
+ break;
+ }
}
- }
- else
- {
- if ( cache_ptr->mdj_enabled ) {
+ else
+ {
+ if ( cache_ptr->mdj_enabled ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"rename/resize on flush when journaling enabled.");
- }
-
- /* The entry is not being destroyed, and thus has not
- * been removed from the cache's data structures.
- *
- * Thus, in addition to updating the entry for the
- * re-size and/or rename, we must also update the
- * cache data structures.
- */
+ }
- switch ( serialize_flags )
- {
- case H5C2__SERIALIZE_RESIZED_FLAG:
- H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr,
- entry_ptr,
- new_len)
- /* The replacement policy code thinks the
- * entry is already clean, so modify is_dirty
- * to meet this expectation.
- */
- entry_ptr->is_dirty = FALSE;
-
- /* update the hash table for the size change*/
- H5C2__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), \
+ /* The entry is not being destroyed, and thus has not
+ * been removed from the cache's data structures.
+ *
+ * Thus, in addition to updating the entry for the
+ * re-size and/or rename, we must also update the
+ * cache data structures.
+ */
+
+ switch ( serialize_flags )
+ {
+ case H5C2__SERIALIZE_RESIZED_FLAG:
+ H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE( \
+ cache_ptr, \
+ entry_ptr, \
+ new_len)
+ /* The replacement policy code thinks the
+ * entry is already clean, so modify is_dirty
+ * to meet this expectation.
+ */
+ entry_ptr->is_dirty = FALSE;
+
+ /* update the hash table for the size change*/
+ H5C2__UPDATE_INDEX_FOR_SIZE_CHANGE( \
+ (cache_ptr), \
(entry_ptr->size),\
(new_len));
- /* The entry can't be protected since we are in
- * the process of flushing it. Thus we must
- * update the replacement policy data structures
- * for the size change. The macro deals with
- * the pinned case.
- */
- H5C2__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, \
- entry_ptr, \
- new_len);
-
- /* The entry can't be in the slist, so no need
- * to update the slist for the size change.
- */
-
- /* finally, set is_dirty to TRUE again, and
- * update the size and image_ptr.
- */
- entry_ptr->is_dirty = TRUE;
- entry_ptr->size = new_len;
- entry_ptr->image_ptr = new_image_ptr;
- break;
+ /* The entry can't be protected since we are
+ * in the process of flushing it. Thus we must
+ * update the replacement policy data
+ * structures for the size change. The macro
+ * deals with the pinned case.
+ */
+ H5C2__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, \
+ entry_ptr, \
+ new_len);
+
+ /* The entry can't be in the slist, so no need
+ * to update the slist for the size change.
+ */
+
+ /* finally, set is_dirty to TRUE again, and
+ * update the size and image_ptr.
+ */
+ entry_ptr->is_dirty = TRUE;
+ entry_ptr->size = new_len;
+ entry_ptr->image_ptr = new_image_ptr;
+ break;
- case (H5C2__SERIALIZE_RESIZED_FLAG |
- H5C2__SERIALIZE_RENAMED_FLAG):
- H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr,
- entry_ptr,
- new_len)
- /* The replacement policy code thinks the
- * entry is already clean, so modify is_dirty
- * to meet this expectation.
- */
- entry_ptr->is_dirty = FALSE;
-
- /* first update the hash table for the rename */
- H5C2__DELETE_FROM_INDEX(cache_ptr, entry_ptr)
- entry_ptr->addr = new_addr;
- H5C2__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL)
-
- /* update the hash table for the size change */
- H5C2__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), \
+ case (H5C2__SERIALIZE_RESIZED_FLAG |
+ H5C2__SERIALIZE_RENAMED_FLAG):
+ H5C2__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE( \
+ cache_ptr, \
+ entry_ptr, \
+ new_len)
+ /* The replacement policy code thinks the
+ * entry is already clean, so modify is_dirty
+ * to meet this expectation.
+ */
+ entry_ptr->is_dirty = FALSE;
+
+ /* first update the hash table for the rename */
+ H5C2__DELETE_FROM_INDEX(cache_ptr, entry_ptr)
+ entry_ptr->addr = new_addr;
+ H5C2__INSERT_IN_INDEX(cache_ptr, entry_ptr, \
+ FAIL)
+
+ /* update the hash table for the size change */
+ H5C2__UPDATE_INDEX_FOR_SIZE_CHANGE( \
+ (cache_ptr), \
(entry_ptr->size),\
(new_len));
- /* The entry can't be protected since we are in
- * the process of flushing it. Thus we must
- * update the replacement policy data structures
- * for the size change. The macro deals with
- * the pinned case.
- */
- H5C2__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, \
- entry_ptr, \
- new_len);
-
- /* The entry can't be in the slist, so no need
- * to update the slist for the size change.
- */
-
- /* finally, set is_dirty to TRUE again, and
- * update the size and image_ptr.
- */
- entry_ptr->is_dirty = TRUE;
-
- entry_ptr->size = new_len;
- entry_ptr->image_ptr = new_image_ptr;
- break;
+ /* The entry can't be protected since we are
+ * in the process of flushing it. Thus we must
+ * update the replacement policy data
+ * structures for the size change. The macro
+ * deals with the pinned case.
+ */
+ H5C2__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, \
+ entry_ptr, \
+ new_len);
+
+ /* The entry can't be in the slist, so no need
+ * to update the slist for the size change.
+ */
+
+ /* finally, set is_dirty to TRUE again, and
+ * update the size and image_ptr.
+ */
+ entry_ptr->is_dirty = TRUE;
+
+ entry_ptr->size = new_len;
+ entry_ptr->image_ptr = new_image_ptr;
+ break;
- default:
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "unexpected serialize flag(s)")
- break;
+ default:
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "unexpected serialize flag(s)")
+ break;
+ }
}
- }
+ }
+ entry_ptr->image_up_to_date = TRUE;
}
/* now write the image to disk */
@@ -8507,6 +8648,10 @@ H5C2_flush_single_entry(H5F_t * f,
}
#ifdef H5_HAVE_PARALLEL
+ /* note that we initialized the serialize_flags to 0, so if
+ * the image was up to date on entry, serialize_flags should
+ * still be 0 at this point.
+ */
if ( serialize_flags != 0 ) {
/* In the parallel case, resizes and renames in
@@ -8571,6 +8716,7 @@ H5C2_flush_single_entry(H5F_t * f,
if ( type_ptr->free_icr(entry_ptr->addr, entry_ptr->size,
(void *)entry_ptr) != SUCCEED )
{
+
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
"free_icr callback failed.")
}
@@ -8681,12 +8827,19 @@ H5C2_load_entry(H5F_t * f,
if ( image_ptr == NULL )
{
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "memory allocation failed for on disk image buffer.\n");
+#endif /* JRM */
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, \
"memory allocation failed for on disk image buffer.")
}
if ( H5F_block_read(f, type->mem_type, addr, len, dxpl_id, image_ptr) < 0 )
{
+#if 0 /* JRM */
+ HDfprintf(stdout, "can't read image.\n.");
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't read image")
}
@@ -8694,6 +8847,9 @@ H5C2_load_entry(H5F_t * f,
if ( thing == NULL )
{
+#if 0 /* JRM */
+ HDfprintf(stdout, "can't deserialize image.\n.");
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't deserialize image")
}
@@ -8701,15 +8857,24 @@ H5C2_load_entry(H5F_t * f,
{
if ( type->image_len(thing, &new_len) != SUCCEED )
{
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "image_len() failed")
+#if 0 /* JRM */
+ HDfprintf(stdout, "image_len() failed.\n.");
+#endif /* JRM */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "image_len() failed.\n");
}
else if ( new_len > len )
{
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "new_len > len")
+#if 0 /* JRM */
+ HDfprintf(stdout, "new_len > len.\n.");
+#endif /* JRM */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "new_len > len.\n");
}
else if ( new_len <= 0 )
{
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "new_len <= 0")
+#if 0 /* JRM */
+ HDfprintf(stdout, "new_len <= 0.\n.");
+#endif /* JRM */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "new_len <= 0.\n")
}
else if ( new_len < len )
{
@@ -8717,6 +8882,9 @@ H5C2_load_entry(H5F_t * f,
if ( thing == NULL )
{
+#if 0 /* JRM */
+ HDfprintf(stdout, "thing null after H5MM_realloc().\n");
+#endif /* JRM */
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, \
"thing null after H5MM_realloc().")
}
@@ -8756,6 +8924,7 @@ H5C2_load_entry(H5F_t * f,
entry_ptr->addr = addr;
entry_ptr->size = len;
entry_ptr->image_ptr = image_ptr;
+ entry_ptr->image_up_to_date = TRUE;
entry_ptr->type = type;
entry_ptr->is_dirty = dirty;
entry_ptr->dirtied = FALSE;
diff --git a/src/H5C2journal.c b/src/H5C2journal.c
index 53d0d71..3445c4f 100644
--- a/src/H5C2journal.c
+++ b/src/H5C2journal.c
@@ -79,9 +79,10 @@ H5C2_begin_journaling(H5F_t * f,
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5C2_begin_journaling, FAIL)
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s entering.\n", FUNC);
+#endif /* JRM */
HDassert( f != NULL );
- HDassert( f->name != NULL );
HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
HDassert( cache_ptr->mdj_enabled == FALSE );
@@ -102,34 +103,91 @@ H5C2_begin_journaling(H5F_t * f,
if ( cache_ptr->mdj_enabled ) {
+ HDfprintf(stdout, "%s: metadata journaling already enabled on entry.\n",
+ FUNC);
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"metadata journaling already enabled on entry.")
}
- result = H5C2_jb__init(&(cache_ptr->mdj_jbrb),
- f->name,
- journal_file_name_ptr,
- buf_size,
- num_bufs,
- use_aio,
- human_readable);
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s Finished initial sanity checks.\n", FUNC);
+#endif /* JRM */
- if ( result != SUCCEED ) {
+ if ( f->name == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, "H5C2_jb__init() failed.")
- }
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s Queueing startup.\n", FUNC);
+#endif /* JRM */
- result = H5C2_mark_journaling_in_progress(f,
- dxpl_id,
- journal_file_name_ptr);
+ if ( cache_ptr->mdj_startup_pending ) {
- if ( result != SUCCEED ) {
+ HDfprintf(stdout,
+ "%s: metadata journaling startup already pending.\n",
+ FUNC);
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "metadata journaling startup already pending.")
+ }
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_mark_journaling_in_progress() failed.")
+ result = H5C2_queue_begin_journaling(f, dxpl_id, cache_ptr,
+ journal_file_name_ptr, buf_size,
+ num_bufs, use_aio, human_readable);
+
+ if ( result < 0 ) {
+
+ HDfprintf(stdout, "%s: H5C2_queue_begin_journaling() failed.\n",
+ FUNC);
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_queue_begin_journaling() failed.")
+ }
+
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s Queueing startup -- done.\n", FUNC);
+#endif /* JRM */
+ } else {
+
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s calling H5C2_jb__init().\n", FUNC);
+#endif /* JRM */
+
+ result = H5C2_jb__init(&(cache_ptr->mdj_jbrb),
+ f->name,
+ journal_file_name_ptr,
+ buf_size,
+ num_bufs,
+ use_aio,
+ human_readable);
+
+ if ( result != SUCCEED ) {
+
+ HDfprintf(stdout, "%s: H5C2_jb__init() failed.\n", FUNC);
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__init() failed.")
+ }
+
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s calling H5C2_mark_journaling_in_progress().\n",
+ FUNC);
+#endif /* JRM */
+
+ result = H5C2_mark_journaling_in_progress(f,
+ dxpl_id,
+ journal_file_name_ptr);
+
+ if ( result != SUCCEED ) {
+
+ HDfprintf(stdout,
+ "%s: H5C2_mark_journaling_in_progress() failed.\n", FUNC);
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_mark_journaling_in_progress() failed.")
+ }
+
+ cache_ptr->mdj_enabled = TRUE;
+ cache_ptr->mdj_startup_pending = FALSE;
}
- cache_ptr->mdj_enabled = TRUE;
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s exiting.\n", FUNC);
+#endif /* JRM */
done:
@@ -160,9 +218,15 @@ H5C2_begin_transaction(H5C2_t * cache_ptr,
const char * api_call_name)
{
herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
FUNC_ENTER_NOAPI(H5C2_begin_transaction, FAIL)
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s entering -- call name = \"%s\".\n",
+ FUNC, api_call_name);
+ HDfprintf(stdout, "%s cache_ptr->mdj_enabled = %d.\n",
+ FUNC, (int)(cache_ptr->mdj_enabled));
+#endif /* JRM */
HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
HDassert( cache_ptr->tl_len == 0 );
@@ -173,17 +237,51 @@ H5C2_begin_transaction(H5C2_t * cache_ptr,
HDassert( api_call_name != NULL );
HDassert( HDstrlen(api_call_name) <= H5C2__MAX_API_NAME_LEN );
+ if ( cache_ptr->mdj_startup_pending ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s calling H5C2_begin_journaling()...", FUNC);
+ fflush(stdout);
+#endif /* JRM */
+ result = H5C2_begin_journaling(cache_ptr->mdj_startup_f,
+ cache_ptr->mdj_startup_dxpl_id,
+ cache_ptr,
+ cache_ptr->mdj_startup_jrnl_file_name,
+ cache_ptr->mdj_startup_buf_size,
+ cache_ptr->mdj_startup_num_bufs,
+ cache_ptr->mdj_startup_use_aio,
+ cache_ptr->mdj_startup_human_readable);
+
+ if ( result < 0 ) {
+
+ HDfprintf(stdout, "%s H5C2_begin_journaling() failed.\n", FUNC);
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C2_begin_journaling() failed.")
+ }
+
+ if ( cache_ptr->mdj_startup_jrnl_file_name != NULL ) {
+
+ cache_ptr->mdj_startup_jrnl_file_name = (char *)
+ H5MM_xfree((void *)(cache_ptr->mdj_startup_jrnl_file_name));
+ }
+#if 0 /* JRM */
+ HDfprintf(stdout, "done.\n");
+ fflush(stdout);
+#endif /* JRM */
+ }
+
if ( cache_ptr->mdj_enabled ) {
if ( cache_ptr->trans_in_progress ) {
+ HDfprintf(stdout, "%s transaction already in progress.\n", FUNC);
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"transaction already in progress?.")
}
- HDstrncpy(cache_ptr->trans_api_name, api_call_name,
+ HDstrncpy(cache_ptr->trans_api_name, api_call_name,
(size_t)H5C2__MAX_API_NAME_LEN);
- cache_ptr->trans_num++;
+
+ (cache_ptr->trans_num)++;
*trans_num_ptr = cache_ptr->trans_num;
@@ -191,7 +289,10 @@ H5C2_begin_transaction(H5C2_t * cache_ptr,
}
done:
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s exiting -- cache_ptr->trans_num = %lld.\n",
+ FUNC, cache_ptr->trans_num);
+#endif /* JRM */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C2_begin_transaction() */
@@ -235,7 +336,7 @@ H5C2_end_journaling(H5F_t * f,
HDassert( f != NULL );
HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
- HDassert( cache_ptr->mdj_enabled == TRUE );
+ /* HDassert( cache_ptr->mdj_enabled == TRUE ); */
HDassert( cache_ptr->trans_in_progress == FALSE );
HDassert( cache_ptr->tl_len == 0 );
HDassert( cache_ptr->tl_size == 0 );
@@ -253,7 +354,7 @@ H5C2_end_journaling(H5F_t * f,
if ( result < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_flush_cache() failed.")
+ "H5C2_flush_cache() failed.")
}
result = H5C2_unmark_journaling_in_progress(f, dxpl_id, cache_ptr);
@@ -307,7 +408,10 @@ H5C2_end_transaction(H5F_t * f,
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5C2_end_transaction, FAIL)
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s call = \"%s\", trans_num = %lld, tl_len = %d.\n",
+ FUNC, api_call_name, trans_num, (int)(cache_ptr->tl_len));
+#endif /* JRM */
HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
HDassert( api_call_name != NULL );
@@ -318,13 +422,20 @@ H5C2_end_transaction(H5F_t * f,
if ( cache_ptr->mdj_enabled ) {
if ( ! ( cache_ptr->trans_in_progress ) ) {
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: transaction not in progress?!?!\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"transaction not in progress?!?!")
}
if ( cache_ptr->trans_num != trans_num ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: trans_num mis-match (%lld/%lld)\n",
+ FUNC, (long long)(trans_num),
+ (long long)(cache_ptr->trans_num));
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "trans_num mis-match?!?!")
}
@@ -337,11 +448,18 @@ H5C2_end_transaction(H5F_t * f,
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_journal_transaction() failed.\n",
+ FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_journal_transaction() failed.")
}
}
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: setting cache_ptr->trans_in_progress = FALSE.\n",
+ FUNC);
+#endif /* JRM */
cache_ptr->trans_in_progress = FALSE;
/* Get the last transaction on disk. If it has changed, remove
@@ -353,6 +471,11 @@ H5C2_end_transaction(H5F_t * f,
&new_last_trans_on_disk);
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s: H5C2_jb__get_last_transaction_on_disk() failed.\n",
+ FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_jb__get_last_transaction_on_disk() failed.")
}
@@ -364,6 +487,11 @@ H5C2_end_transaction(H5F_t * f,
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s: H5C2_update_for_new_last_trans_on_disk() failed.\n",
+ FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_update_for_new_last_trans_on_disk() failed.")
}
@@ -427,12 +555,20 @@ done:
* Programmer: John Mainzer
* April 13, 2008
*
+ * Changes:
+ *
+ * John Mainzer -- 4/2/08
+ * Modified function to report the pending journaling
+ * status if journaling has been enabled, but not yet
+ * configured.
+ *
*-------------------------------------------------------------------------
*/
herr_t
H5C2_get_journal_config(H5C2_t * cache_ptr,
hbool_t * journaling_enabled_ptr,
+ hbool_t * startup_pending_ptr,
char * journal_file_path_ptr,
size_t * jbrb_buf_size_ptr,
int * jbrb_num_bufs_ptr,
@@ -457,6 +593,11 @@ H5C2_get_journal_config(H5C2_t * cache_ptr,
*journaling_enabled_ptr = TRUE;
+ if ( startup_pending_ptr != NULL ) {
+
+ *startup_pending_ptr = FALSE;
+ }
+
if ( journal_file_path_ptr != NULL ) {
HDsnprintf(journal_file_path_ptr,
@@ -485,6 +626,43 @@ H5C2_get_journal_config(H5C2_t * cache_ptr,
*jbrb_human_readable_ptr = (cache_ptr->mdj_jbrb).human_readable;
}
+ } else if ( cache_ptr->mdj_startup_pending ) {
+
+ *journaling_enabled_ptr = TRUE;
+
+ if ( startup_pending_ptr != NULL ) {
+
+ *startup_pending_ptr = TRUE;
+ }
+
+ if ( journal_file_path_ptr != NULL ) {
+
+ HDsnprintf(journal_file_path_ptr,
+ H5AC2__MAX_JOURNAL_FILE_NAME_LEN,
+ "%s",
+ cache_ptr->mdj_startup_jrnl_file_name);
+ }
+
+ if ( jbrb_buf_size_ptr != NULL ) {
+
+ *jbrb_buf_size_ptr = cache_ptr->mdj_startup_buf_size;
+ }
+
+ if ( jbrb_num_bufs_ptr != NULL ) {
+
+ *jbrb_num_bufs_ptr = cache_ptr->mdj_startup_num_bufs;
+ }
+
+ if ( jbrb_use_aio_ptr != NULL ) {
+
+ *jbrb_use_aio_ptr = cache_ptr->mdj_startup_use_aio;
+ }
+
+ if ( jbrb_human_readable_ptr ) {
+
+ *jbrb_human_readable_ptr = cache_ptr->mdj_startup_human_readable;
+ }
+
} else {
*journaling_enabled_ptr = FALSE;
@@ -617,7 +795,7 @@ H5C2_journal_pre_flush(H5C2_t * cache_ptr)
HDassert( cache_ptr->mdj_enabled );
if ( cache_ptr->trans_in_progress ) {
-
+ HDassert(0);
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"Transaction in progress during flush?!?!?.")
}
@@ -684,6 +862,8 @@ H5C2_journal_transaction(H5F_t * f,
{
char buf[H5C2__MAX_API_NAME_LEN + 128];
+ hbool_t resized;
+ hbool_t renamed;
H5C2_cache_entry_t * entry_ptr = NULL;
unsigned serialize_flags = 0;
haddr_t new_addr;
@@ -708,6 +888,9 @@ H5C2_journal_transaction(H5F_t * f,
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_jb__comment() failed.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_jb__comment() failed.")
}
@@ -717,6 +900,9 @@ H5C2_journal_transaction(H5F_t * f,
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_jb__start_transaction() failed.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_jb__start_transaction() failed.")
}
@@ -727,9 +913,16 @@ H5C2_journal_transaction(H5F_t * f,
HDassert( entry_ptr->is_dirty );
HDassert( entry_ptr->last_trans == cache_ptr->trans_num );
+ resized = FALSE;
+ renamed = FALSE;
+
if ( entry_ptr->is_protected )
{
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s: Protected entry in TL at transaction close.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"Protected entry in TL at transaction close.")
}
@@ -741,91 +934,126 @@ H5C2_journal_transaction(H5F_t * f,
if ( entry_ptr->image_ptr == NULL )
{
+#if 0 /* JRM */
+ HDfprintf(stdout,
+ "%s: memory allocation failed for on disk image buffer.\n",
+ FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
"memory allocation failed for on disk image buffer.")
}
}
- result = entry_ptr->type->serialize(entry_ptr->addr,
- entry_ptr->size,
- entry_ptr->image_ptr,
- (void *)entry_ptr,
- &serialize_flags,
- &new_addr,
- &new_len,
- &new_image_ptr);
- if ( result != SUCCEED )
- {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "unable to serialize entry")
- }
-
- if ( serialize_flags != 0 )
- {
- /* if the serialize_flags are not zero, the entry has been
- * modified as a result of the serialize. Pass these changes
- * on to the cache, and don't bother to write a journal entry
- * at this time -- the protect/unprotect/rename will move the
- * entry to the head of the transaction list, where we will
- * handle it later.
- */
- hbool_t resized;
- hbool_t renamed;
-
- resized = (serialize_flags & H5C2__SERIALIZE_RESIZED_FLAG) != 0;
- renamed = (serialize_flags & H5C2__SERIALIZE_RENAMED_FLAG) != 0;
-
- if ( ( renamed ) && ( ! resized ) )
+ /* This should always be true, unless the entry has already been
+ * serialized in this function, and that serialization caused the
+ * entry to be resized (and possibly renamed as well).
+ */
+ if ( ! ( entry_ptr->image_up_to_date ) ) {
+
+ result = entry_ptr->type->serialize(entry_ptr->addr,
+ entry_ptr->size,
+ entry_ptr->image_ptr,
+ (void *)entry_ptr,
+ &serialize_flags,
+ &new_addr,
+ &new_len,
+ &new_image_ptr);
+ if ( result != SUCCEED )
{
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: unable to serialize entry.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "entry renamed but not resized?!?!")
+ "unable to serialize entry")
}
- if ( resized )
+ if ( serialize_flags != 0 )
{
- /* in the following protect/unprotect, use default
- * dxpl_id as we know that the entry is in cache,
- * and thus no I/O will take place.
+ /* if the serialize_flags are not zero, the entry has been
+ * modified as a result of the serialize. Pass these changes
+ * on to the cache, and don't bother to write a journal entry
+ * at this time -- the protect/unprotect/rename will move the
+ * entry to the head of the transaction list, where we will
+ * handle it later.
*/
- thing = H5C2_protect(f, H5P_DATASET_XFER_DEFAULT,
- entry_ptr->type, entry_ptr->addr,
- entry_ptr->size, NULL,
- H5C2__NO_FLAGS_SET);
- if ( thing == NULL )
+ resized = (serialize_flags & H5C2__SERIALIZE_RESIZED_FLAG) != 0;
+ renamed = (serialize_flags & H5C2__SERIALIZE_RENAMED_FLAG) != 0;
+
+ if ( ( renamed ) && ( ! resized ) )
{
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: entry renamed but not resized.\n",
+ FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_protect() failed.")
+ "entry renamed but not resized?!?!")
}
- result = H5C2_unprotect(f, H5P_DATASET_XFER_DEFAULT,
- entry_ptr->type, entry_ptr->addr,
- thing, H5C2__SIZE_CHANGED_FLAG,
- new_len);
-
- if ( result < 0 )
+ if ( resized )
{
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_unprotect() failed.")
+ /* in the following protect/unprotect, use default
+ * dxpl_id as we know that the entry is in cache,
+ * and thus no I/O will take place.
+ */
+ thing = H5C2_protect(f, H5P_DATASET_XFER_DEFAULT,
+ entry_ptr->type, entry_ptr->addr,
+ entry_ptr->size, NULL,
+ H5C2__NO_FLAGS_SET);
+
+ if ( thing == NULL )
+ {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_protect() failed.\n",
+ FUNC);
+#endif /* JRM */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_protect() failed.")
+ }
+
+ result = H5C2_unprotect(f, H5P_DATASET_XFER_DEFAULT,
+ entry_ptr->type, entry_ptr->addr,
+ thing, H5C2__SIZE_CHANGED_FLAG,
+ new_len);
+
+ if ( result < 0 )
+ {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_unprotect() failed.\n",
+ FUNC);
+#endif /* JRM */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_unprotect() failed.")
+ }
+
+ entry_ptr->image_ptr = new_image_ptr;
}
- entry_ptr->image_ptr = new_image_ptr;
- }
-
- if ( renamed )
- {
- result = H5C2_rename_entry(cache_ptr, entry_ptr->type,
- entry_ptr->addr, new_addr);
-
- if ( result < 0 )
+ if ( renamed )
{
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_rename_entr() failed.")
+ result = H5C2_rename_entry(cache_ptr, entry_ptr->type,
+ entry_ptr->addr, new_addr);
+
+ if ( result < 0 )
+ {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_rename_entr() failed.\n",
+ FUNC);
+#endif /* JRM */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_rename_entr() failed.")
+ }
}
}
+
+ entry_ptr->image_up_to_date = TRUE;
}
- else /* generate the journal entry & remove from transaction list */
- {
+
+ /* if the entry hasn't been either resized or renamed, generate
+ * the journal entry, & remove from the transaction list.
+ */
+ if ( ( ! resized ) && ( ! renamed ) ) {
+
result = H5C2_jb__journal_entry(&(cache_ptr->mdj_jbrb),
cache_ptr->trans_num,
entry_ptr->addr,
@@ -834,6 +1062,10 @@ H5C2_journal_transaction(H5F_t * f,
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_jb__journal_entry() failed.\n",
+ FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_jb__journal_entry() failed.")
}
@@ -850,6 +1082,9 @@ H5C2_journal_transaction(H5F_t * f,
if ( result != SUCCEED ) {
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s: H5C2_jb__end_transaction() failed.\n", FUNC);
+#endif /* JRM */
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_jb__end_transaction() failed.")
}
@@ -862,6 +1097,93 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5C2_queue_begin_journaling()
+ *
+ * Purpose: Verify that the HDF5 file name is not available.
+ *
+ * Then make note of the information needed to begin
+ * journaling once the file is fully open.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * 5/1/08
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5C2_queue_begin_journaling(H5F_t * f,
+ hid_t dxpl_id,
+ H5C2_t * cache_ptr,
+ char * journal_file_name_ptr,
+ size_t buf_size,
+ int num_bufs,
+ hbool_t use_aio,
+ hbool_t human_readable)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C2_queue_begin_journaling, FAIL)
+
+ HDassert( f != NULL );
+ HDassert( cache_ptr != NULL );
+ HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
+ HDassert( cache_ptr->mdj_enabled == FALSE );
+ HDassert( cache_ptr->mdj_startup_pending == FALSE );
+ HDassert( cache_ptr->trans_in_progress == FALSE );
+ HDassert( cache_ptr->trans_num == 0 );
+ HDassert( cache_ptr->last_trans_on_disk == 0 );
+ HDassert( cache_ptr->tl_len == 0 );
+ HDassert( cache_ptr->tl_size == 0 );
+ HDassert( cache_ptr->tl_head_ptr == NULL );
+ HDassert( cache_ptr->tl_tail_ptr == NULL );
+ HDassert( cache_ptr->jwipl_len == 0 );
+ HDassert( cache_ptr->jwipl_size == 0 );
+ HDassert( cache_ptr->jwipl_head_ptr == NULL );
+ HDassert( cache_ptr->jwipl_tail_ptr == NULL );
+ HDassert( buf_size > 0 );
+ HDassert( num_bufs > 0 );
+ HDassert( journal_file_name_ptr != NULL );
+
+ if ( cache_ptr->mdj_enabled ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "metadata journaling already enabled on entry.")
+ }
+
+ cache_ptr->mdj_startup_jrnl_file_name =
+ (char *)H5MM_malloc(strlen(journal_file_name_ptr) + 1);
+
+ if ( cache_ptr->mdj_startup_jrnl_file_name == NULL ) {
+
+ if ( cache_ptr->mdj_startup_jrnl_file_name == NULL ) {
+
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
+ "memory allocation failed for jrnl file name buffer.")
+ }
+ }
+
+ HDstrcpy(cache_ptr->mdj_startup_jrnl_file_name, journal_file_name_ptr);
+
+ cache_ptr->mdj_startup_f = f;
+ cache_ptr->mdj_startup_dxpl_id = dxpl_id;
+ cache_ptr->mdj_startup_buf_size = buf_size;
+ cache_ptr->mdj_startup_num_bufs = num_bufs;
+ cache_ptr->mdj_startup_use_aio = use_aio;
+ cache_ptr->mdj_startup_human_readable = human_readable;
+
+ cache_ptr->mdj_startup_pending = TRUE;
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5C2_queue_begin_journaling() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5C2_update_for_new_last_trans_on_disk()
*
* Purpose: Update the journal write in progress list for a change in
@@ -875,6 +1197,13 @@ done:
* set their last_trans fields to zero, and insert then into
* the eviction policy data structures.
*
+ * Similarly, scan the pinned entry list for entries whose
+ * last_trans field is now less than or equal to
+ * cache_ptr->last_trans_on_disk. In this case, just set
+ * the last trans field to 0. Note that here we assume that
+ * the pinned entry list will always be small -- if this
+ * ceases to be the case, we will have re-visit this case.
+ *
* Return: Success: SUCCEED
* Failure: FAIL
*
@@ -907,9 +1236,10 @@ H5C2_update_for_new_last_trans_on_disk(H5C2_t * cache_ptr,
while ( entry_ptr != NULL )
{
- prev_entry_ptr = entry_ptr->next;
+ prev_entry_ptr = entry_ptr->prev;
HDassert( entry_ptr->last_trans > 0 );
+ HDassert( entry_ptr->is_dirty );
if ( entry_ptr->last_trans <= cache_ptr->last_trans_on_disk ) {
@@ -921,6 +1251,24 @@ H5C2_update_for_new_last_trans_on_disk(H5C2_t * cache_ptr,
entry_ptr = prev_entry_ptr;
}
+
+ /* now scan the pinned entry list */
+
+ entry_ptr = cache_ptr->pel_head_ptr;
+
+ while ( entry_ptr != NULL ) {
+
+ if ( entry_ptr->last_trans > 0 ) {
+
+ HDassert( entry_ptr->is_dirty );
+
+ if ( entry_ptr->last_trans <= cache_ptr->last_trans_on_disk ) {
+
+ entry_ptr->last_trans = 0;
+ }
+ }
+ entry_ptr = entry_ptr->next;
+ }
}
done:
@@ -1493,7 +1841,10 @@ H5C2_mark_journaling_in_progress(H5F_t * f,
HDassert( cache_ptr->mdj_conf_block_ptr == NULL );
HDassert( cache_ptr->mdj_file_name_ptr == NULL );
HDassert( journal_file_name_ptr != NULL );
-
+#if 0
+ /* Unfortunately, the flags may not be set yet -- thus we can't
+ * check for this error.
+ */
/* Can't journal a read only file, so verify that we are
* opened read/write and fail if we are not.
*/
@@ -1502,7 +1853,7 @@ H5C2_mark_journaling_in_progress(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"File is opened read only.")
}
-
+#endif
/* first, create a metadata journaling configuration block */
result = H5C2_create_journal_config_block(f,
dxpl_id,
@@ -1897,7 +2248,7 @@ H5C2_jb__flush(H5C2_jbrb_t * struct_ptr)
/* perform sync to ensure everything gets to disk before returning */
/* Note: there is no HDfsync function, so for now, the standard
fsync is being used. */
- if ( fsync(struct_ptr->journal_file_fd) < 0 ) {
+ if ( fsync(struct_ptr->journal_file_fd) != 0 ) {
HGOTO_ERROR(H5E_IO, H5E_SYNCFAIL, FAIL, "Journal file sync failed.")
} /* end if */
@@ -2252,9 +2603,11 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
/* Open journal file */
struct_ptr->journal_file_fd =
HDopen(journal_file_name, O_WRONLY|O_CREAT|O_EXCL, 0777);
-
if ( struct_ptr->journal_file_fd == -1) {
+ HDfprintf(stdout,
+ "%s: Can't create journal file \"%s\". Does it already exist?\n",
+ FUNC, journal_file_name);
HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, \
"Can't create journal file. Does it already exist?")
} /* end if */
@@ -2284,6 +2637,9 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
if ( struct_ptr->buf == NULL ) {
+ HDfprintf(stdout,
+ "%s: allocation of buf pointer array failed.\n",
+ FUNC);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
"allocation of buf pointer array failed.");
} /* end if */
@@ -2294,6 +2650,9 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
if ( (*struct_ptr->buf)[0] == NULL ) {
+ HDfprintf(stdout,
+ "%s: allocation of buffers failed.\n",
+ FUNC);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
"allocation of buffers failed.");
} /* end if */
@@ -2306,6 +2665,9 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
if ( struct_ptr->trans_tracking == NULL ) {
+ HDfprintf(stdout,
+ "%s: allocation of trans_tracking failed.\n",
+ FUNC);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
"allocation of trans_tracking failed.");
} /* end if */
@@ -2341,6 +2703,9 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp, FALSE,
(uint64_t)0) < 0) {
+ HDfprintf(stdout,
+ "%s: H5C2_jb__write_to_buffer() failed.\n",
+ FUNC);
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_jb__write_to_buffer() failed.\n")
} /* end if */
@@ -2383,7 +2748,9 @@ H5C2_jb__start_transaction(H5C2_jbrb_t * struct_ptr,
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5C2_jb__start_transaction, FAIL)
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s trans_num = %lld.\n", FUNC, trans_num);
+#endif /* JRM */
/* Check Arguments */
HDassert(struct_ptr);
HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
@@ -2482,7 +2849,10 @@ H5C2_jb__journal_entry(H5C2_jbrb_t * struct_ptr,
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5C2_jb__journal_entry, FAIL)
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s trans_num = %lld, base_addr = %d, length = %ld.\n",
+ FUNC, trans_num, (int)base_addr, (int)length);
+#endif /* JRM */
/* Check Arguments */
HDassert(struct_ptr);
HDassert(body);
@@ -2591,7 +2961,9 @@ H5C2_jb__end_transaction(H5C2_jbrb_t * struct_ptr,
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5C2_jb__end_transaction, FAIL)
-
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s trans_num = %lld.\n", FUNC, trans_num);
+#endif /* JRM */
/* Check Arguments */
HDassert(struct_ptr);
HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
diff --git a/src/H5C2pkg.h b/src/H5C2pkg.h
index 637e5e9..5245ce6 100644
--- a/src/H5C2pkg.h
+++ b/src/H5C2pkg.h
@@ -805,6 +805,38 @@ struct H5C2_jbrb_t
* mdj_jbrb: Instance of H5C2_jbrb_t used to manage logging of journal
* entries to the journal file.
*
+ * If journaling is requested at file creation time, we must make note of
+ * the request, and delay implementing it until receipt of the first
+ * begin transaction message. This is necessary as the file structure will
+ * not have been fully initialized at the point the request is received.
+ *
+ * The following fields support this facility.
+ *
+ * mdj_startup_pending: Boolean flag used to indicate that we must
+ * do setup for journaling on the next begin transaction
+ * call.
+ *
+ * mdj_startup_f: Pointer to the instance of H5F_t used in the metadata
+ * journaling startup.
+ *
+ * mdj_startup_dxpl_id: dxpl_id used in the metadata journaling startup.
+ *
+ * mdj_startup_jrnl_file_name: Pointer to a string containing the name of
+ * the journal file.
+ *
+ * mdj_startup_buf_size: Size of the buffers used in the metadata journal
+ * buffer ring buffer.
+ *
+ * mdj_startup_num_bufs: Number of buffers in the metadata journal buffer
+ * ring buffer.
+ *
+ * mdj_startup_use_aio: use_aio parameter used when setting up metadata
+ * journaling.
+ *
+ * mdj_startup_human_readable: human_readable parameter used when setting
+ * up metadata journaling.
+ *
+ *
* While a transaction is in progress, we must maintain a list of the
* entries that have been modified during the transaction so we can
* generate the appropriate journal entries. The following fields are
@@ -1206,6 +1238,15 @@ struct H5C2_t
size_t jwipl_size;
H5C2_cache_entry_t * jwipl_head_ptr;
H5C2_cache_entry_t * jwipl_tail_ptr;
+
+ hbool_t mdj_startup_pending;
+ H5F_t * mdj_startup_f;
+ hid_t mdj_startup_dxpl_id;
+ char * mdj_startup_jrnl_file_name;
+ size_t mdj_startup_buf_size;
+ int mdj_startup_num_bufs;
+ hbool_t mdj_startup_use_aio;
+ hbool_t mdj_startup_human_readable;
#if H5C2_COLLECT_CACHE_STATS
@@ -1712,6 +1753,26 @@ if ( ( (hd_ptr) == NULL ) || \
) \
) \
) { \
+ HDfprintf(stdout, "%s: TRANS DLL pre remove SC failed.\n", FUNC); \
+ /* JRM */ /* Debugging code -- remove eventually */ \
+ if ( (hd_ptr) == NULL ) HDfprintf(stdout, "( (hd_ptr) == NULL ).\n" );\
+ if ( (tail_ptr) == NULL ) HDfprintf(stdout, "(tail_ptr) == NULL\n");\
+ if ( (entry_ptr) == NULL ) HDfprintf(stdout, "(entry_ptr) == NULL\n");\
+ if ( (len) <= 0 ) HDfprintf(stdout, "( (len) <= 0 )\n");\
+ if ( (Size) < (entry_ptr)->size ) \
+ HDfprintf(stdout,"( (Size) < (entry_ptr)->size )\n");\
+ if ( ( (Size) == (entry_ptr)->size ) && ( ! ( (len) == 1 ) ) ) \
+ HDfprintf(stdout, "(((Size)==(entry_ptr)->size)&&(!((len) == 1)))\n");\
+ if ( ( (entry_ptr)->trans_prev == NULL ) && ( (hd_ptr) != (entry_ptr) ) ) \
+ HDfprintf(stdout,"(((entry_ptr)->trans_prev==NULL)&&((hd_ptr)!=(entry_ptr)))\n");\
+ if ( ((entry_ptr)->trans_next == NULL) && ((tail_ptr) != (entry_ptr)) ) \
+ HDfprintf(stdout,"(((entry_ptr)->trans_next==NULL)&&((tail_ptr)!=(entry_ptr)))\n"); \
+ if ( ( (len) == 1 ) && \
+ ( ! ( ( (hd_ptr) == (entry_ptr) ) && ( (tail_ptr) == (entry_ptr) ) && \
+ ( (entry_ptr)->trans_next == NULL ) && \
+ ( (entry_ptr)->trans_prev == NULL ) && \
+ ( (Size) == (entry_ptr)->size ) ) ) ) \
+ HDfprintf(stdout,"long condition failed\n"); \
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "TRANS DLL pre remove SC failed") \
}
@@ -3134,11 +3195,11 @@ if ( ( (cache_ptr) == NULL ) || \
\
HDassert( (cache_ptr)->mdj_enabled ); \
HDassert( (cache_ptr)->trans_in_progress ); \
- H5C2__TRANS_DLL_PREPEND((entry_ptr), \
- ((cache_ptr)->jwipl_head_ptr), \
- ((cache_ptr)->jwipl_tail_ptr), \
- ((cache_ptr)->jwipl_len), \
- ((cache_ptr)->jwipl_size), fail_val) \
+ H5C2__DLL_PREPEND((entry_ptr), \
+ ((cache_ptr)->jwipl_head_ptr), \
+ ((cache_ptr)->jwipl_tail_ptr), \
+ ((cache_ptr)->jwipl_len), \
+ ((cache_ptr)->jwipl_size), fail_val) \
\
} else { \
\
@@ -3197,11 +3258,11 @@ if ( ( (cache_ptr) == NULL ) || \
\
HDassert( (cache_ptr)->mdj_enabled ); \
HDassert( (cache_ptr)->trans_in_progress ); \
- H5C2__TRANS_DLL_PREPEND((entry_ptr), \
- ((cache_ptr)->jwipl_head_ptr), \
- ((cache_ptr)->jwipl_tail_ptr), \
- ((cache_ptr)->jwipl_len), \
- ((cache_ptr)->jwipl_size), (fail_val)) \
+ H5C2__DLL_PREPEND((entry_ptr), \
+ ((cache_ptr)->jwipl_head_ptr), \
+ ((cache_ptr)->jwipl_tail_ptr), \
+ ((cache_ptr)->jwipl_len), \
+ ((cache_ptr)->jwipl_size), (fail_val)) \
\
} else { \
\
@@ -3348,6 +3409,110 @@ if ( ( (cache_ptr) == NULL ) || \
/*-------------------------------------------------------------------------
*
+ * Macro: H5C2__UPDATE_RP_FOR_LOAD
+ *
+ * Purpose: Update the replacement policy data structures for a
+ * load from disk of the specified cache entry.
+ *
+ * Note that we update the replacement policy for load only
+ * as a convenience -- the newly loaded entry will be
+ * protected immediately. If this starts to eat up a
+ * significant number of cycles, we will have to re-work
+ * the code to avoid this step.
+ *
+ * At present, we only support the modified LRU policy, so
+ * this function deals with that case unconditionally. If
+ * we ever support other replacement policies, the function
+ * should switch on the current policy and act accordingly.
+ *
+ * In theory, the loaded entry should be clean, but due
+ * to a bug fix, it is possible that we will dirty it during
+ * the load.
+ *
+ * Return: N/A
+ *
+ * Programmer: John Mainzer, 5/02/08
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#if H5C2_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS
+
+#define H5C2__UPDATE_RP_FOR_LOAD(cache_ptr, entry_ptr, fail_val) \
+{ \
+ HDassert( (cache_ptr) ); \
+ HDassert( (cache_ptr)->magic == H5C2__H5C2_T_MAGIC ); \
+ HDassert( (entry_ptr) ); \
+ HDassert( !((entry_ptr)->is_protected) ); \
+ HDassert( !((entry_ptr)->is_pinned) ); \
+ HDassert( !((entry_ptr)->is_read_only) ); \
+ HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
+ HDassert( (entry_ptr)->size > 0 ); \
+ HDassert( (entry_ptr)->last_trans == 0 ); \
+ \
+ /* modified LRU specific code */ \
+ \
+ /* insert the entry at the head of the LRU list. */ \
+ \
+ H5C2__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
+ (cache_ptr)->LRU_tail_ptr, \
+ (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_size, (fail_val)) \
+ \
+ /* insert the entry at the head of the clean or dirty LRU list as \
+ * appropriate. \
+ */ \
+ \
+ if ( entry_ptr->is_dirty ) { \
+ H5C2__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \
+ (cache_ptr)->dLRU_tail_ptr, \
+ (cache_ptr)->dLRU_list_len, \
+ (cache_ptr)->dLRU_list_size, (fail_val)) \
+ } else { \
+ H5C2__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \
+ (cache_ptr)->cLRU_tail_ptr, \
+ (cache_ptr)->cLRU_list_len, \
+ (cache_ptr)->cLRU_list_size, (fail_val)) \
+ } \
+ \
+ /* End modified LRU specific code. */ \
+}
+
+#else /* H5C2_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */
+
+#define H5C2__UPDATE_RP_FOR_LOAD(cache_ptr, entry_ptr, fail_val) \
+{ \
+ HDassert( (cache_ptr) ); \
+ HDassert( (cache_ptr)->magic == H5C2__H5C2_T_MAGIC ); \
+ HDassert( (entry_ptr) ); \
+ HDassert( !((entry_ptr)->is_protected) ); \
+ HDassert( !((entry_ptr)->is_pinned) ); \
+ HDassert( !((entry_ptr)->is_read_only) ); \
+ HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
+ HDassert( (entry_ptr)->size > 0 ); \
+ HDassert( (entry_ptr)->last_trans == 0 ); \
+ \
+ /* modified LRU specific code */ \
+ \
+ /* insert the entry at the head of the LRU list. */ \
+ \
+ H5C2__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \
+ (cache_ptr)->LRU_tail_ptr, \
+ (cache_ptr)->LRU_list_len, \
+ (cache_ptr)->LRU_list_size, (fail_val)) \
+ \
+ /* End modified LRU specific code. */ \
+}
+
+#endif /* H5C2_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */
+
+
+/*-------------------------------------------------------------------------
+ *
* Macro: H5C2__UPDATE_RP_FOR_PROTECT
*
* Purpose: Update the replacement policy data structures for a
@@ -4403,9 +4568,9 @@ if ( cache_ptr->mdj_enabled ) \
* Macro: H5C2__UPDATE_TL_FOR_ENTRY_SIZE_CHANGE
*
* Purpose: Update the transaction list for a change in the size of
- * one of its constituents. Note that it is the caller's
+ * one of its constituents. Note that it is the callers
* responsibility to verify that the entry is in the
- * transaction list.
+ * transaction list if it should be.
*
* Return: N/A
*
@@ -4420,13 +4585,12 @@ if ( cache_ptr->mdj_enabled ) \
#define H5C2__UPDATE_TL_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, \
old_size, new_size) \
-if ( (cache_ptr)->mdj_enabled ) { \
+if ( ( (cache_ptr)->mdj_enabled ) && \
+ ( (entry_ptr)->last_trans == (cache_ptr)->trans_num ) ) { \
HDassert( (cache_ptr)->trans_in_progress ); \
- if ( (entry_ptr)->last_trans == (cache_ptr)->trans_num ) { \
- H5C2__DLL_UPDATE_FOR_SIZE_CHANGE(((cache_ptr)->tl_len), \
- ((cache_ptr)->tl_size), \
- (old_size), (new_size)); \
- } \
+ H5C2__DLL_UPDATE_FOR_SIZE_CHANGE(((cache_ptr)->tl_len), \
+ ((cache_ptr)->tl_size), \
+ (old_size), (new_size)); \
} /* H5C2__UPDATE_TL_FOR_ENTRY_SIZE_CHANGE() */
#endif /* _H5C2pkg_H */
diff --git a/src/H5C2private.h b/src/H5C2private.h
index 4f42927..7806337 100644
--- a/src/H5C2private.h
+++ b/src/H5C2private.h
@@ -572,6 +572,9 @@ typedef herr_t (*H5C2_log_flush_func_t)(H5C2_t * cache_ptr,
* If the entry is dirty, the serialize callback must be used
* to update this image before it is written to disk
*
+ * image_up_to_date: Boolean flag that is set to TRUE when *image_ptr
+ * is up to date, and set to false when the entry is dirtied.
+ *
* type: Pointer to the instance of H5C2_class_t containing pointers
* to the methods for cache entries of the current type. This
* field should be NULL when the instance of H5C2_cache_entry_t
@@ -848,6 +851,7 @@ typedef struct H5C2_cache_entry_t
haddr_t addr;
size_t size;
void * image_ptr;
+ hbool_t image_up_to_date;
const H5C2_class_t * type;
hbool_t is_dirty;
hbool_t dirtied;
@@ -1477,6 +1481,7 @@ H5_DLL herr_t H5C2_end_transaction(H5F_t * f,
H5_DLL herr_t H5C2_get_journal_config(H5C2_t * cache_ptr,
hbool_t * journaling_enabled_ptr,
+ hbool_t * startup_pending_ptr,
char * journal_file_path_ptr,
size_t * jbrb_buf_size_ptr,
int * jbrb_num_bufs_ptr,
@@ -1491,6 +1496,15 @@ H5_DLL herr_t H5C2_journal_pre_flush(H5C2_t * cache_ptr);
H5_DLL herr_t H5C2_journal_transaction(H5F_t * f,
H5C2_t * cache_ptr);
+H5_DLL herr_t H5C2_queue_begin_journaling(H5F_t * f,
+ hid_t dxpl_id,
+ H5C2_t * cache_ptr,
+ char * journal_file_name_ptr,
+ size_t buf_size,
+ int num_bufs,
+ hbool_t use_aio,
+ hbool_t human_readable);
+
H5_DLL herr_t H5C2_update_for_new_last_trans_on_disk(H5C2_t * cache_ptr,
uint64_t new_last_trans_on_disk);