/* test-file.c
 James Larus, Jan. 1990

 Write a large file in various way to find the most efficient buffer size for
 AE.

 Basically, this program writes out a 1MB buffer (but also try it with
 8MBs if you have the disk space) in 4 ways:

 1. In a 1 MB chunk aligned on a pagesize boundary.

 2. In 32K chunks aligned on pagesize boundaries.

 3. In a 1 MB chunk not aligned on a boundary.

 4. In 32K chunks not aligned on boundaries.

 */


#include <sys/file.h>
#include <sys/time.h>
#include <sys/resource.h>

#define SIZE 1048576		/* 2 ^ 20 */
#define CHUNK 32768		/* 2 ^ 15 */
#define JITTER 3

#define TD(te,ts) (float) (((te).tv_sec - (ts).tv_sec) * 1.0 \
			   + (((te).tv_usec - (ts).tv_usec) / 1000000.0))

char *malloc ();


main (argc, argv)
     int argc;
     char *argv[];
{

  register char *buf1, *buf2, *buf3, *buf4;
  register int i;
  register int f1, f2, f3, f4;
  struct rusage start, end;
  register int pagesize = getpagesize ();

  buf1 = malloc (SIZE + pagesize);
  buf1 = (char *) ((int) (buf1 + pagesize - 1) & (~pagesize + 1));
  buf2 = malloc (SIZE + pagesize);
  buf2 = (char *) ((int) (buf2 + pagesize - 1) & (~pagesize + 1));
  buf3 = malloc (SIZE + JITTER);
  buf4 = malloc (SIZE + JITTER);

  for (i = 0; i < SIZE; i ++) buf1[i] = buf2[i] = buf3[i] = buf4[i] = i;
  for (i = SIZE; i < SIZE + JITTER; i++) buf3[i] = buf4[i] = i;

  f1 = open ("file1", O_WRONLY | O_CREAT, 0644);
  f2 = open ("file2", O_WRONLY | O_CREAT, 0644);
  f3 = open ("file3", O_WRONLY | O_CREAT, 0644);
  f4 = open ("file4", O_WRONLY | O_CREAT, 0644);

  getrusage(RUSAGE_SELF, &start);
  write (f1, buf1, SIZE);
  getrusage(RUSAGE_SELF, &end);
  printf ("Write (%d): %.2fu + %.2fs\n", SIZE,
	  TD(end.ru_utime, start.ru_utime),
	  TD(end.ru_stime, start.ru_stime));
  close (f1);
  unlink("file1");

  getrusage(RUSAGE_SELF, &start);
  for (i = 0; i < SIZE; i += CHUNK)
    write (f2, buf2 + i, CHUNK);
  getrusage(RUSAGE_SELF, &end);
  printf ("Write (%d/%d): %.2fu + %.2fs\n", SIZE, CHUNK,
	  TD(end.ru_utime, start.ru_utime),
	  TD(end.ru_stime, start.ru_stime));
  close (f2);
  unlink("file2");

  getrusage(RUSAGE_SELF, &start);
  write (f3, buf3 + JITTER, SIZE);
  getrusage(RUSAGE_SELF, &end);
  printf ("Write (%d + %d): %.2fu + %.2fs\n", SIZE, JITTER,
	  TD(end.ru_utime, start.ru_utime),
	  TD(end.ru_stime, start.ru_stime));
  close (f3);
  unlink("file3");

  getrusage(RUSAGE_SELF, &start);
  for (i = 0; i < SIZE; i += CHUNK)
    write (f4, buf4 + JITTER + i, CHUNK);
  getrusage(RUSAGE_SELF, &end);
  printf ("Write ((%d + %d)/%d): %.2fu + %.2fs\n", SIZE, JITTER, CHUNK,
	  TD(end.ru_utime, start.ru_utime),
	  TD(end.ru_stime, start.ru_stime));

  close (f4);
  unlink("file4");
}
