summaryrefslogtreecommitdiffstats
path: root/test/twriteorder.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/twriteorder.c')
-rw-r--r--test/twriteorder.c267
1 files changed, 136 insertions, 131 deletions
diff --git a/test/twriteorder.c b/test/twriteorder.c
index b104b72..c58b030 100644
--- a/test/twriteorder.c
+++ b/test/twriteorder.c
@@ -5,96 +5,98 @@
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
- * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***********************************************************
-*
-* Test program: twriteorder
-*
-* Test to verify that the write order is strictly consistent.
-* The SWMR feature requires that the order of write is strictly consistent.
-* "Strict consistency in computer science is the most stringent consistency
-* model. It says that a read operation has to return the result of the
-* latest write operation which occurred on that data item."--
-* (http://en.wikipedia.org/wiki/Linearizability#Definition_of_linearizability).
-* This is also an alternative form of what POSIX write require that after a
-* write operation has returned success, all reads issued afterward should
-* get the same data the write has written.
-*
-* Created: Albert Cheng, 2013/8/28.
-*************************************************************/
+ *
+ * Test program: twriteorder
+ *
+ * Test to verify that the write order is strictly consistent.
+ * The SWMR feature requires that the order of write is strictly consistent.
+ * "Strict consistency in computer science is the most stringent consistency
+ * model. It says that a read operation has to return the result of the
+ * latest write operation which occurred on that data item."--
+ * (http://en.wikipedia.org/wiki/Linearizability#Definition_of_linearizability).
+ * This is also an alternative form of what POSIX write require that after a
+ * write operation has returned success, all reads issued afterward should
+ * get the same data the write has written.
+ *
+ * Created: Albert Cheng, 2013/8/28.
+ *************************************************************/
/***********************************************************
-*
-* Algorithm
-*
-* The test simulates what SWMR does by writing chained blocks and see if
-* they can be read back correctly.
-* There is a writer process and multiple read processes.
-* The file is divided into 2KB partitions. Then writer writes 1 chained
-* block, each of 1KB big, in each partition after the first partition.
-* Each chained block has this structure:
-* Byte 0-3: offset address of its child block. The last child uses 0 as NULL.
-* Byte 4-1023: some artificial data.
-* The child block address of Block 1 is NULL (0).
-* The child block address of Block 2 is the offset address of Block 1.
-* The child block address of Block n is the offset address of Block n-1.
-* After all n blocks are written, the offset address of Block n is written
-* to the offset 0 of the first partition.
-* Therefore, by the time the offset address of Block n is written to this
-* position, all n chain-linked blocks have been written.
-*
-* The other reader processes will try to read the address value at the
-* offset 0. The value is initially NULL(0). When it changes to non-zero,
-* it signifies the writer process has written all the chain-link blocks
-* and they are ready for the reader processes to access.
-*
-* If the system, in which the writer and reader processes run, the readers
-* will always get all chain-linked blocks correctly. If the order of write
-* is not maintained, some reader processes may found unexpect block data.
-*
-*************************************************************/
+ *
+ * Algorithm
+ *
+ * The test simulates what SWMR does by writing chained blocks and see if
+ * they can be read back correctly.
+ * There is a writer process and multiple read processes.
+ * The file is divided into 2KB partitions. Then writer writes 1 chained
+ * block, each of 1KB big, in each partition after the first partition.
+ * Each chained block has this structure:
+ * Byte 0-3: offset address of its child block. The last child uses 0 as NULL.
+ * Byte 4-1023: some artificial data.
+ * The child block address of Block 1 is NULL (0).
+ * The child block address of Block 2 is the offset address of Block 1.
+ * The child block address of Block n is the offset address of Block n-1.
+ * After all n blocks are written, the offset address of Block n is written
+ * to the offset 0 of the first partition.
+ * Therefore, by the time the offset address of Block n is written to this
+ * position, all n chain-linked blocks have been written.
+ *
+ * The other reader processes will try to read the address value at the
+ * offset 0. The value is initially NULL(0). When it changes to non-zero,
+ * it signifies the writer process has written all the chain-link blocks
+ * and they are ready for the reader processes to access.
+ *
+ * If the system, in which the writer and reader processes run, the readers
+ * will always get all chain-linked blocks correctly. If the order of write
+ * is not maintained, some reader processes may found unexpected block data.
+ *
+ *************************************************************/
#include "h5test.h"
/* This test uses many POSIX things that are not available on
- * Windows. We're using a check for fork(2) here as a proxy for
- * all POSIX/Unix/Linux things until this test can be made
- * more platform-independent.
+ * Windows.
*/
-#ifdef H5_HAVE_FORK
-
-#define DATAFILE "twriteorder.dat"
-/* #define READERS_MAX 10 */ /* max number of readers */
-#define BLOCKSIZE_DFT 1024 /* 1KB */
-#define PARTITION_DFT 2048 /* 2KB */
-#define NLINKEDBLOCKS_DFT 512 /* default 512 */
-#define SIZE_BLKADDR 4 /* expected sizeof blkaddr */
-#define Hgoto_error(val) {ret_value=val; goto done;}
+#if defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)
+
+#define DATAFILE "twriteorder.dat"
+/* #define READERS_MAX 10 */ /* max number of readers */
+#define BLOCKSIZE_DFT 1024 /* 1KB */
+#define PARTITION_DFT 2048 /* 2KB */
+#define NLINKEDBLOCKS_DFT 512 /* default 512 */
+#define SIZE_BLKADDR 4 /* expected sizeof blkaddr */
+#define Hgoto_error(val) \
+ { \
+ ret_value = val; \
+ goto done; \
+ }
/* type declarations */
typedef enum part_t {
- UC_READWRITE = 0, /* both writer and reader */
- UC_WRITER, /* writer only */
- UC_READER /* reader only */
+ UC_READWRITE = 0, /* both writer and reader */
+ UC_WRITER, /* writer only */
+ UC_READER /* reader only */
} part_t;
/* prototypes */
-int create_wo_file(void);
-int write_wo_file(void);
-int read_wo_file(void);
+int create_wo_file(void);
+int write_wo_file(void);
+int read_wo_file(void);
void usage(const char *prog);
-int setup_parameters(int argc, char * const argv[]);
-int parse_option(int argc, char * const argv[]);
+int setup_parameters(int argc, char *const argv[]);
+int parse_option(int argc, char *const argv[]);
/* Global Variable definitions */
-const char *progname_g="twriteorder"; /* program name */
-int write_fd_g;
-int blocksize_g, part_size_g, nlinkedblock_g;
-part_t launch_g;
+const char *progname_g = "twriteorder"; /* program name */
+int write_fd_g;
+int blocksize_g, part_size_g, nlinkedblock_g;
+part_t launch_g;
/* Function definitions */
@@ -116,9 +118,9 @@ usage(const char *prog)
/* Setup test parameters by parsing command line options.
* Setup default values if not set by options. */
int
-parse_option(int argc, char * const argv[])
+parse_option(int argc, char *const argv[])
{
- int ret_value=0;
+ int ret_value = 0;
int c;
/* command line options: See function usage for a description */
const char *cmd_options = "hb:l:n:p:";
@@ -127,7 +129,7 @@ parse_option(int argc, char * const argv[])
opterr = 0;
while (1) {
- c = getopt (argc, argv, cmd_options);
+ c = getopt(argc, argv, cmd_options);
if (-1 == c)
break;
@@ -136,33 +138,33 @@ parse_option(int argc, char * const argv[])
usage(progname_g);
HDexit(EXIT_SUCCESS);
break;
- case 'b': /* number of planes to write/read */
- if ((blocksize_g = atoi(optarg)) <= 0) {
+ case 'b': /* number of planes to write/read */
+ if ((blocksize_g = HDatoi(optarg)) <= 0) {
HDfprintf(stderr, "bad blocksize %s, must be a positive integer\n", optarg);
usage(progname_g);
Hgoto_error(-1);
};
break;
- case 'n': /* number of planes to write/read */
- if ((nlinkedblock_g = atoi(optarg)) < 2) {
+ case 'n': /* number of planes to write/read */
+ if ((nlinkedblock_g = HDatoi(optarg)) < 2) {
HDfprintf(stderr, "bad number of linked blocks %s, must be greater than 1.\n", optarg);
usage(progname_g);
Hgoto_error(-1);
};
break;
- case 'p': /* number of planes to write/read */
- if ((part_size_g = atoi(optarg)) <= 0) {
+ case 'p': /* number of planes to write/read */
+ if ((part_size_g = HDatoi(optarg)) <= 0) {
HDfprintf(stderr, "bad partition size %s, must be a positive integer\n", optarg);
usage(progname_g);
Hgoto_error(-1);
};
break;
- case 'l': /* launch reader or writer only */
+ case 'l': /* launch reader or writer only */
switch (*optarg) {
- case 'r': /* reader only */
+ case 'r': /* reader only */
launch_g = UC_READER;
break;
- case 'w': /* writer only */
+ case 'w': /* writer only */
launch_g = UC_WRITER;
break;
default:
@@ -182,12 +184,13 @@ parse_option(int argc, char * const argv[])
HDfprintf(stderr, "Unexpected value is %d\n", c);
Hgoto_error(-1);
} /* end outer switch */
- } /* end while */
+ } /* end while */
/* verify partition size must be >= blocksize */
- if (part_size_g < blocksize_g ){
- HDfprintf(stderr, "Blocksize %d should not be bigger than partition size %d\n", blocksize_g, part_size_g);
- Hgoto_error(-1);
+ if (part_size_g < blocksize_g) {
+ HDfprintf(stderr, "Blocksize %d should not be bigger than partition size %d\n", blocksize_g,
+ part_size_g);
+ Hgoto_error(-1);
}
done:
@@ -198,16 +201,17 @@ done:
/* Setup parameters for the test case.
* Return: 0 succeed; -1 fail.
*/
-int setup_parameters(int argc, char * const argv[])
+int
+setup_parameters(int argc, char *const argv[])
{
/* test case defaults */
- blocksize_g = BLOCKSIZE_DFT;
- part_size_g = PARTITION_DFT;
+ blocksize_g = BLOCKSIZE_DFT;
+ part_size_g = PARTITION_DFT;
nlinkedblock_g = NLINKEDBLOCKS_DFT;
- launch_g = UC_READWRITE;
+ launch_g = UC_READWRITE;
/* parse options */
- if (parse_option(argc, argv) < 0){
+ if (parse_option(argc, argv) < 0) {
return -1;
}
@@ -225,19 +229,20 @@ int setup_parameters(int argc, char * const argv[])
*
* Return: 0 succeed; -1 fail.
*/
-int create_wo_file(void)
+int
+create_wo_file(void)
{
- int blkaddr = 0; /* blkaddress of next linked block */
- h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes written */
+ int blkaddr = 0; /* blkaddress of next linked block */
+ h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes written */
/* Create the data file */
- if ((write_fd_g = HDopen(DATAFILE, O_RDWR|O_TRUNC|O_CREAT, H5_POSIX_CREATE_MODE_RW)) < 0) {
+ if ((write_fd_g = HDopen(DATAFILE, O_RDWR | O_TRUNC | O_CREAT, H5_POSIX_CREATE_MODE_RW)) < 0) {
HDprintf("WRITER: error from open\n");
return -1;
}
blkaddr = 0;
/* write it to partition 0 */
- if ((bytes_wrote = HDwrite(write_fd_g, &blkaddr, (size_t)SIZE_BLKADDR)) != SIZE_BLKADDR){
+ if ((bytes_wrote = HDwrite(write_fd_g, &blkaddr, (size_t)SIZE_BLKADDR)) != SIZE_BLKADDR) {
HDprintf("blkaddr write failed\n");
return -1;
}
@@ -246,14 +251,14 @@ int create_wo_file(void)
return 0;
}
-int write_wo_file(void)
+int
+write_wo_file(void)
{
- int blkaddr;
- int blkaddr_old=0;
- int i;
- char buffer[BLOCKSIZE_DFT];
- h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes written */
-
+ int blkaddr;
+ int blkaddr_old = 0;
+ int i;
+ char buffer[BLOCKSIZE_DFT];
+ h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes written */
/* write block 1, 2, ... */
for (i = 1; i < nlinkedblock_g; i++) {
@@ -265,14 +270,14 @@ int write_wo_file(void)
HDmemcpy(&buffer[0], &blkaddr_old, sizeof(blkaddr_old));
/* fill the rest with the lowest byte of i */
- HDmemset(&buffer[4], i & 0xff, (size_t) (BLOCKSIZE_DFT-4));
+ HDmemset(&buffer[4], i & 0xff, (size_t)(BLOCKSIZE_DFT - 4));
/* write the block */
#ifdef DEBUG
HDprintf("writing block at %d\n", blkaddr);
#endif
HDlseek(write_fd_g, (HDoff_t)blkaddr, SEEK_SET);
- if ((bytes_wrote = HDwrite(write_fd_g, buffer, (size_t)blocksize_g)) != blocksize_g){
+ if ((bytes_wrote = HDwrite(write_fd_g, buffer, (size_t)blocksize_g)) != blocksize_g) {
HDprintf("blkaddr write failed in partition %d\n", i);
return -1;
}
@@ -283,7 +288,8 @@ int write_wo_file(void)
/* write the last blkaddr in partition 0 */
HDlseek(write_fd_g, (HDoff_t)0, SEEK_SET);
- if ((bytes_wrote = HDwrite(write_fd_g, &blkaddr_old, (size_t)sizeof(blkaddr_old))) != sizeof(blkaddr_old)){
+ if ((bytes_wrote = HDwrite(write_fd_g, &blkaddr_old, (size_t)sizeof(blkaddr_old))) !=
+ sizeof(blkaddr_old)) {
HDprintf("blkaddr write failed in partition %d\n", 0);
return -1;
}
@@ -295,13 +301,14 @@ int write_wo_file(void)
return 0;
}
-int read_wo_file(void)
+int
+read_wo_file(void)
{
- int read_fd;
- int blkaddr = 0;
- h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually read */
- int linkedblocks_read = 0;
- char buffer[BLOCKSIZE_DFT];
+ int read_fd;
+ int blkaddr = 0;
+ h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually read */
+ int linkedblocks_read = 0;
+ char buffer[BLOCKSIZE_DFT];
/* Open the data file */
if ((read_fd = HDopen(DATAFILE, O_RDONLY)) < 0) {
@@ -325,7 +332,7 @@ int read_wo_file(void)
#endif
while (blkaddr != 0) {
HDlseek(read_fd, (HDoff_t)blkaddr, SEEK_SET);
- if ((bytes_read = HDread(read_fd, buffer, (size_t)blocksize_g)) != blocksize_g){
+ if ((bytes_read = HDread(read_fd, buffer, (size_t)blocksize_g)) != blocksize_g) {
HDprintf("blkaddr read failed in partition %d\n", 0);
return -1;
}
@@ -344,8 +351,7 @@ int read_wo_file(void)
return 0;
}
-
-/* Overall Algorithm:
+/* Overall Algorithm:
* Parse options from user;
* Generate/pre-created the test file needed and close it;
* fork: child processes become the reader processes;
@@ -357,15 +363,15 @@ main(int argc, char *argv[])
{
/*pid_t childpid[READERS_MAX];
int child_ret_value[READERS_MAX];*/
- pid_t childpid=0;
- int child_ret_value;
+ pid_t childpid = 0;
+ int child_ret_value;
pid_t mypid, tmppid;
- int child_status;
- int child_wait_option=0;
- int ret_value = 0;
+ int child_status;
+ int child_wait_option = 0;
+ int ret_value = 0;
/* initialization */
- if (setup_parameters(argc, argv) < 0){
+ if (setup_parameters(argc, argv) < 0) {
Hgoto_error(1);
}
@@ -389,21 +395,21 @@ main(int argc, char *argv[])
/* flush output before possible fork */
HDfflush(stdout);
- if (launch_g==UC_READWRITE) {
+ if (launch_g == UC_READWRITE) {
/* fork process */
- if((childpid = HDfork()) < 0) {
+ if ((childpid = HDfork()) < 0) {
HDperror("fork");
Hgoto_error(1);
};
};
- mypid = getpid();
+ mypid = HDgetpid();
/* ============= */
/* launch reader */
/* ============= */
if (launch_g != UC_WRITER) {
/* child process launch the reader */
- if(0 == childpid) {
+ if (0 == childpid) {
HDprintf("%d: launch reader process\n", mypid);
if (read_wo_file() < 0) {
HDfprintf(stderr, "read_wo_file encountered error\n");
@@ -432,12 +438,12 @@ main(int argc, char *argv[])
/* If readwrite, collect exit code of child process */
/* ================================================ */
if (launch_g == UC_READWRITE) {
- if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0) {
+ if ((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) {
HDperror("waitpid");
Hgoto_error(1);
}
if (WIFEXITED(child_status)) {
- if ((child_ret_value=WEXITSTATUS(child_status)) != 0) {
+ if ((child_ret_value = WEXITSTATUS(child_status)) != 0) {
HDprintf("%d: child process exited with non-zero code (%d)\n", mypid, child_ret_value);
Hgoto_error(2);
}
@@ -447,10 +453,10 @@ main(int argc, char *argv[])
Hgoto_error(2);
}
}
-
+
done:
/* Print result and exit */
- if (ret_value != 0){
+ if (ret_value != 0) {
HDprintf("Error(s) encountered\n");
}
else {
@@ -460,7 +466,7 @@ done:
return ret_value;
}
-#else /* H5_HAVE_FORK */
+#else /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */
int
main(void)
@@ -469,5 +475,4 @@ main(void)
return EXIT_SUCCESS;
} /* end main() */
-#endif /* H5_HAVE_FORK */
-
+#endif /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */