/*
 * Copyright (c) 2004 SuSE, Inc.  All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 * 
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 * 
 *
 * aio-stress
 *
 * will open or create each file on the command line, and start a series
 * of aio to it.  
 *
 * aio is done in a rotating loop.  first file1 gets 8 requests, then
 * file2, then file3 etc.  As each file finishes writing, it is switched
 * to reads
 *
 * io buffers are aligned in case you want to do raw io
 *
 * compile with gcc -Wall -laio -lpthread -o aio-stress aio-stress.c
 *
 * run aio-stress -h to see the options
 *
 * Please mail Chris Mason (mason@suse.com) with bug reports or patches
 */
#define _FILE_OFFSET_BITS 64
#define PROG_VERSION "0.21"
#define NEW_GETEVENTS

#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <libaio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <string.h>
#include <pthread.h>

#define IO_FREE 0
#define IO_PENDING 1
#define RUN_FOREVER -1

#ifndef O_DIRECT
#define O_DIRECT         040000 /* direct disk access hint */
#endif

enum {
    WRITE,
    READ,
    RWRITE,
    RREAD,
    LAST_STAGE,
};

#define USE_MALLOC 0
#define USE_SHM 1
#define USE_SHMFS 2

/* 
 * various globals, these are effectively read only by the time the threads
 * are started
 */
long stages = 0;
unsigned long page_size_mask;
int o_direct = 0;
int o_sync = 0;
int latency_stats = 0;
int completion_latency_stats = 0;
int io_iter = 8;
int iterations = RUN_FOREVER;
int max_io_submit = 0;
long rec_len = 64 * 1024;
int depth = 64;
int num_threads = 1;
int num_contexts = 1;
off_t context_offset = 2 * 1024 * 1024;
int fsync_stages = 1;
int use_shm = 0;
int shm_id;
char *unaligned_buffer = NULL;
char *aligned_buffer = NULL;
int padded_reclen = 0;
int stonewall = 1;
int verify = 0;
char *verify_buf = NULL;
int unlink_files = 0;

struct io_unit;
struct thread_info;

/* pthread mutexes and other globals for keeping the threads in sync */
pthread_cond_t stage_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t stage_mutex = PTHREAD_MUTEX_INITIALIZER;
int threads_ending = 0;
int threads_starting = 0;
struct timeval global_stage_start_time;
struct thread_info *global_thread_info;

/* 
 * latencies during io_submit are measured, these are the 
 * granularities for deviations 
 */
#define DEVIATIONS 6
int deviations[DEVIATIONS] = { 100, 250, 500, 1000, 5000, 10000 };
struct io_latency {
    double max;
    double min;
    double total_io;
    double total_lat;
    double deviations[DEVIATIONS]; 
};

/* container for a series of operations to a file */
struct io_oper {
    /* already open file descriptor, valid for whatever operation you want */
    int fd;

    /* starting byte of the operation */
    off_t start;

    /* ending byte of the operation */
    off_t end;

    /* size of the read/write buffer */
    int reclen;

    /* max number of pending requests before a wait is triggered */
    int depth;

    /* current number of pending requests */
    int num_pending;

    /* last error, zero if there were none */
    int last_err;

    /* total number of errors hit. */
    int num_err;

    /* read,write, random, etc */
    int rw;

    /* number of ios that will get sent to aio */
    int total_ios;

    /* number of ios we've already sent */
    int started_ios;

    /* last offset used in an io operation */
    off_t last_offset;

    /* stonewalled = 1 when we got cut off before submitting all our ios */
    int stonewalled;

    /* list management */
    struct io_oper *next;
    struct io_oper *prev;

    struct timeval start_time;

    char *file_name;
};

/* a single io, and all the tracking needed for it */
struct io_unit {
    /* note, iocb must go first! */
    struct iocb iocb;

    /* pointer to parent io operation struct */
    struct io_oper *io_oper;

    /* aligned buffer */
    char *buf;

    /* size of the aligned buffer (record size) */
    int buf_size;

    /* state of this io unit (free, pending, done) */
    int busy;

    /* result of last operation */
    long res;

    struct io_unit *next;

    struct timeval io_start_time;		/* time of io_submit */
};

struct thread_info {
    io_context_t io_ctx;
    pthread_t tid;

    /* allocated array of io_unit structs */
    struct io_unit *ios;

    /* list of io units available for io */
    struct io_unit *free_ious;

    /* number of io units in the ios array */
    int num_global_ios;

    /* number of io units in flight */
    int num_global_pending;

    /* preallocated array of iocb pointers, only used in run_active */
    struct iocb **iocbs;

    /* preallocated array of events */
    struct io_event *events;

    /* size of the events array */
    int num_global_events;

    /* latency stats for io_submit */
    struct io_latency io_submit_latency;

    /* list of operations still in progress, and of those finished */
    struct io_oper *active_opers;
    struct io_oper *finished_opers;

    /* number of files this thread is doing io on */
    int num_files;

    /* how much io this thread did in the last stage */
    double stage_mb_trans;

    /* latency completion stats i/o time from io_submit until io_getevents */
    struct io_latency io_completion_latency;
};

/*
 * return seconds between start_tv and stop_tv in double precision
 */
