summaryrefslogtreecommitdiffstats
path: root/test/cache.c
diff options
context:
space:
mode:
authorJohn Mainzer <mainzer@hdfgroup.org>2004-07-02 19:35:04 (GMT)
committerJohn Mainzer <mainzer@hdfgroup.org>2004-07-02 19:35:04 (GMT)
commitc49dd7fa363bdb49416b5587654101064fd547f8 (patch)
treee1dbeee84ca50b94dfab9b1ed630d890405c6f78 /test/cache.c
parent072919b9d7fa341c1a886fb92841efa444f0ffae (diff)
downloadhdf5-c49dd7fa363bdb49416b5587654101064fd547f8.zip
hdf5-c49dd7fa363bdb49416b5587654101064fd547f8.tar.gz
hdf5-c49dd7fa363bdb49416b5587654101064fd547f8.tar.bz2
[svn-r8791] Purpose: Rewrote metadata cache (H5AC.c, etc.) to improve performance.
Description: Replaced the old metadata cache with a cache with a modified LRU replacement policy. This should improve the hit rate. Solution: Since we want to flush cache entries in increasing address order, I used the threaded binary B-tree code to store the cache entries. There is a fair bit of overhead here, so we may want to consider other options. While the code is designed to allow the support of other replacement algorithms, at present, only a modified version of LRU is supported. The modified LRU algorithm requires that a user selectable portion of the cache entries be clean. The clean entries are evicted first when writes are not permitted. If the pool of clean entries is used up, the cache grows beyond its user specified maximum size. The cache can also exceed its maximum size if the combined size of the protected (or locked) entries exceeds the maximum size of the cache. Platforms tested: eirene (serial, parallel, fp), h5committested Misc. update:
Diffstat (limited to 'test/cache.c')
-rw-r--r--test/cache.c4067
1 files changed, 4067 insertions, 0 deletions
diff --git a/test/cache.c b/test/cache.c
new file mode 100644
index 0000000..fae8e0b
--- /dev/null
+++ b/test/cache.c
@@ -0,0 +1,4067 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 dirty; /* entry has been modified since
+ * last write
+ */
+ hbool_t protected; /* entry should currently be on
+ * the cache's protected list.
+ */
+} test_entry_t;
+
+
+/* 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;
+ H5TB_TREE * index_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];
+
+ int32_t max_index_len;
+ size_t max_index_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];
+
+#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.dirty = FALSE;
+ entry_ptr->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->dirty) );
+ HDassert( !(entry_ptr->header.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->dirty ) ) {
+
+ pass = FALSE;
+ failure_mssg = "called flush when write_permitted is FALSE.";
+ }
+
+ if ( entry_ptr->dirty ) {
+
+ (entry_ptr->writes)++;
+ entry_ptr->dirty = FALSE;
+ entry_ptr->header.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->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;
+ test_entry_t search_target;
+ H5TB_TREE * index_tree_ptr;
+ H5TB_NODE * node_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 );
+
+ search_target.header.addr = entry_ptr->addr;
+
+ index_tree_ptr = ((local_H5C_t *)cache_ptr)->index_tree_ptr;
+
+ node_ptr = H5TB_dfind(index_tree_ptr, &search_target, NULL);
+
+ if ( node_ptr != NULL ) {
+
+ in_cache = TRUE;
+ HDassert( entry_ptr->addr == entry_ptr->header.addr );
+ HDassert( node_ptr->key == ((void *)(entry_ptr)) );
+ }
+
+ 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.dirty = FALSE;
+ base_addr[j].header.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].dirty = FALSE;
+ base_addr[j].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.dirty ) || ( base_addr[j].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.protected ==
+ base_addr[j].protected );
+
+ if ( ( base_addr[j].header.protected ) ||
+ ( base_addr[j].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),
+ &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->protected) );
+
+ if ( dirty ) {
+
+ (entry_ptr->header).dirty = dirty;
+ entry_ptr->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.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_t new_addr;
+ 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->protected) );
+ HDassert( !(entry_ptr->header.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->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.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->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.protected );
+ HDassert( entry_ptr->protected );
+
+ if ( ( dirty == TRUE ) || ( dirty == FALSE ) ) {
+
+ entry_ptr->header.dirty = dirty;
+ entry_ptr->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.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->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].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].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].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].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)
+{
+ 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;
+
+ TESTING("write permitted check -- 1/0 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)(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);
+
+} /* 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();
+#if 0
+ smoke_check_1();
+ smoke_check_2();
+#endif
+ smoke_check_3();
+ smoke_check_4();
+#if 0
+ write_permitted_check();
+#endif
+ 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() */