/*===========================================================================
  Copyright (C) 1995-2005 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*

.VERSION
051021		last modif

*/

#include <sys/file.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>

#ifdef SYSV_V2
#include <sys/times.h>
#else /* BSD */
#include <sys/timeb.h> 
#endif

#ifndef CLK_TCK
#define CLK_TCK 60
#endif

#include <sys/stat.h>
/*
 * Size of test file.
 * Should make this large with respect
 * to size of buffer cache.
 */
#define   MBYTES 16 

/*
 * Size of memory allocated to remove cache
 */
#define   MAX_MEM 512

/*
 * Sleep time, to let other system to recover
 */
#define   SLEEP_TIME 10


main( argc, argv)
char **argv;
{
	register int i, j;
	register char *buf;
#ifdef SYSV_V2
	struct tms buffer;
	int start, end; 
#else /* BSD */
	struct timeb start, end;
#endif
	float writetime, readtime;
	struct stat sbuf;
	int nblocks;
	float filesize;
	register char * max_mem_ptr;

/**/
	printf("Allocating %d MB RAM to remove cache...\n",MAX_MEM);
        max_mem_ptr = calloc(1024*1024*MAX_MEM,1);
        free(max_mem_ptr);
	printf("and freeing it\n");

	printf("Sleeping %d second to let system to recover\n", SLEEP_TIME);
        sleep(SLEEP_TIME);
/**/

	printf("Run this on an idle system.\n");
	if (argc < 2) {
		printf("Give filename as argument.\n");
		exit(1);
	}

	/*
	 * Write test.
	 */
	j = creat(argv[1], 0666);
	fstat(j, &sbuf);		/* find optimum blocksize */
	printf("blocksize = %d\n", sbuf.st_blksize);
	buf = (char *) malloc((size_t)sbuf.st_blksize);
	nblocks = (MBYTES*1024*1000)/sbuf.st_blksize;
	filesize = (nblocks * sbuf.st_blksize)/(1024*1000);
#ifdef SYSV_V2
	start=times(&buffer);
	for (i = 0; i < nblocks; i++) write(j, buf, sbuf.st_blksize);
	end=times(&buffer);
	writetime = (float)(end - start)/(float)CLK_TCK;
#else /* BSD */
	ftime(&start);
	for (i = 0; i < nblocks; i++) write(j, buf, sbuf.st_blksize);
	ftime(&end);
	writetime = ((end.time - 1) - start.time) +
		    ((end.millitm + 1000) - start.millitm)/1000.0;
#endif
	printf("write time = %.3f, speed = %.3f Mbytes/sec\n",
		writetime, filesize/writetime);
	close(j);

	/*
	 * Read test.
	 */
	j = open(argv[2], 0);
#ifdef SYSV_V2
	start=times(&buffer);
	for (i = 0; i < nblocks; i++) read(j, buf, sbuf.st_blksize);
	end=times(&buffer);
	readtime = (float)(end - start)/(float)CLK_TCK;
#else /* BSD */
	ftime(&start);
	for (i = 0; i < nblocks; i++) read(j, buf, sbuf.st_blksize);
	ftime(&end);
	readtime = ((end.time - 1) - start.time) +
		    ((end.millitm + 1000) - start.millitm)/1000.0;
#endif
	printf("read time = %.3f, speed = %.3f Mbytes/sec\n",
		readtime, filesize/readtime);
	close(j);

	/*
	 * Get rid of junk lying around.
	 */
/*
	unlink(argv[1]);
*/

	printf("Average I/O performance = %.3f Mbytes/sec\n",
		filesize/((writetime + readtime)/2));
	exit(0);
}
