summaryrefslogtreecommitdiffstats
path: root/test/cache_common.c
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/cache_common.c
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/cache_common.c')
-rw-r--r--test/cache_common.c911
1 files changed, 872 insertions, 39 deletions
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,