home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / iozone / part01 < prev    next >
Encoding:
Text File  |  1992-02-08  |  28.8 KB  |  941 lines

  1. Newsgroups: comp.sources.misc
  2. From: norcott_bill@Tandem.COM (Bill Norcott)
  3. Subject:  v28i016:  iozone - IOzone V1.14 - file I/O benchmark, Part01/01
  4. Message-ID: <1992Feb6.225301.22876@sparky.imd.sterling.com>
  5. X-Md4-Signature: c698f1897a720b60ff216b4fb73325bd
  6. Date: Thu, 6 Feb 1992 22:53:01 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: norcott_bill@Tandem.COM (Bill Norcott)
  10. Posting-number: Volume 28, Issue 16
  11. Archive-name: iozone/part01
  12. Environment: AIX, BSD, HP-UX, MS-DOS, POSIX, SVR3.2, ULTRIX, UNIX, VMS
  13. Supersedes: iozone: Volume 25, Issue 42
  14.  
  15. Attached is V1.14 of IOzone.  IOzone measures the speed at which your
  16. system can read and write files of various sizes and record lengths.  It
  17. prints out the answer in bytes-per-second.  This version adds support for
  18. the QNX and NeXt operating systems.  There are now 18 distinct operating
  19. systems supported, plus POSIX.1 systems.  Starting with this version, IOzone
  20. prints out the name of the operating system on which it was compiled.
  21.  
  22. Regards,
  23. Bill Norcott
  24. --------------------------------CUT HERE-------------------------------------
  25. #! /bin/sh
  26.  
  27. # This is a shell archive.  Save this into a file, edit it
  28. # and delete all lines above this comment.  Then give this
  29. # file to sh by executing the command "sh file".  The files
  30. # will be extracted into the current directory owned by
  31. # you with default permissions.
  32.  
  33. # The files contained herein are:
  34.  
  35. # -rw-r--r--   1 bill     posix      26446 Jan 31  1992 iozone.c
  36.  
  37. echo 'x - iozone.c'
  38. if test -f iozone.c; then echo 'shar: not overwriting iozone.c'; else
  39. sed 's/^X//' << '________This_Is_The_END________' > iozone.c
  40. Xchar *help[] = {
  41. X  "       'IO Zone' Benchmark Program",
  42. X  " ",
  43. X  "       Author: Bill Norcott (norcott_bill@tandem.com)",
  44. X  "               1060 Hyde Avenue",
  45. X  "               San Jose, CA  95129",
  46. X  " ",
  47. X  "  Copyright 1991, 1992   William D. Norcott",
  48. X  " ",
  49. X  "  License to freely use and distribute this software is hereby granted ",
  50. X  "  by the author, subject to the condition that this copyright notice ",
  51. X  "  remains intact.  The author retains the exclusive right to publish ",
  52. X  "  derivative works based on this work, including, but not limited to, ",
  53. X  "  revised versions of this work",
  54. X  " ",
  55. X  "  This test writes a X MEGABYTE sequential file in Y byte chunks, then",
  56. X  "  rewinds it  and reads it back.  [The size of the file should be",
  57. X  "  big enough to factor out the effect of any disk cache.]",
  58. X  "        ",
  59. X  "  The file is written (filling any cache buffers), and then read.  If the",
  60. X  "  cache is >= X MB, then most if not all the reads will be satisfied from",
  61. X  "  the cache.  However, if it is less than or equal to .5X MB, then NONE of",
  62. X  "  the reads will be satisfied from the cache.  This is becase after the ",
  63. X  "  file is written, a .5X MB cache will contain the upper .5 MB of the test",
  64. X  "  file, but we will start reading from the beginning of the file (data",
  65. X  "  which is no longer in the cache)",
  66. X  "        ",
  67. X  "  In order for this to be a fair test, the length of the test file must",
  68. X  "  be AT LEAST 2X the amount of disk cache memory for your system.  If",
  69. X  "  not, you are really testing the speed at which your CPU can read blocks",
  70. X  "  out of the cache (not a fair test)",
  71. X  "        ",
  72. X  "  IOZONE does NOT test the raw I/O speed of your disk or system.  It",
  73. X  "  tests the speed of sequential I/O to actual files.  Therefore, this",
  74. X  "  measurement factors in the efficiency of you machines file system,",
  75. X  "  operating system, C compiler, and C runtime library.  It produces a ",
  76. X  "  measurement which is the number of bytes per second that your system",
  77. X  "  can read or write to a file.  ",
  78. X  " ",
  79. X  "  For V1.06, IOZONE adds the 'auto test' feature.  This is activated",
  80. X  "  by the command:  'iozone auto' .  The auto test runs IOZONE repeatedly  ",
  81. X  "  using record sizes from 512 to 8192 bytes, and file sizes from 1 to 16",
  82. X  "  megabytes.  It creates a table of results.",
  83. X  "        ",
  84. X  "  For V1.06, IOZONE lets you specify the number of file system sizes and      ",
  85. X  "  record lengths to test when using auto mode.  Define the constants",
  86. X  "  MEGABYTES_ITER_LIMIT and RECLEN_ITER_LIMIT as seen below      ",
  87. X  "        ",
  88. X  "  For V1.09 you can show the development help by typing 'iozone help'",
  89. X  "        ",
  90. X  "  For V1.10 IOzone traps SIGINT (user interrupt) and SIGTERM",
  91. X  "  (kill from shell) signals and deletes the temporary file",
  92. X  "        ",
  93. X  "  For V1.11 IOzone requires no compilation flags for AIX",
  94. X  "  Also, come miscellaneous cleanups have been made to the source",
  95. X  "        ",
  96. X  "  For V1.12 IOzone support has been added for the MIPS RISCos,",
  97. X  "  Tandem Non-StopUX, and Tandem GUARDIAN 90 operating systems.",
  98. X  "  IOzone is now a 'Conforming POSIX.1 Application'  (IEEE Std 1003.1-1988)",
  99.  
  100. X  "        ",
  101. X  "  For V1.14 IOzone supports Next and QNX systems.  It also prints out",
  102. X  "  the name of the operating system when run.  There is now the option",
  103. X  "  to force IOzone to flush all writes to disk via fsync()",
  104. X  "  Defining USE_FSYNC will make IOzone include in its measurements the time",
  105. X  "  it takes to actually write the data onto disk, as opposed to",
  106. X  "  just writing into the system cache.  BSD UNIX and SVR4 support fsync(),",
  107. X  "  but SVR3 and generic POSIX systems do not.  I have enabled USE_FSYNC",
  108. X  "  for the systems which support it",
  109. X  "        ",
  110. X  " ",
  111. X  "  This program has been ported and tested on the following computer",
  112. X  "  operating systems:",
  113. X  " ",
  114. X  "    Vendor             Operating System    Notes on compiling IOzone",
  115. X  "    -------------------------------------------------------------------------",
  116. X  "    Convergent         Unisys/AT&T Sys5r3  cc -DCONVERGENT -o iozone iozone.c",
  117. X  "    Digital Equipment  ULTRIX V4.1 ",
  118. X  "    Digital Equipment  VAX/VMS V5.4        see below **         ",
  119. X  "    Digital Equipment  VAX/VMS (POSIX) ",
  120. X  "    Hewlett-Packard    HP-UX 7.05",
  121. X  "    IBM                AIX Ver. 3 rel. 1",
  122. X  "    Microsoft          MS-DOS 3.3          tested Borland, Microsoft C",
  123. X  "    MIPS               RISCos 4.52",
  124. X  "    NeXt               NeXt OS 2.x",
  125. X  "    OSF                OSF/1",
  126. X  "    Portable!          POSIX 1003.1-1988   may need to define _POSIX_SOURCE ",
  127. X  "    QNX                QNX 4.0             compile with  -N 40K option",
  128. X  "    SCO                UNIX System V/386 3.2.2",
  129. X  "    SCO                XENIX 3.2",
  130. X  "    Silicon Graphics   UNIX                cc -DSGI -o iozone iozone.c",
  131. X  "    Sony Microsystems  UNIX                same as MIPS",
  132. X  "    Sun Microsystems   SUNOS 4.1.1",
  133. X  "    Tandem Computers   GUARDIAN 90         1. call the source file IOZONEC",
  134. X  "                                           2. C/IN IOZONEC/IOZONE;RUNNABLE",
  135. X  "                                           3. RUN IOZONE",
  136. X  "    Tandem Computers   Non-Stop UX",
  137. X  "        ",
  138. X  "    ** for VMS, define iozone as a foreign command via this DCL command:       ",
  139. X  " ",
  140. X  "       $IOZONE :== $SYS$DISK:[]IOZONE.EXE      ",
  141. X  " ",
  142. X  "       this lets you pass the command line arguments to IOZONE",
  143. X  " ",
  144. X  "  Acknowledgements to the following persons for their feedback on IOzone:       ",
  145. X  " ",
  146. X  "  Andy Puchrik, Michael D. Lawler, Krishna E. Bera, Sam Drake, John H. Hartman, ",
  147. X  "  Ted Lyszczarz, Bill Metzenthen, Jody Winston, Clarence Dold, Axel",
  148. X  "  Dan Hildebrand",
  149. X  "        ",
  150. X  "  --- MODIFICATION HISTORY:",
  151. X  " ",
  152. X  " ",
  153. X  "    3/7/91 William D. Norcott (Bill.Norcott@nuo.mts.dec.com)",
  154. X  "                               created",
  155. X  " ",
  156. X  "    3/22/91 Bill Norcott       tested on OSF/1 ... it works",
  157. X  " ",
  158. X  "    3/24/91 Bill Norcott       V1.02 -- use calloc in TURBOC to",
  159. X  "                                       fix bug with their malloc",
  160. X  " ",
  161. X  "    3/25/91 Bill Norcott       V1.03 -- add ifdef for XENIX",
  162. X  "                                       ",
  163. X  "    3/27/91 Bill Norcott       V1.04 -- Includes for SCO UNIX",
  164. X  "                                       ",
  165. X  "    4/26/91 Bill Norcott       V1.05 -- support AIX and SUNos, check",
  166. X  "                                       length of read() and write()",
  167. X  "    4/26/91 Bill Norcott       V1.06 -- tabulate results of a series ",
  168. X  "                                       of tests",
  169. X  "    5/17/91 Bill Norcott       V1.07 -- use time() for VMS",
  170. X  "    5/20/91 Bill Norcott       V1.08 -- use %ld for Turbo C and",
  171. X  "                                       use #ifdef sun to bypass",
  172. X  "                                       inclusion of limits.h",
  173. X  "    6/19/91 Bill Norcott       V1.09 -- rid #elif to support HP-UX and ",
  174. X  "                                       Silicon Graphics UNIX, and",
  175. X  "                                       add #ifdef SGI",
  176. X  "                                       add #ifdef CONVERGENT",
  177. X  "                                       for Convergent Technologies",
  178. X  "                                       also add help option",
  179. X  "    7/2/91 Bill Norcott        V1.10 -- delete file if get SIGINT",
  180. X  "                                       or SIGTERM",
  181. X  "    8/20/91 Bill Norcott       V1.11 -- require no flags with AIX",
  182. X  "    11/4/91 Bill Norcott       V1.12 -- support MIPS RISCos",
  183. X  "                                         Tandem NonStop-UX, and",
  184. X  "                                        IEEE Std POSIX 1003.1-1988",
  185. X  "    12/4/91 Bill Norcott       V1.13 -- support NeXT; tell host OS type",
  186. X  "    1/23/92 Bill Norcott      V1.14 -- support QNX & use calloc() for buffer",
  187. X  "" };
  188.  
  189. X/******************************************************************
  190.  
  191. X  INCLUDE FILES (system-dependent)
  192.  
  193. X  ******************************************************************/
  194. X/* V1.14 -- use calloc instead of stack for buffer, on all platforms */
  195. X#define usecalloc
  196. X/*
  197. XV1.14b -- check for ultrix which uses sysconf in newer POSIX version
  198. Xbut uses BSD-style time in the pre-POSIX versions
  199. X*/
  200. X#ifdef ultrix
  201. X#ifndef OS_TYPE
  202. X#define OS_TYPE "ULTRIX"
  203. X#define BSDtime
  204. X#endif
  205. X#endif
  206. X/* V1.13 -- support NeXT by treating it like a Sun... Thanks Axel! */
  207. X#ifdef __NeXT__
  208. X#ifndef OS_TYPE
  209. X#define OS_TYPE "NeXT OS"
  210. X#endif
  211. X#define sun
  212. X#endif
  213. X/*
  214. X  define nolimits if your system has no limits.h.  Sun's don't but I
  215. X  take care of this explicitly beginning with V1.08 of IOzone.
  216. X  */
  217. X#ifdef sun
  218. X#ifndef OS_TYPE
  219. X#define OS_TYPE "SunOS"
  220. X#endif
  221. X#define nolimits
  222. X#define BSDtime
  223. X#define USE_FSYNC
  224. X#endif
  225. X/* V1.09 -- Silicon Graphics compile with -DSGI  */
  226. X#ifdef SGI
  227. X#ifndef OS_TYPE
  228. X#define OS_TYPE "Silicon Graphics"
  229. X#endif
  230. X#define nolimits
  231. X#define BSDtime
  232. X#endif
  233.  
  234. X/* V1.13 For MIPS RISC/OS and Tandem NonStop-UX*/
  235. X#ifdef SYSTYPE_BSD43
  236. X#define bsd4_3
  237. X#ifndef OS_TYPE
  238. X#define OS_TYPE "MIPS RISC/os (BSD 4.3 libraries)"
  239. X#endif
  240. X#endif
  241.  
  242. X#ifdef SYSTYPE_SYSV
  243. X#include <sys/utsname.h>
  244. X#define nolimits
  245. X#ifdef T_NONSTOP
  246. X#define OS_TYPE "TANDEM NonStop-UX (System V libraries)"
  247. X#endif
  248. X#ifndef OS_TYPE
  249. X#define OS_TYPE "MIPS RISC/os (System V libraries)"
  250. X#endif
  251. X#define SysVtime
  252. X#include <sys/types.h>
  253. X#include <sys/times.h>
  254. X#include <sys/fcntl.h>
  255. X#endif
  256. X/* V1.14 -- define nolimits and BSDtime for Xenix 2.3.3 */
  257. X/* incl definitions of O_* flags for XENIX */
  258. X#ifdef M_XENIX
  259. X#ifndef OS_TYPE
  260. X#define OS_TYPE "SCO XENIX"
  261. X#endif
  262. X#include <fcntl.h>
  263. X#define nolimits
  264. X#define BSDtime
  265. X#endif
  266.  
  267. X/* V1.12 -- test for POSIX-conformant operating system; requires limits.h */
  268. X#ifndef nolimits
  269. X#include <limits.h>
  270.  
  271. X#ifdef _POSIX_ARG_MAX
  272. X#ifndef OS_TYPE
  273. X#define OS_TYPE "POSIX 1003.1-1988"
  274. X#endif
  275. X#define isposix
  276. X#endif
  277.  
  278. X#endif
  279.  
  280. X/* Tandem's GUARDIAN operating system */
  281. X#include <stdio.h>
  282. X#ifdef __TANDEM
  283. X#ifndef OS_TYPE
  284. X#define OS_TYPE "TANDEM GUARDIAN 90"
  285. X#endif
  286. X#define nosignals
  287. X#define ANSItime
  288. X#define ANSI_MAIN
  289. X#include <fcntl.h>
  290. X#include <stdlib.h>
  291. X#include <string.h>
  292. X#include <time.h>
  293. X#endif
  294. X#ifndef nosignals
  295. X#include <signal.h>
  296. X#endif
  297. X#ifdef  __MSDOS__               /* Turbo C define this way for PCs... */
  298. X#define MSDOS                   /* Microsoft C defines this */
  299. X#endif
  300. X/* VMS and MS-DOS both have ANSI C compilers and use rand()/srand() */
  301. X#ifdef  VMS_POSIX
  302. X#undef   VMS
  303. X#define ANSI_RANDOM     1
  304. X#endif
  305. X#ifdef  MSDOS
  306. X#define ANSI_RANDOM     1
  307. X#endif
  308. X/* Convergent Technologies M680xx based with Unisys/AT&T Sys5r3 */
  309. X#ifdef CONVERGENT
  310. X#ifndef OS_TYPE
  311. X#define OS_TYPE "Convergent Technologies"
  312. X#endif
  313. X#include <fcntl.h>
  314. X#define SysVtime
  315. X#endif
  316. X/* SCO Unix System V */
  317. X#ifdef M_UNIX
  318. X#ifndef OS_TYPE
  319. X#define OS_TYPE "SCO UNIX System V/386"
  320. X#endif
  321. X#include <sys/types.h>
  322. X#include <sys/fcntl.h>
  323. X#endif
  324.  
  325. X/* V1.11 -- With the following includes, AIX no longer requires -Dunix */
  326. X#ifdef _AIX
  327. X#ifndef OS_TYPE
  328. X#define OS_TYPE "AIX"
  329. X#endif
  330. X#include <fcntl.h>
  331. X#include <sys/time.h>
  332. X#endif
  333.  
  334. X#if defined(VMS)
  335. X#ifndef OS_TYPE
  336. X#define OS_TYPE "VAX/VMS"
  337. X#endif
  338. X#define ANSItime
  339. X#define ANSI_RANDOM     1
  340. X#include    <math.h>
  341. X#include    <unixio.h>
  342. X#include    <ssdef.h>
  343. X#include    <file.h>
  344. X#include    <time.h>
  345.  
  346. X#else
  347. X/* ... either MSDOS, POSIX, or a generic non-POSIX UNIX */
  348. X#ifdef MSDOS
  349. X#ifndef OS_TYPE
  350. X#define OS_TYPE "MS-DOS"
  351. X#endif
  352. X#define usecalloc
  353. X#include <fcntl.h>
  354. X#include <time.h>
  355. X#endif
  356. X/* nope, not MS-DOS, try POSIX */
  357. X#ifdef isposix
  358. X#include <time.h>
  359. X#include <sys/times.h>
  360. X#include <fcntl.h>
  361. X#include <unistd.h>
  362. X#else
  363. X#ifdef unix
  364. X#ifndef OS_TYPE
  365. X#define OS_TYPE "UNIX -- vendor unknown"
  366. X#endif
  367. X#include <sys/file.h>
  368. X#endif
  369. X#endif
  370.  
  371. X#endif
  372.  
  373. X/* Define NULL in case we don't have it... */
  374. X#ifndef NULL
  375. X#define NULL 0
  376. X#endif
  377.  
  378. X/* for systems with System V-style time, define SysVtime */
  379. X#ifdef M_SYSV
  380. X#define SysVtime
  381. X#endif
  382.  
  383. X#ifdef SysVtime
  384. X#include <sys/times.h>
  385. X#include <sys/param.h>
  386. X#ifndef CLK_TCK
  387. X#define CLK_TCK HZ
  388. X#endif
  389. X#endif
  390. X/* for systems with BSD style time, define BSDtime */
  391. X#ifdef bsd4_2
  392. X#define USE_FSYNC
  393. X#ifndef OS_TYPE
  394. X#define OS_TYPE "BSD 4.2"
  395. X#endif
  396. X#define BSDtime
  397. X#endif
  398. X#ifdef bsd4_3
  399. X#define USE_FSYNC
  400. X#ifndef OS_TYPE
  401. X#define OS_TYPE "BSD 4.3"
  402. X#endif
  403. X#define BSDtime
  404. X#endif
  405. X#ifdef BSDtime
  406. X#include <sys/time.h>
  407. X#endif
  408.  
  409. X#ifndef OS_TYPE
  410. X#define OS_TYPE "Unknown"
  411. X#endif
  412. X/******************************************************************
  413.  
  414. X  DEFINED CONSTANTS
  415.  
  416. X  ******************************************************************/
  417. X/*
  418. X  V1.14: Define ONETEST to run a single test at runtime as the default
  419. X  V1.14: Define AUTOTEST to run in auto test mode as the default
  420. X  i.e. the behavior of IOzone when it is invoked with no arguments.  ONETEST
  421. X  makes IOzone run a single test using a 1 MB file and 512 byte records.
  422. X  AUTOTEST causes IOzone to use auto test mode.
  423. X  For compatibility with previous versions of IOZONE, ONETEST is the default
  424. X  setting
  425. X*/
  426. X#define ONETEST 1
  427. X#ifndef ONETEST
  428. X#define AUTOTEST
  429. X#endif
  430.  
  431. X/*
  432. X  V1.14: Define USE_FSYNC to force writes to disk during the write phase
  433. X  BSD and BSD-derived UNIX variants and also SVR4 are known to have fsync
  434. X  UNIX).  After the file is written and before it is closed, call fsync()
  435. X  to force the data to be written from cache to disk.  This (mostly) cancels
  436. X  the fact that systems with a lot of memory for cache buffers or memory
  437. X  mapping display artificially high transfer rates during the write phase
  438. X  of IOzone, because the data never makes it onto the disk.
  439.  
  440. X*/
  441. X#if 0
  442. X#define USE_FSYNC
  443. X#endif
  444.  
  445.  
  446. X#define MEGABYTES 1                     /* number of megabytes in file */
  447. X#define RECLEN 512                      /* number of bytes in a record */
  448. X#define FILESIZE 1048576                /*size of file in bytes*/
  449. X#define NUMRECS 2048                    /* number of records */
  450. X#define MAXBUFFERSIZE 16*1024           /*maximum buffer size*/
  451. X#define MINBUFFERSIZE 128
  452. X#define TOOFAST 10
  453. X#define IOZONE_USAGE \
  454. X"\tUsage:\tiozone [megabytes] [record_length_in_bytes] [[path]filename]\n\t\tiozone auto\n\t\tiozone help\n\n"
  455. X#define THISVERSION "V1.14b"
  456. X#define RELEASEDATE "1/31/92"
  457. X  /* Define only one of the following two.  All modern operating systems
  458. X     have time functions so let TIME be defined */
  459. X#ifndef noclock
  460. X#define TIME 1
  461. X#endif
  462.  
  463. X#define MAXNAMESIZE 1000                /* max # of characters in filename */
  464. X#define CONTROL_STRING1 "\t%-8ld%-8ld%-20ld%-20ld\n"
  465. X#define CONTROL_STRING2 "\t%-8s%-8s%-20s%-20s\n"
  466. X  /*
  467. X    For 'auto mode', these defines determine the number of iterations
  468. X    to perform for both the file size and the record length.
  469. X    I.e., if MEGABYTES_ITER_LIMIT = 5 use 1, 2, 4, 8 & 16 megabyte files
  470. X    if RECLEN_ITER_LIMIT = 5 use 512, 1024, 2048, 4096 & 8192 byte records
  471. X    */
  472. X#define MEGABYTES_ITER_LIMIT 5
  473. X#define RECLEN_ITER_LIMIT 5
  474.  
  475. X  /******************************************************************
  476.  
  477. X    FUNCTION DECLARATIONS
  478.  
  479.  
  480. X    ******************************************************************/
  481. Xvoid auto_test();               /* perform automatic test series */
  482. Xvoid show_help();               /* show development help*/
  483. Xstatic double time_so_far();    /* time since start of program */
  484. Xvoid signal_handler();          /* clean up if user interrupts us */
  485. X/******************************************************************
  486.  
  487. X  GLOBAL VARIABLES
  488.  
  489. X  ******************************************************************/
  490. Xint auto_mode;
  491. Xchar filename [MAXNAMESIZE];            /* name of temporary file */
  492. X/******************************************************************
  493.  
  494. X  MAIN -- entry point
  495.  
  496. X  ******************************************************************/
  497. X#ifdef ANSI_MAIN
  498. Xint main(int argc, char *argv[], char *env[])    /* main body of code */
  499. X#else
  500. X     main(argc,argv)
  501. X     int argc;
  502. X     char *argv[];
  503. X#endif
  504. X{
  505. X#ifdef ANSI_MAIN
  506. X  char *fooenv;
  507. X#endif
  508. X  int fd;
  509. X  char *default_filename;
  510.  
  511. X#ifdef  usecalloc
  512. X  char *buffer;
  513. X#else
  514. X  char buffer [MAXBUFFERSIZE];            /*a temporary data buffer*/
  515. X#endif
  516. X  unsigned long i;
  517. X  unsigned long megabytes = MEGABYTES;
  518. X  unsigned long reclen = RECLEN;
  519. X  unsigned long filesize;
  520. X  unsigned long numrecs;
  521. X#ifdef TIME
  522. X  unsigned long filebytes;
  523. X  unsigned long readrate, writerate;
  524. X  unsigned long goodmegs;
  525. X  unsigned long goodrecl;
  526. X  double starttime1, starttime2;
  527. X  double writetime, readtime;
  528. X  double totaltime;
  529. X#endif
  530. X#ifdef usecalloc
  531. X  buffer = (char *) calloc(1, MAXBUFFERSIZE);
  532. X#endif
  533.  
  534. X#if defined (ANSI_MAIN)
  535. X  fooenv= env[0];       /* dummy so we make some use of env (to avoid warnings) */
  536. X#endif
  537.  
  538. X#if defined (__TANDEM)
  539. X  default_filename ="IOZONET"; /* TANDEM GUARDIAN 90 has max 8 char filenames */
  540. X#else
  541. X  default_filename ="iozone.tmp"; /*default name of temporary file*/
  542. X#endif
  543. X  if (!auto_mode)
  544. X    {
  545. X      printf("\n\tIOZONE: Performance Test of Sequential File I/O  --  %s (%s)\n",
  546. X            THISVERSION, RELEASEDATE);
  547. X      printf("\t\tBy Bill Norcott\n\n");
  548. X      printf("\tOperating System: %s\n\n", OS_TYPE);
  549. X#ifndef nosignals
  550. X      signal(SIGINT, signal_handler);      /* handle user interrupt */
  551. X      signal(SIGTERM, signal_handler);     /* handle kill from shell */
  552. X#endif
  553. X    }
  554. X  strcpy(filename,default_filename);
  555. X  switch (argc) {
  556. X  case 1:     /* no args, take all defaults */
  557. X    printf(IOZONE_USAGE);
  558. X#ifdef AUTOTEST
  559. X    auto_mode = 1;
  560. X    auto_test();
  561. X    printf("Completed series of tests\n");
  562. X    exit(0);
  563. X#endif
  564. X    break;
  565. X  case 2:     /* <megabytes|filename> */
  566. X    i = atoi(argv[1]); if (i) {
  567. X      megabytes = i;
  568. X    } else {
  569. X      /*
  570. X       'Auto mode' will be enabled if the first command line argument is
  571. X       the word 'auto'.  This will trigger a series of tests
  572. X       */
  573. X      if ( (strcmp(argv[1], "auto") == 0) ||
  574. X         (strcmp(argv[1], "AUTO") == 0) )
  575. X       {
  576. X         auto_mode = 1;
  577. X         auto_test();
  578. X         printf("Completed series of tests\n");
  579. X         exit(0);
  580. X       } else {
  581. X         auto_mode = 0;
  582. X       }
  583. X      if ( (strcmp(argv[1], "help") == 0) ||
  584. X         (strcmp(argv[1], "HELP") == 0) )
  585. X       {
  586. X         show_help();
  587. X         exit(0);
  588. X       }
  589. X      strcpy(filename,argv[1]);
  590. X    }
  591. X    break;
  592. X  case 3:     /* <megabytes> <reclen|filename> */
  593. X    megabytes = atoi(argv[1]);
  594. X    if (atoi(argv[2])) {
  595. X      reclen = atoi(argv[2]);
  596. X    } else {
  597. X      strcpy(filename,argv[2]);
  598. X    }
  599. X    break;
  600. X  case 4:     /* <megabytes> <reclen> <filename> */
  601. X    megabytes = atoi(argv[1]);
  602. X    reclen = atoi(argv[2]);
  603. X    strcpy(filename,argv[3]);
  604. X    break;
  605. X  default:
  606. X    printf("IOZONE: bad usage\n");
  607. X    printf(IOZONE_USAGE);
  608. X    exit(1);
  609.  
  610. X  }
  611. X  if (!auto_mode)
  612. X    {
  613. X      printf("\tSend comments to:\tnorcott_bill@tandem.com\n\n");
  614. X    }
  615. X  filesize = megabytes*1024*1024;
  616. X  numrecs = filesize/reclen;
  617. X  if (reclen >  MAXBUFFERSIZE) {
  618. X    printf("<Error: Maximum record length is %d bytes\n", MAXBUFFERSIZE);
  619. X    exit(1);
  620. X  }
  621. X  if (reclen < MINBUFFERSIZE) {
  622. X    printf("Error: Minimum record length is %d bytes\n", MINBUFFERSIZE);
  623. X    exit(1);
  624. X  }
  625. X  if (!auto_mode)
  626. X    {
  627. X      printf("\tIOZONE writes a %ld Megabyte sequential file consisting of\n",
  628. X            megabytes);
  629. X      printf("\t%ld records which are each %ld bytes in length.\n",
  630. X            numrecs, reclen);
  631. X      printf("\tIt then reads the file.  It prints the bytes-per-second\n");
  632. X      printf("\trate at which the computer can read and write files.\n\n");
  633. X      printf("\nWriting the %ld Megabyte file, '%s'...", megabytes, filename);
  634. X    }
  635.  
  636. X#if defined (__TANDEM)
  637. X  /*
  638. X    Tandem's GUARDIAN preallocates file space based on primary- and secondary extents.
  639. X    The last 2 parameters to open are the sizes of the primary- and secondary extents,
  640. X    in blocks which are 2K bytes each.  After the primary extent is filled, GUARDIAN
  641. X    allocates up to 15 additional extents, one at a time.
  642. X    */
  643. X#define SPECIAL_CREAT
  644. X#define PRI_EXT_BLOCKS 1024
  645. X#define SEC_EXT_BLOCKS 1024
  646. X  if((fd = creat(filename, 0640,
  647. X                PRI_EXT_BLOCKS, SEC_EXT_BLOCKS))<0){
  648. X    printf("Cannot create temporary file: %s\n", filename);
  649. X    exit(1);
  650. X  }
  651. X#endif
  652. X#ifndef SPECIAL_CREAT
  653. X  if((fd = creat(filename, 0640))<0){
  654. X    printf("Cannot create temporary file: %s\n", filename);
  655. X    exit(1);
  656. X  }
  657. X#endif
  658. X#ifdef TIME
  659. X  starttime1 = time_so_far();
  660. X#endif
  661. X  for(i=0; i<numrecs; i++){
  662. X#ifndef DEBUG_ME
  663. X    if(write(fd, buffer, (unsigned) reclen) != reclen)
  664. X      {
  665. X       printf("Error writing block %d\n", i);
  666. X       perror("iozone");
  667. X       close(fd);
  668. X#ifndef VMS
  669. X       unlink(filename);   /* delete the file */
  670. X       /*stop timer*/
  671. X#endif
  672. X       exit(1);
  673. X      }
  674. X#endif
  675. X  }
  676. X#ifdef USE_FSYNC
  677. X  fsync(fd);
  678. X#endif
  679. X#ifdef TIME
  680. X  writetime = time_so_far() - starttime1;
  681. X  if (!auto_mode)
  682. X    {
  683. X      printf("%f seconds", writetime);
  684. X    }
  685. X#endif
  686. X  close(fd);
  687. X  sleep(5); /* Give writes a chance to complete on UNIX systems */
  688. X#if defined (VMS)
  689. X#define SPECIAL_OPEN_READ
  690. X  if((fd = open(filename, O_RDONLY, 0640))<0){
  691. X    printf("Cannot open temporary file for read\n");
  692. X    exit(1);
  693. X  }
  694. X#endif
  695.  
  696. X#ifdef MSDOS
  697. X#define SPECIAL_OPEN_READ
  698. X  if((fd = open(filename, O_RDONLY, 0640))<0){
  699. X    printf("Cannot open temporary file for read\n");
  700. X    exit(1);
  701. X  }
  702. X#endif
  703.  
  704. X  /*
  705. X    'Generic' case, compiled if no operating system-specific case was invoked
  706. X    */
  707. X#ifndef SPECIAL_OPEN_READ
  708. X  if((fd = open(filename, O_RDONLY))<0){
  709. X    printf("Cannot open temporary file for read\n");
  710. X    exit(1);
  711. X  }
  712. X#endif
  713.  
  714.  
  715.  
  716. X  /*start timing*/
  717. X#ifndef TIME
  718. X  printf("start timing\n");
  719. X#endif
  720. X  if (!auto_mode)
  721. X    {
  722. X      printf("\nReading the file...");
  723. X    }
  724. X#ifdef TIME
  725. X  starttime2 = time_so_far();
  726. X#endif
  727. X  for(i=0; i<numrecs; i++) {
  728. X#ifndef DEBUG_ME
  729. X    if(read(fd, buffer, (unsigned) reclen) != reclen)
  730. X      {
  731. X       printf("Error reading block %d\n", i);
  732. X       exit(1);
  733. X      }
  734. X#endif
  735. X  }
  736. X#ifndef TIME
  737. X  printf("stop timing\n");
  738. X#endif
  739. X#ifdef TIME
  740. X  readtime = time_so_far() - starttime2;
  741. X  if (!auto_mode)
  742. X    {
  743. X      printf("%f seconds\n", readtime);
  744. X    }
  745. X#ifdef DEBUG_ME
  746. X  readtime = 1;
  747. X  writetime = 1;
  748. X#endif
  749. X  if(readtime!=0)
  750. X    {
  751. X      filebytes = numrecs*reclen;
  752. X      readrate = (unsigned long) ((double) filebytes / readtime);
  753. X      writerate = (unsigned long) ((double) filebytes / writetime);
  754. X      if (auto_mode)
  755. X       {
  756. X         printf(CONTROL_STRING1,
  757. X                megabytes,
  758. X                reclen,
  759. X                writerate,
  760. X                readrate);
  761.  
  762. X       } else {
  763. X         printf("\nIOZONE performance measurements:\n");
  764. X         printf("\t%ld bytes/second for writing the file\n", writerate);
  765. X         printf("\t%ld bytes/second for reading the file\n", readrate);
  766. X         totaltime = readtime + writetime;
  767. X         if (totaltime < TOOFAST)
  768. X           {
  769. X             goodmegs = (TOOFAST/totaltime)*2*megabytes;
  770. X             printf("\nThe test completed too quickly to give a good result\n");
  771. X             printf("You will get a more precise measure of this machine's\n");
  772. X             printf("performance by re-running IOZONE using the command:\n");
  773. X             printf("\n\tiozone %ld ", goodmegs);
  774. X             printf("\t(i.e., file size = %ld megabytes)\n", goodmegs);
  775. X           }
  776. X       }
  777. X    } else {
  778. X      goodrecl = reclen/2;
  779. X      printf("\nI/O error during read.  Try again with the command:\n");
  780. X      printf("\n\tiozone %ld %ld ", megabytes,  goodrecl);
  781. X      printf("\t(i.e. record size = %ld bytes)\n",  goodrecl);
  782. X    }
  783. X#endif
  784. X  close(fd);
  785. X#ifndef VMS
  786. X  unlink(filename);   /* delete the file */
  787. X  /*stop timer*/
  788. X#endif
  789. X#ifdef  usecalloc
  790. X  free(buffer);           /* deallocate the memory */
  791. X#endif
  792. X#ifdef VMS
  793. X  return SS$_NORMAL;
  794. X#else
  795. X  return 0;
  796. X#endif
  797. X}
  798. X/******************************************************************
  799.  
  800. X  SHOW_HELP -- show development help of this program
  801.  
  802. X  ******************************************************************/
  803. Xvoid show_help()
  804. X{
  805. X  int i;
  806. X  printf("IOZONE: help mode\n\n");
  807. X  for(i=0; strlen(help[i]); i++)
  808. X    {
  809. X      printf("%s\n", help[i]);
  810. X    }
  811. X}
  812. X/******************************************************************
  813.  
  814. X  SIGNAL_HANDLER -- clean up if user interrupts the program
  815.  
  816. X  ******************************************************************/
  817. Xvoid signal_handler()
  818. X{
  819. X  printf("\nIOZONE: interrupted\n\n");
  820. X#ifndef VMS
  821. X  printf("deleting file: %s\n", filename);
  822. X  unlink(filename);   /* delete the file */
  823. X#endif
  824. X  printf("exiting IOzone\n\n");
  825. X  exit(0);
  826. X}
  827. X/******************************************************************
  828.  
  829. X  AUTO_TEST -- perform series of tests and tabulate results
  830.  
  831. X  ******************************************************************/
  832. Xvoid auto_test()
  833. X{
  834.  
  835. X  int megsi, recszi;
  836. X  char megs[10];
  837. X  char recsz[10];
  838. X  int i,j;
  839. X  int auto_argc = 3;
  840. X  char *auto_argv[3];
  841.  
  842. X  printf("IOZONE: auto-test mode\n\n");
  843. X  printf(CONTROL_STRING2,
  844. X        "MB",
  845. X        "reclen",
  846. X        "bytes/sec written",
  847. X        "bytes/sec read");
  848. X  auto_argv[0] = "IOzone auto-test";
  849. X  auto_argv[1] = megs;
  850. X  auto_argv[2] = recsz;
  851. X  /*
  852. X    Start with file size of 1 megabyte and repeat the test MEGABYTES_ITER_LIMIT
  853. X    times.  Each time we run, the file size is doubled
  854. X    */
  855. X  for(i=0,megsi=1;i<MEGABYTES_ITER_LIMIT;i++,megsi*=2)
  856. X    {
  857. X      sprintf(megs, "%d", megsi);
  858. X      /*
  859. X       Start with record size of 512 bytes and repeat the test RECLEN_ITER_LIMIT
  860. X       times.  Each time we run, the record size is doubled
  861. X       */
  862. X      for (j=0,recszi=512;j<RECLEN_ITER_LIMIT;j++,recszi*=2)
  863. X        {
  864. X         sprintf(recsz, "%d", recszi);
  865. X#ifdef ANSI_MAIN
  866. X         main(auto_argc, auto_argv, NULL);
  867. X#else
  868. X         main(auto_argc, auto_argv);
  869. X#endif
  870. X        }
  871. X    }
  872. X}
  873.  
  874. X#ifdef TIME
  875. Xstatic double
  876. X  time_so_far()
  877. X{
  878. X#if defined(ANSItime)
  879. X  /*
  880. X   *   5/17/91 Bill Norcott        V1.07 -- use time() for VMS
  881. X   The times() function in VMS returns proc & user CPU time in 10-millisecond
  882. X   ticks.  Instead, use time() which lacks the precision but gives clock
  883. X   time in seconds.
  884. X   V1.14 make val of type clock_t if we are dealing with POSIX
  885. X   */
  886.  
  887. X  return (double) time(NULL);
  888.  
  889. X#else
  890. X#ifdef isposix
  891. X  clock_t        val;
  892. X  struct tms tms;
  893.  
  894.  
  895. X  if ((val = times(&tms)) == -1)
  896. X    perror("times");
  897.  
  898. X#ifndef CLK_TCK
  899. X  return ((double) val) / ((double) sysconf(_SC_CLK_TCK));
  900. X#else
  901. X  return ((double) val) / ((double) CLK_TCK);
  902. X#endif
  903. X#endif
  904. X#ifdef SysVtime
  905. X  /* #elif defined(SysVtime) */
  906. X  int        val;
  907. X  struct tms tms;
  908.  
  909. X  if ((val = times(&tms)) == -1)
  910. X    perror("times");
  911.  
  912. X  return ((double) val) / ((double) CLK_TCK);
  913. X#endif
  914. X#if defined(MSDOS)
  915. X  return ((double) clock()) / ((double) CLK_TCK);
  916. X#endif
  917. X#ifndef MSDOS
  918. X#ifndef isposix
  919. X#ifndef SysVtime
  920. X  /* #else */
  921. X  struct timeval tp;
  922.  
  923. X  if (gettimeofday(&tp, (struct timezone *) NULL) == -1)
  924. X    perror("gettimeofday");
  925. X  return ((double) (tp.tv_sec)) +
  926. X    (((double) tp.tv_usec) / 1000000.0);
  927. X#endif
  928. X#endif
  929. X#endif
  930. X#endif
  931. X}
  932. X#endif
  933. ________This_Is_The_END________
  934. if test `wc -l < iozone.c` -ne 893 ; then
  935.         echo 'shar: iozone.c was damaged during transit (should have been 893  bytes)'
  936. fi
  937. fi              ; : end of overwriting check
  938. exit 0
  939.  
  940. exit 0 # Just in case...
  941.