I am new to asynchronous I/O. I need to get it working in some C and Fortran programs on a Linux system. I managed to write a little C test code (included below) that reads asynchronously from two files. The code compiled and ran. What I am wondering, though, is whether I am truly getting asynchronous I/O, or is the I/O really serial? The lustre file system I am dealing with is a bit outdated and it is not clear that it actually supports asynchronous I/O, and no one seems to have a definite answer. So I am wondering are there some timing statements or any kind of output I can add to the code to determine whether it is functioning in a truly asynchronous manner. I'm betting I'll need much larger files than what I am dealing with to do a meaningful test. No idea what else I need.
The code is:
#include <stdio.h>
#include <stdlib.h>
/* for "open()" ... */
#include <fcntl.h>
/* for "bzero()" ... */
#include<strings.h>
/* for asynch I/O ... */
#include <aio.h>
/* for EINPROGRESS ... */
#include <errno.h>
/* for "usleep()" ... */
#include <unistd.h>
#define BUFSIZE 1024
int main() {
int fd0, fd1, readstat0, readstat1;
struct aiocb *ioobjs[2];
ioobjs[0] = malloc(sizeof(struct aiocb));
ioobjs[1] = malloc(sizeof(struct aiocb));
fd0 = open("file.txt", O_RDONLY);
if (fd0 < 0) perror("open");
fd1 = open("otherfile.txt", O_RDONLY);
if (fd1 < 0) perror("open");
bzero((char *)ioobjs[0], sizeof(struct aiocb));
bzero((char *)ioobjs[1], sizeof(struct aiocb));
ioobjs[0]->aio_buf = malloc(BUFSIZE+1);
if (!ioobjs[0]->aio_buf) perror("malloc 0");
ioobjs[1]->aio_buf = malloc(BUFSIZE+1);
if (!ioobjs[1]->aio_buf) perror("malloc 0");
ioobjs[0]->aio_fildes = fd0;
ioobjs[0]->aio_nbytes = BUFSIZE;
ioobjs[0]->aio_offset = 0;
/* Don't forget this! With list I/O, there is no
* particular function call to make. You have to
* tell what you want to do via this member of
* your aiocb struct:
*/
ioobjs[0]->aio_lio_opcode = LIO_READ;
ioobjs[1]->aio_fildes = fd1;
ioobjs[1]->aio_nbytes = BUFSIZE;
ioobjs[1]->aio_offset = 0;
ioobjs[1]->aio_lio_opcode = LIO_READ;
readstat0 = aio_read(ioobjs[0]);
if (readstat0 < 0) perror("reading 0");
readstat1 = aio_read(ioobjs[1]);
if (readstat1 < 0) perror("reading 1");
lio_listio(LIO_NOWAIT, ioobjs, 2, NULL);
/* don't completely understand. gives system time to
* "wrap things up". without this, one of the outputs
* below (maybe both) will have no output to give.
*/
usleep(100);
if ((readstat0 = aio_return( ioobjs[0] )) > 0) {
printf(">>>\n");
printf("%s\n", (char *)(ioobjs[0]->aio_buf));
printf("<<<\n");
} else {
perror("return");
}
if ((readstat1 = aio_return( ioobjs[1] )) > 0) {
printf(">>>\n");
printf("%s\n", (char *)(ioobjs[1]->aio_buf));
printf("<<<\n");
} else {
perror("return");
}
}