static double time_since(struct timeval *start_tv, struct timeval *stop_tv)
{
    double sec, usec;
    double ret;
    sec = stop_tv->tv_sec - start_tv->tv_sec;
    usec = stop_tv->tv_usec - start_tv->tv_usec;
    if (sec > 0 && usec < 0) {
        sec--;
	usec += 1000000;
    } 
    ret = sec + usec / (double)1000000;
    if (ret < 0)
        ret = 0;
    return ret;
}

/*
 * return seconds between start_tv and now in double precision
 */
static double time_since_now(struct timeval *start_tv)
{
    struct timeval stop_time;
    gettimeofday(&stop_time, NULL);
    return time_since(start_tv, &stop_time);
}

/*
 * Add latency info to latency struct 
 */
static void calc_latency(struct timeval *start_tv, struct timeval *stop_tv,
			struct io_latency *lat)
{
    double delta;
    int i;
    delta = time_since(start_tv, stop_tv);
    delta = delta * 1000;

    if (delta > lat->max)
    	lat->max = delta;
    if (!lat->min || delta < lat->min)
    	lat->min = delta;
    lat->total_io++;
    lat->total_lat += delta;
    for (i = 0 ; i < DEVIATIONS ; i++) {
        if (delta < deviations[i]) {
	    lat->deviations[i]++;
	    break;
	}
    }
}

static void oper_list_add(struct io_oper *oper, struct io_oper **list)
{
    if (!*list) {
        *list = oper;
	oper->prev = oper->next = oper;
	return;
    }
    oper->prev = (*list)->prev;
    oper->next = *list;
    (*list)->prev->next = oper;
    (*list)->prev = oper;
    return;
}

static void oper_list_del(struct io_oper *oper, struct io_oper **list)
{
    if ((*list)->next == (*list)->prev && *list == (*list)->next) {
        *list = NULL;
	return;
    }
    oper->prev->next = oper->next;
    oper->next->prev = oper->prev;
    if (*list == oper)
        *list = oper->next;
}

/* worker func to check error fields in the io unit */
static int check_finished_io(struct io_unit *io) {
    int i;
    if (io->res != io->buf_size) {

  		 struct stat s;
  		 fstat(io->io_oper->fd, &s);
  
  		 /*
  		  * If file size is large enough for the read, then this short
  		  * read is an error.
  		  */
  		 if ((io->io_oper->rw == READ || io->io_oper->rw == RREAD) &&
  		     s.st_size > (io->iocb.u.c.offset + io->res)) {
  
  		 		 fprintf(stderr, "io err %lu (%s) op %d, off %Lu size %d\n",
  		 		 		 io->res, strerror(-io->res), io->iocb.aio_lio_opcode,
  		 		 		 io->iocb.u.c.offset, io->buf_size);
  		 		 io->io_oper->last_err = io->res;
  		 		 io->io_oper->num_err++;
  		 		 return -1;
  		 }
    }
    if (verify && io->io_oper->rw == READ) {
        if (memcmp(io->buf, verify_buf, io->io_oper->reclen)) {
	    fprintf(stderr, "verify error, file %s offset %Lu contents (offset:bad:good):\n", 
	            io->io_oper->file_name, io->iocb.u.c.offset);
	    
	    for (i = 0 ; i < io->io_oper->reclen ; i++) {
	        if (io->buf[i] != verify_buf[i]) {
		    fprintf(stderr, "%d:%c:%c ", i, io->buf[i], verify_buf[i]);
		}
	    }
	    fprintf(stderr, "\n");
	}

    }
    return 0;
}

/* worker func to check the busy bits and get an io unit ready for use */
static int grab_iou(struct io_unit *io, struct io_oper *oper) {
    if (io->busy == IO_PENDING)
        return -1;

    io->busy = IO_PENDING;
    io->res = 0;
    io->io_oper = oper;
    return 0;
}

char *stage_name(int rw) {
    switch(rw) {
    case WRITE:
        return "write";
    case READ:
        return "read";
    case RWRITE:
        return "random write";
    case RREAD:
        return "random read";
    }
    return "unknown";
}

static inline double oper_mb_trans(struct io_oper *oper) {
    return ((double)oper->started_ios * (double)oper->reclen) /
                (double)(1024 * 1024);
}

static void print_time(struct io_oper *oper) {
    double runtime;
    double tput;
    double mb;

    runtime = time_since_now(&oper->start_time); 
    mb = oper_mb_trans(oper);
    tput = mb / runtime;
    fprintf(stderr, "%s on %s (%.2f MB/s) %.2f MB in %.2fs\n", 
	    stage_name(oper->rw), oper->file_name, tput, mb, runtime);
}

static void print_lat(char *str, struct io_latency *lat) {
    double avg = lat->total_lat / lat->total_io;
    int i;
    double total_counted = 0;
    fprintf(stderr, "%s min %.2f avg %.2f max %.2f\n\t", 
            str, lat->min, avg, lat->max);

    for (i = 0 ; i < DEVIATIONS ; i++) {
	fprintf(stderr, " %.0f < %d", lat->deviations[i], deviations[i]);
	total_counted += lat->deviations[i];
    }
    if (total_counted && lat->total_io - total_counted)
        fprintf(stderr, " < %.0f", lat->total_io - total_counted);
    fprintf(stderr, "\n");
    memset(lat, 0, sizeof(*lat));
}

static void print_latency(struct thread_info *t)
{
    struct io_latency *lat = &t->io_submit_latency;
    print_lat("latency", lat);
}

