summaryrefslogtreecommitdiffstats
path: root/test/ohdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/ohdr.c')
-rw-r--r--test/ohdr.c181
1 files changed, 171 insertions, 10 deletions
diff --git a/test/ohdr.c b/test/ohdr.c
index dad06cf..109d59c 100644
--- a/test/ohdr.c
+++ b/test/ohdr.c
@@ -68,6 +68,9 @@ test_cont(char *filename, hid_t fapl)
TESTING("object header continuation block");
+ HDmemset(&oh_locA, 0, sizeof(oh_locA));
+ HDmemset(&oh_locB, 0, sizeof(oh_locB));
+
/* Create the file to operate on */
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if(NULL == (f = (H5F_t *)H5I_object(file))) FAIL_STACK_ERROR
@@ -77,13 +80,10 @@ test_cont(char *filename, hid_t fapl)
goto error;
}
- 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;
@@ -107,6 +107,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)
@@ -148,6 +152,149 @@ 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
+ if(H5AC_ignore_tags(f) < 0)
+ 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
@@ -216,7 +363,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();
@@ -226,6 +373,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)
@@ -378,12 +527,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 */
@@ -452,12 +605,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 */
@@ -632,6 +789,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.");