diff options
author | John Mainzer <mainzer@hdfgroup.org> | 2006-10-18 10:51:26 (GMT) |
---|---|---|
committer | John Mainzer <mainzer@hdfgroup.org> | 2006-10-18 10:51:26 (GMT) |
commit | 2d6bb5932951242d23ccef420a328a033f3b4efa (patch) | |
tree | 3650df339b604f381873f55dcb24af501a83bd0b /test/cache_common.c | |
parent | ce30ee9b28e9b68de817845aa5bc965d35ca8967 (diff) | |
download | hdf5-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.c | 911 |
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, |