static void print_completion_latency(struct thread_info *t)
{
    struct io_latency *lat = &t->io_completion_latency;
    print_lat("completion latency", lat);
}

/*
 * updates the fields in the io operation struct that belongs to this
 * io unit, and make the io unit reusable again
 */
void finish_io(struct thread_info *t, struct io_unit *io, long result,
		struct timeval *tv_now) {
    struct io_oper *oper = io->io_oper;

    calc_latency(&io->io_start_time, tv_now, &t->io_completion_latency);
    io->res = result;
    io->busy = IO_FREE;
    io->next = t->free_ious;
    t->free_ious = io;
    oper->num_pending--;
    t->num_global_pending--;
    check_finished_io(io);
    if (oper->num_pending == 0 && 
       (oper->started_ios == oper->total_ios || oper->stonewalled)) 
    {
        print_time(oper);
    } 
}

int read_some_events(struct thread_info *t) {
    struct io_unit *event_io;
    struct io_event *event;
    int nr;
    int i; 
    int min_nr = io_iter;
    struct timeval stop_time;

    if (t->num_global_pending < io_iter)
        min_nr = t->num_global_pending;

#ifdef NEW_GETEVENTS
    nr = io_getevents(t->io_ctx, min_nr, t->num_global_events, t->events,NULL);
#else
    nr = io_getevents(t->io_ctx, t->num_global_events, t->events, NULL);
#endif
    if (nr <= 0)
        return nr;

    gettimeofday(&stop_time, NULL);
    for (i = 0 ; i < nr ; i++) {
	event = t->events + i;
	event_io = (struct io_unit *)((unsigned long)event->obj); 
	finish_io(t, event_io, event->res, &stop_time);
    }
    return nr;
}

/* 
 * finds a free io unit, waiting for pending requests if required.  returns
 * null if none could be found
 */
static struct io_unit *find_iou(struct thread_info *t, struct io_oper *oper)
{
    struct io_unit *event_io;
    int nr;

retry:
    if (t->free_ious) {
        event_io = t->free_ious;
	t->free_ious = t->free_ious->next;
	if (grab_iou(event_io, oper)) {
	    fprintf(stderr, "io unit on free list but not free\n");
	    abort();
	}
	return event_io;
    }
    nr = read_some_events(t);
    if (nr > 0)
    	goto retry;
    else
    	fprintf(stderr, "no free ious after read_some_events\n");
    return NULL;
}

/*
 * wait for all pending requests for this io operation to finish
 */
static int io_oper_wait(struct thread_info *t, struct io_oper *oper) {
    struct io_event event;
    struct io_unit *event_io;

    if (oper == NULL) {
        return 0;
    }

    if (oper->num_pending == 0)
        goto done;

    /* this func is not speed sensitive, no need to go wild reading
     * more than one event at a time
     */
#ifdef NEW_GETEVENTS
    while(io_getevents(t->io_ctx, 1, 1, &event, NULL) > 0) {
#else
    while(io_getevents(t->io_ctx, 1, &event, NULL) > 0) {
#endif
	struct timeval tv_now;
        event_io = (struct io_unit *)((unsigned long)event.obj); 

	gettimeofday(&tv_now, NULL);
	finish_io(t, event_io, event.res, &tv_now);

	if (oper->num_pending == 0)
	    break;
    }
done:
    if (oper->num_err) {
        fprintf(stderr, "%u errors on oper, last %u\n", 
	        oper->num_err, oper->last_err);
    }
    return 0;
}

off_t random_byte_offset(struct io_oper *oper) {
    off_t num;
    off_t rand_byte = oper->start;
    off_t range;
    off_t offset = 1;

    range = (oper->end - oper->start) / (1024 * 1024);
    if ((page_size_mask+1) > (1024 * 1024))
        offset = (page_size_mask+1) / (1024 * 1024);
    if (range < offset)
        range = 0;
    else
        range -= offset;

    /* find a random mb offset */
    num = 1 + (int)((double)range * rand() / (RAND_MAX + 1.0 ));
    rand_byte += num * 1024 * 1024;
    
    /* find a random byte offset */
    num = 1 + (int)((double)(1024 * 1024) * rand() / (RAND_MAX + 1.0));

    /* page align */
    num = (num + page_size_mask) & ~page_size_mask;
    rand_byte += num;

    if (rand_byte + oper->reclen > oper->end) {
	rand_byte -= oper->reclen;
    }
    return rand_byte;
}

/* 
 * build an aio iocb for an operation, based on oper->rw and the
 * last offset used.  This finds the struct io_unit that will be attached
 * to the iocb, and things are ready for submission to aio after this
 * is called.
 *
 * returns null on error
 */
static struct io_unit *build_iocb(struct thread_info *t, struct io_oper *oper)
{
    struct io_unit *io;
    off_t rand_byte;

    io = find_iou(t, oper);
    if (!io) {
        fprintf(stderr, "unable to find io unit\n");
	return NULL;
    }

    switch(oper->rw) {
    case WRITE:
        io_prep_pwrite(&io->iocb,oper->fd, io->buf, oper->reclen, 
	               oper->last_offset);
	oper->last_offset += oper->reclen;
	break;
    case READ:
        io_prep_pread(&io->iocb,oper->fd, io->buf, oper->reclen, 
	              oper->last_offset);
	oper->last_offset += oper->reclen;
	break;
    case RREAD:
	rand_byte = random_byte_offset(oper);
	oper->last_offset = rand_byte;
        io_prep_pread(&io->iocb,oper->fd, io->buf, oper->reclen, 
	              rand_byte);
        break;
    case RWRITE:
	rand_byte = random_byte_offset(oper);
	oper->last_offset = rand_byte;
        io_prep_pwrite(&io->iocb,oper->fd, io->buf, oper->reclen, 
	              rand_byte);
        
        break;
    }

    return io;
}

/* 
 * wait for any pending requests, and then free all ram associated with
 * an operation.  returns the last error the operation hit (zero means none)
 */
static int
finish_oper(struct thread_info *t, struct io_oper *oper)
{
    unsigned long last_err;

    io_oper_wait(t, oper);
    last_err = oper->last_err;
    if (oper->num_pending > 0) {
        fprintf(stderr, "oper num_pending is %d\n", oper->num_pending);
    }
    close(oper->fd);
    free(oper);
    return last_err;
}

/* 
 * allocates an io operation and fills in all the fields.  returns
 * null on error
 */
static struct io_oper * 
create_oper(int fd, int rw, off_t start, off_t end, int reclen, int depth,
            int iter, char *file_name)
{
    struct io_oper *oper;

    oper = malloc (sizeof(*oper));
    if (!oper) {
	fprintf(stderr, "unable to allocate io oper\n");
	return NULL;
    }
    memset(oper, 0, sizeof(*oper));

    oper->depth = depth;
    oper->start = start;
    oper->end = end;
    oper->last_offset = oper->start;
    oper->fd = fd;
    oper->reclen = reclen;
    oper->rw = rw;
    oper->total_ios = (oper->end - oper->start) / oper->reclen;
    oper->file_name = file_name;

    return oper;
}

/*
 * does setup on num_ios worth of iocbs, but does not actually
 * start any io
 */
int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios, 
               struct iocb **my_iocbs) 
{
    int i;
    struct io_unit *io;

