/*------------------------------------------------------------------------- * Function: monitor_dataset * * Purpose: To poll a dataset periodically for changes in dimension sizes. * For dataset with unchanged and/or decreased dimension sizes: * it just prints the dimension size changes * For dataset with increase in at least one of its dimension sizes: * it will print the new appended data to the dataset * * Return: Non-negative on success: dataset can be monitored * Negative on failure: dataset cannot be monitored * * Programmer: Vailin Choi; August 2010 * *------------------------------------------------------------------------- */ static herr_t monitor_dataset(hid_t fid, char *dsetname) { hid_t did; /* dataset id */ hid_t sid; /* dataspace id */ int ndims; /* # of dimensions in the dataspace */ int i, u; /* local index variable */ hsize_t prev_dims[H5S_MAX_RANK]; /* current dataspace dimensions */ hsize_t cur_dims[H5S_MAX_RANK]; /* previous dataspace dimensions */ herr_t ret_value = SUCCEED; /* return value */ HDfprintf(stdout, "Monitoring dataset %s...\n", dsetname); /* Open the dataset for minitoring */ if((did = H5Dopen2(fid, dsetname, H5P_DEFAULT)) < 0) { error_msg("error in opening dataset \"%s\"\n", dsetname); ret_value = FAIL; goto done; } if((sid = H5Dget_space(did)) < 0) { error_msg("error in getting dataspace id for dataset \"%s\"\n", dsetname); ret_value = FAIL; goto done; } /* Get the dataset's dimension sizes */ if((ndims = H5Sget_simple_extent_dims(sid, prev_dims, NULL)) < 0) { error_msg("unable to get dimensions sizes for \"%s\"\n", dsetname); ret_value = FAIL; goto done; } while(1) { /* Refreshes the dataset */ if(H5Drefresh(did) < 0) { ret_value = FAIL; goto done; } /* Get the dataset's current dimension sizes */ if(H5LDget_dset_dims(did, cur_dims) < 0) { error_msg("unable to get dimension sizes for \"%s\"\n", dsetname); ret_value = FAIL; goto done; } /* Check the dimension sizes */ for(i = 0; i < ndims; i++) if(cur_dims[i] != prev_dims[i]) break; /* at least one dimension has changed */ if(i != ndims) { /* Printing changes in dimension sizes */ for(u = 0; u < ndims; u++) { HDfprintf(stdout, "dimension %u: %Hu->%Hu", (unsigned)u, prev_dims[u], cur_dims[u]); if(cur_dims[u] > prev_dims[u]) HDfprintf(stdout, " (increases)\n"); else if(cur_dims[u] < prev_dims[u]) HDfprintf(stdout, " (decreases)\n"); else HDfprintf(stdout, " (unchanged)\n"); } /* Printing elements appended to the dataset if there is */ if(!g_monitor_size_only) { /* See if at least one dimension size has increased */ for(u = 0; u < ndims; u++) { int j; hsize_t start[H5S_MAX_RANK]; hsize_t block[H5S_MAX_RANK]; /* Print the new appended data to the dataset */ if(cur_dims[u] > prev_dims[u]) { HDfprintf(stdout, " Data:\n"); for(j = 0; j < ndims; j++) { start[j] = 0; block[j] = 1; } if((ret_value = slicendump(did, prev_dims, cur_dims, start, block, ndims, ndims)) < 0) goto done; break; } } /* end for */ } HDfflush(stdout); } /* Save the current dimension sizes */ HDmemcpy(prev_dims, cur_dims, (size_t)ndims * sizeof(hsize_t)); /* Sleep before next monitor */ HDsleep(g_polling_interval); } /* end while */ done: /* Closing */ H5E_BEGIN_TRY H5Dclose(did); H5E_END_TRY return(ret_value); } /* monitor_dataset() */
/*------------------------------------------------------------------------- * Function: refresh_verification * * Purpose: This function opens the specified object, and checks to see * that is does not have any attributes on it. It then sends * a signal to the main process, which will flush the object * (putting an attribute on the object on disk). This function * will then refresh the object, and verify that it has picked * up the new metadata reflective of the added attribute. * * Return: 0 on Success, 1 on Failure * * Programmer: Mike McGreevy * July 16, 2010 * * Modifications: * *------------------------------------------------------------------------- */ herr_t refresh_verification(const char * obj_pathname) { /* Variables */ hid_t oid,fid,status = 0; H5O_info_t flushed_oinfo; H5O_info_t refreshed_oinfo; /* Open Object */ if ((fid = H5Fopen(FILENAME, H5F_ACC_SWMR_READ, H5P_DEFAULT)) < 0) PROCESS_ERROR; if ((oid = H5Oopen(fid, obj_pathname, H5P_DEFAULT)) < 0) PROCESS_ERROR; /* Get Object info */ if ((status = H5Oget_info(oid, &flushed_oinfo)) < 0) PROCESS_ERROR; /* Make sure there are no attributes on the object. This is just a sanity check to ensure we didn't erroneously flush the attribute before starting the verification. */ if (flushed_oinfo.num_attrs != 0) PROCESS_ERROR; /* Send Signal to MAIN PROCESS indicating that it can go ahead and modify the object. */ send_signal(SIGNAL_BETWEEN_PROCESSES_1, NULL, NULL); /* Wait for Signal from MAIN PROCESS indicating that it's modified the object and we can run verification now. */ if (wait_for_signal(SIGNAL_BETWEEN_PROCESSES_2) < 0) PROCESS_ERROR; /* Get object info again. This will NOT reflect what's on disk, only what's in the cache. Thus, all values will be unchanged from above, despite newer information being on disk. */ if ((status = H5Oget_info(oid, &refreshed_oinfo)) < 0) PROCESS_ERROR; /* Verify that before doing a refresh, getting the object info returns stale information. (i.e., unchanged from above, despite new info on disk). */ if (flushed_oinfo.addr != refreshed_oinfo.addr) PROCESS_ERROR; if (flushed_oinfo.type != refreshed_oinfo.type) PROCESS_ERROR; if (flushed_oinfo.hdr.version != refreshed_oinfo.hdr.version) PROCESS_ERROR; if (flushed_oinfo.hdr.flags != refreshed_oinfo.hdr.flags) PROCESS_ERROR; if (flushed_oinfo.num_attrs != refreshed_oinfo.num_attrs) PROCESS_ERROR; if (flushed_oinfo.hdr.nmesgs != refreshed_oinfo.hdr.nmesgs) PROCESS_ERROR; if (flushed_oinfo.hdr.nchunks != refreshed_oinfo.hdr.nchunks) PROCESS_ERROR; if (flushed_oinfo.hdr.space.total != refreshed_oinfo.hdr.space.total) PROCESS_ERROR; /* Refresh object */ /* The H5*refresh function called depends on which object we are trying * to refresh. (MIKE: add desired refresh call as parameter so adding new * test cases is easy). */ if ((strcmp(obj_pathname, D1) == 0) || (strcmp(obj_pathname, D2) == 0)) { if (H5Drefresh(oid) < 0) PROCESS_ERROR; } /* end if */ else if ((strcmp(obj_pathname, G1) == 0) || (strcmp(obj_pathname, G2) == 0)) { if (H5Grefresh(oid) < 0) PROCESS_ERROR; } /* end if */ else if ((strcmp(obj_pathname, T1) == 0) || (strcmp(obj_pathname, T2) == 0)) { if (H5Trefresh(oid) < 0) PROCESS_ERROR; } /* end if */ else if ((strcmp(obj_pathname, D3) == 0) || (strcmp(obj_pathname, G3) == 0) || (strcmp(obj_pathname, T3) == 0)) { if (H5Orefresh(oid) < 0) PROCESS_ERROR; } /* end if */ else { HDfprintf(stdout, "Error. %s is an unrecognized object.\n", obj_pathname); PROCESS_ERROR; } /* end else */ /* Get object info. This should now accurately reflect the refreshed object on disk. */ if ((status = H5Oget_info(oid, &refreshed_oinfo)) < 0) PROCESS_ERROR; /* Confirm following attributes are the same: */ if (flushed_oinfo.addr != refreshed_oinfo.addr) PROCESS_ERROR; if (flushed_oinfo.type != refreshed_oinfo.type) PROCESS_ERROR; if (flushed_oinfo.hdr.version != refreshed_oinfo.hdr.version) PROCESS_ERROR; if (flushed_oinfo.hdr.flags != refreshed_oinfo.hdr.flags) PROCESS_ERROR; /* Confirm following attributes are different */ if (flushed_oinfo.num_attrs == refreshed_oinfo.num_attrs) PROCESS_ERROR; if (flushed_oinfo.hdr.nmesgs == refreshed_oinfo.hdr.nmesgs) PROCESS_ERROR; if (flushed_oinfo.hdr.nchunks == refreshed_oinfo.hdr.nchunks) PROCESS_ERROR; if (flushed_oinfo.hdr.space.total == refreshed_oinfo.hdr.space.total) PROCESS_ERROR; /* Close objects */ if (H5Oclose(oid) < 0) PROCESS_ERROR; if (H5Fclose(fid) < 0) PROCESS_ERROR; /* Return */ return SUCCEED; error: return FAIL; } /* refresh_verification */
int main(void) { hid_t fid = -1; /* HDF5 file ID */ hid_t did = -1; /* dataset ID */ hid_t msid = -1; /* memory dataspace ID */ hid_t fsid = -1; /* file dataspace ID */ hsize_t start[RANK]; /* hyperslab start point */ int n_elements = 0; /* size of buffer (elements) */ size_t size = 0; /* size of buffer (bytes) */ int *buffer = NULL; /* data buffer */ int n_dims = -1; /* # dimensions in dataset */ hsize_t dims[RANK]; /* current size of dataset */ hsize_t max_dims[RANK]; /* max size of dataset */ /* Open the VDS file and dataset */ if((fid = H5Fopen(VDS_FILE_NAME, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, H5P_DEFAULT)) < 0) TEST_ERROR if((did = H5Dopen2(fid, VDS_DSET_NAME, H5P_DEFAULT)) < 0) TEST_ERROR /* Create the read buffer */ n_elements = VDS_PLANE[1] * VDS_PLANE[2]; size = n_elements * sizeof(int); if(NULL == (buffer = (int *)HDmalloc(size))) TEST_ERROR /* Create memory dataspace */ if((msid = H5Screate_simple(RANK, VDS_PLANE, NULL)) < 0) TEST_ERROR /* Read data until the dataset is full (via the writer) */ do { /* Refresh metadata */ if(H5Drefresh(did) < 0) TEST_ERROR /* Get the dataset dimensions */ if((fsid = H5Dget_space(did)) < 0) TEST_ERROR if(H5Sget_simple_extent_dims(fsid, dims, max_dims) < 0) TEST_ERROR /* Check the reported size of the VDS */ if((n_dims = H5Sget_simple_extent_ndims(fsid)) < 0) TEST_ERROR if(n_dims != RANK) TEST_ERROR if(H5Sget_simple_extent_dims(fsid, dims, max_dims) < 0) TEST_ERROR /* NOTE: Don't care what dims[0] is. */ if(dims[1] != FULL_HEIGHT) TEST_ERROR if(dims[2] != WIDTH) TEST_ERROR if(max_dims[0] != H5S_UNLIMITED) TEST_ERROR if(max_dims[1] != FULL_HEIGHT) TEST_ERROR if(max_dims[2] != WIDTH) TEST_ERROR /* Continue if there's nothing to read */ if(0 == dims[0]) { if(H5Sclose(fsid) < 0) TEST_ERROR continue; } /* Read a plane from the VDS */ /* At this time, we just make sure we can read planes without errors. */ start[0] = dims[0] - 1; start[1] = 0; start[2] = 0; if(H5Sselect_hyperslab(fsid, H5S_SELECT_SET, start, NULL, VDS_PLANE, NULL) < 0) TEST_ERROR if(H5Dread(did, H5T_NATIVE_INT, msid, fsid, H5P_DEFAULT, buffer) < 0) TEST_ERROR if(H5Sclose(fsid) < 0) TEST_ERROR } while (dims[0] < N_PLANES_TO_WRITE); /* Close file and dataset */ if(H5Sclose(msid) < 0) TEST_ERROR if(H5Dclose(did) < 0) TEST_ERROR if(H5Fclose(fid) < 0) TEST_ERROR HDfree(buffer); HDfprintf(stderr, "SWMR reader exited successfully\n"); return EXIT_SUCCESS; error: H5E_BEGIN_TRY { if(fid >= 0) (void)H5Fclose(fid); if(did >= 0) (void)H5Dclose(did); if(msid >= 0) (void)H5Sclose(msid); if(fsid >= 0) (void)H5Sclose(fsid); if(buffer != NULL) HDfree(buffer); } H5E_END_TRY HDfprintf(stderr, "ERROR: SWMR reader exited with errors\n"); return EXIT_FAILURE; } /* end main */