Re: async-io

From: Henrik Nordstrom <hno@dont-contact.us>
Date: Tue, 25 Apr 2000 01:39:52 +0200

Henrik Nordstrom wrote:
> A simple and dumb test program is attached. In the test above I ran it
> as

...

/Henrik

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>

static struct {
    int create:1;
    int reader:1;
    int makelist:1;
    int elevator:1;
    int length;
    int size;
    char *filename;
    char *myname;
    int filesize;
} options;

void usage(void) {
    fprintf(stderr, "Usage: %s [-e] [-c] -r|-n [-l ops] [-s size] [filename]\n"
                " -s Size of each operation\n"
                " -r Run a reader thread\n"
                " -n Create a list of operations\n"
                " -l Number of operations in each \"chunk\"\n"
                " -t Size of the file\n"
                " -e Single way elevator sort\n"
                "\n", options.myname);
    exit(0);
}

/* Reads offset from stdin */
void reader(int fd) {
    int size = options.size ? options.size : 8192;
    int n = 0, l = 0;
    char *buf;
    struct timeval started, thisblock, ended;
    buf = malloc(size);
    gettimeofday(&started, NULL);
    gettimeofday(&thisblock, NULL);
    printf("%8s %8s %8s %8s %8s\n", "requests","op/s","avg","bytes/s","avg");
    while(gets(buf)) {
        int off = atoi(buf);
        lseek(fd, off, SEEK_SET);
        read(fd, buf, size);
        n++;
        l++;
        if (l == options.length) {
            int diff, ldiff;
            gettimeofday(&ended, NULL);
            diff = (ended.tv_sec - thisblock.tv_sec) * 1000 +
                    (ended.tv_usec - thisblock.tv_usec) / 1000;
            ldiff = (ended.tv_sec - started.tv_sec) * 1000 +
                    (ended.tv_usec - started.tv_usec) / 1000;
            printf("%8d %8d %8d %8d %8d\n", n, l * 1000 / diff, n * 1000 / ldiff,
                    (int)(l * (double) size * 1000 / diff),
                    (int)(n * (double) size * 1000 / ldiff));
            l = 0;
            gettimeofday(&thisblock, NULL);
        }
    }
}

/* Writes offsets to stdout */
int sorter(const void *a1, const void *b1) {
    const int *a = a1, *b = b1;
    return *a - *b;
}
void makelist(int fd) {
    int *offsets;
    int n, l;
    int size = options.filesize;
    struct stat st;
    srandom(time(NULL));
    offsets=calloc(options.length, sizeof(int));
    assert(offsets);
    l = size / options.size;
    while(1) {
        for(n = 0; n <options.length; n++)
            offsets[n]=(random() % l) * options.size;
        if (options.elevator)
            qsort(offsets, options.length, sizeof(int), sorter);
        for(n = 0; n <options.length; n++)
            printf("%d\n",offsets[n]);
    }
}

int main(int argc, char **argv)
{
    int c;
    int fd;
    options.myname=argv[0];
    while((c = getopt(argc, argv, "crnl:s:t:e")) != -1) {
        switch(c) {
        case 'c':
                options.create = 1;
                break;
        case 'r':
                options.reader = 1;
                break;
        case 'n':
                options.makelist = 1;
                break;
        case 'l':
                options.length = atoi(optarg);
                break;
        case 's':
                options.size = atoi(optarg);
                break;
        case 't':
                options.filesize = atoi(optarg);
                break;
        case 'e':
                options.elevator = 1;
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argc!=1)
        usage();
    options.filename = argv[0];
    fd = open(options.filename, O_RDONLY, 0666);
    if (fd == -1) {
        perror("open failed");
        usage();
    }
    if (options.reader && options.makelist) {
        /* Run both jobs by pipeing them to each other */
        int pipefd[2];
        pipe(pipefd);
        if(fork() == 0) {
            /* Child process, runs I/O thread */
            options.makelist = 0;
            close(0);
            dup(pipefd[0]);
        } else {
            /* Master process, runs number generator */
            options.reader = 0;
            close(1);
            dup(pipefd[1]);
        }
        close(pipefd[0]);
        close(pipefd[1]);
    }
    if (options.reader)
        reader(fd);
    if (options.makelist)
        makelist(fd);
}
Received on Mon Apr 24 2000 - 17:40:16 MDT

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:12:24 MST