    if (oper->started_ios == 0)
	gettimeofday(&oper->start_time, NULL);

    if (num_ios == 0)
        num_ios = oper->total_ios;

    if ((oper->started_ios + num_ios) > oper->total_ios)
        num_ios = oper->total_ios - oper->started_ios;   

    for( i = 0 ; i < num_ios ; i++) {
	io = build_iocb(t, oper);
	if (!io) {
	    return -1;    
	}
	my_iocbs[i] = &io->iocb;
    }
    return num_ios;
}

/*
 * runs through the iocbs in the array provided and updates
 * counters in the associated oper struct
 */
static void update_iou_counters(struct iocb **my_iocbs, int nr,
	struct timeval *tv_now) 
{
    struct io_unit *io;
    int i;
    for (i = 0 ; i < nr ; i++) {
	io = (struct io_unit *)(my_iocbs[i]);
	io->io_oper->num_pending++;
	io->io_oper->started_ios++;
	io->io_start_time = *tv_now;	/* set time of io_submit */
    }
}

/* starts some io for a given file, returns zero if all went well */
int run_built(struct thread_info *t, int num_ios, struct iocb **my_iocbs) 
{
    int ret;
    struct timeval start_time;
    struct timeval stop_time;

resubmit:
    gettimeofday(&start_time, NULL);
    ret = io_submit(t->io_ctx, num_ios, my_iocbs);
    gettimeofday(&stop_time, NULL);
    calc_latency(&start_time, &stop_time, &t->io_submit_latency);

    if (ret != num_ios) {
	/* some ios got through */
	if (ret > 0) {
	    update_iou_counters(my_iocbs, ret, &stop_time);
	    my_iocbs += ret;
	    t->num_global_pending += ret;
	    num_ios -= ret;
	}
	/* 
	 * we've used all the requests allocated in aio_init, wait and
	 * retry
	 */
	if (ret > 0 || ret == -EAGAIN) {
	    int old_ret = ret;
	    if ((ret = read_some_events(t) > 0)) {
		goto resubmit;
	    } else {
	    	fprintf(stderr, "ret was %d and now is %d\n", ret, old_ret);
		abort();
	    }
	}

	fprintf(stderr, "ret %d (%s) on io_submit\n", ret, strerror(-ret));
	return -1;
    }
    update_iou_counters(my_iocbs, ret, &stop_time);
    t->num_global_pending += ret;
    return 0;
}

/* 
 * changes oper->rw to the next in a command sequence, or returns zero
 * to say this operation is really, completely done for
 */
static int restart_oper(struct io_oper *oper) {
    int new_rw  = 0;
    if (oper->last_err)
        return 0;

    /* this switch falls through */
    switch(oper->rw) {
    case WRITE:
	if (stages & (1 << READ))
	    new_rw = READ;
    case READ:
	if (!new_rw && stages & (1 << RWRITE))
	    new_rw = RWRITE;
    case RWRITE:
	if (!new_rw && stages & (1 << RREAD))
	    new_rw = RREAD;
    }

    if (new_rw) {
	oper->started_ios = 0;
	oper->last_offset = oper->start;
	oper->stonewalled = 0;

	/* 
	 * we're restarting an operation with pending requests, so the
	 * timing info won't be printed by finish_io.  Printing it here
	 */
	if (oper->num_pending)
	    print_time(oper);

	oper->rw = new_rw;
	return 1;
    } 
    return 0;
}

