summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-10-13 16:17:52 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-10-13 16:17:52 (GMT)
commita294ddffe58114b77b16812c180c62dd453f1407 (patch)
tree2fe3d61e24b39d87cfa3b247582448ee0f318d28 /test
parenta911db88e480efe9f818c0b70fdb8bfade80d417 (diff)
downloadhdf5-a294ddffe58114b77b16812c180c62dd453f1407.zip
hdf5-a294ddffe58114b77b16812c180c62dd453f1407.tar.gz
hdf5-a294ddffe58114b77b16812c180c62dd453f1407.tar.bz2
[svn-r19588] Description:
Bring r19587 from trunk to 1.8 branch: Address issue with object headers being created getting evicted from the metadata cache cache before they are completely initialized. This is done by pinning the object header in the cache until it is completely initialized and attached to a group. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, w/threadsafe, in production mode Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode
Diffstat (limited to 'test')
-rw-r--r--test/ohdr.c173
1 files changed, 166 insertions, 7 deletions
diff --git a/test/ohdr.c b/test/ohdr.c
index 6ae399d..227f693 100644
--- a/test/ohdr.c
+++ b/test/ohdr.c
@@ -75,10 +75,10 @@ test_cont(char *filename, hid_t fapl)
HDmemset(&oh_locA, 0, sizeof(oh_locA));
HDmemset(&oh_locB, 0, sizeof(oh_locB));
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, H5P_GROUP_CREATE_DEFAULT, &oh_locA/*out*/) < 0)
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_locA/*out*/) < 0)
FAIL_STACK_ERROR
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, H5P_GROUP_CREATE_DEFAULT, &oh_locB/*out*/) < 0)
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_locB/*out*/) < 0)
FAIL_STACK_ERROR
time_new = 11111111;
@@ -102,6 +102,10 @@ test_cont(char *filename, hid_t fapl)
if(H5O_msg_create(&oh_locA, H5O_NAME_ID, 0, 0, &short_name, H5P_DATASET_XFER_DEFAULT) < 0)
FAIL_STACK_ERROR
+ if(1 != H5O_link(&oh_locA, 1, H5P_DATASET_XFER_DEFAULT))
+ FAIL_STACK_ERROR
+ if(1 != H5O_link(&oh_locB, 1, H5P_DATASET_XFER_DEFAULT))
+ FAIL_STACK_ERROR
if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
FAIL_STACK_ERROR
if(H5O_expunge_chunks_test(&oh_locA, H5P_DATASET_XFER_DEFAULT) < 0)
@@ -143,6 +147,147 @@ error:
return -1;
} /* test_cont() */
+/*
+ * Verify that object headers are held in the cache until they are linked
+ * to a location in the graph, or assigned an ID. This is done by
+ * creating an object header, then forcing it out of the cache by creating
+ * local heaps until the object header is evicted from the cache, then
+ * modifying the object header. The refcount on the object header is
+ * checked as verifying that the object header has remained in the cache.
+ */
+static herr_t
+test_ohdr_cache(char *filename, hid_t fapl)
+{
+ hid_t file = -1; /* File ID */
+ hid_t my_fapl; /* FAPL ID */
+ hid_t my_dxpl; /* DXPL ID */
+ H5AC_cache_config_t mdc_config; /* Metadata cache configuration info */
+ H5F_t *f = NULL; /* File handle */
+ H5HL_t *lheap, *lheap2, *lheap3; /* Pointer to local heaps */
+ haddr_t lheap_addr, lheap_addr2, lheap_addr3; /* Local heap addresses */
+ H5O_loc_t oh_loc; /* Object header location */
+ time_t time_new; /* Time value for modification time message */
+ unsigned rc; /* Refcount for object */
+
+ TESTING("object header creation in cache");
+
+ /* Make a copy of the FAPL */
+ if((my_fapl = H5Pcopy(fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Tweak down the size of the metadata cache to only 64K */
+ mdc_config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
+ if(H5Pget_mdc_config(my_fapl, &mdc_config) < 0)
+ FAIL_STACK_ERROR
+ mdc_config.set_initial_size = TRUE;
+ mdc_config.initial_size = 32 * 1024;
+ mdc_config.max_size = 64 * 1024;
+ mdc_config.min_size = 8 * 1024;
+ if(H5Pset_mdc_config(my_fapl, &mdc_config) < 0)
+ FAIL_STACK_ERROR
+
+ /* Make a copy of the default DXPL */
+ if((my_dxpl = H5Pcopy(H5P_DATASET_XFER_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Create the file to operate on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
+ FAIL_STACK_ERROR
+ if(H5Pclose(my_fapl) < 0)
+ FAIL_STACK_ERROR
+ if(NULL == (f = (H5F_t *)H5I_object(file)))
+ FAIL_STACK_ERROR
+
+ /* Create object (local heap) that occupies most of cache */
+ if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr) < 0)
+ FAIL_STACK_ERROR
+
+ /* Protect local heap (which actually pins it in the cache) */
+ if(NULL == (lheap = H5HL_protect(f, my_dxpl, lheap_addr, H5AC_READ)))
+ FAIL_STACK_ERROR
+
+ /* Create an object header */
+ HDmemset(&oh_loc, 0, sizeof(oh_loc));
+ if(H5O_create(f, my_dxpl, (size_t)2048, (size_t)1, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
+ FAIL_STACK_ERROR
+
+ /* Query object header information */
+ rc = 0;
+ if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
+ FAIL_STACK_ERROR
+ if(0 != rc)
+ TEST_ERROR
+
+ /* Create object (local heap) that occupies most of cache */
+ if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr2) < 0)
+ FAIL_STACK_ERROR
+
+ /* Protect local heap (which actually pins it in the cache) */
+ if(NULL == (lheap2 = H5HL_protect(f, my_dxpl, lheap_addr2, H5AC_READ)))
+ FAIL_STACK_ERROR
+
+ /* Unprotect local heap (which actually unpins it from the cache) */
+ if(H5HL_unprotect(lheap2) < 0)
+ FAIL_STACK_ERROR
+
+ /* Create object header message in new object header */
+ time_new = 11111111;
+ if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, my_dxpl) < 0)
+ FAIL_STACK_ERROR
+
+ /* Create object (local heap) that occupies most of cache */
+ if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr3) < 0)
+ FAIL_STACK_ERROR
+
+ /* Protect local heap (which actually pins it in the cache) */
+ if(NULL == (lheap3 = H5HL_protect(f, my_dxpl, lheap_addr3, H5AC_READ)))
+ FAIL_STACK_ERROR
+
+ /* Unprotect local heap (which actually unpins it from the cache) */
+ if(H5HL_unprotect(lheap3) < 0)
+ FAIL_STACK_ERROR
+
+ /* Query object header information */
+ /* (Note that this is somewhat of a weak test, since it doesn't actually
+ * verify that the object header was evicted from the cache, but it's
+ * very difficult to verify when an entry is evicted from the cache in
+ * a non-invasive way -QAK)
+ */
+ rc = 0;
+ if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
+ FAIL_STACK_ERROR
+ if(0 != rc)
+ TEST_ERROR
+
+ /* Decrement reference count o object header */
+ if(H5O_dec_rc_by_loc(&oh_loc, my_dxpl) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close object header created */
+ if(H5O_close(&oh_loc) < 0)
+ FAIL_STACK_ERROR
+
+ /* Unprotect local heap (which actually unpins it from the cache) */
+ if(H5HL_unprotect(lheap) < 0)
+ FAIL_STACK_ERROR
+
+ if(H5Pclose(my_dxpl) < 0)
+ FAIL_STACK_ERROR
+ if(H5Fclose(file) < 0)
+ FAIL_STACK_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+
+ return -1;
+} /* test_ohdr_cache() */
+
/*-------------------------------------------------------------------------
* Function: main
@@ -206,7 +351,7 @@ main(void)
*/
TESTING("object header creation");
HDmemset(&oh_loc, 0, sizeof(oh_loc));
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
FAIL_STACK_ERROR
PASSED();
@@ -216,6 +361,8 @@ main(void)
time_new = 11111111;
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
FAIL_STACK_ERROR
+ if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
+ FAIL_STACK_ERROR
if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
FAIL_STACK_ERROR
if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
@@ -366,12 +513,16 @@ main(void)
*/
TESTING("locking messages");
HDmemset(&oh_loc, 0, sizeof(oh_loc));
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
FAIL_STACK_ERROR
/* Create second object header, to guarantee that first object header uses multiple chunks */
HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(1 != H5O_link(&oh_loc2, 1, H5P_DATASET_XFER_DEFAULT))
FAIL_STACK_ERROR
/* Fill object header with messages, creating multiple chunks */
@@ -440,12 +591,16 @@ main(void)
/* Open first object header */
HDmemset(&oh_loc, 0, sizeof(oh_loc));
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
FAIL_STACK_ERROR
/* Create second object header, to guarantee that first object header uses multiple chunks */
HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
- if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
+ if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(1 != H5O_link(&oh_loc2, 1, H5P_DATASET_XFER_DEFAULT))
FAIL_STACK_ERROR
/* Add message to move to object header */
@@ -633,6 +788,10 @@ main(void)
/* Close the file we created */
if(H5Fclose(file) < 0)
TEST_ERROR
+
+ /* Test object header creation metadata cache issues */
+ if(test_ohdr_cache(filename, fapl) < 0)
+ TEST_ERROR
} /* end for */
puts("All object header tests passed.");