diff options
Diffstat (limited to 'test/cache_common.c')
-rw-r--r-- | test/cache_common.c | 2878 |
1 files changed, 2878 insertions, 0 deletions
diff --git a/test/cache_common.c b/test/cache_common.c new file mode 100644 index 0000000..c87fb7f --- /dev/null +++ b/test/cache_common.c @@ -0,0 +1,2878 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: John Mainzer + * 10/27/05 + * + * This file contains common code for tests of the cache + * implemented in H5C.c + */ +#include "h5test.h" +#include "H5Iprivate.h" +#include "H5ACprivate.h" +#include "cache_common.h" + + +/* global variable declarations: */ + +hbool_t write_permitted = TRUE; +hbool_t pass = TRUE; /* set to false on error */ +hbool_t skip_long_tests = TRUE; +hbool_t run_full_test = TRUE; +const char *failure_mssg = NULL; + +test_entry_t pico_entries[NUM_PICO_ENTRIES]; +test_entry_t nano_entries[NUM_NANO_ENTRIES]; +test_entry_t micro_entries[NUM_MICRO_ENTRIES]; +test_entry_t tiny_entries[NUM_TINY_ENTRIES]; +test_entry_t small_entries[NUM_SMALL_ENTRIES]; +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 * entries[NUMBER_OF_ENTRY_TYPES] = +{ + pico_entries, + nano_entries, + micro_entries, + tiny_entries, + small_entries, + medium_entries, + large_entries, + huge_entries, + monster_entries +}; + +const int32_t max_indices[NUMBER_OF_ENTRY_TYPES] = +{ + NUM_PICO_ENTRIES - 1, + NUM_NANO_ENTRIES - 1, + NUM_MICRO_ENTRIES - 1, + NUM_TINY_ENTRIES - 1, + NUM_SMALL_ENTRIES - 1, + NUM_MEDIUM_ENTRIES - 1, + NUM_LARGE_ENTRIES - 1, + NUM_HUGE_ENTRIES - 1, + NUM_MONSTER_ENTRIES - 1 +}; + +const size_t entry_sizes[NUMBER_OF_ENTRY_TYPES] = +{ + PICO_ENTRY_SIZE, + NANO_ENTRY_SIZE, + MICRO_ENTRY_SIZE, + TINY_ENTRY_SIZE, + SMALL_ENTRY_SIZE, + MEDIUM_ENTRY_SIZE, + LARGE_ENTRY_SIZE, + HUGE_ENTRY_SIZE, + MONSTER_ENTRY_SIZE +}; + +const haddr_t base_addrs[NUMBER_OF_ENTRY_TYPES] = +{ + PICO_BASE_ADDR, + NANO_BASE_ADDR, + MICRO_BASE_ADDR, + TINY_BASE_ADDR, + SMALL_BASE_ADDR, + MEDIUM_BASE_ADDR, + LARGE_BASE_ADDR, + HUGE_BASE_ADDR, + MONSTER_BASE_ADDR +}; + +const haddr_t alt_base_addrs[NUMBER_OF_ENTRY_TYPES] = +{ + PICO_ALT_BASE_ADDR, + NANO_ALT_BASE_ADDR, + MICRO_ALT_BASE_ADDR, + TINY_ALT_BASE_ADDR, + SMALL_ALT_BASE_ADDR, + MEDIUM_ALT_BASE_ADDR, + LARGE_ALT_BASE_ADDR, + HUGE_ALT_BASE_ADDR, + MONSTER_ALT_BASE_ADDR +}; + +const char * entry_type_names[NUMBER_OF_ENTRY_TYPES] = +{ + "pico entries -- 1 B", + "nano entries -- 4 B", + "micro entries -- 16 B", + "tiny entries -- 64 B", + "small entries -- 256 B", + "medium entries -- 1 KB", + "large entries -- 4 KB", + "huge entries -- 16 KB", + "monster entries -- 64 KB" +}; + + +/* callback table declaration */ + +const H5C_class_t types[NUMBER_OF_ENTRY_TYPES] = +{ + { + PICO_ENTRY_TYPE, + (H5C_load_func_t)pico_load, + (H5C_flush_func_t)pico_flush, + (H5C_dest_func_t)pico_dest, + (H5C_clear_func_t)pico_clear, + (H5C_size_func_t)pico_size + }, + { + NANO_ENTRY_TYPE, + (H5C_load_func_t)nano_load, + (H5C_flush_func_t)nano_flush, + (H5C_dest_func_t)nano_dest, + (H5C_clear_func_t)nano_clear, + (H5C_size_func_t)nano_size + }, + { + MICRO_ENTRY_TYPE, + (H5C_load_func_t)micro_load, + (H5C_flush_func_t)micro_flush, + (H5C_dest_func_t)micro_dest, + (H5C_clear_func_t)micro_clear, + (H5C_size_func_t)micro_size + }, + { + TINY_ENTRY_TYPE, + (H5C_load_func_t)tiny_load, + (H5C_flush_func_t)tiny_flush, + (H5C_dest_func_t)tiny_dest, + (H5C_clear_func_t)tiny_clear, + (H5C_size_func_t)tiny_size + }, + { + SMALL_ENTRY_TYPE, + (H5C_load_func_t)small_load, + (H5C_flush_func_t)small_flush, + (H5C_dest_func_t)small_dest, + (H5C_clear_func_t)small_clear, + (H5C_size_func_t)small_size + }, + { + MEDIUM_ENTRY_TYPE, + (H5C_load_func_t)medium_load, + (H5C_flush_func_t)medium_flush, + (H5C_dest_func_t)medium_dest, + (H5C_clear_func_t)medium_clear, + (H5C_size_func_t)medium_size + }, + { + LARGE_ENTRY_TYPE, + (H5C_load_func_t)large_load, + (H5C_flush_func_t)large_flush, + (H5C_dest_func_t)large_dest, + (H5C_clear_func_t)large_clear, + (H5C_size_func_t)large_size + }, + { + HUGE_ENTRY_TYPE, + (H5C_load_func_t)huge_load, + (H5C_flush_func_t)huge_flush, + (H5C_dest_func_t)huge_dest, + (H5C_clear_func_t)huge_clear, + (H5C_size_func_t)huge_size + }, + { + MONSTER_ENTRY_TYPE, + (H5C_load_func_t)monster_load, + (H5C_flush_func_t)monster_flush, + (H5C_dest_func_t)monster_dest, + (H5C_clear_func_t)monster_clear, + (H5C_size_func_t)monster_size + } +}; + +static herr_t clear(H5F_t * f, void * thing, hbool_t dest); +static herr_t destroy(H5F_t UNUSED * f, void * thing); +static herr_t flush(H5F_t *f, hid_t UNUSED dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +static void * load(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, + const void UNUSED *udata1, void UNUSED *udata2); +static herr_t size(H5F_t UNUSED * f, void * thing, size_t * size_ptr); + + + +/* address translation funtions: */ + +/*------------------------------------------------------------------------- + * Function: addr_to_type_and_index + * + * Purpose: Given an address, compute the type and index of the + * associated entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +addr_to_type_and_index(haddr_t addr, + int32_t * type_ptr, + int32_t * index_ptr) +{ + int i; + int32_t type; + int32_t idx; + + HDassert( type_ptr ); + HDassert( index_ptr ); + + /* we only have a small number of entry types, so just do a + * linear search. If NUMBER_OF_ENTRY_TYPES grows, we may want + * to do a binary search instead. + */ + i = 1; + if ( addr >= PICO_ALT_BASE_ADDR ) { + + while ( ( i < NUMBER_OF_ENTRY_TYPES ) && + ( addr >= alt_base_addrs[i] ) ) + { + i++; + } + + } else { + + while ( ( i < NUMBER_OF_ENTRY_TYPES ) && + ( addr >= base_addrs[i] ) ) + { + i++; + } + } + + type = i - 1; + + HDassert( ( type >= 0 ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + + if ( addr >= PICO_ALT_BASE_ADDR ) { + + idx = (addr - alt_base_addrs[type]) / entry_sizes[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( (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; + *index_ptr = idx; + + return; + +} /* addr_to_type_and_index() */ + + +#if 0 /* This function has never been used, but we may want it + * some time. Lets keep it for now. + */ +/*------------------------------------------------------------------------- + * Function: type_and_index_to_addr + * + * Purpose: Given a type and index of an entry, compute the associated + * addr and return that value. + * + * Return: computed addr + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +type_and_index_to_addr(int32_t type, + int32_t idx) +{ + haddr_t addr; + + HDassert( ( type >= 0 ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( idx >= 0 ) && ( idx <= max_indices[type] ) ); + + addr = base_addrs[type] + (((haddr_t)idx) * entry_sizes[type]); + + HDassert( addr == (entries[type])[idx].addr ); + + if ( (entries[type])[idx].at_main_addr ) { + + HDassert( addr == (entries[type])[idx].main_addr ); + + } else { + + HDassert( addr == (entries[type])[idx].alt_addr ); + } + + return(addr); + +} /* type_and_index_to_addr() */ + +#endif + + +/* Call back functions: */ + +/*------------------------------------------------------------------------- + * + * Function: H5AC_check_if_write_permitted + * + * Purpose: Determine if a write is permitted under the current + * circumstances, and set *write_permitted_ptr accordingly. + * As a general rule it is, but when we are running in parallel + * mode with collective I/O, we must ensure that a read cannot + * cause a write. + * + * In the event of failure, the value of *write_permitted_ptr + * is undefined. + * + * Return: Non-negative on success/Negative on failure. + * + * Programmer: John Mainzer, 5/15/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +check_write_permitted(const H5F_t UNUSED * f, + hid_t UNUSED dxpl_id, + hbool_t * write_permitted_ptr) +{ + + HDassert( write_permitted_ptr ); + *write_permitted_ptr = write_permitted; + + return(SUCCEED); + +} /* check_write_permitted() */ + + +/*------------------------------------------------------------------------- + * Function: clear & friends + * + * Purpose: clear the entry. The helper functions verify that the + * correct version of clear is being called, and then call + * clear proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +clear(H5F_t * f, + void * thing, + hbool_t dest) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert( entry_ptr->index >= 0 ); + HDassert( entry_ptr->index <= max_indices[entry_ptr->type] ); + 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->header.size == entry_ptr->size ); + HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] ); + + entry_ptr->header.is_dirty = FALSE; + entry_ptr->is_dirty = FALSE; + + entry_ptr->cleared = TRUE; + + if ( dest ) { + + destroy(f, thing); + + } + + return(SUCCEED); + +} /* clear() */ + +herr_t +pico_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +nano_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +micro_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +tiny_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +small_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +medium_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +large_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +huge_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +monster_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + + +/*------------------------------------------------------------------------- + * Function: dest & friends + * + * Purpose: Destroy the entry. The helper functions verify that the + * correct version of dest is being called, and then call + * dest proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +destroy(H5F_t UNUSED * f, + void * thing) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert ( entry_ptr->index >= 0 ); + HDassert ( entry_ptr->index <= max_indices[entry_ptr->type] ); + 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->header.size == entry_ptr->size ); + HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] ); + + HDassert( !(entry_ptr->is_dirty) ); + HDassert( !(entry_ptr->header.is_dirty) ); + + entry_ptr->destroyed = TRUE; + + return(SUCCEED); + +} /* dest() */ + +herr_t +pico_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +nano_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +micro_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +tiny_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +small_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +medium_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +large_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +huge_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +monster_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(destroy(f, thing)); +} + + +/*------------------------------------------------------------------------- + * Function: flush & friends + * + * Purpose: flush the entry and mark it as clean. The helper functions + * verify that the correct version of flush is being called, + * and then call flush proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +flush(H5F_t *f, + hid_t UNUSED dxpl_id, + hbool_t dest, + haddr_t addr, + void *thing) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert( entry_ptr->index >= 0 ); + HDassert( entry_ptr->index <= max_indices[entry_ptr->type] ); + 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->addr == addr ); + HDassert( entry_ptr->header.size == entry_ptr->size ); + HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] ); + HDassert( entry_ptr->header.is_dirty == entry_ptr->is_dirty ); + + entry_ptr->flushed = TRUE; + + if ( ( ! write_permitted ) && ( entry_ptr->is_dirty ) ) { + + pass = FALSE; + failure_mssg = "called flush when write_permitted is FALSE."; + } + + if ( entry_ptr->is_dirty ) { + + (entry_ptr->writes)++; + entry_ptr->is_dirty = FALSE; + entry_ptr->header.is_dirty = FALSE; + } + + if ( dest ) { + + destroy(f, thing); + + } + + return(SUCCEED); + +} /* flush() */ + +herr_t +pico_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +nano_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +micro_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +tiny_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +small_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +medium_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +large_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +huge_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +monster_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + + +/*------------------------------------------------------------------------- + * Function: load & friends + * + * Purpose: "load" the requested entry and mark it as clean. The + * helper functions verify that the correct version of load + * is being called, and then call load proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void * +load(H5F_t UNUSED *f, + hid_t UNUSED dxpl_id, + haddr_t addr, + const void UNUSED *udata1, + void UNUSED *udata2) +{ + int32_t type; + int32_t idx; + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + addr_to_type_and_index(addr, &type, &idx); + + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr->type >= 0 ); + HDassert( entry_ptr->type < NUMBER_OF_ENTRY_TYPES ); + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->index >= 0 ); + 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] ); + + entry_ptr->loaded = TRUE; + + entry_ptr->header.is_dirty = FALSE; + entry_ptr->is_dirty = FALSE; + + (entry_ptr->reads)++; + + return(entry_ptr); + +} /* load() */ + +void * +pico_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +nano_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +micro_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +tiny_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +small_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +medium_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +large_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +huge_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +monster_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 + * + * Purpose: Get the size of the specified entry. The helper functions + * verify that the correct version of size is being called, + * and then call size proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +size(H5F_t UNUSED * f, + void * thing, + size_t * size_ptr) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( size_ptr ); + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert( entry_ptr->index >= 0 ); + HDassert( entry_ptr->index <= max_indices[entry_ptr->type] ); + 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] ); + + *size_ptr = entry_ptr->size; + + return(SUCCEED); + +} /* size() */ + +herr_t +pico_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +nano_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +micro_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +tiny_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +small_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +medium_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +large_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +huge_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +monster_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + + +/**************************************************************************/ +/**************************************************************************/ +/************************** test utility functions: ***********************/ +/**************************************************************************/ +/**************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: entry_in_cache + * + * Purpose: Given a pointer to a cache, an entry type, and an index, + * determine if the entry is currently in the cache. + * + * Return: TRUE if the entry is in the cache, and FALSE otherwise. + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + * JRM - 10/12/04 + * Removed references to local_H5C_t, as we now get direct + * access to the definition of H5C_t via H5Cpkg.h. + * + *------------------------------------------------------------------------- + */ + +hbool_t +entry_in_cache(H5C_t * cache_ptr, + int32_t type, + int32_t idx) +{ + hbool_t in_cache = FALSE; /* will set to TRUE if necessary */ + test_entry_t * base_addr; + test_entry_t * entry_ptr; + H5C_cache_entry_t * test_ptr = NULL; + + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[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 ); + + H5C__SEARCH_INDEX(cache_ptr, entry_ptr->addr, test_ptr) + + if ( test_ptr != NULL ) { + + in_cache = TRUE; + HDassert( test_ptr == (H5C_cache_entry_t *)entry_ptr ); + HDassert( entry_ptr->addr == entry_ptr->header.addr ); + } + + return(in_cache); + +} /* entry_in_cache() */ + + +/*------------------------------------------------------------------------- + * Function: reset_entries + * + * Purpose: reset the contents of the entries arrays to know values. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +reset_entries(void) + +{ + int i; + int j; + int32_t max_index; + haddr_t addr = 0; + haddr_t alt_addr = PICO_ALT_BASE_ADDR; + size_t entry_size; + test_entry_t * base_addr; + + for ( i = 0; i < NUMBER_OF_ENTRY_TYPES; i++ ) + { + entry_size = entry_sizes[i]; + max_index = max_indices[i]; + base_addr = entries[i]; + + HDassert( base_addr ); + + for ( j = 0; j <= max_index; j++ ) + { + /* one can argue that we should fill the header with garbage. + * If this is desired, we can simply comment out the header + * initialization - the headers will be full of garbage soon + * enough. + */ + + base_addr[j].header.addr = (haddr_t)0; + base_addr[j].header.size = (size_t)0; + base_addr[j].header.type = NULL; + base_addr[j].header.is_dirty = FALSE; + base_addr[j].header.is_protected = FALSE; + base_addr[j].header.next = NULL; + base_addr[j].header.prev = NULL; + base_addr[j].header.aux_next = NULL; + base_addr[j].header.aux_prev = NULL; + + base_addr[j].self = &(base_addr[j]); + base_addr[j].addr = addr; + base_addr[j].at_main_addr = TRUE; + base_addr[j].main_addr = addr; + base_addr[j].alt_addr = alt_addr; + base_addr[j].size = entry_size; + base_addr[j].type = i; + base_addr[j].index = j; + base_addr[j].reads = 0; + base_addr[j].writes = 0; + base_addr[j].is_dirty = FALSE; + base_addr[j].is_protected = FALSE; + + base_addr[j].loaded = FALSE; + base_addr[j].cleared = FALSE; + base_addr[j].flushed = FALSE; + base_addr[j].destroyed = FALSE; + + addr += (haddr_t)entry_size; + alt_addr += (haddr_t)entry_size; + } + } + + return; + +} /* reset_entries() */ + + +/*------------------------------------------------------------------------- + * Function: verify_clean + * + * Purpose: Verify that all cache entries are marked as clean. If any + * are not, set pass to FALSE. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +verify_clean(void) + +{ + int i; + int j; + int dirty_count = 0; + int32_t max_index; + test_entry_t * base_addr; + + if ( pass ) { + + for ( i = 0; i < NUMBER_OF_ENTRY_TYPES; i++ ) + { + max_index = max_indices[i]; + base_addr = entries[i]; + + HDassert( base_addr ); + + for ( j = 0; j <= max_index; j++ ) + { + if ( ( base_addr[j].header.is_dirty ) || ( base_addr[j].is_dirty ) ) { + + dirty_count++; + } + } + } + + if ( dirty_count > 0 ) { + + pass = FALSE; + failure_mssg = "verify_clean() found dirty entry(s)."; + } + } + + return; + +} /* verify_clean() */ + + +/*------------------------------------------------------------------------- + * Function: verify_unprotected + * + * Purpose: Verify that no cache entries are marked as protected. If + * any are, set pass to FALSE. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +verify_unprotected(void) + +{ + int i; + int j; + int protected_count = 0; + int32_t max_index; + test_entry_t * base_addr; + + if ( pass ) { + + for ( i = 0; i < NUMBER_OF_ENTRY_TYPES; i++ ) + { + max_index = max_indices[i]; + base_addr = entries[i]; + + HDassert( base_addr ); + + for ( j = 0; j <= max_index; j++ ) + { + HDassert( base_addr[j].header.is_protected == + base_addr[j].is_protected ); + + if ( ( base_addr[j].header.is_protected ) || + ( base_addr[j].is_protected ) ) { + + protected_count++; + } + } + } + + if ( protected_count > 0 ) { + + pass = FALSE; + failure_mssg = "verify_unprotected() found protected entry(s)."; + } + } + + return; + +} /* verify_unprotected() */ + + +/*------------------------------------------------------------------------- + * Function: setup_cache() + * + * Purpose: Allocate a cache of the desired size and configure it for + * use in the test bed. Return a pointer to the new cache + * structure. + * + * Return: Pointer to new cache, or NULL on failure. + * + * Programmer: John Mainzer + * 6/11/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +H5C_t * +setup_cache(size_t max_cache_size, + size_t min_clean_size) +{ + H5C_t * cache_ptr = NULL; + + cache_ptr = H5C_create(max_cache_size, + min_clean_size, + (NUMBER_OF_ENTRY_TYPES - 1), + (const char **)entry_type_names, + check_write_permitted, + TRUE, + NULL, + NULL); + + if ( cache_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5C_create() returned NULL."; + + } else { + + H5C_set_skip_flags(cache_ptr, TRUE, TRUE); + } + + return(cache_ptr); + +} /* setup_cache() */ + + +/*------------------------------------------------------------------------- + * Function: takedown_cache() + * + * Purpose: Flush the specified cache and disable it. If requested, + * dump stats first. If pass is FALSE, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/11/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +takedown_cache(H5C_t * cache_ptr, + hbool_t dump_stats, + hbool_t dump_detailed_stats) +{ + HDassert(cache_ptr); + + if ( pass ) { + + if ( dump_stats ) { + + H5C_stats(cache_ptr, "test cache", dump_detailed_stats); + } + + H5C_dest(NULL, -1, -1, cache_ptr); + } + + return; + +} /* takedown_cache() */ + + +/*------------------------------------------------------------------------- + * Function: flush_cache() + * + * Purpose: Flush the specified cache, destroying all entries if + requested. If requested, dump stats first. + * + * Return: void + * + * Programmer: John Mainzer + * 6/23/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +flush_cache(H5C_t * cache_ptr, + hbool_t destroy_entries, + hbool_t dump_stats, + hbool_t dump_detailed_stats) +{ + herr_t result = 0; + + HDassert(cache_ptr); + + verify_unprotected(); + + if ( pass ) { + + if ( destroy_entries ) { + + result = H5C_flush_cache(NULL, -1, -1, cache_ptr, + H5C__FLUSH_INVALIDATE_FLAG); + + } else { + + result = H5C_flush_cache(NULL, -1, -1, cache_ptr, + H5C__NO_FLAGS_SET); + } + } + + if ( dump_stats ) { + + H5C_stats(cache_ptr, "test cache", dump_detailed_stats); + } + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "error in H5C_flush_cache()."; + } + + return; + +} /* flush_cache() */ + + +/*------------------------------------------------------------------------- + * Function: insert_entry() + * + * Purpose: Insert the entry indicated by the type and index. Mark + * it clean or dirty as indicated. + * + * Note that I don't see much practical use for inserting + * a clean entry, but the interface permits it so we should + * test it. + * + * Do nothing if pass is false. + * + * Return: void + * + * Programmer: John Mainzer + * 6/16/04 + * + * Modifications: + * + * JRM -- 1/13/05 + * Updated function for the flags parameter in + * H5C_insert_entry(), and to allow access to this parameter. + * + * JRM -- 6/17/05 + * The interface no longer permits clean inserts. + * Accordingly, the dirty parameter is no longer meaningfull. + * + *------------------------------------------------------------------------- + */ + +void +insert_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t UNUSED dirty, + unsigned int flags) +{ + herr_t result; + 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] ) ); + + 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->is_protected) ); + + entry_ptr->is_dirty = TRUE; + + result = H5C_insert_entry(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, (void *)entry_ptr, flags); + + 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_insert()."; + +#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", + (int)(entry_ptr->header.is_protected)); + HDfprintf(stdout, "entry_ptr->header.type != &(types[type]) = %d\n", + (int)(entry_ptr->header.type != &(types[type]))); + HDfprintf(stdout, + "entry_ptr->size != entry_ptr->header.size = %d\n", + (int)(entry_ptr->size != entry_ptr->header.size)); + HDfprintf(stdout, + "entry_ptr->addr != entry_ptr->header.addr = %d\n", + (int)(entry_ptr->addr != entry_ptr->header.addr)); +#endif + } + + HDassert( entry_ptr->header.is_dirty ); + HDassert( ((entry_ptr->header).type)->id == type ); + } + + return; + +} /* insert_entry() */ + + +/*------------------------------------------------------------------------- + * Function: rename_entry() + * + * Purpose: Rename the entry indicated by the type and index to its + * main or alternate address as indicated. If the entry is + * already at the desired entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/21/04 + * + * Modifications: + * + * JRM -- 6/17/05 + * Updated code to reflect the fact that renames automatically + * dirty entries. + * + *------------------------------------------------------------------------- + */ + +void +rename_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t main_addr) +{ + herr_t result; + hbool_t done = TRUE; /* will set to FALSE if we have work to do */ + haddr_t old_addr = HADDR_UNDEF; + haddr_t new_addr = HADDR_UNDEF; + 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] ) ); + + 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->is_protected) ); + HDassert( !(entry_ptr->header.is_protected) ); + + if ( entry_ptr->at_main_addr && !main_addr ) { + + /* rename to alt addr */ + + HDassert( entry_ptr->addr == entry_ptr->main_addr ); + + done = FALSE; + old_addr = entry_ptr->addr; + new_addr = entry_ptr->alt_addr; + + } else if ( !(entry_ptr->at_main_addr) && main_addr ) { + + /* rename to main addr */ + + HDassert( entry_ptr->addr == entry_ptr->alt_addr ); + + done = FALSE; + old_addr = entry_ptr->addr; + new_addr = entry_ptr->main_addr; + } + + if ( ! done ) { + + entry_ptr->is_dirty = TRUE; + + result = H5C_rename_entry(cache_ptr, &(types[type]), + old_addr, new_addr); + } + + if ( ! done ) { + + if ( ( result < 0 ) || ( entry_ptr->header.addr != new_addr ) ) { + + pass = FALSE; + failure_mssg = "error in H5C_rename_entry()."; + + } else { + + entry_ptr->addr = new_addr; + entry_ptr->at_main_addr = main_addr; + } + } + + HDassert( ((entry_ptr->header).type)->id == type ); + + HDassert( entry_ptr->header.is_dirty ); + HDassert( entry_ptr->is_dirty ); + + return; + +} /* rename_entry() */ + + +/*------------------------------------------------------------------------- + * Function: protect_entry() + * + * Purpose: Protect the entry indicated by the type and index. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/11/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +protect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx) +{ + /* const char * fcn_name = "protect_entry()"; */ + test_entry_t * base_addr; + test_entry_t * entry_ptr; + H5C_cache_entry_t * cache_entry_ptr; + + if ( pass ) { + + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[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->is_protected) ); + + cache_entry_ptr = H5C_protect(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, NULL, NULL); + + if ( ( cache_entry_ptr != (void *)entry_ptr ) || + ( !(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 ) ) { + +#if 0 + /* I've written the following debugging code several times + * now. Lets keep it around so I don't have to write it + * again. + * - JRM + */ + HDfprintf(stdout, "( cache_entry_ptr != (void *)entry_ptr ) = %d\n", + (int)( cache_entry_ptr != (void *)entry_ptr )); + HDfprintf(stdout, "cache_entry_ptr = 0x%lx, entry_ptr = 0x%lx\n", + (long)cache_entry_ptr, (long)entry_ptr); + HDfprintf(stdout, "entry_ptr->header.is_protected = %d\n", + (int)(entry_ptr->header.is_protected)); + HDfprintf(stdout, + "( entry_ptr->header.type != &(types[type]) ) = %d\n", + (int)( entry_ptr->header.type != &(types[type]) )); + HDfprintf(stdout, + "entry_ptr->size = %d, entry_ptr->header.size = %d\n", + (int)(entry_ptr->size), (int)(entry_ptr->header.size)); + HDfprintf(stdout, + "entry_ptr->addr = %d, entry_ptr->header.addr = %d\n", + (int)(entry_ptr->addr), (int)(entry_ptr->header.addr)); +#endif + pass = FALSE; + failure_mssg = "error in H5C_protect()."; + + } else { + + entry_ptr->is_protected = TRUE; + + } + + HDassert( ((entry_ptr->header).type)->id == type ); + } + + return; + +} /* protect_entry() */ + + +/*------------------------------------------------------------------------- + * Function: unprotect_entry() + * + * Purpose: Unprotect the entry indicated by the type and index. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/12/04 + * + * Modifications: + * + * JRM -- 1/7/05 + * Updated for the replacement of the deleted parameter in + * H5C_unprotect() with the new flags parameter. + * + * JRM - 6/17/05 + * Modified function to use the new dirtied parameter of + * H5C_unprotect(). + * + * JRM -- 9/8/05 + * Update for new entry size parameter in H5C_unprotect(). + * We don't use them here for now. + * + *------------------------------------------------------------------------- + */ + +void +unprotect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + int dirty, + unsigned int flags) +{ + /* const char * fcn_name = "unprotect_entry()"; */ + herr_t result; + 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] ) ); + + 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->header.is_protected ); + HDassert( entry_ptr->is_protected ); + + if ( ( dirty == TRUE ) || ( dirty == FALSE ) ) { + + flags |= (dirty ? H5AC__DIRTIED_FLAG : H5AC__NO_FLAGS_SET); + entry_ptr->is_dirty = (entry_ptr->is_dirty || dirty); + } + + result = H5C_unprotect(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, (void *)entry_ptr, + flags, 0); + + 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; + } + + HDassert( ((entry_ptr->header).type)->id == type ); + + if ( ( flags & H5AC__DIRTIED_FLAG ) != 0 + && ( (flags & H5C__DELETED_FLAG) == 0 ) ) { + + HDassert( entry_ptr->header.is_dirty ); + HDassert( entry_ptr->is_dirty ); + } + } + + return; + +} /* unprotect_entry() */ + + +/*------------------------------------------------------------------------- + * Function: row_major_scan_forward() + * + * Purpose: Do a sequence of inserts, protects, unprotects, renames, + * destroys while scanning through the set of entries. If + * pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/12/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +row_major_scan_forward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + hbool_t do_renames, + hbool_t rename_to_main_addr, + hbool_t do_destroys, + int dirty_destroys, + int dirty_unprotects) +{ + const char * fcn_name = "row_major_scan_forward"; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s(): entering.\n", fcn_name); + + HDassert( lag > 5 ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + idx = -lag; + + while ( ( pass ) && ( idx <= (max_indices[type] + lag) ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) && + ( ((idx + lag) % 2) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( (idx + lag - 1) >= 0 ) && + ( (idx + lag - 1) <= max_indices[type] ) && + ( ( (idx + lag - 1) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx + lag - 1)); + + protect_entry(cache_ptr, type, (idx + lag - 1)); + } + + if ( ( pass ) && ( (idx + lag - 2) >= 0 ) && + ( (idx + lag - 2) <= max_indices[type] ) && + ( ( (idx + lag - 2) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag - 2)); + + unprotect_entry(cache_ptr, type, idx+lag-2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( do_renames ) && ( (idx + lag - 2) >= 0 ) && + ( (idx + lag - 2) <= max_indices[type] ) && + ( ( (idx + lag - 2) % 3 ) == 0 ) ) { + + rename_entry(cache_ptr, type, (idx + lag - 2), + rename_to_main_addr); + } + + + if ( ( pass ) && ( (idx + lag - 3) >= 0 ) && + ( (idx + lag - 3) <= max_indices[type] ) && + ( ( (idx + lag - 3) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx + lag - 3)); + + protect_entry(cache_ptr, type, (idx + lag - 3)); + } + + if ( ( pass ) && ( (idx + lag - 5) >= 0 ) && + ( (idx + lag - 5) <= max_indices[type] ) && + ( ( (idx + lag - 5) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag - 5)); + + unprotect_entry(cache_ptr, type, idx+lag-5, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + + if ( ( pass ) && ( (idx - lag + 2) >= 0 ) && + ( (idx - lag + 2) <= max_indices[type] ) && + ( ( (idx - lag + 2) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag + 2)); + + unprotect_entry(cache_ptr, type, idx-lag+2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( (idx - lag + 1) >= 0 ) && + ( (idx - lag + 1) <= max_indices[type] ) && + ( ( (idx - lag + 1) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx - lag + 1)); + + protect_entry(cache_ptr, type, (idx - lag + 1)); + } + + + if ( do_destroys ) { + + if ( ( pass ) && ( (idx - lag) >= 0 ) && + ( ( idx - lag) <= max_indices[type] ) ) { + + switch ( (idx - lag) %4 ) { + + case 0: /* we just did an insert */ + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + break; + + case 1: + if ( (entries[type])[idx-lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + } else { + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_unprotects, + H5C__NO_FLAGS_SET); + } + break; + + case 2: /* we just did an insrt */ + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__DELETED_FLAG); + break; + + case 3: + if ( (entries[type])[idx-lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__DELETED_FLAG); + } else { + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_destroys, + H5C__DELETED_FLAG); + } + break; + + default: + HDassert(0); /* this can't happen... */ + break; + } + } + + } else { + + if ( ( pass ) && ( (idx - lag) >= 0 ) && + ( ( idx - lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag)); + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx++; + } + type++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* row_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_row_major_scan_forward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning through the set of entries. + * If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 10/21/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_row_major_scan_forward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts) +{ + const char * fcn_name = "hl_row_major_scan_forward"; + int32_t type; + int32_t idx; + int32_t i; + int32_t lag = 100; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s(): entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 200 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + idx = -lag; + + local_max_index = MIN(max_index, max_indices[type]); + + while ( ( pass ) && ( idx <= (local_max_index + lag) ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) && + ( ((idx + lag) % 2) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + i = idx; + + while ( ( pass ) && ( i >= idx - lag ) && ( i >= 0 ) ) + { + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + i--; + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx++; + } + type++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_row_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: row_major_scan_backward() + * + * Purpose: Do a sequence of inserts, protects, unprotects, renames, + * destroys while scanning backwards through the set of + * entries. If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/12/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +row_major_scan_backward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + hbool_t do_renames, + hbool_t rename_to_main_addr, + hbool_t do_destroys, + int dirty_destroys, + int dirty_unprotects) +{ + const char * fcn_name = "row_major_scan_backward"; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s(): Entering.\n", fcn_name); + + HDassert( lag > 5 ); + + type = NUMBER_OF_ENTRY_TYPES - 1; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type >= 0 ) ) + { + idx = max_indices[type] + lag; + + while ( ( pass ) && ( idx >= -lag ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx - lag) >= 0 ) && + ( (idx - lag) <= max_indices[type] ) && + ( ((idx - lag) % 2) == 1 ) && + ( ! entry_in_cache(cache_ptr, type, (idx - lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx - lag)); + + insert_entry(cache_ptr, type, (idx - lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( (idx - lag + 1) >= 0 ) && + ( (idx - lag + 1) <= max_indices[type] ) && + ( ( (idx - lag + 1) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx - lag + 1)); + + protect_entry(cache_ptr, type, (idx - lag + 1)); + } + + if ( ( pass ) && ( (idx - lag + 2) >= 0 ) && + ( (idx - lag + 2) <= max_indices[type] ) && + ( ( (idx - lag + 2) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag + 2)); + + unprotect_entry(cache_ptr, type, idx-lag+2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( do_renames ) && ( (idx - lag + 2) >= 0 ) && + ( (idx - lag + 2) <= max_indices[type] ) && + ( ( (idx - lag + 2) % 3 ) == 0 ) ) { + + rename_entry(cache_ptr, type, (idx - lag + 2), + rename_to_main_addr); + } + + + if ( ( pass ) && ( (idx - lag + 3) >= 0 ) && + ( (idx - lag + 3) <= max_indices[type] ) && + ( ( (idx - lag + 3) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx - lag + 3)); + + protect_entry(cache_ptr, type, (idx - lag + 3)); + } + + if ( ( pass ) && ( (idx - lag + 5) >= 0 ) && + ( (idx - lag + 5) <= max_indices[type] ) && + ( ( (idx - lag + 5) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag + 5)); + + unprotect_entry(cache_ptr, type, idx-lag+5, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + + if ( ( pass ) && ( (idx + lag - 2) >= 0 ) && + ( (idx + lag - 2) <= max_indices[type] ) && + ( ( (idx + lag - 2) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag - 2)); + + unprotect_entry(cache_ptr, type, idx+lag-2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( (idx + lag - 1) >= 0 ) && + ( (idx + lag - 1) <= max_indices[type] ) && + ( ( (idx + lag - 1) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx + lag - 1)); + + protect_entry(cache_ptr, type, (idx + lag - 1)); + } + + + if ( do_destroys ) { + + if ( ( pass ) && ( (idx + lag) >= 0 ) && + ( ( idx + lag) <= max_indices[type] ) ) { + + switch ( (idx + lag) %4 ) { + + case 0: + if ( (entries[type])[idx+lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + } else { + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_unprotects, + H5C__NO_FLAGS_SET); + } + break; + + case 1: /* we just did an insert */ + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + break; + + case 2: + if ( (entries[type])[idx + lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__DELETED_FLAG); + } else { + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_destroys, + H5C__DELETED_FLAG); + } + break; + + case 3: /* we just did an insrt */ + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__DELETED_FLAG); + break; + + default: + HDassert(0); /* this can't happen... */ + break; + } + } + } else { + + if ( ( pass ) && ( (idx + lag) >= 0 ) && + ( ( idx + lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag)); + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx--; + } + type--; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* row_major_scan_backward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_row_major_scan_backward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning through the set of entries. + * If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 10/21/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_row_major_scan_backward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts) +{ + const char * fcn_name = "hl_row_major_scan_backward"; + int32_t type; + int32_t idx; + int32_t i; + int32_t lag = 100; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s(): entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 200 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = NUMBER_OF_ENTRY_TYPES - 1; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type >= 0 ) ) + { + idx = max_indices[type] + lag; + + local_max_index = MIN(max_index, max_indices[type]); + + while ( ( pass ) && ( idx >= -lag ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= local_max_index ) && + ( ((idx + lag) % 2) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + i = idx; + + while ( ( pass ) && ( i >= idx - lag ) && ( i >= 0 ) ) + { + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + i--; + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx--; + } + type--; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_row_major_scan_backward() */ + + +/*------------------------------------------------------------------------- + * Function: col_major_scan_forward() + * + * Purpose: Do a sequence of inserts, protects, and unprotects + * while scanning through the set of entries. If + * pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/23/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +col_major_scan_forward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "col_major_scan_forward()"; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = -lag; + + while ( ( pass ) && ( (idx - lag) <= MAX_ENTRIES ) ) + { + type = 0; + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) && + ( ((idx + lag) % 3) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + if ( ( pass ) && ( (idx - lag) >= 0 ) && + ( (idx - lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag)); + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type++; + } + + idx++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* col_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_col_major_scan_forward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning through the set of entries. If + * pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 19/25/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_col_major_scan_forward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "hl_col_major_scan_forward()"; + int32_t type; + int32_t idx; + int32_t lag = 200; + int32_t i; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 500 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = 0; + + local_max_index = MIN(max_index, MAX_ENTRIES); + + while ( ( pass ) && ( idx <= local_max_index ) ) + { + + i = idx; + + while ( ( pass ) && ( i >= 0 ) && ( i >= (idx - lag) ) ) { + + type = 0; + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + if ( ( pass ) && ( do_inserts ) && ( i == idx ) && + ( i <= local_max_index ) && + ( (i % 3) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, i) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, i); + + insert_entry(cache_ptr, type, i, dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + } + + if ( ( pass ) && ( i >= 0 ) && + ( i <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type++; + } + + i--; + } + + idx++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_col_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: col_major_scan_backward() + * + * Purpose: Do a sequence of inserts, protects, and unprotects + * while scanning backwards through the set of + * entries. If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/23/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +col_major_scan_backward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "col_major_scan_backward()"; + int mile_stone = 1; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = MAX_ENTRIES + lag; + + if ( verbose ) /* 1 */ + HDfprintf(stdout, "%s: point %d.\n", fcn_name, mile_stone++); + + + while ( ( pass ) && ( (idx + lag) >= 0 ) ) + { + type = NUMBER_OF_ENTRY_TYPES - 1; + + while ( ( pass ) && ( type >= 0 ) ) + { + if ( ( pass ) && ( do_inserts) && ( (idx - lag) >= 0 ) && + ( (idx - lag) <= max_indices[type] ) && + ( ((idx - lag) % 3) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx - lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx - lag)); + + insert_entry(cache_ptr, type, (idx - lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + if ( ( pass ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag)); + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type--; + } + + idx--; + } + + if ( verbose ) /* 2 */ + HDfprintf(stdout, "%s: point %d.\n", fcn_name, mile_stone++); + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + if ( verbose ) + HDfprintf(stdout, "%s: exiting.\n", fcn_name); + + return; + +} /* col_major_scan_backward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_col_major_scan_backward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning backwards through the set of + * entries. If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 10/25/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_col_major_scan_backward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "hl_col_major_scan_backward()"; + int32_t type; + int32_t idx; + int32_t lag = 50; + int32_t i; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 500 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = 0; + + local_max_index = MIN(max_index, MAX_ENTRIES); + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = local_max_index; + + while ( ( pass ) && ( idx >= 0 ) ) + { + + i = idx; + + while ( ( pass ) && ( i <= local_max_index ) && ( i <= (idx + lag) ) ) { + + type = 0; + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + if ( ( pass ) && ( do_inserts ) && ( i == idx ) && + ( i <= local_max_index ) && + ( ! entry_in_cache(cache_ptr, type, i) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, i); + + insert_entry(cache_ptr, type, i, dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + } + + if ( ( pass ) && ( i >= 0 ) && + ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type++; + } + + i++; + } + + idx--; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_col_major_scan_backward() */ + |