static int oper_runnable(struct io_oper *oper) {
    struct stat buf;
    int ret;

    /* first context is always runnable, if started_ios > 0, no need to
     * redo the calculations
     */
    if (oper->started_ios || oper->start == 0)
        return 1;
    /*
     * only the sequential phases force delays in starting */
    if (oper->rw >= RWRITE)
        return 1;
    ret = fstat(oper->fd, &buf);
    if (ret < 0) {
        perror("fstat");
	exit(1);
    }
    if (S_ISREG(buf.st_mode) && buf.st_size < oper->start)
        return 0;
    return 1;
}

/*
 * runs through all the io operations on the active list, and starts
 * a chunk of io on each.  If any io operations are completely finished,
 * it either switches them to the next stage or puts them on the 
 * finished list.
 *
 * this function stops after max_io_submit iocbs are sent down the 
 * pipe, even if it has not yet touched all the operations on the 
 * active list.  Any operations that have finished are moved onto
 * the finished_opers list.
 */
static int run_active_list(struct thread_info *t,
			 int io_iter,
			 int max_io_submit)
{
    struct io_oper *oper;
    struct io_oper *built_opers = NULL;
    struct iocb **my_iocbs = t->iocbs;
    int ret = 0;
    int num_built = 0;

    oper = t->active_opers;
    while(oper) {
	if (!oper_runnable(oper)) {
	    oper = oper->next;
	    if (oper == t->active_opers)
	        break;
	    continue;
	}
	ret = build_oper(t, oper, io_iter, my_iocbs);
	if (ret >= 0) {
	    my_iocbs += ret;
	    num_built += ret;
	    oper_list_del(oper, &t->active_opers);
	    oper_list_add(oper, &built_opers);
	    oper = t->active_opers;
	    if (num_built + io_iter > max_io_submit)
	        break;
	} else
	    break;
    }
    if (num_built) {
	ret = run_built(t, num_built, t->iocbs);
	if (ret < 0) {
	    fprintf(stderr, "error %d on run_built\n", ret);
	    exit(1);
	}
	while(built_opers) {
	    oper = built_opers;
	    oper_list_del(oper, &built_opers);
	    oper_list_add(oper, &t->active_opers);
	    if (oper->started_ios == oper->total_ios) {
		oper_list_del(oper, &t->active_opers);
		oper_list_add(oper, &t->finished_opers);
	    }
	}
    }
    return 0;
}

void drop_shm() {
    int ret;
    struct shmid_ds ds;
    if (use_shm != USE_SHM)
        return;

    ret = shmctl(shm_id, IPC_RMID, &ds);
    if (ret) {
        perror("shmctl IPC_RMID");
    }
}

void aio_setup(io_context_t *io_ctx, int n)
{
    int res = io_queue_init(n, io_ctx);
    if (res != 0) {
	fprintf(stderr, "io_queue_setup(%d) returned %d (%s)\n",
		n, res, strerror(-res));
	exit(3);
    }
}

/*
 * allocate io operation and event arrays for a given thread
 */
int setup_ious(struct thread_info *t, 
              int num_files, int depth, 
	      int reclen, int max_io_submit) {
    int i;
    size_t bytes = num_files * depth * sizeof(*t->ios);

    t->ios = malloc(bytes);
    if (!t->ios) {
	fprintf(stderr, "unable to allocate io units\n");
	return -1;
    }
    memset(t->ios, 0, bytes);

    for (i = 0 ; i < depth * num_files; i++) {
	t->ios[i].buf = aligned_buffer;
	aligned_buffer += padded_reclen;
	t->ios[i].buf_size = reclen;
	if (verify)
	    memset(t->ios[i].buf, 'b', reclen);
	else
	    memset(t->ios[i].buf, 0, reclen);
	t->ios[i].next = t->free_ious;
	t->free_ious = t->ios + i;
    }
    if (verify) {
        verify_buf = aligned_buffer;
        memset(verify_buf, 'b', reclen);
    }

    t->iocbs = malloc(sizeof(struct iocb *) * max_io_submit);
    if (!t->iocbs) {
        fprintf(stderr, "unable to allocate iocbs\n");
	goto free_buffers;
    }

    memset(t->iocbs, 0, max_io_submit * sizeof(struct iocb *));

    t->events = malloc(sizeof(struct io_event) * depth * num_files);
    if (!t->events) {
        fprintf(stderr, "unable to allocate ram for events\n");
	goto free_buffers;
    }
    memset(t->events, 0, num_files * sizeof(struct io_event)*depth);

    t->num_global_ios = num_files * depth;
    t->num_global_events = t->num_global_ios;
    return 0;

free_buffers:
    if (t->ios)
        free(t->ios);
    if (t->iocbs)
        free(t->iocbs);  
    if (t->events)
        free(t->events);
    return -1;
}

/*
 * The buffers used for file data are allocated as a single big
 * malloc, and then each thread and operation takes a piece and uses
 * that for file data.  This lets us do a large shm or bigpages alloc
 * and without trying to find a special place in each thread to map the
 * buffers to
 */
