/* rawio.c: measure raw disk I/O throughput */
/*-
 * Copyright (c) 1999
 *	Nan Yang Computer Services Limited.  All rights reserved.
 *
 *  This software is distributed under the so-called ``Berkeley
 *  License'':
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Nan Yang Computer
 *      Services Limited.
 * 4. Neither the name of the Company nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *  
 * This software is provided ``as is'', and any express or implied
 * warranties, including, but not limited to, the implied warranties of
 * merchantability and fitness for a particular purpose are disclaimed.
 * In no event shall the company or contributors be liable for any
 * direct, indirect, incidental, special, exemplary, or consequential
 * damages (including, but not limited to, procurement of substitute
 * goods or services; loss of use, data, or profits; or business
 * interruption) however caused and on any theory of liability, whether
 * in contract, strict liability, or tort (including negligence or
 * otherwise) arising in any way out of the use of this software, even if
 * advised of the possibility of such damage.
 *
 * $Id: rawio.c,v 1.7 1999/07/21 02:10:09 grog Exp grog $
 */

#define LINELENGTH 200					    /* max length of program line */
#define MAXLINES 54					    /* number of lines on page */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <signal.h>
#ifdef	__FreeBSD__
#include <sys/random.h>
#endif
#ifdef	linux
#include <asm/types.h>
#include <linux/random.h>
#endif

/* submitted by Andy Doran <ad@psn.ie> */
#if defined (__NetBSD__) || defined (linux)
#include <errno.h>
#define srandomdev() srand ((unsigned) time (NULL))
#endif

#ifndef MAXPHYS
#define MAXPHYS 262144
#endif

#define SKIPSTART 16384					    /* amount to leave untouched at start of dev */

char buf [MAXPHYS];
int file;
int length;

int count;
enum operation
{
  RandomRead = 1,
  SequentialRead = 2,
  RandomWrite = 4,
  SequentialWrite = 8,
  }
op;
int openflags;						    /* flags to pass to open(2) */
enum operation thisop;					    /* current one we're looking at */
int test;						    /* number of test */
char *testname [] = {"RR", "SR", "RW", "SW"};		    /* names to identify tests */

char *args;
off_t offset;
int lines;
#define MAXCHILD 256					    /* maximum number of processes to start */
pid_t apid [MAXCHILD];
int nproc = 8;						    /* (default) number to start */

struct timeval start_time;
struct timeval end_time [MAXCHILD];			    /* one end time per process */
float elapsed_time;
float user_time;
float system_time;

struct rusage rusage [MAXCHILD];			    /* and associated rusage info */
struct rusage total_rusage;				    /* total values */

pid_t endproc [MAXCHILD];				    /* note the pid of each proc as it finishes */

/* Shared memory segment for communicating with
 * the children.  Each child accesses only its
 * element of the array.  The parent doesn't
 * touch them until they exit */
struct childinfo
{
  int reads;
  int writes;
  long long bytes_read;
  long long bytes_written;
  }
*childinfo;

int total_reads;
int total_writes;
long long total_bytes_read;
long long total_bytes_written;

/* child code */
void dochild (int test, int proc);

#define PAGELENGTH 60					    /* get this from termcap */
void
  checklines (int increment)
{
  char prompt [2];
  if ((lines += increment) >= PAGELENGTH)
    {
    fprintf (stderr, "More...");
    fgets (prompt, 2, stdin);
    lines = 0;
    }
  }

int maxchunk = 16384;					    /* maximum size of transfer */
long long filesize = 0;
int recs = 16384;					    /* number of records to transfer */
char *device;						    /* name of device to open */
int proc;						    /* index of this process in childinfo (child) */
							    /* index of current child (parent) */
int verbose = 0;					    /* verbosity flag */
int heading = 1;					    /* print heading if != 0 */
char *id;						    /* name of test */

int main (int argc, unsigned char *argv [])
{
  int mean = 0;
  int i;

#define MAXRANDOM 16384
  srandomdev ();
  printf ("#define MAXRANDOM %d\n"
	  "int randoms [] = {\n",
	  MAXRANDOM );
  for (i = 0; i < 16384; i++)
    {
    printf ("\t%i,", random ());
    if ((i & 03) == 3)					    /* end of line */
      printf ("\n");
    }
  printf ("};\n");
  printf ("\nint random2 [] = {\n");
  for (i = 0; i < 16384; i++)
    {
    printf ("\t%i,", random ());
    if ((i & 03) == 3)					    /* end of line */
      printf ("\n");
    }
  printf ("};\n");
  return 0;
  }


syntax highlighted by Code2HTML, v. 0.9.1