summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorJohn Mainzer <mainzer@hdfgroup.org>2006-10-18 10:51:26 (GMT)
committerJohn Mainzer <mainzer@hdfgroup.org>2006-10-18 10:51:26 (GMT)
commit2d6bb5932951242d23ccef420a328a033f3b4efa (patch)
tree3650df339b604f381873f55dcb24af501a83bd0b /test
parentce30ee9b28e9b68de817845aa5bc965d35ca8967 (diff)
downloadhdf5-2d6bb5932951242d23ccef420a328a033f3b4efa.zip
hdf5-2d6bb5932951242d23ccef420a328a033f3b4efa.tar.gz
hdf5-2d6bb5932951242d23ccef420a328a033f3b4efa.tar.bz2
[svn-r12774] Modified flush code in the metadata cache to allow it to
handle flush callbacks which can dirty other entries, and resize and/or rename the target entry. This feature is needed by the fractal heap code. Also added associated test code. H5Commit tested. Test failed on heping, but the error appears to be a syntax error in an un-related file. Tests on copper & sol passed, along with tests on phoenix.
Diffstat (limited to 'test')
-rw-r--r--test/cache.c5429
-rw-r--r--test/cache_common.c911
-rw-r--r--test/cache_common.h215
3 files changed, 6501 insertions, 54 deletions
diff --git a/test/cache.c b/test/cache.c
index 440b5e3..ac9d198 100644
--- a/test/cache.c
+++ b/test/cache.c
@@ -75,6 +75,19 @@ static void check_flush_cache__pinned_single_entry_test(H5C_t * cache_ptr,
hbool_t expected_cleared,
hbool_t expected_flushed,
hbool_t expected_destroyed);
+static void check_flush_cache__flush_ops(H5C_t * cache_ptr);
+static void check_flush_cache__flush_op_test(H5C_t * cache_ptr,
+ int test_num,
+ unsigned int flush_flags,
+ int spec_size,
+ struct fo_flush_cache_test_spec spec[],
+ int init_expected_index_len,
+ size_t init_expected_index_size,
+ int expected_index_len,
+ size_t expected_index_size,
+ int check_size,
+ struct fo_flush_entry_check check[]);
+static void check_flush_cache__flush_op_eviction_test(H5C_t * cache_ptr);
static void check_flush_protected_err(void);
static void check_get_entry_status(void);
static void check_expunge_entry(void);
@@ -2366,6 +2379,11 @@ check_flush_cache(void)
if ( pass ) {
+ check_flush_cache__flush_ops(cache_ptr);
+ }
+
+ if ( pass ) {
+
takedown_cache(cache_ptr, FALSE, FALSE);
}
@@ -4280,6 +4298,13 @@ check_flush_cache__multi_entry_test(H5C_t * cache_ptr,
test_entry_t * base_addr;
test_entry_t * entry_ptr;
+#if 0 /* JRM */
+ /* This gets used a lot, so lets leave it in. */
+
+ HDfprintf(stdout, "check_flush_cache__multi_entry_test: test %d\n",
+ test_num);
+#endif /* JRM */
+
if ( cache_ptr == NULL ) {
pass = FALSE;
@@ -4498,6 +4523,13 @@ check_flush_cache__pe_multi_entry_test(H5C_t * cache_ptr,
test_entry_t * base_addr;
test_entry_t * entry_ptr;
+#if 0 /* JRM */
+ /* This is useful debugging code. Leave it in for now. */
+
+ HDfprintf(stdout, "check_flush_cache__pe_multi_entry_test: test %d\n",
+ test_num);
+#endif /* JRM */
+
if ( cache_ptr == NULL ) {
pass = FALSE;
@@ -4697,6 +4729,5392 @@ check_flush_cache__pe_multi_entry_test(H5C_t * cache_ptr,
/*-------------------------------------------------------------------------
+ * Function: check_flush_cache__flush_ops()
+ *
+ * Purpose: Run the flush ops cache tests.
+ *
+ * These are tests that test the cache's ability to handle
+ * the case in which the flush callback dirties, resizes,
+ * and/or renames entries.
+ *
+ * Do nothing if pass is FALSE on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 9/3/06
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_flush_cache__flush_ops(H5C_t * cache_ptr)
+{
+ /* const char * fcn_name = "check_flush_cache__flush_ops"; */
+
+ if ( cache_ptr == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "cache_ptr NULL on entry to flush ops test.";
+ }
+ else if ( ( cache_ptr->index_len != 0 ) ||
+ ( cache_ptr->index_size != 0 ) ) {
+
+ pass = FALSE;
+ failure_mssg = "cache not empty at beginning of flush ops test.";
+ }
+
+ if ( pass ) /* test #1 */
+ {
+ /* start with a very simple test, in which there are two entries
+ * resident in cache, and the second entry dirties the first in
+ * the flush callback. No size changes, and no flush flags.
+ */
+ int test_num = 1;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 2;
+ int init_expected_index_len = 2;
+ size_t init_expected_index_size = 2 * PICO_ENTRY_SIZE;
+ int expected_index_len = 2;
+ size_t expected_index_size = 2 * PICO_ENTRY_SIZE;
+ struct fo_flush_cache_test_spec spec[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ 0,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #2 */
+ {
+ /* Same as test 1, only this time set the flush invalidate flag.
+ * Note that we must repeat all tests with the flush invalidate flag
+ * as this triggers a different set of code to execute the flush.
+ *
+ * Create two entries resident in cache, and have the second entry
+ * dirty the first in the flush callback.
+ */
+ int test_num = 2;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 2;
+ int init_expected_index_len = 2;
+ size_t init_expected_index_size = 2 * PICO_ENTRY_SIZE;
+ int expected_index_len = 0;
+ size_t expected_index_size = 0;
+ struct fo_flush_cache_test_spec spec[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE,0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #3 */
+ {
+ /* Single entry test verifying that the cache can handle the case in
+ * which the call back function resizes the entry for which it has
+ * been called.
+ */
+ int test_num = 3;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = VARIABLE_ENTRY_SIZE / 4;
+ int expected_index_len = 1;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE / 2;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #4 */
+ {
+ /* Repeat test #4 with the flush invalidate flag.
+ *
+ * Single entry test verifying that the cache can handle the case in
+ * which the call back function resizes the entry for which it has
+ * been called.
+ */
+ int test_num = 4;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = VARIABLE_ENTRY_SIZE / 4;
+ int expected_index_len = 0;
+ size_t expected_index_size = 0;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #5 & #6 */
+ {
+ /* Single entry test verifying that the cache can handle the case in
+ * which the call back function renames the entry for which it has
+ * been called.
+ *
+ * Run this entry twice, as the first run moves the entry to its
+ * alternate address, and the second moves it back.
+ */
+ int test_num = 5; /* and 6 */
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 1;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ /* this change forces the rename to move the target entry back to its
+ * main address. The first test moved it to its alternate address.
+ *
+ * Note that these two tests are not the same, as in the first test,
+ * the renamed entry is moved forward in the slist. In the second
+ * it is moved backwards.
+ *
+ * Since there is only one entry in the cache, this doesn't really
+ * matter in this case. But we will do similar tests later with
+ * other entries in the cache.
+ */
+ if ( pass ) {
+
+ spec[0].flush_ops[0].flag = TRUE;
+ test_num = 6;
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+ }
+
+ if ( pass ) /* test #7 & #8 */
+ {
+ /* Run tests 5 & 6 again, using the flush invalidate flag on the
+ * second test.
+ *
+ * Single entry test verifying that the cache can handle the case in
+ * which the call back function renames the entry for which it has
+ * been called.
+ *
+ * Run this entry twice, as the first run moves the entry to its
+ * alternate address, and the second moves it back.
+ */
+ int test_num = 7; /* and 8 */
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 1;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ /* this change forces the rename to move the target entry back to its
+ * main address. The first test moved it to its alternate address.
+ *
+ * Note that these two tests are not the same, as in the first test,
+ * the renamed entry is moved forward in the slist. In the second
+ * it is moved backwards.
+ *
+ * Since there is only one entry in the cache, this doesn't really
+ * matter in this case. But we will do similar tests later with
+ * other entries in the cache.
+ */
+
+ if ( pass ) {
+
+ test_num = 8;
+ flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ expected_index_len = 0;
+ expected_index_size = 0;
+ spec[0].flush_ops[0].flag = TRUE;
+ spec[0].expected_destroyed = TRUE;
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+ }
+
+ if ( pass ) /* test #9 & #10 */
+ {
+ /* Single entry test verifying that the cache can handle the case in
+ * which the call back function both resizes and renames the entry
+ * for which it has been called.
+ *
+ * Again, we run this entry twice, as the first run moves the entry to its
+ * alternate address, and the second moves it back.
+ */
+ int test_num = 9; /* and 10 */
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = VARIABLE_ENTRY_SIZE / 2;
+ int expected_index_len = 1;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE / 4;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 2,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ /* this change forces the rename to move the target entry back to its
+ * main address. The first test moved it to its alternate address.
+ *
+ * Note that these two tests are not the same, as in the first test,
+ * the renamed entry is moved forward in the slist. In the second
+ * it is moved backwards.
+ *
+ * Since there is only one entry in the cache, this doesn't really
+ * matter in this case. But we will do similar tests later with
+ * other entries in the cache.
+ */
+ if ( pass ) {
+
+ spec[0].flush_ops[0].flag = TRUE;
+ test_num = 10;
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+ }
+
+ if ( pass ) /* test #11 & #12 */
+ {
+ /* Repeat the previous test with the flush invalidate flag on the
+ * second test.
+ *
+ * Single entry test verifying that the cache can handle the case in
+ * which the call back function both resizes and renames the entry
+ * for which it has been called.
+ *
+ * Again, we run this entry twice, as the first run moves the entry to its
+ * alternate address, and the second moves it back.
+ */
+ int test_num = 11; /* and 12 */
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = VARIABLE_ENTRY_SIZE / 2;
+ int expected_index_len = 1;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE / 4;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 2,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ /* this change forces the rename to move the target entry back to its
+ * main address. The first test moved it to its alternate address.
+ *
+ * Note that these two tests are not the same, as in the first test,
+ * the renamed entry is moved forward in the slist. In the second
+ * it is moved backwards.
+ *
+ * Since there is only one entry in the cache, this doesn't really
+ * matter in this case. But we will do similar tests later with
+ * other entries in the cache.
+ */
+ if ( pass ) {
+
+ test_num = 12;
+ flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ expected_index_len = 0;
+ expected_index_size = 0;
+ spec[0].flush_ops[1].flag = TRUE;
+ spec[0].expected_destroyed = TRUE;
+
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+ }
+
+ if ( pass ) /* test #13 */
+ {
+ /* Test the ability of the cache to handle the case in which
+ * the flush function of an entry that is resident in cache
+ * dirties two entries that are not in cache. No size
+ * changes.
+ *
+ * At present, I am assured that this case will never occur, but
+ * lets make sure we can handle it regardless.
+ */
+ int test_num = 13;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = 1 * PICO_ENTRY_SIZE;
+ int expected_index_len = 3;
+ size_t expected_index_size = 3 * PICO_ENTRY_SIZE;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 2,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, 0, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, 0, 2, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 2;
+ struct fo_flush_entry_check checks[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ PICO_ENTRY_SIZE,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ PICO_ENTRY_SIZE,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #14 */
+ {
+ /* Repeat previous test with the flush invalidate flag.
+ *
+ * Test the ability of the cache to handle the case in which
+ * the flush function of an entry that is resident in cache
+ * dirties two entries that are not in cache. No size
+ * changes.
+ *
+ * At present, I am assured that this case will never occur, but
+ * lets make sure we can handle it regardless.
+ */
+ int test_num = 14;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = 1 * PICO_ENTRY_SIZE;
+ int expected_index_len = 0;
+ size_t expected_index_size = (size_t)0;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 2,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, 0, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, 0, 2, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 2;
+ struct fo_flush_entry_check checks[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ PICO_ENTRY_SIZE,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ PICO_ENTRY_SIZE,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #15 */
+ {
+ /* Test the ability of the cache to handle the case in which
+ * the flush function of an entry that is resident in cache
+ * resizes and dirties two entries that are not in cache.
+ *
+ * At present, I am assured that this case will never occur, but
+ * lets make sure we can handle it regardless.
+ */
+ int test_num = 15;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = 1 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 3;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE +
+ (VARIABLE_ENTRY_SIZE / 4) +
+ (VARIABLE_ENTRY_SIZE / 2);
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 4,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 2;
+ struct fo_flush_entry_check checks[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #16 */
+ {
+ /* Repeat previous test with the flush invalidate flag.
+ *
+ * Test the ability of the cache to handle the case in which
+ * the flush function of an entry that is resident in cache
+ * resizes and dirties two entries that are not in cache.
+ *
+ * At present, I am assured that this case will never occur, but
+ * lets make sure we can handle it regardless.
+ */
+ int test_num = 16;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = 1 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 0;
+ size_t expected_index_size = (size_t)0;
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 4,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 2;
+ struct fo_flush_entry_check checks[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #17 & #18 */
+ {
+ /* Test the ability of the cache to handle the case in which
+ * the flush function of an entry that is resident in cache
+ * resizes, dirties, and renames two entries that are not in cache.
+ *
+ * At present, I am assured that this case will never occur, but
+ * lets make sure we can handle it regardless.
+ */
+ int test_num = 17; /* and 18 */
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = 1 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 3;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE +
+ (VARIABLE_ENTRY_SIZE / 4) +
+ (VARIABLE_ENTRY_SIZE / 2);
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 2;
+ struct fo_flush_entry_check checks[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ /* this change forces the renames to move the target entries back to
+ * their main address. The first test moved them to their alternate
+ * address.
+ *
+ * Note that these two tests are not the same, as in the first test,
+ * the renamed entries are moved forward in the slist. In the second
+ * they are moved backwards.
+ */
+ if ( pass ) {
+
+ test_num = 18;
+ spec[0].flush_ops[2].flag = TRUE;
+ spec[0].flush_ops[5].flag = TRUE;
+ checks[0].at_main_addr = TRUE;
+ checks[1].at_main_addr = TRUE;
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+ }
+
+ if ( pass ) /* test #19 & #20 */
+ {
+ /* Repeat the above test with the flush invalidate flag on the
+ * second test.
+ *
+ * Test the ability of the cache to handle the case in which
+ * the flush function of an entry that is resident in cache
+ * resizes, dirties, and renames two entries that are not in cache.
+ *
+ * At present, I am assured that this case will never occur, but
+ * lets make sure we can handle it regardless.
+ */
+ int test_num = 19; /* and 20 */
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 1;
+ int init_expected_index_len = 1;
+ size_t init_expected_index_size = 1 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 3;
+ size_t expected_index_size = VARIABLE_ENTRY_SIZE +
+ (VARIABLE_ENTRY_SIZE / 4) +
+ (VARIABLE_ENTRY_SIZE / 2);
+ struct fo_flush_cache_test_spec spec[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 2;
+ struct fo_flush_entry_check checks[2] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ /* this change forces the renames to move the target entries back to
+ * their main address. The first test moved them to their alternate
+ * address.
+ *
+ * Note that these two tests are not the same, as in the first test,
+ * the renamed entries are moved forward in the slist. In the second
+ * they are moved backwards.
+ */
+ if ( pass ) {
+
+ test_num = 20;
+ flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ expected_index_len = 0;
+ expected_index_size = (size_t)0;
+ spec[0].expected_destroyed = TRUE;
+ spec[0].flush_ops[2].flag = TRUE;
+ spec[0].flush_ops[5].flag = TRUE;
+ checks[0].at_main_addr = TRUE;
+ checks[0].in_cache = FALSE;
+ checks[0].expected_destroyed = TRUE;
+ checks[1].at_main_addr = TRUE;
+ checks[1].in_cache = FALSE;
+ checks[1].expected_destroyed = TRUE;
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+ }
+
+ if ( pass ) /* test #21 */
+ {
+ /* Now mix things up a bit.
+ *
+ * Load several entries, two of which have flush functions that
+ * resize, dirty, and rename two entries that are not in the
+ * cache. Mark only one of these entries, and then flush the
+ * cache with the flush marked entries flag.
+ *
+ * This is the only test in which we test the
+ * H5C__FLUSH_MARKED_ENTRIES_FLAG. The hope is that since
+ * we test the two features extensively by themselves, so
+ * it should be sufficient to verify that they play together
+ * as expected.
+ */
+ int test_num = 21;
+ unsigned int flush_flags = H5C__FLUSH_MARKED_ENTRIES_FLAG;
+ int spec_size = 4;
+ int init_expected_index_len = 4;
+ size_t init_expected_index_size = (2 * VARIABLE_ENTRY_SIZE) + (2 * PICO_ENTRY_SIZE);
+ int expected_index_len = 6;
+ size_t expected_index_size = (2 * VARIABLE_ENTRY_SIZE) +
+ (VARIABLE_ENTRY_SIZE / 4) +
+ (VARIABLE_ENTRY_SIZE / 2) +
+ (2 * PICO_ENTRY_SIZE);
+ struct fo_flush_cache_test_spec spec[4] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SET_FLUSH_MARKER_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 11,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 10, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 10, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 10, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 12, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 12, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 12, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SET_FLUSH_MARKER_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 4;
+ struct fo_flush_entry_check checks[4] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ TRUE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ TRUE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 10,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 12,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ reset_entries();
+ }
+
+ if ( pass ) /* test #22 */
+ {
+ /* Mix things up some more.
+ *
+ * Load lots of entries, some of which have flush functions that
+ * resize, dirty, and rename two entries that are not in the
+ * cache.
+ *
+ * Also load entries that have flush ops on entries that are in
+ * cache.
+ */
+ int test_num = 22;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 6;
+ int init_expected_index_len = 6;
+ size_t init_expected_index_size = (2 * VARIABLE_ENTRY_SIZE) + (4 * PICO_ENTRY_SIZE);
+ int expected_index_len = 10;
+ size_t expected_index_size = (2 * VARIABLE_ENTRY_SIZE) +
+ (2 * (VARIABLE_ENTRY_SIZE / 4)) +
+ (2 * (VARIABLE_ENTRY_SIZE / 2)) +
+ (4 * PICO_ENTRY_SIZE);
+ struct fo_flush_cache_test_spec spec[6] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 11,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 10, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 10, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 10, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 12, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 12, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 12, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 4,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 10,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 5,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 20,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 4;
+ struct fo_flush_entry_check checks[4] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 10,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 12,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ reset_entries();
+ }
+
+ if ( pass ) /* test #23 */
+ {
+ /* Repeat test #23 with the flush invalidate flag set.
+ *
+ * Mix things up some more.
+ *
+ * Load lots of entries, some of which have flush functions that
+ * resize, dirty, and rename two entries that are not in the
+ * cache.
+ *
+ * Also load entries that have flush ops on entries that are in
+ * cache.
+ */
+ int test_num = 23;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 6;
+ int init_expected_index_len = 6;
+ size_t init_expected_index_size = (2 * VARIABLE_ENTRY_SIZE) + (4 * PICO_ENTRY_SIZE);
+ int expected_index_len = 0;
+ size_t expected_index_size = 0;
+ struct fo_flush_cache_test_spec spec[6] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 2, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 11,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 6,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 10, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 10, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 10, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 12, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 12, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 12, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 1,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 4,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 10,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 5,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 20,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 4;
+ struct fo_flush_entry_check checks[4] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 0,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 10,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 12,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ reset_entries();
+ }
+
+ /* So much for tests involving only flush operations.
+ *
+ * Now create some tests mixing flush ops and pins.
+ */
+ if ( pass ) /* test #24 */
+ {
+ /* Pico entries 50 and 150 pin pico entry 100, and also dirty
+ * pico entry 100 on flush.
+ */
+ int test_num = 24;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 3;
+ int init_expected_index_len = 3;
+ size_t init_expected_index_size = 3 * PICO_ENTRY_SIZE;
+ int expected_index_len = 3;
+ size_t expected_index_size = 3 * PICO_ENTRY_SIZE;
+ struct fo_flush_cache_test_spec spec[3] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 100,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 50,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 1,
+ /* pin_type = */ {PICO_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 150,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 1,
+ /* pin_type = */ {PICO_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__DIRTY, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #25 */
+ {
+ /* Repeat the previous test with the flush invalidate flag.
+ *
+ * Pico entries 50 and 150 pin pico entry 100, and also dirty
+ * pico entry 100 on flush.
+ */
+ int test_num = 25;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 3;
+ int init_expected_index_len = 3;
+ size_t init_expected_index_size = 3 * PICO_ENTRY_SIZE;
+ int expected_index_len = 0;
+ size_t expected_index_size = (size_t)0;
+ struct fo_flush_cache_test_spec spec[3] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 100,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 50,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 1,
+ /* pin_type = */ {PICO_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ PICO_ENTRY_TYPE,
+ /* entry_index = */ 150,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 1,
+ /* pin_type = */ {PICO_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 1,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, PICO_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__DIRTY, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ (size_t)0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+ }
+
+ if ( pass ) /* test #26 */
+ {
+ /* This one is complex.
+ *
+ * In the following overvies table, VET stands for
+ * VARIABLE_ENTRY_TYPE.
+ *
+ * In trying to follow what happens when we flush the
+ * set of entries constructed below, recall that each
+ * flush operation is executed the first time the
+ * entry is flushed, and then not executed again.
+ * This may be a weakness in the tests, but that
+ * is the way it is for now.
+ *
+ * After thinking about it for a while, I'm not sure that
+ * the interaction between pins and flush operations needs
+ * all that much testing, as the two are essentially
+ * orthoginal. Thus this is a bit of a smoke check to
+ * verify that we get the expected results.
+ *
+ * (VET, 100) initially not resident in cache
+ *
+ * (VET, 200) initially clean and resident in cache
+ *
+ * (VET, 300) initially not resident in cache
+ *
+ * (VET, 2100) initially clean and resident in cache
+ *
+ * (VET, 2200) initially not resident in cache
+ *
+ * (VET, 2300) initially clean and resident in cache
+ *
+ * (VET, 1000) initially clean, and in cache
+ * dirties (VET, 100)
+ * resizes (VET, 200)
+ * dirty (VET, 300) -- dirty first to bring into cache.
+ * renames (VET, 300)
+ *
+ * (VET, 2000) initially clean, and in cache
+ * dirties (VET, 2100)
+ * resizes (VET, 2200)
+ * renames (VET, 2300)
+ *
+ * (VET, 350) initially clean, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * resizes (VET, 350)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 450) initially dirty, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * renames (VET, 450)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 650) initially clean, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * resizes (VET, 650)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 750) initially dirty, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * resizes (VET, 750)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 500) initially dirty, and in cache
+ * dirties (VET, 350)
+ * dirties (VET, 450)
+ * dirties (VET, 650)
+ * dirties (VET, 750)
+ */
+ int test_num = 26;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 10;
+ int init_expected_index_len = 10;
+ size_t init_expected_index_size = 10 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 13;
+ size_t expected_index_size = 9 * VARIABLE_ENTRY_SIZE;
+ struct fo_flush_cache_test_spec spec[10] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 200,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2100,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2300,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1000,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 4,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 200, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 300, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 300, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 4,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2000,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2200, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 2300, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 5,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 350,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 350, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 6,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 450,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 450, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 7,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 650,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 650, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 8,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 750,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 750, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 9,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 500,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 4,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 350, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 450, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 650, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 750, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 3;
+ struct fo_flush_entry_check checks[3] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 100,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 300,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2200,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ TRUE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ reset_entries();
+ }
+
+ if ( pass ) /* test #27 */
+ {
+ /* Repeat test #26 with the flush invalidate flag.
+ *
+ * In the following overview table, VET stands for
+ * VARIABLE_ENTRY_TYPE.
+ *
+ * In trying to follow what happens when we flush the
+ * set of entries constructed below, recall that each
+ * flush operation is executed the first time the
+ * entry is flushed, and then not executed again.
+ * This may be a weakness in the tests, but that
+ * is the way it is for now.
+ *
+ * After thinking about it for a while, I'm not sure that
+ * the interaction between pins and flush operations needs
+ * all that much testing, as the two are essentially
+ * orthoginal. The big thing is to verify that flushes of
+ * pinned entries with flush ops result in the expected
+ * updates of the cache.
+ *
+ * Thus this is a bit of a smoke check to * verify that we
+ * get the expected results.
+ *
+ * (VET, 100) initially not resident in cache
+ *
+ * (VET, 200) initially clean and resident in cache
+ *
+ * (VET, 300) initially not resident in cache
+ *
+ * (VET, 2100) initially clean and resident in cache
+ *
+ * (VET, 2200) initially not resident in cache
+ *
+ * (VET, 2300) initially clean and resident in cache
+ *
+ * (VET, 1000) initially clean, and in cache
+ * dirties (VET, 100)
+ * resizes (VET, 200)
+ * dirty (VET, 300) -- dirty first to bring into cache.
+ * renames (VET, 300)
+ *
+ * (VET, 2000) initially clean, and in cache
+ * dirties (VET, 2100)
+ * resizes (VET, 2200)
+ * renames (VET, 2300)
+ *
+ * (VET, 350) initially clean, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * resizes (VET, 350)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 450) initially dirty, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * renames (VET, 450)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 650) initially clean, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * resizes (VET, 650)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 750) initially dirty, and in cache
+ * pins (VET, 1000)
+ * dirties (VET, 1000)
+ * resizes (VET, 750)
+ * pins (VET, 2000)
+ * dirties (VET, 2000)
+ *
+ * (VET, 500) initially dirty, and in cache
+ * dirties (VET, 350)
+ * dirties (VET, 450)
+ * dirties (VET, 650)
+ * dirties (VET, 750)
+ */
+ int test_num = 27;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 10;
+ int init_expected_index_len = 10;
+ size_t init_expected_index_size = 10 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 0;
+ size_t expected_index_size = (size_t)0;
+ struct fo_flush_cache_test_spec spec[10] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 200,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2100,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2300,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 1000,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 4,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 200, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 300, FALSE, 0 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 300, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 4,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2000,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 2200, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 2300, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 5,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 350,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 350, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 6,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 450,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 450, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 7,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 650,
+ /* insert_flag = */ TRUE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 650, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 8,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 750,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 2,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {1000, 2000, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 1000, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 2000, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 750, FALSE, VARIABLE_ENTRY_SIZE / 4 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 9,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 500,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 4,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 350, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 450, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 650, FALSE, 0 },
+ { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 750, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 3;
+ struct fo_flush_entry_check checks[3] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 100,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 300,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 2200,
+ /* expected_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ TRUE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ reset_entries();
+ }
+
+ if ( pass ) /* test #28 */
+ {
+ /* Test the expected fheap case, in which an entry dirties
+ * and resizes itself, and dirties an entry which it has
+ * pinned.
+ */
+ int test_num = 28;
+ unsigned int flush_flags = H5C__NO_FLAGS_SET;
+ int spec_size = 5;
+ int init_expected_index_len = 5;
+ size_t init_expected_index_size = 3 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 5;
+ size_t expected_index_size = 4 * VARIABLE_ENTRY_SIZE;
+ struct fo_flush_cache_test_spec spec[5] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 100,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 200,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* num_pins = */ 1,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 200, FALSE, VARIABLE_ENTRY_SIZE },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 200, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 300,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* num_pins = */ 1,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {400, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 400, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 300, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 300, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 400,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ },
+ {
+ /* entry_num = */ 4,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 500,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* num_pins = */ 1,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 500, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 500, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ 0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ reset_entries();
+ }
+
+ if ( pass ) /* test #29 */
+ {
+ /* Repeat test #28 with the flush invalidate flag.
+ *
+ * Test the expected fheap case, in which an entry dirties
+ * and resizes itself, and dirties an entry which it has
+ * pinned.
+ */
+ int test_num = 29;
+ unsigned int flush_flags = H5C__FLUSH_INVALIDATE_FLAG;
+ int spec_size = 5;
+ int init_expected_index_len = 5;
+ size_t init_expected_index_size = 3 * VARIABLE_ENTRY_SIZE;
+ int expected_index_len = 0;
+ size_t expected_index_size = 0;
+ struct fo_flush_cache_test_spec spec[5] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 100,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 1,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 200,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 2,
+ /* num_pins = */ 1,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 200, FALSE, VARIABLE_ENTRY_SIZE },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 200, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 2,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 300,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* num_pins = */ 1,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {400, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 400, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 300, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 300, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 3,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 400,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__NO_FLAGS_SET,
+ /* new_size = */ 0,
+ /* num_pins = */ 0,
+ /* pin_type = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 0,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ },
+ {
+ /* entry_num = */ 4,
+ /* entry_type = */ VARIABLE_ENTRY_TYPE,
+ /* entry_index = */ 500,
+ /* insert_flag = */ FALSE,
+ /* flags = */ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ /* new_size = */ VARIABLE_ENTRY_SIZE / 4,
+ /* num_pins = */ 1,
+ /* pin_type = */ {VARIABLE_ENTRY_TYPE, 0, 0, 0, 0, 0, 0, 0},
+ /* pin_idx = */ {100, 0, 0, 0, 0, 0, 0, 0},
+ /* num_flush_ops = */ 3,
+ /* flush_ops = */
+ /* op_code: type: idx: flag: size: */
+ { { FLUSH_OP__DIRTY, VARIABLE_ENTRY_TYPE, 100, FALSE, 0 },
+ { FLUSH_OP__RESIZE, VARIABLE_ENTRY_TYPE, 500, FALSE, VARIABLE_ENTRY_SIZE / 2 },
+ { FLUSH_OP__RENAME, VARIABLE_ENTRY_TYPE, 500, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 },
+ { FLUSH_OP__NO_OP, 0, 0, FALSE, 0 } },
+ /* expected_loaded = */ TRUE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ TRUE,
+ /* expected_destroyed = */ TRUE
+ }
+ };
+ int check_size = 0;
+ struct fo_flush_entry_check checks[1] =
+ {
+ {
+ /* entry_num = */ 0,
+ /* entry_type = */ 0,
+ /* entry_index = */ 0,
+ /* expected_size = */ 0,
+ /* in_cache = */ FALSE,
+ /* at_main_addr = */ FALSE,
+ /* is_dirty = */ FALSE,
+ /* is_protected = */ FALSE,
+ /* is_pinned = */ FALSE,
+ /* expected_loaded = */ FALSE,
+ /* expected_cleared = */ FALSE,
+ /* expected_flushed = */ FALSE,
+ /* expected_destroyed = */ FALSE
+ }
+ };
+
+ check_flush_cache__flush_op_test(cache_ptr,
+ test_num,
+ flush_flags,
+ spec_size,
+ spec,
+ init_expected_index_len,
+ init_expected_index_size,
+ expected_index_len,
+ expected_index_size,
+ check_size,
+ checks);
+
+ reset_entries();
+ }
+
+ /* finally finish up with the flush ops eviction test */
+ check_flush_cache__flush_op_eviction_test(cache_ptr);
+
+ return;
+
+} /* check_flush_cache__flush_ops() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: check_flush_cache__flush_op_test()
+ *
+ * Purpose: Run a flush op flush cache test. Of the nature of
+ * flush operations, this is a multi-entry test.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 9/3/06
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_flush_cache__flush_op_test(H5C_t * cache_ptr,
+ int test_num,
+ unsigned int flush_flags,
+ int spec_size,
+ struct fo_flush_cache_test_spec spec[],
+ int init_expected_index_len,
+ size_t init_expected_index_size,
+ int expected_index_len,
+ size_t expected_index_size,
+ int check_size,
+ struct fo_flush_entry_check check[])
+{
+ /* const char * fcn_name = "check_flush_cache__flush_op_test"; */
+ static char msg[128];
+ herr_t result;
+ int i;
+ int j;
+ test_entry_t * base_addr;
+ test_entry_t * entry_ptr;
+
+#if 0 /* This is useful debugging code -- lets keep it around. */
+ HDfprintf(stdout, "check_flush_cache__flush_op_test: test %d\n",
+ test_num);
+#endif
+
+ if ( cache_ptr == NULL ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "cache_ptr NULL on entry to flush op test #%d.",
+ test_num);
+ failure_mssg = msg;
+ }
+ else if ( ( cache_ptr->index_len != 0 ) ||
+ ( cache_ptr->index_size != 0 ) ) {
+
+ pass = FALSE;
+
+ HDsnprintf(msg, (size_t)128,
+ "cache not empty at beginning of flush op test #%d.",
+ test_num);
+ failure_mssg = msg;
+ }
+ else if ( ( spec_size < 1 ) || ( spec == NULL ) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "missing/bad test spec on entry to flush op test #%d.",
+ test_num);
+ failure_mssg = msg;
+ }
+
+ i = 0;
+ while ( ( pass ) && ( i < spec_size ) )
+ {
+ if ( ( spec[i].entry_num != i ) ||
+ ( spec[i].entry_type < 0 ) ||
+ ( spec[i].entry_type >= NUMBER_OF_ENTRY_TYPES ) ||
+ ( spec[i].entry_index < 0 ) ||
+ ( spec[i].entry_index > max_indices[spec[i].entry_type] ) ||
+ ( spec[i].num_pins < 0 ) ||
+ ( spec[i].num_pins > MAX_PINS ) ||
+ ( spec[i].num_flush_ops < 0 ) ||
+ ( spec[i].num_flush_ops > MAX_FLUSH_OPS ) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "bad data in spec[%d] on entry to flush op test #%d.",
+ i, test_num);
+ failure_mssg = msg;
+ }
+ i++;
+ }
+
+ i = 0;
+ while ( ( pass ) && ( i < check_size ) )
+ {
+ if ( ( check[i].entry_num != i ) ||
+ ( check[i].entry_type < 0 ) ||
+ ( check[i].entry_type >= NUMBER_OF_ENTRY_TYPES ) ||
+ ( check[i].entry_index < 0 ) ||
+ ( check[i].entry_index > max_indices[check[i].entry_type] ) ||
+ ( check[i].expected_size <= (size_t)0 ) ||
+ ( ( check[i].in_cache != TRUE ) &&
+ ( check[i].in_cache != FALSE ) ) ||
+ ( ( check[i].at_main_addr != TRUE ) &&
+ ( check[i].at_main_addr != FALSE ) ) ||
+ ( ( check[i].is_dirty != TRUE ) &&
+ ( check[i].is_dirty != FALSE ) ) ||
+ ( ( check[i].is_protected != TRUE ) &&
+ ( check[i].is_protected != FALSE ) ) ||
+ ( ( check[i].is_pinned != TRUE ) &&
+ ( check[i].is_pinned != FALSE ) ) ||
+ ( ( check[i].expected_loaded != TRUE ) &&
+ ( check[i].expected_loaded != FALSE ) ) ||
+ ( ( check[i].expected_cleared != TRUE ) &&
+ ( check[i].expected_cleared != FALSE ) ) ||
+ ( ( check[i].expected_flushed != TRUE ) &&
+ ( check[i].expected_flushed != FALSE ) ) ||
+ ( ( check[i].expected_destroyed != TRUE ) &&
+ ( check[i].expected_destroyed != FALSE ) ) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "bad data in check[%d] on entry to flush op test #%d.",
+ i, test_num);
+ failure_mssg = msg;
+ }
+ i++;
+ }
+
+ i = 0;
+ while ( ( pass ) && ( i < spec_size ) )
+ {
+ if ( spec[i].insert_flag ) {
+
+ insert_entry(cache_ptr, spec[i].entry_type, spec[i].entry_index,
+ TRUE, spec[i].flags);
+
+ } else {
+
+ protect_entry(cache_ptr, spec[i].entry_type, spec[i].entry_index);
+
+ unprotect_entry_with_size_change(cache_ptr, spec[i].entry_type,
+ spec[i].entry_index,
+ spec[i].flags, spec[i].new_size);
+ }
+
+ for ( j = 0; j < spec[i].num_pins; j++ )
+ {
+ create_pinned_entry_dependency(cache_ptr,
+ spec[i].entry_type,
+ spec[i].entry_index,
+ spec[i].pin_type[j],
+ spec[i].pin_idx[j]);
+ }
+
+ for ( j = 0; j < spec[i].num_flush_ops; j++ )
+ {
+ add_flush_op(spec[i].entry_type,
+ spec[i].entry_index,
+ spec[i].flush_ops[j].op_code,
+ spec[i].flush_ops[j].type,
+ spec[i].flush_ops[j].idx,
+ spec[i].flush_ops[j].flag,
+ spec[i].flush_ops[j].size);
+ }
+
+ i++;
+ }
+
+ if ( pass ) {
+
+ if ( ( cache_ptr->index_len != init_expected_index_len ) ||
+ ( cache_ptr->index_size != init_expected_index_size ) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Unexpected cache len/size before flush in flush op test #%d.",
+ test_num);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ result = H5C_flush_cache(NULL, -1, -1, cache_ptr, flush_flags);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "flush with flags 0x%x failed in flush op test #%d.",
+ flush_flags, test_num);
+ failure_mssg = msg;
+ }
+ }
+
+
+ i = 0;
+ while ( ( pass ) && ( i < spec_size ) )
+ {
+ base_addr = entries[spec[i].entry_type];
+ entry_ptr = &(base_addr[spec[i].entry_index]);
+
+ if ( ( entry_ptr->loaded != spec[i].expected_loaded ) ||
+ ( entry_ptr->cleared != spec[i].expected_cleared ) ||
+ ( entry_ptr->flushed != spec[i].expected_flushed ) ||
+ ( entry_ptr->destroyed != spec[i].expected_destroyed ) ) {
+
+#if 0 /* This is useful debugging code. Lets keep it around. */
+
+ HDfprintf(stdout,
+ "loaded = %d(%d), clrd = %d(%d), flshd = %d(%d), dest = %d(%d)\n",
+ (int)(entry_ptr->loaded),
+ (int)(spec[i].expected_loaded),
+ (int)(entry_ptr->cleared),
+ (int)(spec[i].expected_cleared),
+ (int)(entry_ptr->flushed),
+ (int)(spec[i].expected_flushed),
+ (int)(entry_ptr->destroyed),
+ (int)(spec[i].expected_destroyed));
+
+ HDfprintf(stdout, "entry_ptr->header.is_dirty = %d\n",
+ (int)(entry_ptr->header.is_dirty));
+#endif
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Bad status on entry %d after flush op test #%d.",
+ i, test_num);
+ failure_mssg = msg;
+ }
+ i++;
+ }
+
+ if ( pass ) {
+
+ i = 0;
+ while ( ( pass ) && ( i < check_size ) )
+ {
+ if ( check[i].in_cache != entry_in_cache(cache_ptr,
+ check[i].entry_type,
+ check[i].entry_index) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Check1 failed on entry %d after flush op test #%d.",
+ i, test_num);
+ failure_mssg = msg;
+ }
+
+ base_addr = entries[check[i].entry_type];
+ entry_ptr = &(base_addr[check[i].entry_index]);
+
+ if ( ( entry_ptr->size != check[i].expected_size ) ||
+ ( ( ! entry_ptr->header.destroy_in_progress ) &&
+ ( check[i].in_cache ) &&
+ ( entry_ptr->header.size != check[i].expected_size ) ) ||
+ ( entry_ptr->at_main_addr != check[i].at_main_addr ) ||
+ ( entry_ptr->is_dirty != check[i].is_dirty ) ||
+ ( entry_ptr->header.is_dirty != check[i].is_dirty ) ||
+ ( entry_ptr->is_protected != check[i].is_protected ) ||
+ ( entry_ptr->header.is_protected != check[i].is_protected ) ||
+ ( entry_ptr->is_pinned != check[i].is_pinned ) ||
+ ( entry_ptr->header.is_pinned != check[i].is_pinned ) ||
+ ( entry_ptr->loaded != check[i].expected_loaded ) ||
+ ( entry_ptr->cleared != check[i].expected_cleared ) ||
+ ( entry_ptr->flushed != check[i].expected_flushed ) ||
+ ( entry_ptr->destroyed != check[i].expected_destroyed ) ) {
+
+#if 0 /* This is useful debugging code. Lets keep it around for a while. */
+
+ if ( entry_ptr->size != check[i].expected_size ) {
+ HDfprintf(stdout, "entry_ptr->size (expected) = %d (%d).\n",
+ (int)(entry_ptr->size),
+ (int)(check[i].expected_size));
+ }
+ if ( ( ! entry_ptr->header.destroy_in_progress ) &&
+ ( check[i].in_cache ) &&
+ ( entry_ptr->header.size != check[i].expected_size ) ) {
+ HDfprintf(stdout,
+ "(!destroy in progress and in cache and size (expected) = %d (%d).\n",
+ (int)(entry_ptr->header.size),
+ (int)(check[i].expected_size));
+ }
+ if ( entry_ptr->at_main_addr != check[i].at_main_addr ) {
+ HDfprintf(stdout, "(%d,%d) at main addr (expected) = %d (%d).\n",
+ (int)(check[i].entry_type),
+ (int)(check[i].entry_index),
+ (int)(entry_ptr->at_main_addr),
+ (int)(check[i].at_main_addr));
+ }
+ if ( entry_ptr->is_dirty != check[i].is_dirty ) {
+ HDfprintf(stdout, "entry_ptr->is_dirty (expected) = %d (%d).\n",
+ (int)(entry_ptr->is_dirty),
+ (int)(check[i].is_dirty));
+ }
+ if ( entry_ptr->header.is_dirty != check[i].is_dirty ) {
+ HDfprintf(stdout, "entry_ptr->header.is_dirty (expected) = %d (%d).\n",
+ (int)(entry_ptr->header.is_dirty),
+ (int)(check[i].is_dirty));
+ }
+ if ( entry_ptr->is_protected != check[i].is_protected ) {
+ HDfprintf(stdout, "entry_ptr->is_protected (expected) = %d (%d).\n",
+ (int)(entry_ptr->is_protected),
+ (int)(check[i].is_protected));
+ }
+ if ( entry_ptr->header.is_protected != check[i].is_protected ) {
+ HDfprintf(stdout, "entry_ptr->header.is_protected (expected) = %d (%d).\n",
+ (int)(entry_ptr->is_protected),
+ (int)(check[i].is_protected));
+ }
+ if ( entry_ptr->is_pinned != check[i].is_pinned ) {
+ HDfprintf(stdout, "entry_ptr->is_pinned (expected) = %d (%d).\n",
+ (int)(entry_ptr->is_pinned),
+ (int)(check[i].is_pinned));
+ }
+ if ( entry_ptr->header.is_pinned != check[i].is_pinned ) {
+ HDfprintf(stdout, "entry_ptr->header.is_pinned (expected) = %d (%d).\n",
+ (int)(entry_ptr->header.is_pinned),
+ (int)(check[i].is_pinned));
+ }
+ if ( entry_ptr->loaded != check[i].expected_loaded ) {
+ HDfprintf(stdout, "entry_ptr->loaded (expected) = %d (%d).\n",
+ (int)(entry_ptr->loaded),
+ (int)(check[i].expected_loaded));
+ }
+ if ( entry_ptr->cleared != check[i].expected_cleared ) {
+ HDfprintf(stdout, "entry_ptr->cleared (expected) = %d (%d).\n",
+ (int)(entry_ptr->cleared),
+ (int)(check[i].expected_cleared));
+ }
+ if ( entry_ptr->flushed != check[i].expected_flushed ) {
+ HDfprintf(stdout, "entry_ptr->flushed (expected) = %d (%d).\n",
+ (int)(entry_ptr->flushed),
+ (int)(check[i].expected_flushed));
+ }
+ if ( entry_ptr->destroyed != check[i].expected_destroyed ) {
+ HDfprintf(stdout, "entry_ptr->destroyed (expected) = %d (%d).\n",
+ (int)(entry_ptr->destroyed),
+ (int)(check[i].expected_destroyed));
+ }
+#endif
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Check2 failed on entry %d after flush op test #%d.",
+ i, test_num);
+ failure_mssg = msg;
+ }
+ i++;
+ }
+ }
+
+ if ( pass ) {
+
+ if ( ( ( (flush_flags & H5C__FLUSH_INVALIDATE_FLAG) == 0 )
+ &&
+ ( ( cache_ptr->index_len != expected_index_len )
+ ||
+ ( cache_ptr->index_size != expected_index_size )
+ )
+ )
+ ||
+ ( ( (flush_flags & H5C__FLUSH_INVALIDATE_FLAG) != 0 )
+ &&
+ ( ( cache_ptr->index_len != 0 )
+ ||
+ ( cache_ptr->index_size != 0 )
+ )
+ )
+ ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Unexpected cache len/size after flush in flush op test #%d.",
+ test_num);
+ failure_mssg = msg;
+ }
+ }
+
+ /* clean up the cache to prep for the next test */
+ if ( pass ) {
+
+ result = H5C_flush_cache(NULL, -1, -1, cache_ptr,
+ H5C__FLUSH_INVALIDATE_FLAG);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Flush failed on cleanup in flush op test #%d.",
+ test_num);
+ failure_mssg = msg;
+ }
+ else if ( ( cache_ptr->index_len != 0 ) ||
+ ( cache_ptr->index_size != 0 ) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Unexpected cache len/size after cleanup in flush op test #%d.",
+ test_num);
+ failure_mssg = msg;
+
+ }
+ }
+
+ i = 0;
+ while ( ( pass ) && ( i < spec_size ) )
+ {
+ base_addr = entries[spec[i].entry_type];
+ entry_ptr = &(base_addr[spec[i].entry_index]);
+
+ entry_ptr->size = entry_sizes[spec[i].entry_type];
+
+ entry_ptr->loaded = FALSE;
+ entry_ptr->cleared = FALSE;
+ entry_ptr->flushed = FALSE;
+ entry_ptr->destroyed = FALSE;
+
+ i++;
+ }
+
+ i = 0;
+ while ( ( pass ) && ( i < check_size ) )
+ {
+ base_addr = entries[check[i].entry_type];
+ entry_ptr = &(base_addr[check[i].entry_index]);
+
+ entry_ptr->size = entry_sizes[check[i].entry_type];
+
+ entry_ptr->loaded = FALSE;
+ entry_ptr->cleared = FALSE;
+ entry_ptr->flushed = FALSE;
+ entry_ptr->destroyed = FALSE;
+
+ i++;
+ }
+
+ return;
+
+} /* check_flush_cache__flush_op_test() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: check_flush_cache__flush_op_eviction_test()
+ *
+ * Purpose: Verify that flush operations work as expected when an
+ * entry is evicted.
+ *
+ * Do nothing if pass is FALSE on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 10/3/06
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_flush_cache__flush_op_eviction_test(H5C_t * cache_ptr)
+{
+ /* const char * fcn_name = "check_flush_cache__flush_op_eviction_test"; */
+ int i;
+ int num_variable_entries = 8;
+ int num_monster_entries = 31;
+ int num_large_entries = 0;
+ herr_t result;
+ test_entry_t * entry_ptr;
+ test_entry_t * base_addr;
+ struct expected_entry_status expected[8 + 31 + 14] =
+ {
+ /* the expected array is used to maintain a table of the expected status of every
+ * entry used in this test. Note that since the function that processes this
+ * array only processes as much of it as it is told to, we don't have to
+ * worry about maintaining the status of entries that we haven't used yet.
+ */
+ /* entry entry in at main */
+ /* type: index: size: cache: addr: dirty: prot: pinned: loaded: clrd: flshd: dest: */
+ { VARIABLE_ENTRY_TYPE, 0, VARIABLE_ENTRY_SIZE/2, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE },
+ { VARIABLE_ENTRY_TYPE, 1, VARIABLE_ENTRY_SIZE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { VARIABLE_ENTRY_TYPE, 2, VARIABLE_ENTRY_SIZE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { VARIABLE_ENTRY_TYPE, 3, VARIABLE_ENTRY_SIZE/2, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { VARIABLE_ENTRY_TYPE, 4, VARIABLE_ENTRY_SIZE/2, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { VARIABLE_ENTRY_TYPE, 5, VARIABLE_ENTRY_SIZE/2, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { VARIABLE_ENTRY_TYPE, 6, VARIABLE_ENTRY_SIZE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { VARIABLE_ENTRY_TYPE, 7, VARIABLE_ENTRY_SIZE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 0, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 1, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 2, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 3, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 4, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 5, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 6, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 7, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 8, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 9, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 10, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 11, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 12, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 13, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 14, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 15, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 16, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 17, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 18, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 19, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 20, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 21, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 22, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 23, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 24, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 25, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 26, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 27, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 28, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 29, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { MONSTER_ENTRY_TYPE, 30, MONSTER_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 0, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 1, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 2, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 3, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 4, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 5, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 6, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 7, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 8, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 9, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 10, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 11, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 12, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE },
+ { LARGE_ENTRY_TYPE, 13, LARGE_ENTRY_SIZE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE }
+ };
+
+ if ( cache_ptr == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "cache_ptr NULL on entry to flush ops test.";
+ }
+ else if ( ( cache_ptr->index_len != 0 ) ||
+ ( cache_ptr->index_size != 0 ) ) {
+
+ pass = FALSE;
+ failure_mssg = "cache not empty at start of flush ops eviction test.";
+ }
+ else if ( ( cache_ptr->max_cache_size != (2 * 1024 * 1024 ) ) ||
+ ( cache_ptr->min_clean_size != (1 * 1024 * 1024 ) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected cache config at start of flush op eviction test.";
+
+ } else {
+
+ /* set min clean size to zero for this test as it simplifies
+ * computing the expected cache size after each operation.
+ */
+
+ cache_ptr->min_clean_size = 0;
+ }
+
+ if ( pass ) {
+
+ /* the basic idea in this test is to insert a bunch of entries
+ * with flush operations associated with them, and then load
+ * other entries into the cache until the cache is full. At
+ * that point, load yet more entries into the cache, and see
+ * if the flush operations are performed as expected.
+ *
+ * To make things a bit more interesting, we also include a
+ * couple of pins.
+ */
+
+ /* reset the stats before we start. If stats are enabled, we will
+ * check to see if they are as expected at the end.
+ */
+ H5C_stats__reset(cache_ptr);
+
+
+ /* load a few entries with pin relationships and flush ops.
+ * Start by just loading the entries.
+ */
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 0);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 0,
+ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ (VARIABLE_ENTRY_SIZE / 2));
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 1);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 1,
+ H5C__NO_FLAGS_SET, 0);
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 2);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 2,
+ H5C__NO_FLAGS_SET, 0);
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 3);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 3,
+ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ (VARIABLE_ENTRY_SIZE / 2));
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 4);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 4,
+ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ (VARIABLE_ENTRY_SIZE / 2));
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 5);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 5,
+ H5C__DIRTIED_FLAG | H5C__SIZE_CHANGED_FLAG,
+ (VARIABLE_ENTRY_SIZE / 2));
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 6);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 6,
+ H5C__NO_FLAGS_SET, 0);
+
+ protect_entry(cache_ptr, VARIABLE_ENTRY_TYPE, 7);
+ unprotect_entry_with_size_change(cache_ptr, VARIABLE_ENTRY_TYPE, 7,
+ H5C__NO_FLAGS_SET, 0);
+
+ if ( ( cache_ptr->index_len != 8 ) ||
+ ( cache_ptr->index_size != (4 * (VARIABLE_ENTRY_SIZE / 2)) +
+ (4 * VARIABLE_ENTRY_SIZE) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 1.";
+ }
+ }
+
+ if ( pass ) {
+
+ /* Now set up the pinning relationships:
+ *
+ * Briefly, (VET, 0) is pinned by (VET, 1), (VET, 2), and (VET, 3)
+ * (VET, 7) is pinned by (VET, 3), and (VET, 5)
+ */
+ create_pinned_entry_dependency(cache_ptr, VARIABLE_ENTRY_TYPE, 1,
+ VARIABLE_ENTRY_TYPE, 0);
+ create_pinned_entry_dependency(cache_ptr, VARIABLE_ENTRY_TYPE, 2,
+ VARIABLE_ENTRY_TYPE, 0);
+ create_pinned_entry_dependency(cache_ptr, VARIABLE_ENTRY_TYPE, 3,
+ VARIABLE_ENTRY_TYPE, 0);
+ create_pinned_entry_dependency(cache_ptr, VARIABLE_ENTRY_TYPE, 3,
+ VARIABLE_ENTRY_TYPE, 7);
+ create_pinned_entry_dependency(cache_ptr, VARIABLE_ENTRY_TYPE, 5,
+ VARIABLE_ENTRY_TYPE, 7);
+
+ /* Next, set up the flush operations:
+ *
+ * Briefly, (VET, 1) dirties (VET, 0)
+ * resizes (VET, 0) to 3/4 VARIABLE_ENTRY_SIZE
+ *
+ * (VET, 2) dirties (VET, 0)
+ * resizes (VET, 0) to VARIABLE_ENTRY_SIZE
+ * renames (VET, 0) to its alternate address
+ *
+ * (VET, 3) dirties (VET, 0)
+ * resizes itself to VARIABLE_ENTRY_SIZE
+ *
+ * (VET, 7) dirties (VET, 6)
+ */
+ add_flush_op(VARIABLE_ENTRY_TYPE, 1, FLUSH_OP__DIRTY,
+ VARIABLE_ENTRY_TYPE, 0, FALSE, 0);
+ add_flush_op(VARIABLE_ENTRY_TYPE, 1, FLUSH_OP__RESIZE,
+ VARIABLE_ENTRY_TYPE, 0, FALSE,
+ 3 * VARIABLE_ENTRY_SIZE / 4);
+
+ add_flush_op(VARIABLE_ENTRY_TYPE, 2, FLUSH_OP__DIRTY,
+ VARIABLE_ENTRY_TYPE, 0, FALSE, 0);
+ add_flush_op(VARIABLE_ENTRY_TYPE, 2, FLUSH_OP__RESIZE,
+ VARIABLE_ENTRY_TYPE, 0, FALSE, VARIABLE_ENTRY_SIZE);
+ add_flush_op(VARIABLE_ENTRY_TYPE, 2, FLUSH_OP__RENAME,
+ VARIABLE_ENTRY_TYPE, 0, FALSE, 0);
+
+ add_flush_op(VARIABLE_ENTRY_TYPE, 3, FLUSH_OP__DIRTY,
+ VARIABLE_ENTRY_TYPE, 0, FALSE, 0);
+ add_flush_op(VARIABLE_ENTRY_TYPE, 3, FLUSH_OP__RESIZE,
+ VARIABLE_ENTRY_TYPE, 3, FALSE, VARIABLE_ENTRY_SIZE);
+
+ add_flush_op(VARIABLE_ENTRY_TYPE, 7, FLUSH_OP__DIRTY,
+ VARIABLE_ENTRY_TYPE, 6, FALSE, 0);
+ }
+
+ if ( pass ) {
+
+ /* to summarize, at present the following variable size entries
+ * are in cache with the following characteristics:
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) Y 5 KB Y Y - -
+ *
+ * (VET, 1) Y 10 KB N N 0 dirty (VET, 0),
+ * resize (VET, 0) to 7.5 KB
+ *
+ * (VET, 2) Y 10 KB N N 0 dirty (VET, 0)
+ * resize (VET, 0) to 10 KB
+ * rename (VET, 0) to its alternate address
+ *
+ * (VET, 3) Y 5 KB Y N 0, 7 dirty (VET, 0)
+ * resize (VET, 3) to 10 KB
+ *
+ * (VET, 4) Y 5 KB Y N - -
+ *
+ * (VET, 5) Y 5 KB Y N 7 -
+ *
+ * (VET, 6) Y 10 KB N N - -
+ *
+ * (VET, 7) Y 10 KB N Y - dirty (VET, 6)
+ *
+ * Recall that in this test bed, flush operations are excuted the
+ * first time the associated entry is flushed, and are then
+ * deleted.
+ */
+
+ /* Now fill up the cache with other, unrelated entries */
+ for ( i = 0; i < 31; i++ )
+ {
+ protect_entry(cache_ptr, MONSTER_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, MONSTER_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ for ( i = 0; i < 1; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* The cache should now be exactly full */
+ if ( ( cache_ptr->index_len != 40 ) ||
+ ( cache_ptr->index_size != 2 * 1024 * 1024 ) ||
+ ( cache_ptr->index_size != ((4 * VARIABLE_ENTRY_SIZE / 2) +
+ (4 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (1 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 2.";
+
+ } else {
+
+ /* verify the expected status of all entries we have loaded to date: */
+ num_large_entries = 1;
+ verify_entry_status(cache_ptr,
+ 0,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+ }
+
+
+ if ( pass ) {
+
+ /* Now load a large entry. This should result in the eviction
+ * of (VET,1), and the increase in the size of (VET, 0) from .5
+ * VARIABLE_ENTRY_SIZE to .75 VARIABLE_ENTRY_SIZE.
+ *
+ * The following table illustrates the intended state of affairs
+ * after the eviction:
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) Y 7.5 KB Y Y - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) Y 10 KB N N 0 dirty (VET, 0)
+ * resize (VET, 0) to 10 KB
+ * rename (VET, 0) to its alternate address
+ *
+ * (VET, 3) Y 5 KB Y N 0, 7 dirty (VET, 0)
+ * resize (VET, 3) to 10 KB
+ *
+ * (VET, 4) Y 5 KB Y N - -
+ *
+ * (VET, 5) Y 5 KB Y N 7 -
+ *
+ * (VET, 6) Y 10 KB N N - -
+ *
+ * (VET, 7) Y 10 KB Y Y - dirty (VET, 6)
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ */
+ expected[0].size = 3 * VARIABLE_ENTRY_SIZE / 4;
+ expected[1].in_cache = FALSE;
+ expected[1].flushed = TRUE;
+ expected[1].destroyed = TRUE;
+
+ num_large_entries = 2;
+
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, 1);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, 1,
+ H5C__DIRTIED_FLAG, 0);
+
+ if ( ( cache_ptr->index_len != 40 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (VARIABLE_ENTRY_SIZE) +
+ (VARIABLE_ENTRY_SIZE / 4) +
+ (LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((1 * 3 * VARIABLE_ENTRY_SIZE / 4 ) +
+ (3 * VARIABLE_ENTRY_SIZE / 2 ) +
+ (3 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (2 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 3.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 1,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* Now load another large entry. This should result in the eviction
+ * of (VET, 2), the increase in the size of (VET, 0) from .75
+ * VARIABLE_ENTRY_SIZE to 1.0 VARIABLE_ENTRY_SIZE, and the renaming
+ * of (VET, 0) to its alternate address.
+ *
+ * The following table shows the expected states of the variable
+ * size entries after the test.
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) Y 10 KB Y Y - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) N 10 KB N N - -
+ *
+ * (VET, 3) Y 5 KB Y N 0, 7 dirty (VET, 0)
+ * resize (VET, 3) to 10 KB
+ *
+ * (VET, 4) Y 5 KB Y N - -
+ *
+ * (VET, 5) Y 5 KB Y N 7 -
+ *
+ * (VET, 6) Y 10 KB N N - -
+ *
+ * (VET, 7) Y 10 KB Y Y - dirty (VET, 6)
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ */
+ expected[0].size = VARIABLE_ENTRY_SIZE;
+ expected[0].at_main_addr = FALSE;
+ expected[2].in_cache = FALSE;
+ expected[2].flushed = TRUE;
+ expected[2].destroyed = TRUE;
+
+ num_large_entries = 3;
+
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, 2);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, 2,
+ H5C__DIRTIED_FLAG, 0);
+
+ if ( ( cache_ptr->index_len != 40 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (2 * VARIABLE_ENTRY_SIZE) +
+ (VARIABLE_ENTRY_SIZE / 2) +
+ (2 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((3 * VARIABLE_ENTRY_SIZE / 2) +
+ (3 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (3 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 4.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 2,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* load two more large entries. This should result in (VET, 3) being
+ * flushed, and increasing its size from 1/2 VARIABLE_ENTRY_SIZE to
+ * VARIABLE_ENTRY_SIZE.
+ *
+ * As a result of this size increase, the cache will have to look
+ * for another entry to evict. After flushing (VET, 4) and (VET, 5),
+ * it should evict (VET, 6), yielding the needed memory.
+ *
+ * The following table shows the expected states of the variable
+ * size entries after the test.
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) Y 10 KB Y Y - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) N 10 KB N N - -
+ *
+ * (VET, 3) Y 10 KB N N 0, 7 -
+ *
+ * (VET, 4) Y 5 KB N N - -
+ *
+ * (VET, 5) Y 5 KB N N 7 -
+ *
+ * (VET, 6) N 10 KB N N - -
+ *
+ * (VET, 7) Y 10 KB Y Y - dirty (VET, 6)
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ */
+
+ expected[3].size = VARIABLE_ENTRY_SIZE;
+ expected[3].is_dirty = FALSE;
+ expected[3].flushed = TRUE;
+ expected[4].is_dirty = FALSE;
+ expected[4].flushed = TRUE;
+ expected[5].is_dirty = FALSE;
+ expected[5].flushed = TRUE;
+ expected[6].in_cache = FALSE;
+ expected[6].flushed = TRUE;
+ expected[6].destroyed = TRUE;
+
+ num_large_entries = 5;
+
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, 3);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, 3,
+ H5C__DIRTIED_FLAG, 0);
+
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, 4);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, 4,
+ H5C__DIRTIED_FLAG, 0);
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 41 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (3 * VARIABLE_ENTRY_SIZE) +
+ (1 * VARIABLE_ENTRY_SIZE ) + /* size increases of (VET, 0) & (VET, 3) */
+ (4 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((2 * VARIABLE_ENTRY_SIZE / 2) +
+ (3 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (5 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 5.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 3,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* now touch all the non VARIABLE_ENTRY_TYPE entries in the
+ * cache to bring all the VARIABLE_ENTRY_TYPE entries to the
+ * end of the LRU list.
+ *
+ * Note that we don't have to worry about (VET, 0) and (VET, 7)
+ * as they are pinned and thus not in the LRU list to begin with.
+ */
+ for ( i = 0; i < 31; i++ )
+ {
+ protect_entry(cache_ptr, MONSTER_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, MONSTER_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ for ( i = 0; i < 5; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 41 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (2 * VARIABLE_ENTRY_SIZE) +
+ (4 * LARGE_ENTRY_SIZE) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 6.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 4,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* Now load three more large entries. This should result
+ * in the eviction of (VET, 3), and the unpinning of (VET, 0)
+ *
+ * The following table shows the expected states of the variable
+ * size entries after the test.
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) Y 10 KB Y N - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) N 10 KB N N - -
+ *
+ * (VET, 3) N 10 KB N N - -
+ *
+ * (VET, 4) Y 5 KB N N - -
+ *
+ * (VET, 5) Y 5 KB N N 7 -
+ *
+ * (VET, 6) N 10 KB N N - -
+ *
+ * (VET, 7) Y 10 KB Y Y - dirty (VET, 6)
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ */
+
+ expected[0].is_pinned = FALSE;
+ expected[3].in_cache = FALSE;
+ expected[3].destroyed = TRUE;
+
+ num_large_entries = 8;
+
+ for ( i = 5; i < 8; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 43 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (3 * VARIABLE_ENTRY_SIZE) +
+ (7 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((2 * VARIABLE_ENTRY_SIZE / 2) +
+ (2 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (8 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 7.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 5,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* load another large entry. (VET, 4) should be evicted.
+ *
+ * The following table shows the expected states of the variable
+ * size entries after the test.
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) Y 10 KB Y N - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) N 10 KB N N - -
+ *
+ * (VET, 3) N 10 KB N N - -
+ *
+ * (VET, 4) N 5 KB N N - -
+ *
+ * (VET, 5) Y 5 KB N N 7 -
+ *
+ * (VET, 6) N 10 KB N N - -
+ *
+ * (VET, 7) Y 10 KB Y Y - dirty (VET, 6)
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ */
+
+ expected[4].in_cache = FALSE;
+ expected[4].destroyed = TRUE;
+
+ num_large_entries = 9;
+
+ for ( i = 8; i < 9; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 43 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (3 * VARIABLE_ENTRY_SIZE) -
+ (VARIABLE_ENTRY_SIZE / 2) +
+ (8 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((1 * VARIABLE_ENTRY_SIZE / 2) +
+ (2 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (9 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 8.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 6,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* Load another large entry.
+ *
+ * (VET, 5) should be evicted, and (VET, 7) should be unpinned.
+ *
+ * The following table shows the expected states of the variable
+ * size entries after the test.
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) Y 10 KB Y N - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) N 10 KB N N - -
+ *
+ * (VET, 3) N 10 KB N N - -
+ *
+ * (VET, 4) N 5 KB N N - -
+ *
+ * (VET, 5) N 5 KB N N - -
+ *
+ * (VET, 6) N 10 KB N N - -
+ *
+ * (VET, 7) Y 10 KB Y N - dirty (VET, 6)
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ */
+
+ expected[5].in_cache = FALSE;
+ expected[5].destroyed = TRUE;
+ expected[7].is_pinned = FALSE;
+
+ num_large_entries = 10;
+
+ for ( i = 9; i < 10; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 43 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (4 * VARIABLE_ENTRY_SIZE) +
+ (9 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((2 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (10 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 9.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 7,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* Again, touch all the non VARIABLE_ENTRY_TYPE entries in the
+ * cache to bring all the VARIABLE_ENTRY_TYPE entries to the
+ * end of the LRU list.
+ *
+ * Both (VET, 0) and (VET, 7) have been unpinned, so they are
+ * now in the LRU list.
+ */
+ for ( i = 0; i < 31; i++ )
+ {
+ protect_entry(cache_ptr, MONSTER_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, MONSTER_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ for ( i = 0; i < 10; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 43 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (4 * VARIABLE_ENTRY_SIZE) +
+ (9 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((2 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (10 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 10.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 8,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* load two more large entries.
+ *
+ * (VET, 0) should be flushed, but not evicted initially since it is dirty.
+ *
+ * (VET, 7) should be evicted, but (VET, 7) has an eviction operation that
+ * dirties (VET, 6). Since (VET, 6) is not in the cache, it will be loaded.
+ * Since this results in no net increase in free space, the cache will
+ * continue to attempt to create free space.
+ *
+ * The cache will then flush all the monster and large entries, but since they
+ * are all dirty, they will not be evicted.
+ *
+ * Finally, it will reach (VET, 0) again, and evict it on the second pass.
+ * This finally makes the necessary space.
+ *
+ * The following table shows the expected states of the variable
+ * size entries after the test.
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) N 10 KB N N - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) N 10 KB N N - -
+ *
+ * (VET, 3) N 10 KB N N - -
+ *
+ * (VET, 4) N 5 KB N N - -
+ *
+ * (VET, 5) N 5 KB N N - -
+ *
+ * (VET, 6) Y 10 KB Y N - -
+ *
+ * (VET, 7) N 10 KB N N - -
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ *
+ * Note that we reset the loaded, cleared, flushed, and destroyed fields of
+ * (VET,6) so we can track what is happening.
+ */
+ base_addr = entries[VARIABLE_ENTRY_TYPE];
+ entry_ptr = &(base_addr[6]);
+ entry_ptr->loaded = FALSE;
+ entry_ptr->cleared = FALSE;
+ entry_ptr->flushed = FALSE;
+ entry_ptr->destroyed = FALSE;
+
+ expected[0].in_cache = FALSE;
+ expected[0].is_dirty = FALSE;
+ expected[0].flushed = TRUE;
+ expected[0].destroyed = TRUE;
+ expected[6].in_cache = TRUE;
+ expected[6].is_dirty = TRUE;
+ expected[6].loaded = TRUE;
+ expected[6].flushed = FALSE;
+ expected[6].destroyed = FALSE;
+ expected[7].in_cache = FALSE;
+ expected[7].flushed = TRUE;
+ expected[7].destroyed = TRUE;
+
+ num_large_entries = 12;
+
+ /* a newly loaded entry is not inserted in the cache until after space has been
+ * made for it. Thus (LET, 11) will not be flushed.
+ */
+ for ( i = num_variable_entries;
+ i < num_variable_entries + num_monster_entries + num_large_entries - 1;
+ i++ )
+ {
+ expected[i].is_dirty = FALSE;
+ expected[i].flushed = TRUE;
+ }
+
+ for ( i = 10; i < 12; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 44 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (5 * VARIABLE_ENTRY_SIZE) +
+ (11 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((1 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (12 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 11.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 9,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* Again, touch all the non VARIABLE_ENTRY_TYPE entries in the
+ * cache to bring the last remaining VARIABLE_ENTRY_TYPE entry to the
+ * end of the LRU list.
+ */
+ for ( i = 0; i < num_monster_entries; i++ )
+ {
+ protect_entry(cache_ptr, MONSTER_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, MONSTER_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ for ( i = 0; i < num_large_entries; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* update the expected array to mark all these entries dirty again. */
+ for ( i = num_variable_entries;
+ i < num_variable_entries + num_monster_entries + num_large_entries - 1;
+ i++ )
+ {
+ expected[i].is_dirty = TRUE;
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 44 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (5 * VARIABLE_ENTRY_SIZE) +
+ (11 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((1 * VARIABLE_ENTRY_SIZE) +
+ (31 * MONSTER_ENTRY_SIZE) +
+ (12 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 12.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 10,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ if ( pass ) {
+
+ /* Load two more large entries.
+ *
+ * Since (VET, 6) is dirty, at first this will just cause (VET, 6) to be flushed.
+ *
+ * But all other entries in the cache are dirty, so the cache will flush them all,
+ * and then evict (VET, 6) on the second pass.
+ *
+ * The following table shows the expected states of the variable
+ * size entries after the test.
+ *
+ * in
+ * entry: cache? size: dirty? pinned? pins: flush operations:
+ *
+ * (VET, 0) N 10 KB N N - -
+ *
+ * (VET, 1) N 10 KB N N - -
+ *
+ * (VET, 2) N 10 KB N N - -
+ *
+ * (VET, 3) N 10 KB N N - -
+ *
+ * (VET, 4) N 5 KB N N - -
+ *
+ * (VET, 5) N 5 KB N N - -
+ *
+ * (VET, 6) N 10 KB N N - -
+ *
+ * (VET, 7) N 10 KB N N - -
+ *
+ * Start by updating the expected table for the expected changes in entry status:
+ */
+
+ expected[6].in_cache = FALSE;
+ expected[6].is_dirty = FALSE;
+ expected[6].flushed = TRUE;
+ expected[6].destroyed = TRUE;
+
+ num_large_entries = 14;
+
+ /* a newly loaded entry is not inserted in the cache until after space has been
+ * made for it. Thus (LET, 13) will not be flushed.
+ */
+ for ( i = num_variable_entries;
+ i < num_variable_entries + num_monster_entries + num_large_entries - 1;
+ i++ )
+ {
+ expected[i].is_dirty = FALSE;
+ expected[i].flushed = TRUE;
+ }
+
+ for ( i = 12; i < 14; i++ )
+ {
+ protect_entry(cache_ptr, LARGE_ENTRY_TYPE, i);
+ unprotect_entry_with_size_change(cache_ptr, LARGE_ENTRY_TYPE, i,
+ H5C__DIRTIED_FLAG, 0);
+ }
+
+ /* verify cache size */
+ if ( ( cache_ptr->index_len != 45 ) ||
+ ( cache_ptr->index_size != (2 * 1024 * 1024) -
+ (6 * VARIABLE_ENTRY_SIZE) +
+ (13 * LARGE_ENTRY_SIZE) ) ||
+ ( cache_ptr->index_size != ((31 * MONSTER_ENTRY_SIZE) +
+ (14 * LARGE_ENTRY_SIZE)) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected size/len in flush op eviction test 13.";
+ }
+
+ /* verify entry status */
+ verify_entry_status(cache_ptr,
+ 11,
+ (num_variable_entries + num_monster_entries + num_large_entries),
+ expected);
+ }
+
+ /* at this point we have cycled all the variable size entries through the cache.
+ *
+ * flush the cache and end the test.
+ */
+
+ if ( pass ) {
+
+ result = H5C_flush_cache(NULL, -1, -1, cache_ptr,
+ H5C__FLUSH_INVALIDATE_FLAG);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "Cache flush invalidate failed after flush op eviction test";
+ }
+ else if ( ( cache_ptr->index_len != 0 ) ||
+ ( cache_ptr->index_size != 0 ) ) {
+
+ pass = FALSE;
+ failure_mssg = "Unexpected cache len/size after cleanup of flush op eviction test";
+
+ }
+ }
+
+#if H5C_COLLECT_CACHE_STATS
+ /* If we are collecting stats, check to see if we get the expected
+ * values.
+ *
+ * Testing the stats code is fairly new, but given the extent
+ * to which I find myself depending on the stats, I've decided
+ * to start testing the stats whenever it is convenient to do
+ * so.
+ */
+ if ( pass ) {
+
+ if ( ( cache_ptr->insertions[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_insertions[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->clears[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->flushes[VARIABLE_ENTRY_TYPE] != 14 ) ||
+ ( cache_ptr->evictions[VARIABLE_ENTRY_TYPE] != 9 ) ||
+ ( cache_ptr->renames[VARIABLE_ENTRY_TYPE] != 1 ) ||
+ ( cache_ptr->entry_flush_renames[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->cache_flush_renames[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pins[VARIABLE_ENTRY_TYPE] != 2 ) ||
+ ( cache_ptr->unpins[VARIABLE_ENTRY_TYPE] != 2 ) ||
+ ( cache_ptr->dirty_pins[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_flushes[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_clears[VARIABLE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->size_increases[VARIABLE_ENTRY_TYPE] != 3 ) ||
+ ( cache_ptr->size_decreases[VARIABLE_ENTRY_TYPE] != 4 ) ||
+ ( cache_ptr->entry_flush_size_changes[VARIABLE_ENTRY_TYPE] != 1 ) ||
+ ( cache_ptr->cache_flush_size_changes[VARIABLE_ENTRY_TYPE] != 0 ) ) {
+
+ pass = FALSE;
+ failure_mssg = "Unexpected variable size entry stats.";
+ }
+ }
+
+ if ( pass ) {
+
+ if ( ( cache_ptr->insertions[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_insertions[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->clears[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->flushes[LARGE_ENTRY_TYPE] != 38 ) ||
+ ( cache_ptr->evictions[LARGE_ENTRY_TYPE] != 14 ) ||
+ ( cache_ptr->renames[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->entry_flush_renames[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->cache_flush_renames[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pins[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->unpins[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->dirty_pins[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_flushes[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_clears[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->size_increases[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->size_decreases[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->entry_flush_size_changes[LARGE_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->cache_flush_size_changes[LARGE_ENTRY_TYPE] != 0 ) ) {
+
+ pass = FALSE;
+ failure_mssg = "Unexpected monster entry stats.";
+ }
+ }
+
+ if ( pass ) {
+
+ if ( ( cache_ptr->insertions[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_insertions[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->clears[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->flushes[MONSTER_ENTRY_TYPE] != 93 ) ||
+ ( cache_ptr->evictions[MONSTER_ENTRY_TYPE] != 31 ) ||
+ ( cache_ptr->renames[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->entry_flush_renames[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->cache_flush_renames[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pins[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->unpins[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->dirty_pins[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_flushes[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->pinned_clears[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->size_increases[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->size_decreases[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->entry_flush_size_changes[MONSTER_ENTRY_TYPE] != 0 ) ||
+ ( cache_ptr->cache_flush_size_changes[MONSTER_ENTRY_TYPE] != 0 ) ) {
+
+ pass = FALSE;
+ failure_mssg = "Unexpected monster entry stats.";
+ }
+ }
+#endif /* H5C_COLLECT_CACHE_STATS */
+
+ if ( pass ) {
+
+ reset_entries();
+ }
+
+ return;
+
+} /* check_flush_cache__flush_op_eviction_test() */
+
+
+/*-------------------------------------------------------------------------
* Function: check_flush_cache__single_entry()
*
* Purpose: Verify that flush_cache behaves as expected when the cache
@@ -6462,6 +11880,8 @@ check_flush_cache__single_entry_test(H5C_t * cache_ptr,
( entry_ptr->flushed != expected_flushed ) ||
( entry_ptr->destroyed != expected_destroyed ) ) {
+#if 0 /* This is useful debugging code -- lets keep it for a while */
+
HDfprintf(stdout,
"loaded = %d(%d), clrd = %d(%d), flshd = %d(%d), dest = %d(%d)\n",
(int)(entry_ptr->loaded),
@@ -6472,7 +11892,7 @@ check_flush_cache__single_entry_test(H5C_t * cache_ptr,
(int)expected_flushed,
(int)(entry_ptr->destroyed),
(int)expected_destroyed);
-
+#endif
pass = FALSE;
HDsnprintf(msg, (size_t)128,
"Unexpected entry status after flush in single entry test #%d.",
@@ -18740,6 +24160,10 @@ main(void)
run_full_test = FALSE;
#endif /* NDEBUG */
+#if 0
+ run_full_test = TRUE;
+#endif
+
#if 1
smoke_check_1();
smoke_check_2();
@@ -18750,7 +24174,7 @@ main(void)
smoke_check_7();
smoke_check_8();
#endif
-#if 1
+
write_permitted_check();
check_insert_entry();
check_flush_cache();
@@ -18777,7 +24201,6 @@ main(void)
check_auto_cache_resize_epoch_markers();
check_auto_cache_resize_input_errs();
check_auto_cache_resize_aux_fcns();
-#endif
return(0);
diff --git a/test/cache_common.c b/test/cache_common.c
index 3e9b596..dc19ac2 100644
--- a/test/cache_common.c
+++ b/test/cache_common.c
@@ -41,6 +41,7 @@ test_entry_t medium_entries[NUM_MEDIUM_ENTRIES];
test_entry_t large_entries[NUM_LARGE_ENTRIES];
test_entry_t huge_entries[NUM_HUGE_ENTRIES];
test_entry_t monster_entries[NUM_MONSTER_ENTRIES];
+test_entry_t variable_entries[NUM_VARIABLE_ENTRIES];
test_entry_t * entries[NUMBER_OF_ENTRY_TYPES] =
{
@@ -52,7 +53,8 @@ test_entry_t * entries[NUMBER_OF_ENTRY_TYPES] =
medium_entries,
large_entries,
huge_entries,
- monster_entries
+ monster_entries,
+ variable_entries
};
const int32_t max_indices[NUMBER_OF_ENTRY_TYPES] =
@@ -65,7 +67,8 @@ const int32_t max_indices[NUMBER_OF_ENTRY_TYPES] =
NUM_MEDIUM_ENTRIES - 1,
NUM_LARGE_ENTRIES - 1,
NUM_HUGE_ENTRIES - 1,
- NUM_MONSTER_ENTRIES - 1
+ NUM_MONSTER_ENTRIES - 1,
+ NUM_VARIABLE_ENTRIES - 1
};
const size_t entry_sizes[NUMBER_OF_ENTRY_TYPES] =
@@ -78,7 +81,8 @@ const size_t entry_sizes[NUMBER_OF_ENTRY_TYPES] =
MEDIUM_ENTRY_SIZE,
LARGE_ENTRY_SIZE,
HUGE_ENTRY_SIZE,
- MONSTER_ENTRY_SIZE
+ MONSTER_ENTRY_SIZE,
+ VARIABLE_ENTRY_SIZE
};
const haddr_t base_addrs[NUMBER_OF_ENTRY_TYPES] =
@@ -91,7 +95,8 @@ const haddr_t base_addrs[NUMBER_OF_ENTRY_TYPES] =
MEDIUM_BASE_ADDR,
LARGE_BASE_ADDR,
HUGE_BASE_ADDR,
- MONSTER_BASE_ADDR
+ MONSTER_BASE_ADDR,
+ VARIABLE_BASE_ADDR
};
const haddr_t alt_base_addrs[NUMBER_OF_ENTRY_TYPES] =
@@ -104,7 +109,8 @@ const haddr_t alt_base_addrs[NUMBER_OF_ENTRY_TYPES] =
MEDIUM_ALT_BASE_ADDR,
LARGE_ALT_BASE_ADDR,
HUGE_ALT_BASE_ADDR,
- MONSTER_ALT_BASE_ADDR
+ MONSTER_ALT_BASE_ADDR,
+ VARIABLE_ALT_BASE_ADDR
};
const char * entry_type_names[NUMBER_OF_ENTRY_TYPES] =
@@ -117,7 +123,8 @@ const char * entry_type_names[NUMBER_OF_ENTRY_TYPES] =
"medium entries -- 1 KB",
"large entries -- 4 KB",
"huge entries -- 16 KB",
- "monster entries -- 64 KB"
+ "monster entries -- 64 KB",
+ "variable entries -- 1B - 10KB"
};
@@ -196,13 +203,21 @@ const H5C_class_t types[NUMBER_OF_ENTRY_TYPES] =
(H5C_dest_func_t)monster_dest,
(H5C_clear_func_t)monster_clear,
(H5C_size_func_t)monster_size
+ },
+ {
+ VARIABLE_ENTRY_TYPE,
+ (H5C_load_func_t)variable_load,
+ (H5C_flush_func_t)variable_flush,
+ (H5C_dest_func_t)variable_dest,
+ (H5C_clear_func_t)variable_clear,
+ (H5C_size_func_t)variable_size
}
};
static herr_t clear(H5F_t * f, void * thing, hbool_t dest);
static herr_t destroy(H5F_t * f, void * thing);
static herr_t flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned UNUSED * flags_ptr);
static void * load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
const void *udata1, void *udata2);
static herr_t size(H5F_t * f, void * thing, size_t * size_ptr);
@@ -267,18 +282,18 @@ addr_to_type_and_index(haddr_t addr,
if ( addr >= PICO_ALT_BASE_ADDR ) {
idx = (addr - alt_base_addrs[type]) / entry_sizes[type];
+ HDassert( ( idx >= 0 ) && ( idx <= max_indices[type] ) );
HDassert( !((entries[type])[idx].at_main_addr) );
HDassert( addr == (entries[type])[idx].alt_addr );
} else {
idx = (addr - base_addrs[type]) / entry_sizes[type];
+ HDassert( ( idx >= 0 ) && ( idx <= max_indices[type] ) );
HDassert( (entries[type])[idx].at_main_addr );
HDassert( addr == (entries[type])[idx].main_addr );
}
- HDassert( ( idx >= 0 ) && ( idx <= max_indices[type] ) );
-
HDassert( addr == (entries[type])[idx].addr );
*type_ptr = type;
@@ -388,6 +403,8 @@ check_write_permitted(const H5F_t UNUSED * f,
*
* Modifications:
*
+ * Added variable_clear. -- JRM 8/30/06
+ *
*-------------------------------------------------------------------------
*/
@@ -410,7 +427,8 @@ clear(H5F_t * f,
HDassert( entry_ptr == entry_ptr->self );
HDassert( entry_ptr->header.addr == entry_ptr->addr );
HDassert( entry_ptr->header.size == entry_ptr->size );
- HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] );
+ HDassert( ( entry_ptr->type == VARIABLE_ENTRY_TYPE ) ||
+ ( entry_ptr->size == entry_sizes[entry_ptr->type] ) );
entry_ptr->header.is_dirty = FALSE;
entry_ptr->is_dirty = FALSE;
@@ -490,6 +508,14 @@ monster_clear(H5F_t * f, void * thing, hbool_t dest)
return(clear(f, thing, dest));
}
+herr_t
+variable_clear(H5F_t * f, void * thing, hbool_t dest)
+{
+ HDassert ( ((test_entry_t *)thing)->type == VARIABLE_ENTRY_TYPE );
+ return(clear(f, thing, dest));
+}
+
+
/*-------------------------------------------------------------------------
* Function: dest & friends
@@ -510,6 +536,9 @@ monster_clear(H5F_t * f, void * thing, hbool_t dest)
* pinned by the target entry, and to unpin those entries
* if the reference count drops to zero.
*
+ * JRM -- 8/30/06
+ * Added variable_destroy().
+ *
*-------------------------------------------------------------------------
*/
@@ -534,9 +563,11 @@ destroy(H5F_t UNUSED * f,
HDassert( entry_ptr == entry_ptr->self );
HDassert( entry_ptr->cache_ptr != NULL );
HDassert( entry_ptr->cache_ptr->magic == H5C__H5C_T_MAGIC );
- HDassert( entry_ptr->header.addr == entry_ptr->addr );
+ HDassert( ( entry_ptr->header.destroy_in_progress ) ||
+ ( entry_ptr->header.addr == entry_ptr->addr ) );
HDassert( entry_ptr->header.size == entry_ptr->size );
- HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] );
+ HDassert( ( entry_ptr->type == VARIABLE_ENTRY_TYPE ) ||
+ ( entry_ptr->size == entry_sizes[entry_ptr->type] ) );
HDassert( !(entry_ptr->is_dirty) );
HDassert( !(entry_ptr->header.is_dirty) );
@@ -645,6 +676,13 @@ monster_dest(H5F_t * f, void * thing)
return(destroy(f, thing));
}
+herr_t
+variable_dest(H5F_t * f, void * thing)
+{
+ HDassert ( ((test_entry_t *)thing)->type == VARIABLE_ENTRY_TYPE );
+ return(destroy(f, thing));
+}
+
/*-------------------------------------------------------------------------
* Function: flush & friends
@@ -660,6 +698,12 @@ monster_dest(H5F_t * f, void * thing)
*
* Modifications:
*
+ * JRM -- 8/30/06
+ * Added variable_flush() and flags_ptr parameter.
+ *
+ * JRM -- 9/1/06
+ * Added support for flush operations.
+ *
*-------------------------------------------------------------------------
*/
@@ -668,8 +712,10 @@ flush(H5F_t *f,
hid_t UNUSED dxpl_id,
hbool_t dest,
haddr_t addr,
- void *thing)
+ void *thing,
+ unsigned * flags_ptr)
{
+ int i;
test_entry_t * entry_ptr;
test_entry_t * base_addr;
@@ -685,8 +731,26 @@ flush(H5F_t *f,
HDassert( entry_ptr->header.addr == entry_ptr->addr );
HDassert( entry_ptr->addr == addr );
HDassert( entry_ptr->header.size == entry_ptr->size );
- HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] );
+ HDassert( ( entry_ptr->type == VARIABLE_ENTRY_TYPE ) ||
+ ( entry_ptr->size == entry_sizes[entry_ptr->type] ) );
HDassert( entry_ptr->header.is_dirty == entry_ptr->is_dirty );
+ HDassert( entry_ptr->cache_ptr != NULL );
+ HDassert( entry_ptr->cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( entry_ptr->num_flush_ops >= 0 );
+ HDassert( entry_ptr->num_flush_ops < MAX_FLUSH_OPS );
+
+ if ( entry_ptr->num_flush_ops > 0 ) {
+
+ for ( i = 0; i < entry_ptr->num_flush_ops; i++ )
+ {
+ execute_flush_op(entry_ptr->cache_ptr,
+ entry_ptr,
+ &((entry_ptr->flush_ops)[i]),
+ flags_ptr);
+ }
+ entry_ptr->num_flush_ops = 0;
+ entry_ptr->flush_op_self_resize_in_progress = FALSE;
+ }
entry_ptr->flushed = TRUE;
@@ -713,69 +777,87 @@ flush(H5F_t *f,
} /* flush() */
-herr_t
-pico_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+herr_t
+pico_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-nano_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+nano_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-micro_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+micro_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-tiny_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+tiny_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-small_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+small_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-medium_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+medium_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-large_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+large_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-huge_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+huge_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
herr_t
-monster_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
+monster_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
{
HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE );
- return(flush(f, dxpl_id, dest, addr, thing));
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
+}
+
+herr_t
+variable_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr,
+ void *thing, unsigned * flags_ptr)
+{
+ HDassert ( ((test_entry_t *)thing)->type == VARIABLE_ENTRY_TYPE );
+ return(flush(f, dxpl_id, dest, addr, thing, flags_ptr));
}
+
/*-------------------------------------------------------------------------
* Function: load & friends
@@ -791,6 +873,9 @@ monster_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing)
*
* Modifications:
*
+ * JRM -- 8/30/06
+ * Added variable_load().
+ *
*-------------------------------------------------------------------------
*/
@@ -819,7 +904,18 @@ load(H5F_t UNUSED *f,
HDassert( entry_ptr->index <= max_indices[type] );
HDassert( entry_ptr == entry_ptr->self );
HDassert( entry_ptr->addr == addr );
- HDassert( entry_ptr->size == entry_sizes[type] );
+#if 1 /* JRM */
+ if ( ! ( ( entry_ptr->type == VARIABLE_ENTRY_TYPE ) ||
+ ( entry_ptr->size == entry_sizes[type] ) ) ) {
+
+ HDfprintf(stdout, "entry type/index/size = %d/%d/%ld\n",
+ (int)(entry_ptr->type),
+ (int)(entry_ptr->index),
+ (long)(entry_ptr->size));
+ }
+#endif /* JRM */
+ HDassert( ( entry_ptr->type == VARIABLE_ENTRY_TYPE ) ||
+ ( entry_ptr->size == entry_sizes[type] ) );
entry_ptr->loaded = TRUE;
@@ -895,6 +991,13 @@ monster_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
return(load(f, dxpl_id, addr, udata1, udata2));
}
+void *
+variable_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *udata1, void *udata2)
+{
+ return(load(f, dxpl_id, addr, udata1, udata2));
+}
+
/*-------------------------------------------------------------------------
* Function: size & friends
@@ -910,6 +1013,9 @@ monster_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
*
* Modifications:
*
+ * JRM -- 8/30/06
+ * Added variable_size().
+ *
*-------------------------------------------------------------------------
*/
@@ -932,7 +1038,8 @@ size(H5F_t UNUSED * f,
HDassert( entry_ptr == &(base_addr[entry_ptr->index]) );
HDassert( entry_ptr == entry_ptr->self );
HDassert( entry_ptr->header.addr == entry_ptr->addr );
- HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] );
+ HDassert( ( entry_ptr->type == VARIABLE_ENTRY_TYPE ) || \
+ ( entry_ptr->size == entry_sizes[entry_ptr->type] ) );
*size_ptr = entry_ptr->size;
@@ -1003,6 +1110,14 @@ monster_size(H5F_t * f, void * thing, size_t * size_ptr)
return(size(f, thing, size_ptr));
}
+herr_t
+variable_size(H5F_t * f, void * thing, size_t * size_ptr)
+{
+ HDassert ( ((test_entry_t *)thing)->type == VARIABLE_ENTRY_TYPE );
+ return(size(f, thing, size_ptr));
+}
+
+
/**************************************************************************/
/**************************************************************************/
@@ -1011,6 +1126,72 @@ monster_size(H5F_t * f, void * thing, size_t * size_ptr)
/**************************************************************************/
/*-------------------------------------------------------------------------
+ * Function: add_flush_op
+ *
+ * Purpose: Do noting if pass is FALSE on entry.
+ *
+ * Otherwise, add the specified flush operation to the
+ * target instance of test_entry_t.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 9/1/06
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+add_flush_op(int target_type,
+ int target_idx,
+ int op_code,
+ int type,
+ int idx,
+ hbool_t flag,
+ size_t new_size)
+{
+ int i;
+ test_entry_t * target_base_addr;
+ test_entry_t * target_entry_ptr;
+
+ HDassert( ( 0 <= target_type ) && ( target_type < NUMBER_OF_ENTRY_TYPES ) );
+ HDassert( ( 0 <= target_idx ) &&
+ ( target_idx <= max_indices[target_type] ) );
+ HDassert( ( 0 <= op_code ) && ( op_code <= FLUSH_OP__MAX_OP ) );
+ HDassert( ( op_code != FLUSH_OP__RESIZE ) ||
+ ( type == VARIABLE_ENTRY_TYPE ) );
+ HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) );
+ HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) );
+ HDassert( ( flag == TRUE ) || ( flag == FALSE ) );
+ HDassert( new_size <= VARIABLE_ENTRY_SIZE );
+
+ if ( pass ) {
+
+ target_base_addr = entries[target_type];
+ target_entry_ptr = &(target_base_addr[target_idx]);
+
+ HDassert( target_entry_ptr->index == target_idx );
+ HDassert( target_entry_ptr->type == target_type );
+ HDassert( target_entry_ptr == target_entry_ptr->self );
+ HDassert( target_entry_ptr->num_flush_ops < MAX_FLUSH_OPS );
+
+ i = (target_entry_ptr->num_flush_ops)++;
+ (target_entry_ptr->flush_ops)[i].op_code = op_code;
+ (target_entry_ptr->flush_ops)[i].type = type;
+ (target_entry_ptr->flush_ops)[i].idx = idx;
+ (target_entry_ptr->flush_ops)[i].flag = flag;
+ (target_entry_ptr->flush_ops)[i].size = new_size;
+
+ }
+
+ return;
+
+} /* add_flush_op() */
+
+
+/*-------------------------------------------------------------------------
* Function: create_pinned_entry_dependency
*
* Purpose: Do noting if pass is FALSE on entry.
@@ -1093,6 +1274,194 @@ create_pinned_entry_dependency(H5C_t * cache_ptr,
/*-------------------------------------------------------------------------
+ * Function: dirty_entry
+ *
+ * Purpose: Given a pointer to a cache, an entry type, and an index,
+ * dirty the target entry.
+ *
+ * If the dirty_pin parameter is true, verify that the
+ * target entry is in the cache and is pinned. If it
+ * isn't, scream and die. If it is, use the
+ * H5C_mark_pinned_entry_dirty() call to dirty it.
+ *
+ * Do nothing if pass is false on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 6/10/04
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+dirty_entry(H5C_t * cache_ptr,
+ int32_t type,
+ int32_t idx,
+ hbool_t dirty_pin)
+{
+ test_entry_t * base_addr;
+ test_entry_t * entry_ptr;
+
+ HDassert( cache_ptr );
+ HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) );
+ HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) );
+
+ if ( pass ) {
+
+ if ( dirty_pin ) {
+
+ if ( ! entry_in_cache(cache_ptr, type, idx) ) {
+
+ pass = FALSE;
+ failure_mssg = "entry to be dirty pinned is not in cache.";
+
+ } else {
+
+ base_addr = entries[type];
+ entry_ptr = &(base_addr[idx]);
+
+ HDassert( entry_ptr->index == idx );
+ HDassert( entry_ptr->type == type );
+ HDassert( entry_ptr == entry_ptr->self );
+
+ if ( ! ( (entry_ptr->header).is_pinned ) ) {
+
+ pass = FALSE;
+ failure_mssg = "entry to be dirty pinned is not pinned.";
+
+ } else {
+
+ mark_pinned_entry_dirty(cache_ptr, type, idx, FALSE, 0);
+
+ }
+ }
+ } else {
+
+ protect_entry(cache_ptr, type, idx);
+ unprotect_entry(cache_ptr, type, idx, TRUE, H5C__NO_FLAGS_SET);
+ }
+ }
+
+ return;
+
+} /* dirty_entry() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: execute_flush_op
+ *
+ * Purpose: Given a pointer to an instance of struct flush_op, execute
+ * it.
+ *
+ * Do nothing if pass is false on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 9/1/06
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+execute_flush_op(H5C_t * cache_ptr,
+ struct test_entry_t * entry_ptr,
+ struct flush_op * op_ptr,
+ unsigned * flags_ptr)
+{
+ HDassert( cache_ptr != NULL );
+ HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( entry_ptr != NULL );
+ HDassert( entry_ptr = entry_ptr->self );
+ HDassert( entry_ptr->header.addr == entry_ptr->addr );
+ HDassert( ( entry_ptr->flush_op_self_resize_in_progress ) ||
+ ( entry_ptr->header.size == entry_ptr->size ) );
+ HDassert( op_ptr != NULL );
+ HDassert( ( 0 <= entry_ptr->type ) &&
+ ( entry_ptr->type < NUMBER_OF_ENTRY_TYPES ) );
+ HDassert( ( 0 <= entry_ptr->index ) &&
+ ( entry_ptr->index <= max_indices[entry_ptr->type] ) );
+ HDassert( ( 0 <= op_ptr->type ) &&
+ ( op_ptr->type < NUMBER_OF_ENTRY_TYPES ) );
+ HDassert( ( 0 <= op_ptr->idx ) &&
+ ( op_ptr->idx <= max_indices[op_ptr->type] ) );
+ HDassert( ( op_ptr->flag == FALSE ) || ( op_ptr->flag == TRUE ) );
+ HDassert( flags_ptr != NULL );
+
+ if ( pass ) {
+
+ switch ( op_ptr->op_code )
+ {
+ case FLUSH_OP__NO_OP:
+ break;
+
+ case FLUSH_OP__DIRTY:
+ HDassert( ( entry_ptr->type != op_ptr->type ) ||
+ ( entry_ptr->index != op_ptr->idx ) );
+
+ dirty_entry(cache_ptr, op_ptr->type, op_ptr->idx, op_ptr->flag);
+ break;
+
+ case FLUSH_OP__RESIZE:
+ if ( ( entry_ptr->type == op_ptr->type ) &&
+ ( entry_ptr->index == op_ptr->idx ) ) {
+
+ /* the flush operation is acting on the entry to
+ * which it is attached. Handle this here:
+ */
+ HDassert( entry_ptr->type == VARIABLE_ENTRY_TYPE );
+ HDassert( op_ptr->size > 0 );
+ HDassert( op_ptr->size <= VARIABLE_ENTRY_SIZE );
+
+ entry_ptr->size = op_ptr->size;
+ (*flags_ptr) |= H5C_CALLBACK__SIZE_CHANGED_FLAG;
+ entry_ptr->flush_op_self_resize_in_progress = TRUE;
+
+ /* if the entry is in the process of being destroyed,
+ * set the header size to match the entry size so as
+ * to avoid a spurious failure in the destroy callback.
+ */
+ if ( entry_ptr->header.destroy_in_progress ) {
+
+ entry_ptr->header.size = entry_ptr->size;
+ }
+
+ } else {
+
+ /* change the size of some other entry */
+
+ resize_entry(cache_ptr, op_ptr->type, op_ptr->idx,
+ op_ptr->size, op_ptr->flag);
+ }
+ break;
+
+ case FLUSH_OP__RENAME:
+ rename_entry(cache_ptr, op_ptr->type, op_ptr->idx,
+ op_ptr->flag);
+ break;
+
+ default:
+ pass = FALSE;
+ failure_mssg = "Undefined flush op code.";
+ break;
+ }
+ }
+
+ return;
+
+} /* execute_flush_op() */
+
+
+/*-------------------------------------------------------------------------
* Function: entry_in_cache
*
* Purpose: Given a pointer to a cache, an entry type, and an index,
@@ -1228,6 +1597,17 @@ reset_entries(void)
base_addr[j].pin_idx[k] = -1;
}
+ base_addr[j].num_flush_ops = 0;
+ for ( k = 0; k < MAX_FLUSH_OPS; k++ )
+ {
+ base_addr[j].flush_ops[k].op_code = FLUSH_OP__NO_OP;
+ base_addr[j].flush_ops[k].type = -1;
+ base_addr[j].flush_ops[k].idx = -1;
+ base_addr[j].flush_ops[k].flag = FALSE;
+ base_addr[j].flush_ops[k].size = 0;
+ }
+ base_addr[j].flush_op_self_resize_in_progress = FALSE;
+
base_addr[j].loaded = FALSE;
base_addr[j].cleared = FALSE;
base_addr[j].flushed = FALSE;
@@ -1244,6 +1624,91 @@ reset_entries(void)
/*-------------------------------------------------------------------------
+ * Function: resize_entry
+ *
+ * Purpose: Given a pointer to a cache, an entry type, an index, and
+ * a size, set the size of the target entry to the size. Note
+ * that at present, the type of the entry must be
+ * VARIABLE_ENTRY_TYPE.
+ *
+ * If the resize_pin parameter is true, verify that the
+ * target entry is in the cache and is pinned. If it
+ * isn't, scream and die. If it is, use the
+ * H5C_mark_pinned_entry_dirty() call to resize it.
+ *
+ * Do nothing if pass is false on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 6/10/04
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+resize_entry(H5C_t * cache_ptr,
+ int32_t type,
+ int32_t idx,
+ size_t new_size,
+ hbool_t resize_pin)
+{
+ test_entry_t * base_addr;
+ test_entry_t * entry_ptr;
+
+ HDassert( cache_ptr );
+ HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) );
+ HDassert( type == VARIABLE_ENTRY_TYPE );
+ HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) );
+ HDassert( ( 0 < new_size ) && ( new_size <= entry_sizes[type] ) );
+
+ if ( pass ) {
+
+ base_addr = entries[type];
+ entry_ptr = &(base_addr[idx]);
+
+ HDassert( entry_ptr->index == idx );
+ HDassert( entry_ptr->type == type );
+ HDassert( entry_ptr == entry_ptr->self );
+
+ if ( resize_pin ) {
+
+ if ( ! entry_in_cache(cache_ptr, type, idx) ) {
+
+ pass = FALSE;
+ failure_mssg = "entry to be resized pinned is not in cache.";
+
+ } else {
+
+ if ( ! ( (entry_ptr->header).is_pinned ) ) {
+
+ pass = FALSE;
+ failure_mssg = "entry to be resized pinned is not pinned.";
+
+ } else {
+
+ mark_pinned_entry_dirty(cache_ptr, type, idx,
+ TRUE, new_size);
+ }
+ }
+ } else {
+
+ protect_entry(cache_ptr, type, idx);
+ unprotect_entry_with_size_change(cache_ptr, type, idx,
+ H5C__SIZE_CHANGED_FLAG, new_size);
+ }
+ }
+
+ return;
+
+} /* resize_entry() */
+
+
+/*-------------------------------------------------------------------------
* Function: verify_clean
*
* Purpose: Verify that all cache entries are marked as clean. If any
@@ -1282,7 +1747,8 @@ verify_clean(void)
for ( j = 0; j <= max_index; j++ )
{
- if ( ( base_addr[j].header.is_dirty ) || ( base_addr[j].is_dirty ) ) {
+ if ( ( base_addr[j].header.is_dirty ) ||
+ ( base_addr[j].is_dirty ) ) {
dirty_count++;
}
@@ -1302,6 +1768,248 @@ verify_clean(void)
/*-------------------------------------------------------------------------
+ * Function: verify_entry_status
+ *
+ * Purpose: Verify that a list of entries have the expected status.
+ * If any discrepencies are found, set the failure message
+ * and set pass to FALSE.
+ *
+ * Do nothing if pass is FALSE on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 10/8/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+verify_entry_status(H5C_t * cache_ptr,
+ int tag,
+ int num_entries,
+ struct expected_entry_status expected[])
+{
+ static char msg[128];
+ hbool_t in_cache;
+ int i;
+ test_entry_t * entry_ptr;
+ test_entry_t * base_addr;
+
+ i = 0;
+ while ( ( pass ) && ( i < num_entries ) )
+ {
+ base_addr = entries[expected[i].entry_type];
+ entry_ptr = &(base_addr[expected[i].entry_index]);
+
+ if ( ( ! expected[i].in_cache ) &&
+ ( ( expected[i].is_dirty ) ||
+ ( expected[i].is_protected ) ||
+ ( expected[i].is_pinned ) ) ) {
+
+ pass = FALSE;
+ sprintf(msg, "Contradictory data in expected[%d].\n", i);
+ failure_mssg = msg;
+ }
+
+ if ( pass ) {
+
+ in_cache = entry_in_cache(cache_ptr, expected[i].entry_type,
+ expected[i].entry_index);
+
+ if ( in_cache != expected[i].in_cache ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) in cache actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)in_cache,
+ (int)expected[i].in_cache);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ if ( entry_ptr->size != expected[i].size ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) size actualexpected = %ld/%ld.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (long)(entry_ptr->size),
+ (long)expected[i].size);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( ( pass ) && ( in_cache ) ) {
+
+ if ( entry_ptr->header.size != expected[i].size ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) header size actual/expected = %ld/%ld.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (long)(entry_ptr->header.size),
+ (long)expected[i].size);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ if ( entry_ptr->at_main_addr != expected[i].at_main_addr ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) at main addr actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->at_main_addr),
+ (int)expected[i].at_main_addr);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ if ( entry_ptr->is_dirty != expected[i].is_dirty ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) is_dirty actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->is_dirty),
+ (int)expected[i].is_dirty);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( ( pass ) && ( in_cache ) ) {
+
+ if ( entry_ptr->header.is_dirty != expected[i].is_dirty ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) header is_dirty actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->header.is_dirty),
+ (int)expected[i].is_dirty);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ if ( entry_ptr->is_protected != expected[i].is_protected ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) is_protected actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->is_protected),
+ (int)expected[i].is_protected);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( ( pass ) && ( in_cache ) ) {
+
+ if ( entry_ptr->header.is_protected != expected[i].is_protected ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) header is_protected actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->header.is_protected),
+ (int)expected[i].is_protected);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ if ( entry_ptr->is_pinned != expected[i].is_pinned ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) is_pinned actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->is_pinned),
+ (int)expected[i].is_pinned);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( ( pass ) && ( in_cache ) ) {
+
+ if ( entry_ptr->header.is_pinned != expected[i].is_pinned ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d, %d) header is_pinned actual/expected = %d/%d.\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->header.is_pinned),
+ (int)expected[i].is_pinned);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ if ( ( entry_ptr->loaded != expected[i].loaded ) ||
+ ( entry_ptr->cleared != expected[i].cleared ) ||
+ ( entry_ptr->flushed != expected[i].flushed ) ||
+ ( entry_ptr->destroyed != expected[i].destroyed ) ) {
+
+ pass = FALSE;
+ sprintf(msg,
+ "%d entry (%d,%d) loaded = %d(%d), clrd = %d(%d), flshd = %d(%d), dest = %d(%d)\n",
+ tag,
+ (int)expected[i].entry_type,
+ (int)expected[i].entry_index,
+ (int)(entry_ptr->loaded),
+ (int)(expected[i].loaded),
+ (int)(entry_ptr->cleared),
+ (int)(expected[i].cleared),
+ (int)(entry_ptr->flushed),
+ (int)(expected[i].flushed),
+ (int)(entry_ptr->destroyed),
+ (int)(expected[i].destroyed));
+ failure_mssg = msg;
+ }
+ }
+ i++;
+ } /* while */
+
+ return;
+
+} /* verify_entry_status() */
+
+
+/*-------------------------------------------------------------------------
* Function: verify_unprotected
*
* Purpose: Verify that no cache entries are marked as protected. If
@@ -1649,8 +2357,7 @@ insert_entry(H5C_t * cache_ptr,
pass = FALSE;
failure_mssg = "error in H5C_insert().";
-#if 0
- /* This is useful debugging code. Lets keep it around. */
+#if 0 /* This is useful debugging code. Lets keep it around. */
HDfprintf(stdout, "result = %d\n", (int)result);
HDfprintf(stdout, "entry_ptr->header.is_protected = %d\n",
@@ -1934,7 +2641,9 @@ rename_entry(H5C_t * cache_ptr,
if ( ! done ) {
- if ( ( result < 0 ) || ( entry_ptr->header.addr != new_addr ) ) {
+ if ( ( result < 0 ) ||
+ ( ( ! ( entry_ptr->header.destroy_in_progress ) ) &&
+ ( entry_ptr->header.addr != new_addr ) ) ) {
pass = FALSE;
failure_mssg = "error in H5C_rename_entry().";
@@ -2241,6 +2950,130 @@ unprotect_entry(H5C_t * cache_ptr,
/*-------------------------------------------------------------------------
+ * Function: unprotect_entry_with_size_change()
+ *
+ * Purpose: Version of unprotect_entry() that allow access to the new
+ * size change parameters in H5C_unprotect_entry()
+ *
+ * At present, only the sizes of VARIABLE_ENTRY_TYPE entries
+ * can be changed. Thus this function will scream and die
+ * if the H5C__SIZE_CHANGED_FLAG is set and the type is not
+ * VARIABLE_ENTRY_TYPE.
+ *
+ * Do nothing if pass is FALSE on entry.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 8/31/06
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+unprotect_entry_with_size_change(H5C_t * cache_ptr,
+ int32_t type,
+ int32_t idx,
+ unsigned int flags,
+ size_t new_size)
+{
+ /* const char * fcn_name = "unprotect_entry_with_size_change()"; */
+ herr_t result;
+ hbool_t dirty_flag_set;
+ hbool_t pin_flag_set;
+ hbool_t unpin_flag_set;
+ hbool_t size_changed_flag_set;
+ test_entry_t * base_addr;
+ test_entry_t * entry_ptr;
+
+ if ( pass ) {
+
+ HDassert( cache_ptr );
+ HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) );
+ HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) );
+ HDassert( new_size <= entry_sizes[type] );
+
+ base_addr = entries[type];
+ entry_ptr = &(base_addr[idx]);
+
+ HDassert( entry_ptr->index == idx );
+ HDassert( entry_ptr->type == type );
+ HDassert( entry_ptr == entry_ptr->self );
+ HDassert( entry_ptr->cache_ptr == cache_ptr );
+ HDassert( entry_ptr->header.is_protected );
+ HDassert( entry_ptr->is_protected );
+
+ dirty_flag_set = ((flags & H5C__DIRTIED_FLAG) != 0 );
+ pin_flag_set = ((flags & H5C__PIN_ENTRY_FLAG) != 0 );
+ unpin_flag_set = ((flags & H5C__UNPIN_ENTRY_FLAG) != 0 );
+ size_changed_flag_set = ((flags & H5C__SIZE_CHANGED_FLAG) != 0 );
+
+ HDassert ( ! ( pin_flag_set && unpin_flag_set ) );
+ HDassert ( ( ! pin_flag_set ) || ( ! (entry_ptr->is_pinned) ) );
+ HDassert ( ( ! unpin_flag_set ) || ( entry_ptr->is_pinned ) );
+ HDassert ( ( ! size_changed_flag_set ) || ( new_size > 0 ) );
+ HDassert ( ( ! size_changed_flag_set ) ||
+ ( type == VARIABLE_ENTRY_TYPE ) );
+
+ entry_ptr->is_dirty = (entry_ptr->is_dirty || dirty_flag_set);
+
+ if ( size_changed_flag_set ) {
+
+ entry_ptr->is_dirty = TRUE;
+ entry_ptr->size = new_size;
+ }
+
+ result = H5C_unprotect(NULL, -1, -1, cache_ptr, &(types[type]),
+ entry_ptr->addr, (void *)entry_ptr,
+ flags, new_size);
+
+ if ( ( result < 0 ) ||
+ ( entry_ptr->header.is_protected ) ||
+ ( entry_ptr->header.type != &(types[type]) ) ||
+ ( entry_ptr->size != entry_ptr->header.size ) ||
+ ( entry_ptr->addr != entry_ptr->header.addr ) ) {
+
+ pass = FALSE;
+ failure_mssg = "error in H5C_unprotect().";
+
+ }
+ else
+ {
+ entry_ptr->is_protected = FALSE;
+
+ if ( pin_flag_set ) {
+
+ HDassert ( entry_ptr->header.is_pinned );
+ entry_ptr->is_pinned = TRUE;
+
+ } else if ( unpin_flag_set ) {
+
+ HDassert ( ! ( entry_ptr->header.is_pinned ) );
+ entry_ptr->is_pinned = FALSE;
+
+ }
+ }
+
+ HDassert( ((entry_ptr->header).type)->id == type );
+
+ if ( ( flags & H5C__DIRTIED_FLAG ) != 0
+ && ( (flags & H5C__DELETED_FLAG) == 0 ) ) {
+
+ HDassert( entry_ptr->header.is_dirty );
+ HDassert( entry_ptr->is_dirty );
+ }
+ }
+
+ return;
+
+} /* unprotect_entry_with_size_change() */
+
+
+/*-------------------------------------------------------------------------
* Function: row_major_scan_forward()
*
* Purpose: Do a sequence of inserts, protects, unprotects, renames,
diff --git a/test/cache_common.h b/test/cache_common.h
index c6c2a32..460661a 100644
--- a/test/cache_common.h
+++ b/test/cache_common.h
@@ -43,8 +43,9 @@
#define LARGE_ENTRY_TYPE 6
#define HUGE_ENTRY_TYPE 7
#define MONSTER_ENTRY_TYPE 8
+#define VARIABLE_ENTRY_TYPE 9
-#define NUMBER_OF_ENTRY_TYPES 9
+#define NUMBER_OF_ENTRY_TYPES 10
#define PICO_ENTRY_SIZE (size_t)1
#define NANO_ENTRY_SIZE (size_t)4
@@ -55,6 +56,7 @@
#define LARGE_ENTRY_SIZE (size_t)(4 * 1024)
#define HUGE_ENTRY_SIZE (size_t)(16 * 1024)
#define MONSTER_ENTRY_SIZE (size_t)(64 * 1024)
+#define VARIABLE_ENTRY_SIZE (size_t)(10 * 1024)
#define NUM_PICO_ENTRIES (10 * 1024)
#define NUM_NANO_ENTRIES (10 * 1024)
@@ -65,6 +67,7 @@
#define NUM_LARGE_ENTRIES (10 * 1024)
#define NUM_HUGE_ENTRIES (10 * 1024)
#define NUM_MONSTER_ENTRIES (10 * 1024)
+#define NUM_VARIABLE_ENTRIES (10 * 1024)
#define MAX_ENTRIES (10 * 1024)
@@ -85,9 +88,11 @@
(LARGE_ENTRY_SIZE * NUM_LARGE_ENTRIES))
#define MONSTER_BASE_ADDR (haddr_t)(HUGE_BASE_ADDR + \
(HUGE_ENTRY_SIZE * NUM_HUGE_ENTRIES))
-
-#define PICO_ALT_BASE_ADDR (haddr_t)(MONSTER_BASE_ADDR + \
+#define VARIABLE_BASE_ADDR (haddr_t)(MONSTER_BASE_ADDR + \
(MONSTER_ENTRY_SIZE * NUM_MONSTER_ENTRIES))
+
+#define PICO_ALT_BASE_ADDR (haddr_t)(VARIABLE_BASE_ADDR + \
+ (VARIABLE_ENTRY_SIZE * NUM_VARIABLE_ENTRIES))
#define NANO_ALT_BASE_ADDR (haddr_t)(PICO_ALT_BASE_ADDR + \
(PICO_ENTRY_SIZE * NUM_PICO_ENTRIES))
#define MICRO_ALT_BASE_ADDR (haddr_t)(NANO_ALT_BASE_ADDR + \
@@ -104,10 +109,75 @@
(LARGE_ENTRY_SIZE * NUM_LARGE_ENTRIES))
#define MONSTER_ALT_BASE_ADDR (haddr_t)(HUGE_ALT_BASE_ADDR + \
(HUGE_ENTRY_SIZE * NUM_HUGE_ENTRIES))
+#define VARIABLE_ALT_BASE_ADDR (haddr_t)(MONSTER_ALT_BASE_ADDR + \
+ (MONSTER_ENTRY_SIZE * NUM_MONSTER_ENTRIES))
#define MAX_PINS 8 /* Maximum number of entries that can be
* directly pinned by a single entry.
*/
+
+#define FLUSH_OP__NO_OP 0
+#define FLUSH_OP__DIRTY 1
+#define FLUSH_OP__RESIZE 2
+#define FLUSH_OP__RENAME 3
+#define FLUSH_OP__MAX_OP 3
+
+#define MAX_FLUSH_OPS 10 /* Maximum number of flush operations
+ * that can be associated with a
+ * cache entry.
+ */
+
+typedef struct flush_op
+{
+ int op_code; /* integer op code indicating the
+ * operation to be performed. At
+ * present it must be one of:
+ *
+ * FLUSH_OP__NO_OP
+ * FLUSH_OP__DIRTY
+ * FLUSH_OP__RESIZE
+ * FLUSH_OP__RENAME
+ */
+ int type; /* type code of the cache entry that
+ * is the target of the operation.
+ * This value is passed into the
+ * function implementing the flush
+ * operation.
+ */
+ int idx; /* index of the cache entry that
+ * is the target of the operation.
+ * This value is passed into the
+ * function implementing the flush
+ * operation.
+ */
+ hbool_t flag; /* boolean flag passed into the
+ * function implementing the flush
+ * operation. The meaning of the
+ * flag is dependant upon the flush
+ * operation:
+ *
+ * FLUSH_OP__DIRTY: TRUE iff the
+ * target is pinned, and is to
+ * be dirtied via the
+ * H5C_mark_pinned_entry_dirty()
+ * call.
+ *
+ * FLUSH_OP__RESIZE: TRUE iff the
+ * target is pinned, and is to
+ * be resized via the
+ * H5C_mark_pinned_entry_dirty()
+ * call.
+ *
+ * FLUSH_OP__RENAME: TRUE iff the
+ * target is to be renamed to
+ * its main address.
+ */
+ size_t size; /* New target size in the
+ * FLUSH_OP__RENAME operation.
+ * Unused elsewhere.
+ */
+} flush_op;
+
typedef struct test_entry_t
{
H5C_cache_entry_t header; /* entry data used by the cache
@@ -172,6 +242,32 @@ typedef struct test_entry_t
int pin_idx[MAX_PINS]; /* array of the indicies of
* entries pinned by this entry.
*/
+ int num_flush_ops; /* integer field containing the
+ * number of flush operations to
+ * be executed when the entry is
+ * flushed. This value must lie in
+ * the closed interval
+ * [0, MAX_FLUSH_OPS].
+ */
+ struct flush_op flush_ops[MAX_FLUSH_OPS]; /* Array of instances
+ * of struct flush_op detailing the
+ * flush operations (if any) that
+ * are to be executed when the entry
+ * is flushed from the cache.
+ *
+ * num_flush_ops contains the number
+ * of valid entries in this array.
+ */
+ hbool_t flush_op_self_resize_in_progress; /* Boolean flag
+ * that is set to TRUE iff this
+ * entry is being flushed, it has
+ * been resized by a resize flush
+ * op, and the flush function has
+ * not yet returned, This field is
+ * used to turn off overactive santity
+ * checking code that would otherwise
+ * cause a false test failure.
+ */
hbool_t loaded; /* entry has been loaded since the
* last time it was reset.
*/
@@ -290,6 +386,42 @@ struct pe_flush_cache_test_spec
hbool_t expected_destroyed;
};
+struct fo_flush_entry_check
+{
+ int entry_num;
+ int entry_type;
+ int entry_index;
+ size_t expected_size;
+ hbool_t in_cache;
+ hbool_t at_main_addr;
+ hbool_t is_dirty;
+ hbool_t is_protected;
+ hbool_t is_pinned;
+ hbool_t expected_loaded;
+ hbool_t expected_cleared;
+ hbool_t expected_flushed;
+ hbool_t expected_destroyed;
+};
+
+struct fo_flush_cache_test_spec
+{
+ int entry_num;
+ int entry_type;
+ int entry_index;
+ hbool_t insert_flag;
+ unsigned int flags;
+ size_t new_size;
+ int num_pins;
+ int pin_type[MAX_PINS];
+ int pin_idx[MAX_PINS];
+ int num_flush_ops;
+ struct flush_op flush_ops[MAX_FLUSH_OPS];
+ hbool_t expected_loaded;
+ hbool_t expected_cleared;
+ hbool_t expected_flushed;
+ hbool_t expected_destroyed;
+};
+
struct rename_entry_test_spec
{
int entry_type;
@@ -298,6 +430,22 @@ struct rename_entry_test_spec
hbool_t is_pinned;
};
+struct expected_entry_status
+{
+ int entry_type;
+ int entry_index;
+ size_t size;
+ hbool_t in_cache;
+ hbool_t at_main_addr;
+ hbool_t is_dirty;
+ hbool_t is_protected;
+ hbool_t is_pinned;
+ hbool_t loaded;
+ hbool_t cleared;
+ hbool_t flushed;
+ hbool_t destroyed;
+};
+
@@ -344,6 +492,7 @@ herr_t medium_clear(H5F_t * f, void * thing, hbool_t dest);
herr_t large_clear(H5F_t * f, void * thing, hbool_t dest);
herr_t huge_clear(H5F_t * f, void * thing, hbool_t dest);
herr_t monster_clear(H5F_t * f, void * thing, hbool_t dest);
+herr_t variable_clear(H5F_t * f, void * thing, hbool_t dest);
herr_t pico_dest(H5F_t * f, void * thing);
@@ -355,26 +504,29 @@ herr_t medium_dest(H5F_t * f, void * thing);
herr_t large_dest(H5F_t * f, void * thing);
herr_t huge_dest(H5F_t * f, void * thing);
herr_t monster_dest(H5F_t * f, void * thing);
+herr_t variable_dest(H5F_t * f, void * thing);
herr_t pico_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t nano_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t micro_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t tiny_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t small_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t medium_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t large_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t huge_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
herr_t monster_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
- haddr_t addr, void *thing);
+ haddr_t addr, void *thing, unsigned * flags_ptr);
+herr_t variable_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest,
+ haddr_t addr, void *thing, unsigned * flags_ptr);
void * pico_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
@@ -395,6 +547,8 @@ void * huge_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
const void *udata1, void *udata2);
void * monster_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
const void *udata1, void *udata2);
+void * variable_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *udata1, void *udata2);
herr_t pico_size(H5F_t * f, void * thing, size_t * size_ptr);
@@ -406,6 +560,7 @@ herr_t medium_size(H5F_t * f, void * thing, size_t * size_ptr);
herr_t large_size(H5F_t * f, void * thing, size_t * size_ptr);
herr_t huge_size(H5F_t * f, void * thing, size_t * size_ptr);
herr_t monster_size(H5F_t * f, void * thing, size_t * size_ptr);
+herr_t variable_size(H5F_t * f, void * thing, size_t * size_ptr);
/* callback table extern */
@@ -414,6 +569,15 @@ extern const H5C_class_t types[NUMBER_OF_ENTRY_TYPES];
/* function declarations: */
+void add_flush_op(int target_type,
+ int target_idx,
+ int op_code,
+ int type,
+ int idx,
+ hbool_t flag,
+ size_t size);
+
+
void addr_to_type_and_index(haddr_t addr,
int32_t * type_ptr,
int32_t * index_ptr);
@@ -423,6 +587,11 @@ haddr_t type_and_index_to_addr(int32_t type,
int32_t idx);
#endif
+void dirty_entry(H5C_t * cache_ptr,
+ int32_t type,
+ int32_t idx,
+ hbool_t dirty_pin);
+
void expunge_entry(H5C_t * cache_ptr,
int32_t type,
int32_t idx);
@@ -462,8 +631,19 @@ void create_pinned_entry_dependency(H5C_t * cache_ptr,
int pinned_type,
int pinned_idx);
+void execute_flush_op(H5C_t * cache_ptr,
+ struct test_entry_t * entry_ptr,
+ struct flush_op * op_ptr,
+ unsigned * flags_ptr);
+
void reset_entries(void);
+void resize_entry(H5C_t * cache_ptr,
+ int32_t type,
+ int32_t idx,
+ size_t new_size,
+ hbool_t resize_pin);
+
H5C_t * setup_cache(size_t max_cache_size, size_t min_clean_size);
void row_major_scan_forward(H5C_t * cache_ptr,
@@ -571,7 +751,18 @@ void unprotect_entry(H5C_t * cache_ptr,
int dirty,
unsigned int flags);
+void unprotect_entry_with_size_change(H5C_t * cache_ptr,
+ int32_t type,
+ int32_t idx,
+ unsigned int flags,
+ size_t new_size);
+
void verify_clean(void);
+void verify_entry_status(H5C_t * cache_ptr,
+ int tag,
+ int num_entries,
+ struct expected_entry_status expected[]);
+
void verify_unprotected(void);