int setup_shared_mem(int num_threads, int num_files, int depth, 
                     int reclen, int max_io_submit) 
{
    char *p = NULL;
    size_t total_ram;
    
    padded_reclen = (reclen + page_size_mask) / (page_size_mask+1);
    padded_reclen = padded_reclen * (page_size_mask+1);
    total_ram = num_files * depth * padded_reclen + num_threads;
    if (verify)
    	total_ram += padded_reclen;

    if (use_shm == USE_MALLOC) {
	p = malloc(total_ram + page_size_mask);
    } else if (use_shm == USE_SHM) {
        shm_id = shmget(IPC_PRIVATE, total_ram, IPC_CREAT | 0700);
	if (shm_id < 0) {
	    perror("shmget");
	    drop_shm();
	    goto free_buffers;
	}
	p = shmat(shm_id, (char *)0x50000000, 0);
        if ((long)p == -1) {
	    perror("shmat");
	    goto free_buffers;
	}
	/* won't really be dropped until we shmdt */
	drop_shm();
    } else if (use_shm == USE_SHMFS) {
        char mmap_name[16]; /* /dev/shm/ + null + XXXXXX */    
	int fd;

	strcpy(mmap_name, "/dev/shm/XXXXXX");
	fd = mkstemp(mmap_name);
        if (fd < 0) {
	    perror("mkstemp");
	    goto free_buffers;
	}
	unlink(mmap_name);
	ftruncate(fd, total_ram);
	shm_id = fd;
	p = mmap((char *)0x50000000, total_ram,
	         PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

        if (p == MAP_FAILED) {
	    perror("mmap");
	    goto free_buffers;
	}
    }
    if (!p) {
        fprintf(stderr, "unable to allocate buffers\n");
	goto free_buffers;
    }
    unaligned_buffer = p;
    p = (char*)((intptr_t) (p + page_size_mask) & ~page_size_mask);
    aligned_buffer = p;
    return 0;

free_buffers:
    drop_shm();
    if (unaligned_buffer)
        free(unaligned_buffer);
    return -1;
}

/*
 * runs through all the thread_info structs and calculates a combined
 * throughput
 */
void global_thread_throughput(struct thread_info *t, char *this_stage) {
    int i;
    double runtime = time_since_now(&global_stage_start_time);
    double total_mb = 0;
    double min_trans = 0;

    for (i = 0 ; i < num_threads ; i++) {
        total_mb += global_thread_info[i].stage_mb_trans;
	if (!min_trans || t->stage_mb_trans < min_trans)
	    min_trans = t->stage_mb_trans;
    }
    if (total_mb) {
	fprintf(stderr, "%s throughput (%.2f MB/s) ", this_stage,
	        total_mb / runtime);
	fprintf(stderr, "%.2f MB in %.2fs", total_mb, runtime);
        if (stonewall)
	    fprintf(stderr, " min transfer %.2fMB", min_trans);
        fprintf(stderr, "\n");
    }
}


/* this is the meat of the state machine.  There is a list of
 * active operations structs, and as each one finishes the required
 * io it is moved to a list of finished operations.  Once they have
 * all finished whatever stage they were in, they are given the chance
 * to restart and pick a different stage (read/write/random read etc)
 *
 * various timings are printed in between the stages, along with
 * thread synchronization if there are more than one threads.
 */
int worker(struct thread_info *t)
{
    struct io_oper *oper;
    char *this_stage = NULL;
    struct timeval stage_time;
    int status = 0;
    int iteration = 0;
    int cnt;

    aio_setup(&t->io_ctx, 512);

restart:
    if (num_threads > 1) {
        pthread_mutex_lock(&stage_mutex);
	threads_starting++;
	if (threads_starting == num_threads) {
	    threads_ending = 0;
	    gettimeofday(&global_stage_start_time, NULL);
	    pthread_cond_broadcast(&stage_cond);
	}
	while (threads_starting != num_threads)
	    pthread_cond_wait(&stage_cond, &stage_mutex);
        pthread_mutex_unlock(&stage_mutex);
    }
    if (t->active_opers) {
        this_stage = stage_name(t->active_opers->rw);
	gettimeofday(&stage_time, NULL);
	t->stage_mb_trans = 0;
    }

    cnt = 0;
    /* first we send everything through aio */
    while(t->active_opers && (cnt < iterations || iterations == RUN_FOREVER)) {
	if (stonewall && threads_ending) {
	    oper = t->active_opers;
	    oper->stonewalled = 1;
	    oper_list_del(oper, &t->active_opers);
	    oper_list_add(oper, &t->finished_opers);
	} else {
	    run_active_list(t, io_iter,  max_io_submit);
        }
	cnt++;
    }
    if (latency_stats)
        print_latency(t);

    if (completion_latency_stats)
	print_completion_latency(t);

    /* then we wait for all the operations to finish */
    oper = t->finished_opers;
    do {
	if (!oper)
		break;
	io_oper_wait(t, oper);
	oper = oper->next;
    } while(oper != t->finished_opers);

    /* then we do an fsync to get the timing for any future operations
     * right, and check to see if any of these need to get restarted
     */
    oper = t->finished_opers;
    while(oper) {
	if (fsync_stages)
            fsync(oper->fd);
	t->stage_mb_trans += oper_mb_trans(oper);
	if (restart_oper(oper)) {
	    oper_list_del(oper, &t->finished_opers);
	    oper_list_add(oper, &t->active_opers);
	    oper = t->finished_opers;
	    continue;
	}
	oper = oper->next;
	if (oper == t->finished_opers)
	    break;
    } 

    if (t->stage_mb_trans && t->num_files > 0) {
        double seconds = time_since_now(&stage_time);
	fprintf(stderr, "thread %d %s totals (%.2f MB/s) %.2f MB in %.2fs\n", 
	        t - global_thread_info, this_stage, t->stage_mb_trans/seconds, 
		t->stage_mb_trans, seconds);
    }

    if (num_threads > 1) {
	pthread_mutex_lock(&stage_mutex);
	threads_ending++;
	if (threads_ending == num_threads) {
	    threads_starting = 0;
	    pthread_cond_broadcast(&stage_cond);
	    global_thread_throughput(t, this_stage);
	}
	while(threads_ending != num_threads)
	    pthread_cond_wait(&stage_cond, &stage_mutex);
	pthread_mutex_unlock(&stage_mutex);
    }
    
    /* someone got restarted, go back to the beginning */
    if (t->active_opers && (cnt < iterations || iterations == RUN_FOREVER)) {
	iteration++;
        goto restart;
    }

    /* finally, free all the ram */
    while(t->finished_opers) {
	oper = t->finished_opers;
	oper_list_del(oper, &t->finished_opers);
	status = finish_oper(t, oper);
    }

    if (t->num_global_pending) {
        fprintf(stderr, "global num pending is %d\n", t->num_global_pending);
    }
    io_queue_release(t->io_ctx);
    
    return status;
}

typedef void * (*start_routine)(void *);
int run_workers(struct thread_info *t, int num_threads)
{
    int ret;
    int thread_ret;
    int i;

    for(i = 0 ; i < num_threads ; i++) {
        ret = pthread_create(&t[i].tid, NULL, (start_routine)worker, t + i);
	if (ret) {
	    perror("pthread_create");
	    exit(1);
	}
    }
    for(i = 0 ; i < num_threads ; i++) {
        ret = pthread_join(t[i].tid, (void *)&thread_ret);
        if (ret) {
	    perror("pthread_join");
	    exit(1);
	}
    }
    return 0;
}

off_t parse_size(char *size_arg, off_t mult) {
    char c;
    int num;
    off_t ret;
    c = size_arg[strlen(size_arg) - 1];
    if (c > '9') {
        size_arg[strlen(size_arg) - 1] = '\0';
    }
    num = atoi(size_arg);
    switch(c) {
    case 'g':
    case 'G':
        mult = 1024 * 1024 * 1024;
	break;
    case 'm':
    case 'M':
        mult = 1024 * 1024;
	break;
    case 'k':
    case 'K':
        mult = 1024;
	break;
    case 'b':
    case 'B':
        mult = 1;
	break;
    }
    ret = mult * num;
    return ret;
}

void print_usage(void) {
    printf("usage: aio-stress [-s size] [-r size] [-a size] [-d num] [-b num]\n");
    printf("                  [-i num] [-t num] [-c num] [-C size] [-nxhOS ]\n");
    printf("                  file1 [file2 ...]\n");
    printf("\t-a size in KB at which to align buffers\n");
    printf("\t-b max number of iocbs to give io_submit at once\n");
    printf("\t-c number of io contexts per file\n");
    printf("\t-C offset between contexts, default 2MB\n");
    printf("\t-s size in MB of the test file(s), default 1024MB\n");
    printf("\t-r record size in KB used for each io, default 64KB\n");
    printf("\t-d number of pending aio requests for each file, default 64\n");
    printf("\t-i number of ios per file sent before switching\n\t   to the next file, default 8\n");
    printf("\t-I total number of ayncs IOs the program will run, default is run until Cntl-C\n");
    printf("\t-O Use O_DIRECT (not available in 2.4 kernels),\n");
    printf("\t-S Use O_SYNC for writes\n");
    printf("\t-o add an operation to the list: write=0, read=1,\n"); 
    printf("\t   random write=2, random read=3.\n");
    printf("\t   repeat -o to specify multiple ops: -o 0 -o 1 etc.\n");
    printf("\t-m shm use ipc shared memory for io buffers instead of malloc\n");
    printf("\t-m shmfs mmap a file in /dev/shm for io buffers\n");
    printf("\t-n no fsyncs between write stage and read stage\n");
    printf("\t-l print io_submit latencies after each stage\n");
    printf("\t-L print io completion latencies after each stage\n");
    printf("\t-t number of threads to run\n");
    printf("\t-u unlink files after completion\n");
    printf("\t-v verification of bytes written\n");
    printf("\t-x turn off thread stonewalling\n");
    printf("\t-h this message\n");
    printf("\n\t   the size options (-a -s and -r) allow modifiers -s 400{k,m,g}\n");
    printf("\t   translate to 400KB, 400MB and 400GB\n");
    printf("version %s\n", PROG_VERSION);
}

int main(int ac, char **av) 
{
    int rwfd;
    int i;
    int j;
    int c;

    off_t file_size = 1 * 1024 * 1024 * 1024;
    int first_stage = WRITE;
    struct io_oper *oper;
    int status = 0;
    int num_files = 0;
    int open_fds = 0;
    struct thread_info *t;

    page_size_mask = getpagesize() - 1;

    while(1) {
	c = getopt(ac, av, "a:b:c:C:m:s:r:d:i:I:o:t:lLnhOSxvu");
	if  (c < 0)
	    break;

        switch(c) {
	case 'a':
	    page_size_mask = parse_size(optarg, 1024);
	    page_size_mask--;
	    break;
	case 'c':
	    num_contexts = atoi(optarg);
	    break;
	case 'C':
	    context_offset = parse_size(optarg, 1024 * 1024);
	case 'b':
	    max_io_submit = atoi(optarg);
	    break;
	case 's':
	    file_size = parse_size(optarg, 1024 * 1024);
	    break;
	case 'd':
	    depth = atoi(optarg);
	    break;
	case 'r':
	    rec_len = parse_size(optarg, 1024);
	    break;
	case 'i':
	    io_iter = atoi(optarg);
	    break;
        case 'I':
          iterations = atoi(optarg);
        break;
	case 'n':
	    fsync_stages = 0;
	    break;
	case 'l':
	    latency_stats = 1;
	    break;
	case 'L':
	    completion_latency_stats = 1;
	    break;
	case 'm':
	    if (!strcmp(optarg, "shm")) {
		fprintf(stderr, "using ipc shm\n");
	        use_shm = USE_SHM;
	    } else if (!strcmp(optarg, "shmfs")) {
	        fprintf(stderr, "using /dev/shm for buffers\n");
		use_shm = USE_SHMFS;
	    }
	    break;
	case 'o': 
	    i = atoi(optarg);
	    stages |= 1 << i;
	    fprintf(stderr, "adding stage %s\n", stage_name(i));
	    break;
	case 'O':
	    o_direct = O_DIRECT;
	    break;
	case 'S':
	    o_sync = O_SYNC;
	    break;
	case 't':
	    num_threads = atoi(optarg);
	    break;
	case 'x':
	    stonewall = 0;
	    break;
	case 'u':
	    unlink_files = 1;
	    break;
	case 'v':
	    verify = 1;
	    break;
	case 'h':
	default:
	    print_usage();
	    exit(1);
	}
    }

    /* 
     * make sure we don't try to submit more ios than we have allocated
     * memory for
     */
    if (depth < io_iter) {
	io_iter = depth;
        fprintf(stderr, "dropping io_iter to %d\n", io_iter);
    }

    if (optind >= ac) {
	print_usage();
	exit(1);
    }

    num_files = ac - optind;

    if (num_threads > (num_files * num_contexts)) {
        num_threads = num_files * num_contexts;
	fprintf(stderr, "dropping thread count to the number of contexts %d\n", 
	        num_threads);
    }

    t = malloc(num_threads * sizeof(*t));
    if (!t) {
        perror("malloc");
	exit(1);
    }
    global_thread_info = t;

    /* by default, allow a huge number of iocbs to be sent towards
     * io_submit
     */
    if (!max_io_submit)
        max_io_submit = num_files * io_iter * num_contexts;

    /*
     * make sure we don't try to submit more ios than max_io_submit allows 
     */
    if (max_io_submit < io_iter) {
        io_iter = max_io_submit;
	fprintf(stderr, "dropping io_iter to %d\n", io_iter);
    }

    if (!stages) {
        stages = (1 << WRITE) | (1 << READ) | (1 << RREAD) | (1 << RWRITE);
    } else {
        for (i = 0 ; i < LAST_STAGE; i++) {
	    if (stages & (1 << i)) {
	        first_stage = i;
		fprintf(stderr, "starting with %s\n", stage_name(i));
		break;
	    }
	}
    }

    if (file_size < num_contexts * context_offset) {
        fprintf(stderr, "file size %Lu too small for %d contexts\n", 
	        file_size, num_contexts);
	exit(1);
    }

    fprintf(stderr, "file size %LuMB, record size %luKB, depth %d, ios per iteration %d\n", file_size / (1024 * 1024), rec_len / 1024, depth, io_iter);
    fprintf(stderr, "max io_submit %d, buffer alignment set to %luKB\n", 
            max_io_submit, (page_size_mask + 1)/1024);
    fprintf(stderr, "threads %d files %d contexts %d context offset %LuMB verification %s\n", 
            num_threads, num_files, num_contexts, 
	    context_offset / (1024 * 1024), verify ? "on" : "off");
    /* open all the files and do any required setup for them */
    for (i = optind ; i < ac ; i++) {
	int thread_index;
	for (j = 0 ; j < num_contexts ; j++) {
	    thread_index = open_fds % num_threads;
	    open_fds++;

	    rwfd = open(av[i], O_CREAT | O_RDWR | o_direct | o_sync, 0600);
	    assert(rwfd != -1);

	    oper = create_oper(rwfd, first_stage, j * context_offset, 
	                       file_size - j * context_offset, rec_len, 
			       depth, io_iter, av[i]);
	    if (!oper) {
		fprintf(stderr, "error in create_oper\n");
		exit(-1);
	    }
	    oper_list_add(oper, &t[thread_index].active_opers);
	    t[thread_index].num_files++;
	}
    }
    if (setup_shared_mem(num_threads, num_files * num_contexts, 
                         depth, rec_len, max_io_submit))
    {
        exit(1);
    }
    for (i = 0 ; i < num_threads ; i++) {
	if (setup_ious(&t[i], t[i].num_files, depth, rec_len, max_io_submit))
		exit(1);
    }
    if (num_threads > 1){
        printf("Running multi thread version num_threads:%d\n", num_threads);
        run_workers(t, num_threads);
    } else {
        printf("Running single thread version \n");
	status = worker(t);
    }
    if (unlink_files) {
	for (i = optind ; i < ac ; i++) {
	    printf("Cleaning up file %s \n", av[i]);
	    unlink(av[i]);
	}
    }

    if (status) {
	exit(1);
    }
    return status;
}

