diff options
author | cvs2svn <no_author@cvs2svn> | 2004-10-01 23:00:55 (GMT) |
---|---|---|
committer | cvs2svn <no_author@cvs2svn> | 2004-10-01 23:00:55 (GMT) |
commit | d5d34def1ca98fdacc9b31d992a865f07104d379 (patch) | |
tree | 2b96c01730364fa3fb82ad7168dc46c3fc5bf77e /test | |
parent | 709ffbd151ddf363b5c3ea59aa222c3b67075ce0 (diff) | |
download | hdf5-d5d34def1ca98fdacc9b31d992a865f07104d379.zip hdf5-d5d34def1ca98fdacc9b31d992a865f07104d379.tar.gz hdf5-d5d34def1ca98fdacc9b31d992a865f07104d379.tar.bz2 |
[svn-r9355] This commit was manufactured by cvs2svn to create branch 'hdf5_1_6'.
Diffstat (limited to 'test')
-rw-r--r-- | test/cache.c | 4160 |
1 files changed, 4160 insertions, 0 deletions
diff --git a/test/cache.c b/test/cache.c new file mode 100644 index 0000000..bdd27d1 --- /dev/null +++ b/test/cache.c @@ -0,0 +1,4160 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 + * 6/9/04 + * + * This file contains tests for the cache implemented in + * H5C.c + */ +#include "h5test.h" +#include "H5Iprivate.h" + +const char *FILENAME[] = { + "cache", + NULL +}; + +#include "H5TBprivate.h" +#include "H5Cprivate.h" + +/* with apologies for the abuse of terminology... */ + +#define PICO_ENTRY_TYPE 0 +#define NANO_ENTRY_TYPE 1 +#define MICRO_ENTRY_TYPE 2 +#define TINY_ENTRY_TYPE 3 +#define SMALL_ENTRY_TYPE 4 +#define MEDIUM_ENTRY_TYPE 5 +#define LARGE_ENTRY_TYPE 6 +#define HUGE_ENTRY_TYPE 7 +#define MONSTER_ENTRY_TYPE 8 + +#define NUMBER_OF_ENTRY_TYPES 9 + +#define PICO_ENTRY_SIZE (size_t)1 +#define NANO_ENTRY_SIZE (size_t)4 +#define MICRO_ENTRY_SIZE (size_t)16 +#define TINY_ENTRY_SIZE (size_t)64 +#define SMALL_ENTRY_SIZE (size_t)256 +#define MEDIUM_ENTRY_SIZE (size_t)1024 +#define LARGE_ENTRY_SIZE (size_t)(4 * 1024) +#define HUGE_ENTRY_SIZE (size_t)(16 * 1024) +#define MONSTER_ENTRY_SIZE (size_t)(64 * 1024) + +#define NUM_PICO_ENTRIES (10 * 1024) +#define NUM_NANO_ENTRIES (10 * 1024) +#define NUM_MICRO_ENTRIES (10 * 1024) +#define NUM_TINY_ENTRIES (10 * 1024) +#define NUM_SMALL_ENTRIES (10 * 1024) +#define NUM_MEDIUM_ENTRIES (10 * 1024) +#define NUM_LARGE_ENTRIES (10 * 1024) +#define NUM_HUGE_ENTRIES (10 * 1024) +#define NUM_MONSTER_ENTRIES (10 * 1024) + +#define MAX_ENTRIES (10 * 1024) + +#define PICO_BASE_ADDR (haddr_t)0 +#define NANO_BASE_ADDR (haddr_t)(PICO_BASE_ADDR + \ + (PICO_ENTRY_SIZE * NUM_PICO_ENTRIES)) +#define MICRO_BASE_ADDR (haddr_t)(NANO_BASE_ADDR + \ + (NANO_ENTRY_SIZE * NUM_NANO_ENTRIES)) +#define TINY_BASE_ADDR (haddr_t)(MICRO_BASE_ADDR + \ + (MICRO_ENTRY_SIZE * NUM_MICRO_ENTRIES)) +#define SMALL_BASE_ADDR (haddr_t)(TINY_BASE_ADDR + \ + (TINY_ENTRY_SIZE * NUM_TINY_ENTRIES)) +#define MEDIUM_BASE_ADDR (haddr_t)(SMALL_BASE_ADDR + \ + (SMALL_ENTRY_SIZE * NUM_SMALL_ENTRIES)) +#define LARGE_BASE_ADDR (haddr_t)(MEDIUM_BASE_ADDR + \ + (MEDIUM_ENTRY_SIZE * NUM_MEDIUM_ENTRIES)) +#define HUGE_BASE_ADDR (haddr_t)(LARGE_BASE_ADDR + \ + (LARGE_ENTRY_SIZE * NUM_LARGE_ENTRIES)) +#define MONSTER_BASE_ADDR (haddr_t)(HUGE_BASE_ADDR + \ + (HUGE_ENTRY_SIZE * NUM_HUGE_ENTRIES)) + +#define PICO_ALT_BASE_ADDR (haddr_t)(MONSTER_BASE_ADDR + \ + (MONSTER_ENTRY_SIZE * NUM_MONSTER_ENTRIES)) +#define NANO_ALT_BASE_ADDR (haddr_t)(PICO_ALT_BASE_ADDR + \ + (PICO_ENTRY_SIZE * NUM_PICO_ENTRIES)) +#define MICRO_ALT_BASE_ADDR (haddr_t)(NANO_ALT_BASE_ADDR + \ + (NANO_ENTRY_SIZE * NUM_NANO_ENTRIES)) +#define TINY_ALT_BASE_ADDR (haddr_t)(MICRO_ALT_BASE_ADDR + \ + (MICRO_ENTRY_SIZE * NUM_MICRO_ENTRIES)) +#define SMALL_ALT_BASE_ADDR (haddr_t)(TINY_ALT_BASE_ADDR + \ + (TINY_ENTRY_SIZE * NUM_TINY_ENTRIES)) +#define MEDIUM_ALT_BASE_ADDR (haddr_t)(SMALL_ALT_BASE_ADDR + \ + (SMALL_ENTRY_SIZE * NUM_SMALL_ENTRIES)) +#define LARGE_ALT_BASE_ADDR (haddr_t)(MEDIUM_ALT_BASE_ADDR + \ + (MEDIUM_ENTRY_SIZE * NUM_MEDIUM_ENTRIES)) +#define HUGE_ALT_BASE_ADDR (haddr_t)(LARGE_ALT_BASE_ADDR + \ + (LARGE_ENTRY_SIZE * NUM_LARGE_ENTRIES)) +#define MONSTER_ALT_BASE_ADDR (haddr_t)(HUGE_ALT_BASE_ADDR + \ + (HUGE_ENTRY_SIZE * NUM_HUGE_ENTRIES)) + +typedef struct test_entry_t +{ + H5C_cache_entry_t header; /* entry data used by the cache + * -- must be first + */ + struct test_entry_t * self; /* pointer to this entry -- used for + * sanity checking. + */ + haddr_t addr; /* where the cache thinks this entry + * is located + */ + hbool_t at_main_addr; /* boolean flag indicating whether + * the entry is supposed to be at + * either its main or alternate + * address. + */ + haddr_t main_addr; /* initial location of the entry + */ + haddr_t alt_addr; /* location to which the entry + * can be relocated or "renamed" + */ + size_t size; /* how big the cache thinks this + * entry is + */ + int32_t type; /* indicates which entry array this + * entry is in + */ + int32_t index; /* index in its entry array + */ + int32_t reads; /* number of times this entry has + * been loaded. + */ + int32_t writes; /* number of times this entry has + * been written + */ + hbool_t is_dirty; /* entry has been modified since + * last write + */ + hbool_t is_protected; /* entry should currently be on + * the cache's protected list. + */ +} test_entry_t; + +/* The following is a cut down copy of the hash table manipulation + * macros from H5C.c, which have been further modified to avoid references + * to the error reporting macros. Needless to say, these macros must be + * updated as necessary. + */ + +#define H5C__HASH_TABLE_LEN (32 * 1024) /* must be a power of 2 */ +#define H5C__HASH_MASK ((size_t)(H5C__HASH_TABLE_LEN - 1) << 3) +#define H5C__HASH_FCN(x) (int)(((x) & H5C__HASH_MASK) >> 3) + +#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( ! H5F_addr_defined(Addr) ) || \ + ( H5C__HASH_FCN(Addr) < 0 ) || \ + ( H5C__HASH_FCN(Addr) >= H5C__HASH_TABLE_LEN ) ) { \ + HDfprintf(stdout, "Pre HT search SC failed.\n"); \ +} + +#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len < 1 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( H5F_addr_ne((entry_ptr)->addr, (Addr)) ) || \ + ( (entry_ptr)->size <= 0 ) || \ + ( ((cache_ptr)->index)[k] == NULL ) || \ + ( ( ((cache_ptr)->index)[k] != (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev == NULL ) ) || \ + ( ( ((cache_ptr)->index)[k] == (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev != NULL ) ) || \ + ( ( (entry_ptr)->ht_prev != NULL ) && \ + ( (entry_ptr)->ht_prev->ht_next != (entry_ptr) ) ) || \ + ( ( (entry_ptr)->ht_next != NULL ) && \ + ( (entry_ptr)->ht_next->ht_prev != (entry_ptr) ) ) ) { \ + HDfprintf(stdout, "Post successful HT search SC failed.\n"); \ +} + + +#define H5C__SEARCH_INDEX(cache_ptr, Addr, entry_ptr) \ +{ \ + int k; \ + int depth = 0; \ + H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr) \ + k = H5C__HASH_FCN(Addr); \ + entry_ptr = ((cache_ptr)->index)[k]; \ + while ( ( entry_ptr ) && ( H5F_addr_ne(Addr, (entry_ptr)->addr) ) ) \ + { \ + (entry_ptr) = (entry_ptr)->ht_next; \ + (depth)++; \ + } \ + if ( entry_ptr ) \ + { \ + H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k) \ + if ( entry_ptr != ((cache_ptr)->index)[k] ) \ + { \ + if ( (entry_ptr)->ht_next ) \ + { \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ + } \ + HDassert( (entry_ptr)->ht_prev != NULL ); \ + (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ + ((cache_ptr)->index)[k]->ht_prev = (entry_ptr); \ + (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ + (entry_ptr)->ht_prev = NULL; \ + ((cache_ptr)->index)[k] = (entry_ptr); \ + } \ + } \ +} + + +/* The following is a local copy of the H5C_t structure -- any changes in + * that structure must be reproduced here. The typedef is used to allow + * local access to the cache's private data. + */ + +#define H5C__H5C_T_MAGIC 0x005CAC0E +#define H5C__MAX_NUM_TYPE_IDS 9 + +typedef struct local_H5C_t +{ + uint32_t magic; + + int32_t max_type_id; + const char * (* type_name_table_ptr); + + size_t max_cache_size; + size_t min_clean_size; + + H5C_write_permitted_func_t check_write_permitted; + + int32_t index_len; + size_t index_size; + H5C_cache_entry_t * (index[H5C__HASH_TABLE_LEN]); + + + int32_t tree_len; + size_t tree_size; + H5TB_TREE * tree_ptr; + + int32_t pl_len; + size_t pl_size; + H5C_cache_entry_t * pl_head_ptr; + H5C_cache_entry_t * pl_tail_ptr; + + int32_t LRU_list_len; + size_t LRU_list_size; + H5C_cache_entry_t * LRU_head_ptr; + H5C_cache_entry_t * LRU_tail_ptr; + + int32_t cLRU_list_len; + size_t cLRU_list_size; + H5C_cache_entry_t * cLRU_head_ptr; + H5C_cache_entry_t * cLRU_tail_ptr; + + int32_t dLRU_list_len; + size_t dLRU_list_size; + H5C_cache_entry_t * dLRU_head_ptr; + H5C_cache_entry_t * dLRU_tail_ptr; + +#if H5C_COLLECT_CACHE_STATS + + /* stats fields */ + int64_t hits[H5C__MAX_NUM_TYPE_IDS]; + int64_t misses[H5C__MAX_NUM_TYPE_IDS]; + int64_t insertions[H5C__MAX_NUM_TYPE_IDS]; + int64_t clears[H5C__MAX_NUM_TYPE_IDS]; + int64_t flushes[H5C__MAX_NUM_TYPE_IDS]; + int64_t evictions[H5C__MAX_NUM_TYPE_IDS]; + int64_t renames[H5C__MAX_NUM_TYPE_IDS]; + + int64_t total_ht_insertions; + int64_t total_ht_deletions; + int64_t successful_ht_searches; + int64_t total_successful_ht_search_depth; + int64_t failed_ht_searches; + int64_t total_failed_ht_search_depth; + + int32_t max_index_len; + size_t max_index_size; + + int32_t max_tree_len; + size_t max_tree_size; + + int32_t max_pl_len; + size_t max_pl_size; + +#if H5C_COLLECT_CACHE_ENTRY_STATS + + int32_t max_accesses[H5C__MAX_NUM_TYPE_IDS]; + int32_t min_accesses[H5C__MAX_NUM_TYPE_IDS]; + int32_t max_clears[H5C__MAX_NUM_TYPE_IDS]; + int32_t max_flushes[H5C__MAX_NUM_TYPE_IDS]; + size_t max_size[H5C__MAX_NUM_TYPE_IDS]; + +#endif /* H5C_COLLECT_CACHE_ENTRY_STATS */ + +#endif /* H5C_COLLECT_CACHE_STATS */ + + hbool_t skip_file_checks; + hbool_t skip_dxpl_id_checks; + +} local_H5C_t; + + +/* global variable declarations: */ + +static hbool_t write_permitted = TRUE; +static hbool_t pass = TRUE; /* set to false on error */ +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" +}; + + +/* call back function declarations: */ + +static herr_t check_write_permitted(H5F_t UNUSED * f, + hid_t UNUSED dxpl_id, + hbool_t * write_permitted_ptr); + +static herr_t clear(H5F_t * f, void * thing, hbool_t dest); + +herr_t pico_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t nano_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t micro_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t tiny_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t small_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t medium_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t large_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t huge_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t monster_clear(H5F_t * f, void * thing, hbool_t dest); + + +static herr_t destroy(H5F_t UNUSED * f, void * thing); + +herr_t pico_dest(H5F_t * f, void * thing); +herr_t nano_dest(H5F_t * f, void * thing); +herr_t micro_dest(H5F_t * f, void * thing); +herr_t tiny_dest(H5F_t * f, void * thing); +herr_t small_dest(H5F_t * f, void * thing); +herr_t medium_dest(H5F_t * f, void * thing); +herr_t large_dest(H5F_t * f, void * thing); +herr_t huge_dest(H5F_t * f, void * thing); +herr_t monster_dest(H5F_t * f, void * thing); + + +static herr_t flush(H5F_t *f, hid_t UNUSED 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); +herr_t nano_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t micro_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t tiny_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t small_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t medium_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t large_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t huge_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t monster_flush(H5F_t *f, hid_t 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); + +void * pico_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * nano_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * micro_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * tiny_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * small_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * medium_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * large_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * huge_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * monster_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); + + +static herr_t size(H5F_t UNUSED * f, void * thing, size_t * size_ptr); + +herr_t pico_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t nano_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t micro_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t tiny_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t small_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t medium_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t large_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t huge_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t monster_size(H5F_t * f, void * thing, size_t * size_ptr); + + +/* callback table declaration */ + +static 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 + } +}; + + +/* private function declarations: */ + +static void addr_to_type_and_index(haddr_t addr, + int32_t * type_ptr, + int32_t * index_ptr); + +#if 0 /* keep this for a while -- it may be useful */ +static haddr_t type_and_index_to_addr(int32_t type, + int32_t idx); +#endif + +static void insert_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t dirty); + +static void rename_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t main_addr); + +static void protect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx); + +hbool_t entry_in_cache(H5C_t * cache_ptr, + int32_t type, + int32_t idx); + +static void reset_entries(void); + +static H5C_t * setup_cache(size_t max_cache_size, size_t min_clean_size); + +static 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); + +static 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); + +static 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); + +static 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); + +static void smoke_check_1(void); +static void smoke_check_2(void); +static void smoke_check_3(void); +static void smoke_check_4(void); +static void write_permitted_check(void); +static void check_flush_protected_err(void); +static void check_destroy_protected_err(void); +static void check_duplicate_insert_err(void); +static void check_rename_err(void); +static void check_double_protect_err(void); +static void check_double_unprotect_err(void); + +static void takedown_cache(H5C_t * cache_ptr, + hbool_t dump_stats, + hbool_t dump_detailed_stats); + +static void flush_cache(H5C_t * cache_ptr, + hbool_t destroy_entries, + hbool_t dump_stats, + hbool_t dump_detailed_stats); + +static void unprotect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + int dirty, + hbool_t deleted); + +static void verify_clean(void); + +static void verify_unprotected(void); + + + +/* 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: + * + *------------------------------------------------------------------------- + */ +static 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: + * + *------------------------------------------------------------------------- + */ +static 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: + * + *------------------------------------------------------------------------- + */ + +static herr_t +check_write_permitted(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: + * + *------------------------------------------------------------------------- + */ + +static 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; + + 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: + * + *------------------------------------------------------------------------- + */ + +static 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) ); + + 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: + * + *------------------------------------------------------------------------- + */ + +static 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] ); + + 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: + * + *------------------------------------------------------------------------- + */ + +static 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->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: + * + *------------------------------------------------------------------------- + */ + +static 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: + * + *------------------------------------------------------------------------- + */ + +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(((local_H5C_t *)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: + * + *------------------------------------------------------------------------- + */ + +static 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; + + 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: + * + *------------------------------------------------------------------------- + */ + +static 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: + * + *------------------------------------------------------------------------- + */ + +static 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: + * + *------------------------------------------------------------------------- + */ + +static 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); + + 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: + * + *------------------------------------------------------------------------- + */ + +static 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: + * + *------------------------------------------------------------------------- + */ + +static 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, + H5F_FLUSH_INVALIDATE); + + } else { + + result = H5C_flush_cache(NULL, -1, -1, cache_ptr, 0); + } + } + + 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: + * + *------------------------------------------------------------------------- + */ + +static void +insert_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t dirty) +{ + 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) ); + + if ( dirty ) { + + (entry_ptr->header).is_dirty = dirty; + entry_ptr->is_dirty = dirty; + } + + result = H5C_insert_entry(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, (void *)entry_ptr); + + 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()."; + } + + 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: + * + *------------------------------------------------------------------------- + */ + +static 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 ) { + + result = H5C_rename_entry(NULL, 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 ); + + return; + +} /* insert_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: + * + *------------------------------------------------------------------------- + */ + +static 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 ) ) { + + 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: + * + *------------------------------------------------------------------------- + */ + +#define NO_CHANGE -1 + +static void +unprotect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + int dirty, + hbool_t deleted) +{ + /* 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 ) ) { + + entry_ptr->header.is_dirty = dirty; + entry_ptr->is_dirty = dirty; + } + + result = H5C_unprotect(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, (void *)entry_ptr, deleted); + + 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 ); + } + + 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: + * + *------------------------------------------------------------------------- + */ + +static 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); + } + + + 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, FALSE); + } + + + 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, FALSE); + } + + 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, FALSE); + } + + 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, FALSE); + break; + + case 1: + if ( (entries[type])[idx-lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, FALSE); + } else { + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_unprotects, FALSE); + } + break; + + case 2: /* we just did an insrt */ + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, TRUE); + break; + + case 3: + if ( (entries[type])[idx-lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, TRUE); + } else { + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_destroys, TRUE); + } + 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, FALSE); + } + } + + 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: 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: + * + *------------------------------------------------------------------------- + */ + +static 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); + } + + + 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, FALSE); + } + + + 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, FALSE); + } + + 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, FALSE); + } + + 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, FALSE); + } else { + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_unprotects, FALSE); + } + break; + + case 1: /* we just did an insert */ + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, FALSE); + break; + + case 2: + if ( (entries[type])[idx + lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, TRUE); + } else { + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_destroys, TRUE); + } + break; + + case 3: /* we just did an insrt */ + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, TRUE); + 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, FALSE); + } + } + + 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: 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: + * + *------------------------------------------------------------------------- + */ + +static 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); + } + + 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, FALSE); + } + + 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: 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: + * + *------------------------------------------------------------------------- + */ + +static 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); + } + + 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, FALSE); + } + + 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() */ + + +/**************************************************************************/ +/**************************************************************************/ +/********************************* tests: *********************************/ +/**************************************************************************/ +/**************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: smoke_check_1() + * + * Purpose: A basic functional test, inserts, destroys, and renames in + * the mix, along with repeated protects and unprotects. + * All entries are marked as clean. + * + * Return: void + * + * Programmer: John Mainzer + * 6/16/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +smoke_check_1(void) +{ + const char * fcn_name = "smoke_check_1"; + hbool_t show_progress = FALSE; + hbool_t dirty_inserts = FALSE; + int dirty_unprotects = FALSE; + int dirty_destroys = FALSE; + hbool_t display_stats = FALSE; + int32_t lag = 10; + int mile_stone = 1; + H5C_t * cache_ptr = NULL; + + TESTING("smoke check #1 -- all clean, ins, dest, ren, 4/2 MB cache"); + + pass = TRUE; + + if ( show_progress ) /* 1 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + reset_entries(); + + if ( show_progress ) /* 2 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + cache_ptr = setup_cache((size_t)(4 * 1024 * 1024), + (size_t)(2 * 1024 * 1024)); + + if ( show_progress ) /* 3 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ TRUE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 4 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ FALSE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ TRUE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 5 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 6 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush and destroy all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ TRUE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 7 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 8 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ FALSE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 9 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 10 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + takedown_cache(cache_ptr, display_stats, TRUE); + + if ( show_progress ) /* 11 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + verify_clean(); + verify_unprotected(); + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* smoke_check_1() */ + + +/*------------------------------------------------------------------------- + * Function: smoke_check_2() + * + * Purpose: A basic functional test, with inserts, destroys, and + * renames in the mix, along with some repeated protects + * and unprotects. About half the entries are marked as + * dirty. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +smoke_check_2(void) +{ + const char * fcn_name = "smoke_check_2"; + hbool_t show_progress = FALSE; + hbool_t dirty_inserts = TRUE; + int dirty_unprotects = TRUE; + int dirty_destroys = TRUE; + hbool_t display_stats = FALSE; + int32_t lag = 10; + int mile_stone = 1; + H5C_t * cache_ptr = NULL; + + TESTING("smoke check #2 -- ~1/2 dirty, ins, dest, ren, 4/2 MB cache"); + + pass = TRUE; + + if ( show_progress ) /* 1 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + reset_entries(); + + if ( show_progress ) /* 2 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + cache_ptr = setup_cache((size_t)(4 * 1024 * 1024), + (size_t)(2 * 1024 * 1024)); + + if ( show_progress ) /* 3 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ TRUE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 4 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ FALSE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ TRUE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 5 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 6 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush and destroy all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ TRUE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 7 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 8 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ FALSE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 9 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 10 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + takedown_cache(cache_ptr, display_stats, TRUE); + + if ( show_progress ) /* 11 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + verify_clean(); + verify_unprotected(); + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* smoke_check_2() */ + + +/*------------------------------------------------------------------------- + * Function: smoke_check_3() + * + * Purpose: A basic functional test on a tiny cache, with inserts, + * destroys, and renames in the mix, along with repeated + * protects and unprotects. All entries are marked as clean. + * + * Return: void + * + * Programmer: John Mainzer + * 6/16/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +smoke_check_3(void) +{ + const char * fcn_name = "smoke_check_3"; + hbool_t show_progress = FALSE; + hbool_t dirty_inserts = FALSE; + int dirty_unprotects = FALSE; + int dirty_destroys = FALSE; + hbool_t display_stats = FALSE; + int32_t lag = 10; + int mile_stone = 1; + H5C_t * cache_ptr = NULL; + + TESTING("smoke check #3 -- all clean, ins, dest, ren, 2/1 KB cache"); + + pass = TRUE; + + if ( show_progress ) /* 1 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + reset_entries(); + + if ( show_progress ) /* 2 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + if ( show_progress ) /* 3 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ TRUE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 4 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ FALSE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ TRUE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 5 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 6 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush and destroy all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ TRUE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 7 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 8 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ FALSE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 9 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 10 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + takedown_cache(cache_ptr, display_stats, TRUE); + + if ( show_progress ) /* 11 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + verify_clean(); + verify_unprotected(); + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* smoke_check_3() */ + + +/*------------------------------------------------------------------------- + * Function: smoke_check_4() + * + * Purpose: A basic functional test on a tiny cache, with inserts, + * destroys, and renames in the mix, along with repeated + * protects and unprotects. About half the entries are + * marked as dirty. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +smoke_check_4(void) +{ + const char * fcn_name = "smoke_check_4"; + hbool_t show_progress = FALSE; + hbool_t dirty_inserts = TRUE; + int dirty_unprotects = TRUE; + int dirty_destroys = TRUE; + hbool_t display_stats = FALSE; + int32_t lag = 10; + int mile_stone = 1; + H5C_t * cache_ptr = NULL; + + TESTING("smoke check #4 -- ~1/2 dirty, ins, dest, ren, 2/1 KB cache"); + + pass = TRUE; + + if ( show_progress ) /* 1 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + reset_entries(); + + if ( show_progress ) /* 2 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + if ( show_progress ) /* 3 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ TRUE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 4 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ FALSE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ TRUE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 5 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ FALSE, + /* dirty_destroys */ dirty_destroys, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 6 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush and destroy all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ TRUE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 7 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 8 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ FALSE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 9 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ dirty_inserts, + /* dirty_unprotects */ dirty_unprotects); + + if ( show_progress ) /* 10 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + takedown_cache(cache_ptr, display_stats, TRUE); + + if ( show_progress ) /* 11 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + verify_clean(); + verify_unprotected(); + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* smoke_check_4() */ + + +/*------------------------------------------------------------------------- + * Function: write_permitted_check() + * + * Purpose: A basic test of the write permitted function. In essence, + * we load the cache up with dirty entryies, set + * write_permitted to FALSE, and then protect a bunch of + * entries. If there are any writes while write_permitted is + * FALSE, the test will fail. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +write_permitted_check(void) +{ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + + const char * fcn_name = "write_permitted_check"; + hbool_t show_progress = FALSE; + hbool_t display_stats = FALSE; + int32_t lag = 10; + int mile_stone = 1; + H5C_t * cache_ptr = NULL; + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + TESTING("write permitted check -- 1/0 MB cache"); + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + + pass = TRUE; + + if ( show_progress ) /* 1 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + reset_entries(); + + if ( show_progress ) /* 2 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + cache_ptr = setup_cache((size_t)(1 * 1024 * 1024), + (size_t)(0)); + + if ( show_progress ) /* 3 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ TRUE, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ TRUE, + /* dirty_destroys */ TRUE, + /* dirty_unprotects */ TRUE); + + if ( show_progress ) /* 4 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + write_permitted = FALSE; + + row_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ FALSE, + /* dirty_inserts */ FALSE, + /* do_renames */ TRUE, + /* rename_to_main_addr */ TRUE, + /* do_destroys */ FALSE, + /* dirty_destroys */ FALSE, + /* dirty_unprotects */ NO_CHANGE); + + if ( show_progress ) /* 5 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + write_permitted = TRUE; + + row_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ TRUE, + /* do_renames */ TRUE, + /* rename_to_main_addr */ FALSE, + /* do_destroys */ FALSE, + /* dirty_destroys */ TRUE, + /* dirty_unprotects */ TRUE); + + if ( show_progress ) /* 6 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + /* flush and destroy all entries in the cache: */ + + flush_cache(/* cache_ptr */ cache_ptr, + /* destroy_entries */ TRUE, + /* dump_stats */ FALSE, + /* dump_detailed_stats */ FALSE); + + if ( show_progress ) /* 7 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + col_major_scan_forward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ TRUE, + /* dirty_inserts */ TRUE, + /* dirty_unprotects */ TRUE); + + if ( show_progress ) /* 8 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + write_permitted = FALSE; + + col_major_scan_backward(/* cache_ptr */ cache_ptr, + /* lag */ lag, + /* verbose */ FALSE, + /* reset_stats */ TRUE, + /* display_stats */ display_stats, + /* display_detailed_stats */ TRUE, + /* do_inserts */ FALSE, + /* dirty_inserts */ FALSE, + /* dirty_unprotects */ NO_CHANGE); + + write_permitted = TRUE; + + if ( show_progress ) /* 9 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + takedown_cache(cache_ptr, display_stats, TRUE); + + if ( show_progress ) /* 10 */ + HDfprintf(stdout, "%s() - %0d -- pass = %d\n", + fcn_name, mile_stone++, (int)pass); + + verify_clean(); + verify_unprotected(); + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + SKIPPED(); + + HDfprintf(stdout, " Clean and dirty LRU lists disabled.\n"); + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +} /* write_permitted_check() */ + + +/*------------------------------------------------------------------------- + * Function: check_flush_protected_err() + * + * Purpose: Verify that an attempt to flush the cache when it contains + * a protected entry will generate an error. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_flush_protected_err(void) +{ + const char * fcn_name = "check_flush_protected_err"; + H5C_t * cache_ptr = NULL; + + TESTING("flush cache with protected entry error"); + + pass = TRUE; + + /* allocate a cache, protect an entry, and try to flush. This + * should fail. Unprotect the entry and flush again -- should + * succeed. + */ + + if ( pass ) { + + reset_entries(); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + protect_entry(cache_ptr, 0, 0); + + if ( H5C_flush_cache(NULL, -1, -1, cache_ptr, 0) >= 0 ) { + + pass = FALSE; + failure_mssg = "flush succeeded on cache with protected entry.\n"; + + } else { + + unprotect_entry(cache_ptr, 0, 0, TRUE, FALSE); + + if ( H5C_flush_cache(NULL, -1, -1, cache_ptr, 0) < 0 ) { + + pass = FALSE; + failure_mssg = "flush failed after unprotect.\n"; + + } else { + + takedown_cache(cache_ptr, FALSE, FALSE); + } + } + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_flush_protected_err() */ + + +/*------------------------------------------------------------------------- + * Function: check_destroy_protected_err() + * + * Purpose: Verify that an attempt to destroy the cache when it contains + * a protected entry will generate an error. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_destroy_protected_err(void) +{ + const char * fcn_name = "check_destroy_protected_err"; + H5C_t * cache_ptr = NULL; + + TESTING("destroy cache with protected entry error"); + + pass = TRUE; + + /* allocate a cache, protect an entry, and try to flush. This + * should fail. Unprotect the entry and flush again -- should + * succeed. + */ + + if ( pass ) { + + reset_entries(); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + protect_entry(cache_ptr, 0, 0); + + if ( H5C_dest(NULL, -1, -1, cache_ptr) >= 0 ) { + + pass = FALSE; + failure_mssg = "destroy succeeded on cache with protected entry.\n"; + + } else { + + unprotect_entry(cache_ptr, 0, 0, TRUE, FALSE); + + if ( H5C_dest(NULL, -1, -1, cache_ptr) < 0 ) { + + pass = FALSE; + failure_mssg = "destroy failed after unprotect.\n"; + + } + } + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_destroy_protected_err() */ + + +/*------------------------------------------------------------------------- + * Function: check_duplicate_insert_err() + * + * Purpose: Verify that an attempt to insert and entry that is + * alread in the cache will generate an error. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_duplicate_insert_err(void) +{ + const char * fcn_name = "check_duplicate_insert_err"; + herr_t result; + H5C_t * cache_ptr = NULL; + test_entry_t * base_addr; + test_entry_t * entry_ptr; + + TESTING("duplicate entry insertion error"); + + pass = TRUE; + + /* allocate a cache, protect an entry, and then try to insert + * the entry again. This should fail. Unprotect the entry and + * destroy the cache -- should succeed. + */ + + if ( pass ) { + + reset_entries(); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + protect_entry(cache_ptr, 0, 0); + + if ( pass ) { + + base_addr = entries[0]; + entry_ptr = &(base_addr[0]); + + result = H5C_insert_entry(NULL, -1, -1, cache_ptr, + &(types[0]), entry_ptr->addr, + (void *)entry_ptr); + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "insert of duplicate entry succeeded.\n"; + + } else { + + unprotect_entry(cache_ptr, 0, 0, TRUE, FALSE); + + takedown_cache(cache_ptr, FALSE, FALSE); + } + } + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s(): failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_duplicate_insert_err() */ + + +/*------------------------------------------------------------------------- + * Function: check_rename_err() + * + * Purpose: Verify that an attempt to rename an entry to the address + * of an existing entry will generate an error. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_rename_err(void) +{ + const char * fcn_name = "check_rename_err()"; + herr_t result; + H5C_t * cache_ptr = NULL; + test_entry_t * entry_0_0_ptr; + test_entry_t * entry_0_1_ptr; + test_entry_t * entry_1_0_ptr; + + TESTING("rename to existing entry errors"); + + pass = TRUE; + + /* allocate a cache, and insert several entries. Try to rename + * entries to other entries resident in the cache. This should + * fail. Destroy the cache -- should succeed. + */ + + if ( pass ) { + + reset_entries(); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + insert_entry(cache_ptr, 0, 0, TRUE); + insert_entry(cache_ptr, 0, 1, TRUE); + insert_entry(cache_ptr, 1, 0, TRUE); + + entry_0_0_ptr = &((entries[0])[0]); + entry_0_1_ptr = &((entries[0])[1]); + entry_1_0_ptr = &((entries[1])[0]); + } + + if ( pass ) { + + result = H5C_rename_entry(NULL, cache_ptr, &(types[0]), + entry_0_0_ptr->addr, entry_0_1_ptr->addr); + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "rename to addr of same type succeeded.\n"; + } + } + + if ( pass ) { + + result = H5C_rename_entry(NULL, cache_ptr, &(types[0]), + entry_0_0_ptr->addr, entry_1_0_ptr->addr); + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "rename to addr of different type succeeded.\n"; + } + } + + if ( pass ) { + + takedown_cache(cache_ptr, FALSE, FALSE); + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_rename_err() */ + + +/*------------------------------------------------------------------------- + * Function: check_double_protect_err() + * + * Purpose: Verify that an attempt to protect an entry that is already + * protected will generate an error. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_double_protect_err(void) +{ + const char * fcn_name = "check_double_protect_err()"; + H5C_t * cache_ptr = NULL; + test_entry_t * entry_ptr; + H5C_cache_entry_t * cache_entry_ptr; + + TESTING("protect a protected entry error"); + + pass = TRUE; + + /* allocate a cache, protect an entry, and then try to protect + * the entry again. This should fail. Unprotect the entry and + * destroy the cache -- should succeed. + */ + + if ( pass ) { + + reset_entries(); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + protect_entry(cache_ptr, 0, 0); + + entry_ptr = &((entries[0])[0]); + } + + if ( pass ) { + + cache_entry_ptr = H5C_protect(NULL, -1, -1, cache_ptr, &(types[0]), + entry_ptr->addr, NULL, NULL); + + if ( cache_entry_ptr != NULL ) { + + pass = FALSE; + failure_mssg = "attempt to protect a protected entry succeeded.\n"; + } + } + + if ( pass ) { + + unprotect_entry(cache_ptr, 0, 0, FALSE, FALSE); + } + + if ( pass ) { + + takedown_cache(cache_ptr, FALSE, FALSE); + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_double_protect_err() */ + + +/*------------------------------------------------------------------------- + * Function: check_double_unprotect_err() + * + * Purpose: Verify that an attempt to unprotect an entry that is already + * unprotected will generate an error. + * + * Return: void + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_double_unprotect_err(void) +{ + const char * fcn_name = "check_double_unprotect_err()"; + herr_t result; + H5C_t * cache_ptr = NULL; + test_entry_t * entry_ptr; + + TESTING("unprotect an unprotected entry error"); + + pass = TRUE; + + /* allocate a cache, protect an entry, unprotect it, and then try to + * unprotect the entry again. This should fail. Destroy the cache + * -- should succeed. + */ + + if ( pass ) { + + reset_entries(); + + cache_ptr = setup_cache((size_t)(2 * 1024), + (size_t)(1 * 1024)); + + protect_entry(cache_ptr, 0, 0); + + unprotect_entry(cache_ptr, 0, 0, FALSE, FALSE); + + entry_ptr = &((entries[0])[0]); + } + + if ( pass ) { + + result = H5C_unprotect(NULL, -1, -1, cache_ptr, &(types[0]), + entry_ptr->addr, (void *)entry_ptr, FALSE); + + if ( result > 0 ) { + + pass = FALSE; + failure_mssg = + "attempt to unprotect an unprotected entry succeeded.\n"; + } + } + + if ( pass ) { + + takedown_cache(cache_ptr, FALSE, FALSE); + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_double_unprotect_err() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Run tests on the cache code contained in H5C.c + * + * Return: Success: + * + * Failure: + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + H5open(); + + smoke_check_1(); + smoke_check_2(); + smoke_check_3(); + smoke_check_4(); + write_permitted_check(); + check_flush_protected_err(); + check_destroy_protected_err(); + check_duplicate_insert_err(); + check_rename_err(); + check_double_protect_err(); + check_double_unprotect_err(); + + return(0); + +} /* main() */ |