mirror of https://gitee.com/openkylin/hdf5.git
244 lines
8.0 KiB
C
244 lines
8.0 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Copyright by The HDF Group. *
|
||
* 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 COPYING file, which can be found at the root of the source code *
|
||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||
* If you do not have access to either file, you may request a copy from *
|
||
* help@hdfgroup.org. *
|
||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||
|
||
/*-------------------------------------------------------------------------
|
||
*
|
||
* Created: atomic_writer.c
|
||
*
|
||
* Purpose: This is the "writer" part of the standalone test to check
|
||
* atomic read-write operation on a system.
|
||
* a) atomic_writer.c--the writer (this file)
|
||
* b) atomic_reader.c--the reader
|
||
* c) atomic_data--the name of the data file used by writer and reader
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
|
||
/***********/
|
||
/* Headers */
|
||
/***********/
|
||
|
||
#include <assert.h>
|
||
#include <errno.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
#if !defined(WIN32) && !defined(__MINGW32__)
|
||
|
||
#include <fcntl.h>
|
||
#include <unistd.h>
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/wait.h>
|
||
|
||
/****************/
|
||
/* Local Macros */
|
||
/****************/
|
||
|
||
#define FILENAME "atomic_data"
|
||
|
||
/********************/
|
||
/* Local Prototypes */
|
||
/********************/
|
||
|
||
static void usage(void);
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: usage
|
||
*
|
||
* Purpose: To print information about the command line options
|
||
*
|
||
* Parameters: None
|
||
*
|
||
* Return: void
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
static void
|
||
usage(void)
|
||
{
|
||
printf("\n");
|
||
printf("Usage error!\n");
|
||
printf("Usage: atomic_writer -n <number of integers to write> -i <number of iterations for writer>\n");
|
||
printf(" Note**The number of integers for option n has to be positive\n");
|
||
printf(" Note**The number of integers for option i has to be positive\n");
|
||
printf("\n");
|
||
} /* usage() */
|
||
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: main
|
||
*
|
||
* Purpose: To write a series of integers to a file for the reader to verify the data.
|
||
* A write is atomic if the whole amount written in one operation is not interleaved
|
||
* with data from any other process.
|
||
* (1) Iterate with i iterations
|
||
* (2) Write a series of integers (0 to n-1) to the file with this pattern:
|
||
* offset 0: 0000000000000000000000000000000
|
||
* offset 1: 111111111111111111111111111111
|
||
* offset 2: 22222222222222222222222222222
|
||
* offset 3: 3333333333333333333333333333
|
||
* ...
|
||
* ...
|
||
* offset n-1: (n-1)
|
||
*
|
||
* At the end of the writes, the data in the file will be:
|
||
* 01234567........(n-1)
|
||
*
|
||
* Note:
|
||
* (a) The # of integers (via -n option) used by the writer and reader should be the same.
|
||
* (b) The data file used by the writer and reader should be the same.
|
||
*
|
||
* Future enhancement:
|
||
* 1) Provide default values for n and i and allow user to run with either 0 or 1 option
|
||
* 2) Use HDF library HD<system calls> instead of the system calls
|
||
* 3) Handle large sized buffer (gigabytes) if needed
|
||
*
|
||
* Return: Success: EXIT_SUCCESS
|
||
* Failure: EXIT_FAILURE
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
int
|
||
main(int argc, char *argv[])
|
||
{
|
||
int fd = -1; /* file descriptor */
|
||
ssize_t bytes_wrote; /* the nubmer of bytes written */
|
||
unsigned int *buf = NULL; /* buffer to hold written data */
|
||
unsigned int n, u, i; /* local index variable */
|
||
int temp; /* temporary variable */
|
||
unsigned int iterations = 0; /* the input for "-i" */
|
||
unsigned int num = 0; /* the input for "-n" */
|
||
int opt = 0; /* option char */
|
||
|
||
/* Ensure the # of arguments is as expected */
|
||
if(argc != 5) {
|
||
usage();
|
||
exit(EXIT_FAILURE);
|
||
} /* end if */
|
||
|
||
/* Parse command line options */
|
||
while((opt = getopt(argc, argv, "n:i:")) != -1) {
|
||
switch(opt) {
|
||
case 'n':
|
||
if((temp = atoi(optarg)) < 0) {
|
||
usage();
|
||
exit(EXIT_FAILURE);
|
||
} /* end if */
|
||
num = (unsigned int)temp;
|
||
break;
|
||
case 'i':
|
||
if((temp = atoi(optarg)) < 0) {
|
||
usage();
|
||
exit(EXIT_FAILURE);
|
||
} /* end if */
|
||
iterations = (unsigned int)temp;
|
||
break;
|
||
default:
|
||
printf("Invalid option encountered\n");
|
||
break;
|
||
} /* end switch */
|
||
} /* end while */
|
||
|
||
printf("WRITER: # of integers to write = %u; # of iterations = %d\n", num, iterations);
|
||
|
||
/* Remove existing data file if needed */
|
||
if(remove(FILENAME) < 0) {
|
||
if(errno == ENOENT)
|
||
printf("WRITER: remove %s--%s\n", FILENAME, strerror(errno));
|
||
else {
|
||
printf("WRITER: error from remove: %d--%s\n", errno, strerror(errno));
|
||
goto error;
|
||
} /* end else */
|
||
} else
|
||
printf("WRITER: %s is removed\n", FILENAME);
|
||
|
||
/* Create the data file */
|
||
if((fd = open(FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0664)) < 0) {
|
||
printf("WRITER: error from open\n");
|
||
goto error;
|
||
} /* end if */
|
||
|
||
/* Allocate buffer for holding data to be written */
|
||
if((buf = (unsigned int *)malloc(num * sizeof(unsigned int))) == NULL) {
|
||
printf("WRITER: error from malloc\n");
|
||
if(fd >= 0 && close(fd) < 0)
|
||
printf("WRITER: error from close\n");
|
||
goto error;
|
||
} /* end if */
|
||
|
||
printf("\n");
|
||
|
||
for(i = 1; i <= iterations; i++) {
|
||
printf("WRITER: *****start iteration %u*****\n", i);
|
||
|
||
/* Write the series of integers to the file */
|
||
for(n = 0; n < num; n++) {
|
||
|
||
/* Set up data to be written */
|
||
for(u=0; u < num; u++)
|
||
buf[u] = n;
|
||
|
||
/* Position the file to the proper location */
|
||
if(lseek(fd, (off_t)(n*sizeof(unsigned int)), SEEK_SET) < 0) {
|
||
printf("WRITER: error from lseek\n");
|
||
goto error;
|
||
} /* end if */
|
||
|
||
/* Write the data */
|
||
if((bytes_wrote = write(fd, buf, ((num-n) * sizeof(unsigned int)))) < 0) {
|
||
printf("WRITER: error from write\n");
|
||
goto error;
|
||
} /* end if */
|
||
|
||
/* Verify the bytes written is correct */
|
||
if(bytes_wrote != (ssize_t)((num-n) * sizeof(unsigned int))) {
|
||
printf("WRITER: error from bytes written\n");
|
||
goto error;
|
||
} /* end if */
|
||
} /* end for */
|
||
|
||
printf("WRITER: *****end iteration %u*****\n\n", i);
|
||
|
||
} /* end for */
|
||
|
||
/* Close the file */
|
||
if(close(fd) < 0) {
|
||
printf("WRITER: error from close\n");
|
||
goto error;
|
||
} /* end if */
|
||
|
||
/* Free the buffer */
|
||
if(buf)
|
||
free(buf);
|
||
|
||
return EXIT_SUCCESS;
|
||
|
||
error:
|
||
return EXIT_FAILURE;
|
||
} /* end main() */
|
||
|
||
#else /* WIN32 / MINGW32 */
|
||
|
||
int
|
||
main(void)
|
||
{
|
||
printf("Non-POSIX platform. Exiting.\n");
|
||
return EXIT_FAILURE;
|
||
} /* end main() */
|
||
|
||
#endif /* WIN32 / MINGW32 */
|
||
|