home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / iozone / part01 < prev    next >
Encoding:
Text File  |  1992-11-03  |  48.2 KB  |  1,399 lines

  1. Newsgroups: comp.sources.misc
  2. From: norcott_bill@tandem.com (Bill Norcott)
  3. Subject: v33i032: iozone - IOzone V1.16 sequential file I/O benchmark, Part01/01
  4. Message-ID: <1992Nov2.184557.4957@sparky.imd.sterling.com>
  5. X-Md4-Signature: 61e8711544d26c50135e66768f69584b
  6. Date: Mon, 2 Nov 1992 18:45:57 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: norcott_bill@tandem.com (Bill Norcott)
  10. Posting-number: Volume 33, Issue 32
  11. Archive-name: iozone/part01
  12. Environment: AIX, BSD, HP-UX, MS-DOS, POSIX, SVR3.2, ULTRIX, UNIX, VMS, NeXt
  13. Supersedes: iozone: Volume 30, Issue 16
  14.  
  15. Attached is the latest release of IOzone in the form of a shell
  16. archive.  IOzone is a portable benchmark which measures the speed at
  17. which your system reads and writes sequential files.  It works with
  18. raw devices such as tape drives, as well as with disk files.  IOzone
  19. has been ported to many UNIX platforms, as well as VAX/VMS, GUARDIAN
  20. 90, NeXt, MS-DOS, POSIX and ANSI C.  This posting contains a README
  21. file which describes the benchmarks, and the source file iozone.c
  22.  
  23. Regards,
  24. Bill Norcott
  25. -----------------
  26. #! /bin/sh
  27. # This is a shell archive.  Remove anything before this line, then feed it
  28. # into a shell via "sh file" or similar.  To overwrite existing files,
  29. # type "sh file -c".
  30. # Contents:  README iozone.c
  31. # Wrapped by kent@sparky on Mon Nov  2 12:36:44 1992
  32. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  33. echo If this archive is complete, you will see the following message:
  34. echo '          "shar: End of archive 1 (of 1)."'
  35. if test -f 'README' -a "${1}" != "-c" ; then 
  36.   echo shar: Will not clobber existing file \"'README'\"
  37. else
  38.   echo shar: Extracting \"'README'\" \(10345 characters\)
  39.   sed "s/^X//" >'README' <<'END_OF_FILE'
  40. X
  41. X    IOZONE: Performance Test of Sequential File I/O  --  V1.16 (10/28/92)
  42. X        By Bill Norcott
  43. X
  44. X    Operating System: ANSI C
  45. X
  46. XIOZONE: help mode
  47. X
  48. X       'IO Zone' Benchmark Program
  49. X       Author: Bill Norcott (norcott_bill@tandem.com)
  50. X               1060 Hyde Avenue
  51. X               San Jose, CA  95129
  52. X  Copyright 1991, 1992   William D. Norcott
  53. X  License to freely use and distribute this software is hereby granted 
  54. X  by the author, subject to the condition that this copyright notice 
  55. X  remains intact.  The author retains the exclusive right to publish 
  56. X  derivative works based on this work, including, but not limited to, 
  57. X  revised versions of this work
  58. X  This test writes a X MEGABYTE sequential file in Y byte chunks, then
  59. X  rewinds it  and reads it back.  [The size of the file should be
  60. X  big enough to factor out the effect of any disk cache.].  Finally,
  61. X  IOZONE deletes the temporary file
  62. X        
  63. X  The file is written (filling any cache buffers), and then read.  If the
  64. X  cache is >= X MB, then most if not all the reads will be satisfied from
  65. X  the cache.  However, if it is less than or equal to .5X MB, then NONE of
  66. X  the reads will be satisfied from the cache.  This is becase after the 
  67. X  file is written, a .5X MB cache will contain the upper .5 MB of the test
  68. X  file, but we will start reading from the beginning of the file (data
  69. X  which is no longer in the cache)
  70. X        
  71. X  In order for this to be a fair test, the length of the test file must
  72. X  be AT LEAST 2X the amount of disk cache memory for your system.  If
  73. X  not, you are really testing the speed at which your CPU can read blocks
  74. X  out of the cache (not a fair test)
  75. X        
  76. X  IOZONE does not normally test the raw I/O speed of your disk or system.
  77. X  It tests the speed of sequential I/O to actual files.  Therefore, this
  78. X  measurement factors in the efficiency of you machines file system,
  79. X  operating system, C compiler, and C runtime library.  It produces a 
  80. X  measurement which is the number of bytes per second that your system
  81. X  can read or write to a file.  
  82. X  You use IOZONE to test the I/O speed of a UNIX 'RAW DEVICE' such
  83. X  as a tape drive, hard disk drive, floppy disk drive, etc.  To do this,
  84. X  you must define the symbol NO_DELETE when you compile IOZONE.  If you
  85. X  fail to define NO_DELETE, IOZONE will treat the raw device as a 
  86. X  temporary file, and WILL DELETE THE RAW DEVICE after the test completes!
  87. X  When testing raw devices, any UNIX buffer caching is bypassed.  IOZONE
  88. X  still is using the read()/write() system calls, so you are not quite
  89. X  testing the device at the low level of say, disk controller diagnostics.
  90. X  On the other hand, that kind of testing is highly system- and device-
  91. X  specific, and my goal for IOZONE has been to build a highly portable
  92. X  benchmark -- not one which is tied to a particular operating system or
  93. X  hardware configuration.  In practice, I have tested raw disk and tape
  94. X  peripherals and the results are very close to the manufacturer's specs
  95. X  for those devices.
  96. X  For V1.06, IOZONE adds the 'auto test' feature.  This is activated
  97. X  by the command:  'iozone auto' .  The auto test runs IOZONE repeatedly  
  98. X  using record sizes from 512 to 8192 bytes, and file sizes from 1 to 16
  99. X  megabytes.  It creates a table of results.
  100. X        
  101. X  For V1.06, IOZONE lets you specify the number of file system sizes and      
  102. X  record lengths to test when using auto mode.  Define the constants
  103. X  MEGABYTES_ITER_LIMIT and RECLEN_ITER_LIMIT as seen below      
  104. X        
  105. X  For V1.09 you can show the development help by typing 'iozone help'
  106. X        
  107. X  For V1.10 IOzone traps SIGINT (user interrupt) and SIGTERM
  108. X  (kill from shell) signals and deletes the temporary file
  109. X        
  110. X  For V1.11 IOzone requires no compilation flags for AIX
  111. X  Also, come miscellaneous cleanups have been made to the source
  112. X        
  113. X  For V1.12 IOzone support has been added for the MIPS RISCos,
  114. X  Tandem Non-StopUX, and Tandem GUARDIAN 90 operating systems.
  115. X  IOzone is now a 'Conforming POSIX.1 Application'  (IEEE Std 1003.1-1988)
  116. X        
  117. X  For V1.14 IOzone supports Next and QNX systems.  It also prints out
  118. X  the name of the operating system when run.  There is now the option
  119. X  to force IOzone to flush all writes to disk via fsync()
  120. X  Defining USE_FSYNC will make IOzone include in its measurements the time
  121. X  it takes to actually write the data onto disk, as opposed to
  122. X  just writing into the system cache.  BSD UNIX and SVR4 support fsync(),
  123. X  but SVR3 and generic POSIX systems do not.  I have enabled USE_FSYNC
  124. X  for the systems which support it
  125. X        
  126. X  For V1.14, we now officially support AT&T SVR4.  It has worked just
  127. X  fine using SVR4 with previous versions of IOzone.  Also, for systems
  128. X  which use the times() function, we calculate the 'base time' the first
  129. X  time we ever call time_so_far(), then subtract this time from all
  130. X  future measurements.  This increases the precision of our measurement
  131. X  and fixes a loss-of-precision problem which occurred on some systems
  132. X        
  133. X  For V1.15, add the NO_DELETE symbol.  If you define NO_DELETE during
  134. X  the compilation (e.g., for UNIX systems compile with cc -DNO_DELETE),
  135. X  IOzone will not delete the 'temporary' file which it reads & writes.
  136. X  This is REQUIRED when testing RAW DEVICES such as disks and tape drives!
  137. X        
  138. X  This program has been ported and tested on the following computer
  139. X  operating systems:
  140. X    Vendor             Operating System    Notes on compiling IOzone
  141. X    -------------------------------------------------------------------------
  142. X    Apollo          Domain/OS           no cc switches -- BSD domain
  143. X    AT&T               UNIX System V Release 4
  144. X    AT&T 6386WGS       AT&T UNIX 5.3.2     can't get it to compile with cc
  145. X                          It should work with gcc via:
  146. X                          'gcc -ansi -o iozone iozone.c'
  147. X    Generic AT&T       UNIX System V R3    may need cc -DSVR3
  148. X    Convergent         Unisys/AT&T Sys5r3  cc -DCONVERGENT -o iozone iozone.c
  149. X    Digital Equipment  ULTRIX V4.1 
  150. X    Digital Equipment  VAX/VMS V5.4        see below **         
  151. X    Digital Equipment  VAX/VMS (POSIX) 
  152. X    Hewlett-Packard    HP-UX 7.05
  153. X    IBM                AIX Ver. 3 rel. 1
  154. X    Interactive        UNIX System V R3    
  155. X    Microsoft          MS-DOS 3.3          tested Borland, Microsoft C
  156. X    MIPS               RISCos 4.52
  157. X    NeXt               NeXt OS 2.x
  158. X    OSF                OSF/1
  159. X    Portable!          POSIX 1003.1-1988   may need to -D_POSIX_SOURCE
  160. X    QNX                QNX 4.0
  161. X    SCO                UNIX System V/386 3.2.2
  162. X    SCO                XENIX 2.3
  163. X    SCO                XENIX 3.2
  164. X    Silicon Graphics   UNIX                cc -DSGI -o iozone iozone.c
  165. X    Sony Microsystems  UNIX                same as MIPS
  166. X    Sun Microsystems   SUNOS 4.1.1
  167. X    Tandem Computers   GUARDIAN 90         1. call the source file IOZONEC
  168. X                                           2. C/IN IOZONEC/IOZONE;RUNNABLE
  169. X                                           3. RUN IOZONE
  170. X    Tandem Computers   Non-Stop UX
  171. X        
  172. X    ** for VMS, define iozone as a foreign command via this DCL command:       
  173. X       $IOZONE :== $SYS$DISK:[]IOZONE.EXE      
  174. X       this lets you pass the command line arguments to IOZONE
  175. X  Acknowledgements to the following persons for their feedback on IOzone:       
  176. X  Andy Puchrik, Michael D. Lawler, Krishna E. Bera, Sam Drake, John H. Hartman, 
  177. X  Ted Lyszczarz, Bill Metzenthen, Jody Winston, Clarence Dold, Axel
  178. X  Dan Hildebrand, Joe Nordman, Bob Fritz, Jeff Johnson
  179. X        
  180. X  --- MODIFICATION HISTORY:
  181. X    3/7/91 William D. Norcott (Bill.Norcott@nuo.mts.dec.com)
  182. X                               created
  183. X    3/22/91 Bill Norcott       tested on OSF/1 ... it works
  184. X    3/24/91 Bill Norcott       V1.02 -- use calloc in TURBOC to
  185. X                                       fix bug with their malloc
  186. X    3/25/91 Bill Norcott       V1.03 -- add ifdef for XENIX
  187. X                                       
  188. X    3/27/91 Bill Norcott       V1.04 -- Includes for SCO UNIX
  189. X                                       
  190. X    4/26/91 Bill Norcott       V1.05 -- support AIX and SUNos, check
  191. X                                       length of read() and write()
  192. X    4/26/91 Bill Norcott       V1.06 -- tabulate results of a series 
  193. X                                       of tests
  194. X    5/17/91 Bill Norcott       V1.07 -- use time() for VMS
  195. X    5/20/91 Bill Norcott       V1.08 -- use %ld for Turbo C and
  196. X                                       use #ifdef sun to bypass
  197. X                                       inclusion of limits.h
  198. X    6/19/91 Bill Norcott       V1.09 -- rid #elif to support HP-UX and 
  199. X                                       Silicon Graphics UNIX, and
  200. X                                       add #ifdef SGI
  201. X                                       add #ifdef CONVERGENT
  202. X                                       for Convergent Technologies
  203. X                                       also add help option
  204. X    7/2/91 Bill Norcott        V1.10 -- delete file if get SIGINT
  205. X                                       or SIGTERM
  206. X    8/20/91 Bill Norcott       V1.11 -- require no flags with AIX
  207. X    11/4/91 Bill Norcott       V1.12 -- support MIPS RISCos
  208. X                                         Tandem NonStop-UX, and
  209. X                                        IEEE Std POSIX 1003.1-1988
  210. X    12/4/91 Bill Norcott       V1.13 -- support NeXT; tell host OS type
  211. X    1/23/92 Bill Norcott      V1.14 -- support QNX & use calloc() for buffer
  212. X    5/1/92 Bill Norcott      V1.15 -- support SVR4; fix loss of precision
  213. X                                       in times() function.  
  214. X                                       support Interactive UNIX
  215. X                                       detect ANSI if no O/S
  216. X                                       Also, define for generic SVR3
  217. X                                       Apollo Domain/OS
  218. X                                       Define NO_DELETE and iozone wont
  219. X                                       delete the temp file.  Needed to
  220. X                                       test raw devices without deleting
  221. X                                       them
  222. X    10/28/92 Bill Norcott    V1.16 -- bug fix: some unsigned longs changed
  223. X                                      to unsigned in V1.15 caused problem
  224. X                                      so change back.  Also, note problems
  225. X                     with AT&T 6386WGS systems
  226. END_OF_FILE
  227.   if test 10345 -ne `wc -c <'README'`; then
  228.     echo shar: \"'README'\" unpacked with wrong size!
  229.   fi
  230.   # end of 'README'
  231. fi
  232. if test -f 'iozone.c' -a "${1}" != "-c" ; then 
  233.   echo shar: Will not clobber existing file \"'iozone.c'\"
  234. else
  235.   echo shar: Extracting \"'iozone.c'\" \(35038 characters\)
  236.   sed "s/^X//" >'iozone.c' <<'END_OF_FILE'
  237. Xchar *help[] = {
  238. X  "       'IO Zone' Benchmark Program",
  239. X  " ",
  240. X  "       Author: Bill Norcott (norcott_bill@tandem.com)",
  241. X  "               1060 Hyde Avenue",
  242. X  "               San Jose, CA  95129",
  243. X  " ",
  244. X  "  Copyright 1991, 1992   William D. Norcott",
  245. X  " ",
  246. X  "  License to freely use and distribute this software is hereby granted ",
  247. X  "  by the author, subject to the condition that this copyright notice ",
  248. X  "  remains intact.  The author retains the exclusive right to publish ",
  249. X  "  derivative works based on this work, including, but not limited to, ",
  250. X  "  revised versions of this work",
  251. X  " ",
  252. X  "  This test writes a X MEGABYTE sequential file in Y byte chunks, then",
  253. X  "  rewinds it  and reads it back.  [The size of the file should be",
  254. X  "  big enough to factor out the effect of any disk cache.].  Finally,",
  255. X  "  IOZONE deletes the temporary file",
  256. X  "        ",
  257. X  "  The file is written (filling any cache buffers), and then read.  If the",
  258. X  "  cache is >= X MB, then most if not all the reads will be satisfied from",
  259. X  "  the cache.  However, if it is less than or equal to .5X MB, then NONE of",
  260. X  "  the reads will be satisfied from the cache.  This is becase after the ",
  261. X  "  file is written, a .5X MB cache will contain the upper .5 MB of the test",
  262. X  "  file, but we will start reading from the beginning of the file (data",
  263. X  "  which is no longer in the cache)",
  264. X  "        ",
  265. X  "  In order for this to be a fair test, the length of the test file must",
  266. X  "  be AT LEAST 2X the amount of disk cache memory for your system.  If",
  267. X  "  not, you are really testing the speed at which your CPU can read blocks",
  268. X  "  out of the cache (not a fair test)",
  269. X  "        ",
  270. X  "  IOZONE does not normally test the raw I/O speed of your disk or system.",
  271. X  "  It tests the speed of sequential I/O to actual files.  Therefore, this",
  272. X  "  measurement factors in the efficiency of you machines file system,",
  273. X  "  operating system, C compiler, and C runtime library.  It produces a ",
  274. X  "  measurement which is the number of bytes per second that your system",
  275. X  "  can read or write to a file.  ",
  276. X  " ",
  277. X  "  You use IOZONE to test the I/O speed of a UNIX 'RAW DEVICE' such",
  278. X  "  as a tape drive, hard disk drive, floppy disk drive, etc.  To do this,",
  279. X  "  you must define the symbol NO_DELETE when you compile IOZONE.  If you",   
  280. X  "  fail to define NO_DELETE, IOZONE will treat the raw device as a ",
  281. X  "  temporary file, and WILL DELETE THE RAW DEVICE after the test completes!",
  282. X  "  When testing raw devices, any UNIX buffer caching is bypassed.  IOZONE",
  283. X  "  still is using the read()/write() system calls, so you are not quite",
  284. X  "  testing the device at the low level of say, disk controller diagnostics.",
  285. X  "  On the other hand, that kind of testing is highly system- and device-",
  286. X  "  specific, and my goal for IOZONE has been to build a highly portable",
  287. X  "  benchmark -- not one which is tied to a particular operating system or",
  288. X  "  hardware configuration.  In practice, I have tested raw disk and tape",
  289. X  "  peripherals and the results are very close to the manufacturer's specs",
  290. X  "  for those devices.", 
  291. X  " ",
  292. X  "  For V1.06, IOZONE adds the 'auto test' feature.  This is activated",
  293. X  "  by the command:  'iozone auto' .  The auto test runs IOZONE repeatedly  ",
  294. X  "  using record sizes from 512 to 8192 bytes, and file sizes from 1 to 16",
  295. X  "  megabytes.  It creates a table of results.",
  296. X  "        ",
  297. X  "  For V1.06, IOZONE lets you specify the number of file system sizes and      ",
  298. X  "  record lengths to test when using auto mode.  Define the constants",
  299. X  "  MEGABYTES_ITER_LIMIT and RECLEN_ITER_LIMIT as seen below      ",
  300. X  "        ",
  301. X  "  For V1.09 you can show the development help by typing 'iozone help'",
  302. X  "        ",
  303. X  "  For V1.10 IOzone traps SIGINT (user interrupt) and SIGTERM",
  304. X  "  (kill from shell) signals and deletes the temporary file",
  305. X  "        ",
  306. X  "  For V1.11 IOzone requires no compilation flags for AIX",
  307. X  "  Also, come miscellaneous cleanups have been made to the source",
  308. X  "        ",
  309. X  "  For V1.12 IOzone support has been added for the MIPS RISCos,",
  310. X  "  Tandem Non-StopUX, and Tandem GUARDIAN 90 operating systems.",
  311. X  "  IOzone is now a 'Conforming POSIX.1 Application'  (IEEE Std 1003.1-1988)",
  312. X  "        ",
  313. X  "  For V1.14 IOzone supports Next and QNX systems.  It also prints out", 
  314. X  "  the name of the operating system when run.  There is now the option",
  315. X  "  to force IOzone to flush all writes to disk via fsync()",
  316. X  "  Defining USE_FSYNC will make IOzone include in its measurements the time",
  317. X  "  it takes to actually write the data onto disk, as opposed to",
  318. X  "  just writing into the system cache.  BSD UNIX and SVR4 support fsync(),",
  319. X  "  but SVR3 and generic POSIX systems do not.  I have enabled USE_FSYNC",
  320. X  "  for the systems which support it",
  321. X  "        ",
  322. X  "  For V1.14, we now officially support AT&T SVR4.  It has worked just",
  323. X  "  fine using SVR4 with previous versions of IOzone.  Also, for systems",
  324. X  "  which use the times() function, we calculate the 'base time' the first",
  325. X  "  time we ever call time_so_far(), then subtract this time from all",
  326. X  "  future measurements.  This increases the precision of our measurement",
  327. X  "  and fixes a loss-of-precision problem which occurred on some systems",
  328. X  "        ",
  329. X  "  For V1.15, add the NO_DELETE symbol.  If you define NO_DELETE during",
  330. X  "  the compilation (e.g., for UNIX systems compile with cc -DNO_DELETE),",
  331. X  "  IOzone will not delete the 'temporary' file which it reads & writes.",
  332. X  "  This is REQUIRED when testing RAW DEVICES such as disks and tape drives!",
  333. X  "        ",
  334. X  " ",
  335. X  "  This program has been ported and tested on the following computer",
  336. X  "  operating systems:",
  337. X  " ",
  338. X  "    Vendor             Operating System    Notes on compiling IOzone",
  339. X  "    -------------------------------------------------------------------------",
  340. X  "    Apollo          Domain/OS           no cc switches -- BSD domain", 
  341. X  "    AT&T               UNIX System V Release 4",
  342. X  "    AT&T 6386WGS       AT&T UNIX 5.3.2     can't get it to compile with cc",
  343. X  "                          It should work with gcc via:",
  344. X  "                          'gcc -ansi -o iozone iozone.c'",
  345. X  "    Generic AT&T       UNIX System V R3    may need cc -DSVR3",
  346. X  "    Convergent         Unisys/AT&T Sys5r3  cc -DCONVERGENT -o iozone iozone.c",
  347. X  "    Digital Equipment  ULTRIX V4.1 ",
  348. X  "    Digital Equipment  VAX/VMS V5.4        see below **         ",
  349. X  "    Digital Equipment  VAX/VMS (POSIX) ",
  350. X  "    Hewlett-Packard    HP-UX 7.05",
  351. X  "    IBM                AIX Ver. 3 rel. 1",
  352. X  "    Interactive        UNIX System V R3    ",
  353. X  "    Microsoft          MS-DOS 3.3          tested Borland, Microsoft C",
  354. X  "    MIPS               RISCos 4.52",
  355. X  "    NeXt               NeXt OS 2.x",
  356. X  "    OSF                OSF/1",
  357. X  "    Portable!          POSIX 1003.1-1988   may need to -D_POSIX_SOURCE",
  358. X  "    QNX                QNX 4.0",
  359. X  "    SCO                UNIX System V/386 3.2.2",
  360. X  "    SCO                XENIX 2.3",
  361. X  "    SCO                XENIX 3.2",
  362. X  "    Silicon Graphics   UNIX                cc -DSGI -o iozone iozone.c",
  363. X  "    Sony Microsystems  UNIX                same as MIPS",
  364. X  "    Sun Microsystems   SUNOS 4.1.1",
  365. X  "    Tandem Computers   GUARDIAN 90         1. call the source file IOZONEC",
  366. X  "                                           2. C/IN IOZONEC/IOZONE;RUNNABLE",
  367. X  "                                           3. RUN IOZONE",
  368. X  "    Tandem Computers   Non-Stop UX",
  369. X  "        ",
  370. X  "    ** for VMS, define iozone as a foreign command via this DCL command:       ",
  371. X  " ",
  372. X  "       $IOZONE :== $SYS$DISK:[]IOZONE.EXE      ",
  373. X  " ",
  374. X  "       this lets you pass the command line arguments to IOZONE",
  375. X  " ",
  376. X  "  Acknowledgements to the following persons for their feedback on IOzone:       ",
  377. X  " ",
  378. X  "  Andy Puchrik, Michael D. Lawler, Krishna E. Bera, Sam Drake, John H. Hartman, ",
  379. X  "  Ted Lyszczarz, Bill Metzenthen, Jody Winston, Clarence Dold, Axel",
  380. X  "  Dan Hildebrand, Joe Nordman, Bob Fritz, Jeff Johnson",
  381. X  "        ",
  382. X  "  --- MODIFICATION HISTORY:",
  383. X  " ",
  384. X  " ",
  385. X  "    3/7/91 William D. Norcott (Bill.Norcott@nuo.mts.dec.com)",
  386. X  "                               created",
  387. X  " ",
  388. X  "    3/22/91 Bill Norcott       tested on OSF/1 ... it works",
  389. X  " ",
  390. X  "    3/24/91 Bill Norcott       V1.02 -- use calloc in TURBOC to",
  391. X  "                                       fix bug with their malloc",
  392. X  " ",
  393. X  "    3/25/91 Bill Norcott       V1.03 -- add ifdef for XENIX",
  394. X  "                                       ",
  395. X  "    3/27/91 Bill Norcott       V1.04 -- Includes for SCO UNIX",
  396. X  "                                       ",
  397. X  "    4/26/91 Bill Norcott       V1.05 -- support AIX and SUNos, check",
  398. X  "                                       length of read() and write()",
  399. X  "    4/26/91 Bill Norcott       V1.06 -- tabulate results of a series ",
  400. X  "                                       of tests",
  401. X  "    5/17/91 Bill Norcott       V1.07 -- use time() for VMS",
  402. X  "    5/20/91 Bill Norcott       V1.08 -- use %ld for Turbo C and",
  403. X  "                                       use #ifdef sun to bypass",
  404. X  "                                       inclusion of limits.h",
  405. X  "    6/19/91 Bill Norcott       V1.09 -- rid #elif to support HP-UX and ",
  406. X  "                                       Silicon Graphics UNIX, and",
  407. X  "                                       add #ifdef SGI",
  408. X  "                                       add #ifdef CONVERGENT",
  409. X  "                                       for Convergent Technologies",
  410. X  "                                       also add help option",
  411. X  "    7/2/91 Bill Norcott        V1.10 -- delete file if get SIGINT",
  412. X  "                                       or SIGTERM",
  413. X  "    8/20/91 Bill Norcott       V1.11 -- require no flags with AIX",
  414. X  "    11/4/91 Bill Norcott       V1.12 -- support MIPS RISCos",
  415. X  "                                         Tandem NonStop-UX, and",
  416. X  "                                        IEEE Std POSIX 1003.1-1988",
  417. X  "    12/4/91 Bill Norcott       V1.13 -- support NeXT; tell host OS type",
  418. X  "    1/23/92 Bill Norcott      V1.14 -- support QNX & use calloc() for buffer",
  419. X  "    5/1/92 Bill Norcott      V1.15 -- support SVR4; fix loss of precision",
  420. X  "                                       in times() function.  ",
  421. X  "                                       support Interactive UNIX",
  422. X  "                                       detect ANSI if no O/S",
  423. X  "                                       Also, define for generic SVR3",
  424. X  "                                       Apollo Domain/OS",
  425. X  "                                       Define NO_DELETE and iozone wont",
  426. X  "                                       delete the temp file.  Needed to",
  427. X  "                                       test raw devices without deleting",
  428. X  "                                       them",
  429. X  "    10/28/92 Bill Norcott    V1.16 -- bug fix: some unsigned longs changed",
  430. X  "                                      to unsigned in V1.15 caused problem",
  431. X  "                                      so change back.  Also, note problems",
  432. X  "                     with AT&T 6386WGS systems",
  433. X  " ",
  434. X  "" };
  435. X
  436. X/******************************************************************
  437. X  
  438. X  INCLUDE FILES (system-dependent)
  439. X  
  440. X  ******************************************************************/
  441. X/* 
  442. XV1.15 -- Define the symbol NO_DELETE if you plan to use IOzone to test
  443. Xthe speed of UNIX raw devices such as disk- and tape drives.  This will
  444. Xtell IOzone NOT to delete the file after the test completes
  445. X*/
  446. X/* #define NO_DELETE */
  447. X/* 
  448. XV1.15 -- If you have a generic System V R3 not on my list of supported
  449. Xsystems, define SVR3 when you compile IOzone. If you have to use this, please
  450. Xsend tell me what preprocessor symbols your C compiler defines which
  451. Xwill help me test for your particular system... do a 'man cc' on a
  452. XUNIX system to check, or just do a 'man cc > cc.txt' and mail me
  453. Xcc.txt
  454. X*/
  455. X/*  Define the following if you have a generic System V R3 system which
  456. Xis not one of the specific versions listed above
  457. X*/
  458. X/* #define SVR3 */
  459. X#ifdef SVR3
  460. X#ifndef OS_TYPE
  461. X#define OS_TYPE "'Generic' UNIX System V Release 3 -- vendor unknown" 
  462. X#endif
  463. X#include <fcntl.h>
  464. X#include <sys/types.h>
  465. X#define SysVtime
  466. X#endif
  467. X/* V1.15 -- add Apollo Domain O/S to the list -- it also worked in previous
  468. Xversions, now it will print its identity
  469. X*/
  470. X#ifdef apollo
  471. X#ifndef OS_TYPE
  472. X#define OS_TYPE "Apollo Domain/OS -- using BSD libraries"
  473. X#define BSDtime
  474. X#define USE_FSYNC
  475. X#endif
  476. X#endif
  477. X
  478. X/* V1.14 -- use calloc instead of stack for buffer, on all platforms */
  479. X#define usecalloc
  480. X/* 
  481. XV1.14b -- check for ultrix which uses sysconf in newer POSIX version 
  482. Xbut uses BSD-style time in the pre-POSIX versions
  483. XV1.15 use fsync() for ultrix even though V4.2 will pick up other options
  484. Xfrom POSIX
  485. X*/
  486. X#ifdef ultrix
  487. X#ifndef OS_TYPE
  488. X#define OS_TYPE "ULTRIX 4.0 or earlier"
  489. X#define BSDtime
  490. X#define USE_FSYNC
  491. X#endif
  492. X#endif
  493. X/* V1.13 -- support NeXT by treating it like a Sun... Thanks Axel! */
  494. X#ifdef __NeXT__
  495. X#ifndef OS_TYPE
  496. X#define OS_TYPE "NeXT OS"
  497. X#endif
  498. X#define sun
  499. X#endif
  500. X/*
  501. X  define nolimits if your system has no limits.h.  Sun's don't but I
  502. X  take care of this explicitly beginning with V1.08 of IOzone.
  503. X  */
  504. X#ifdef sun
  505. X#ifndef OS_TYPE
  506. X#define OS_TYPE "SunOS"
  507. X#endif
  508. X#define nolimits
  509. X#define BSDtime
  510. X#define USE_FSYNC
  511. X#endif
  512. X/* V1.09 -- Silicon Graphics compile with -DSGI  */
  513. X#ifdef SGI
  514. X#ifndef OS_TYPE
  515. X#define OS_TYPE "Silicon Graphics"
  516. X#endif
  517. X#define nolimits
  518. X#define BSDtime
  519. X#endif
  520. X
  521. X/* V1.13 For MIPS RISC/OS and Tandem NonStop-UX*/
  522. X#ifdef SYSTYPE_BSD43
  523. X#define bsd4_3
  524. X#ifndef OS_TYPE
  525. X#define OS_TYPE "MIPS RISC/os (BSD 4.3 libraries)"
  526. X#endif
  527. X#endif
  528. X
  529. X#ifdef SYSTYPE_SYSV
  530. X#include <sys/utsname.h>
  531. X#define nolimits
  532. X#ifdef T_NONSTOP
  533. X#define OS_TYPE "TANDEM NonStop-UX (System V libraries)"
  534. X#endif
  535. X#ifndef OS_TYPE
  536. X#define OS_TYPE "MIPS RISC/os (System V libraries)"
  537. X#endif
  538. X#define SysVtime
  539. X#include <sys/types.h>
  540. X#include <sys/times.h>
  541. X#include <sys/fcntl.h>
  542. X#endif
  543. X/* V1.14 -- define nolimits and BSDtime for Xenix 2.3.3 */
  544. X/* incl definitions of O_* flags for XENIX */
  545. X#ifdef M_UNIX
  546. X#define SCOunix
  547. X#else
  548. X#ifdef M_XENIX
  549. X#define SCOxenix
  550. X#endif
  551. X#endif
  552. X
  553. X/* SCO Unix System V */
  554. X#ifdef SCOunix
  555. X#define OS_TYPE "SCO UNIX System V/386"
  556. X#include <sys/types.h>
  557. X#include <sys/fcntl.h>
  558. X#endif
  559. X
  560. X#ifdef SCOxenix
  561. X#ifdef XENIX_2_3
  562. X#define OS_TYPE "SCO XENIX 2.3.x"
  563. X#define BSDtime
  564. X#else
  565. X#define OS_TYPE "SCO XENIX 3.x"
  566. X#define SysVtime
  567. X#endif
  568. X#endif
  569. X
  570. X/* V1.12 -- test for POSIX-conformant operating system; requires limits.h */
  571. X/*
  572. XV1.15 -- I have been told that there is a problem in the times() POSIX 
  573. Xfunction in Ultrix V4.1 and greater.  It seems to return the time in
  574. Xwhole seconds (expressed in terms of clock ticks) instead of correctly
  575. Xreturning the elapsed time in clock ticks ALTHOUGH POSIX 1003.1-1988 
  576. Xand ISO 9945 CLEARLY STATE that "times() shall return the elapsed real 
  577. Xtime, in clock ticks."  
  578. X
  579. XThis means calling times() twice in the same second and subtracting
  580. Xthe two values, produces an answer of 0, which IOzone detects as an error.
  581. X
  582. XI thought I had a problem in V1.14 under Ultrix with loss of precision, 
  583. Xi.e. taking the difference of two large floating point numbers, 
  584. Xbut the problem seems be that Ultrix times() *inherently* has a 
  585. Xloss of precision, so my "fix" can't fix the broken system call.  
  586. XUntil they fix it in Ultrix I am going to use BSD-style everything
  587. Xfor Ultrix
  588. X*/
  589. X#ifndef nolimits
  590. X
  591. X#include <limits.h>
  592. X#ifdef _POSIX_ARG_MAX
  593. X#ifndef ultrix
  594. X#ifndef OS_TYPE
  595. X#define OS_TYPE "POSIX 1003.1-1988"
  596. X#endif
  597. X#define isposix
  598. X#undef USE_FSYNC
  599. X#else
  600. X/* It's ultrix disguised as POSIX; still use BSD calls until they fix it */
  601. X#undef OS_TYPE
  602. X#define OS_TYPE "ULTRIX 4.1 or later"
  603. X#endif
  604. X#endif
  605. X#endif
  606. X
  607. X/* Tandem's GUARDIAN operating system */
  608. X#include <stdio.h>
  609. X#ifdef __TANDEM
  610. X#ifndef OS_TYPE
  611. X#define OS_TYPE "TANDEM GUARDIAN 90"
  612. X#endif
  613. X#define nosignals
  614. X#define ANSItime
  615. X#define ANSI_MAIN
  616. X#include <fcntl.h>
  617. X#include <stdlib.h>
  618. X#include <string.h>
  619. X#include <time.h>
  620. X#endif
  621. X#ifndef nosignals
  622. X#include <signal.h>
  623. X#endif
  624. X#ifdef  __MSDOS__               /* Turbo C define this way for PCs... */
  625. X#define MSDOS                   /* Microsoft C defines this */
  626. X#endif
  627. X/* VMS and MS-DOS both have ANSI C compilers and use rand()/srand() */
  628. X#ifdef  VMS_POSIX
  629. X#undef   VMS
  630. X#define ANSI_RANDOM     1
  631. X#endif
  632. X#ifdef  MSDOS
  633. X#define ANSI_RANDOM     1
  634. X#endif
  635. X/* Convergent Technologies M680xx based with Unisys/AT&T Sys5r3 */
  636. X#ifdef CONVERGENT
  637. X#ifndef OS_TYPE
  638. X#define OS_TYPE "Convergent Technologies" 
  639. X#endif
  640. X#include <fcntl.h>
  641. X#define SysVtime
  642. X#endif
  643. X/* Interactive UNIX System V Release 3.2 */
  644. X#ifdef isc386
  645. X#ifndef OS_TYPE
  646. X#define OS_TYPE "Interactive UNIX System V/386" 
  647. X#endif
  648. X#include <fcntl.h>
  649. X#define SysVtime
  650. X#endif
  651. X
  652. X/* V1.11 -- With the following includes, AIX no longer requires -Dunix */
  653. X#ifdef _AIX
  654. X#ifndef OS_TYPE
  655. X#define OS_TYPE "AIX"
  656. X#endif
  657. X#include <fcntl.h>
  658. X#include <sys/time.h>
  659. X#endif
  660. X
  661. X#if defined(VMS)
  662. X#ifndef OS_TYPE
  663. X#define OS_TYPE "VAX/VMS"
  664. X#endif
  665. X#define ANSItime
  666. X#define ANSI_RANDOM     1
  667. X#include    <math.h>
  668. X#include    <unixio.h>
  669. X#include    <ssdef.h>
  670. X#include    <file.h>
  671. X#include    <time.h>
  672. X
  673. X#else
  674. X/* ... either MSDOS, POSIX, or a generic non-POSIX UNIX */
  675. X#ifdef MSDOS
  676. X#ifndef OS_TYPE
  677. X#define OS_TYPE "MS-DOS"
  678. X#endif
  679. X#define usecalloc
  680. X#include <fcntl.h>
  681. X#include <time.h>
  682. X#endif
  683. X/* nope, not MS-DOS, try POSIX */
  684. X#ifdef isposix
  685. X#include <time.h>
  686. X#include <sys/times.h>
  687. X#include <fcntl.h>
  688. X#include <unistd.h>
  689. X#else
  690. X#ifdef unix
  691. X#include <fcntl.h>
  692. X#else 
  693. X#define O_RDONLY 0
  694. X#endif
  695. X#endif
  696. X#endif
  697. X
  698. X/* for systems with System V-style time, define SysVtime */
  699. X#ifdef M_SYSV
  700. X#define SysVtime
  701. X#endif
  702. X
  703. X/* for systems with BSD style time, define BSDtime */
  704. X#ifdef bsd4_2
  705. X#define USE_FSYNC
  706. X#ifndef OS_TYPE
  707. X#define OS_TYPE "BSD 4.2"
  708. X#endif
  709. X#define BSDtime
  710. X#endif
  711. X#ifdef bsd4_3
  712. X#define USE_FSYNC
  713. X#ifndef OS_TYPE
  714. X#define OS_TYPE "BSD 4.3"
  715. X#endif
  716. X#define BSDtime
  717. X#endif
  718. X/*
  719. XIf we made it this far and still don't know which operating system
  720. Xwe are running, check if we at least have ANSI C so we can do some
  721. Xkind of time functions.  On the other hand, if we know what O/S
  722. Xwe are running use the (more precise) time routines for that O/S,
  723. Xeven if we do have ANSI C.  If we don't know what O/S we are and
  724. Xwe don't have ANSI C, but we are some flavor of UNIX, I will use
  725. Xtime() which any UNIX will have.  For the worst case we are not 
  726. Xany form of UNIX nor a supported proprietary O/S, and we don't have 
  727. XANSI C either,  one of two things will happen:
  728. X1. If you define NOTIMER then you will have to use a stopwatch
  729. X2. If NOTIMER not defined, we will assume we can use time()
  730. X*/
  731. X#ifndef OS_TYPE
  732. X#ifdef __STDC__
  733. X#define OS_TYPE "ANSI C"
  734. X#define ANSItime
  735. X#include    <time.h>
  736. X#endif
  737. X#endif
  738. X
  739. X#ifndef OS_TYPE
  740. X#ifdef unix
  741. X#define OS_TYPE "UNIX (can't tell if System V or BSD) -- using time()"
  742. X#define ANSItime
  743. X#include    <time.h>
  744. X#endif
  745. X#endif
  746. X
  747. X#ifndef OS_TYPE
  748. X#if NOTIMER
  749. X#define OS_TYPE "System type unknown & not ANSI C -- disabling timing"
  750. X#define noclock 1
  751. X#else
  752. X#define OS_TYPE "System type unknown & not ANSI C -- using time()"
  753. X#define ANSItime
  754. X#include    <time.h>
  755. X#endif
  756. X#endif
  757. X
  758. X#ifdef SysVtime
  759. X#undef BSDtime
  760. X#include <sys/times.h>
  761. X#include <sys/param.h>
  762. X#ifndef CLK_TCK
  763. X#define CLK_TCK HZ
  764. X#endif
  765. X#endif
  766. X
  767. X#ifdef BSDtime
  768. X#undef SysVtime
  769. X#include <sys/time.h>
  770. X#endif
  771. X
  772. X/******************************************************************
  773. X  
  774. X  DEFINED CONSTANTS
  775. X  
  776. X  ******************************************************************/
  777. X/* Define NULL in case we don't have it... */
  778. X#ifndef NULL
  779. X#define NULL 0
  780. X#endif
  781. X/* 
  782. X  V1.14: Define ONETEST to run a single test at runtime as the default
  783. X  V1.14: Define AUTOTEST to run in auto test mode as the default
  784. X  i.e. the behavior of IOzone when it is invoked with no arguments.  ONETEST
  785. X  makes IOzone run a single test using a 1 MB file and 512 byte records.
  786. X  AUTOTEST causes IOzone to use auto test mode.
  787. X  For compatibility with previous versions of IOZONE, ONETEST is the default
  788. X  setting
  789. X*/
  790. X#define ONETEST 1
  791. X#ifndef ONETEST
  792. X#define AUTOTEST
  793. X#endif
  794. X
  795. X/* 
  796. X  V1.14: Define USE_FSYNC to force writes to disk during the write phase
  797. X  BSD and BSD-derived UNIX variants and also SVR4 are known to have fsync 
  798. X  UNIX).  After the file is written and before it is closed, call fsync()
  799. X  to force the data to be written from cache to disk.  This (mostly) cancels
  800. X  the fact that systems with a lot of memory for cache buffers or memory
  801. X  mapping display artificially high transfer rates during the write phase
  802. X  of IOzone, because the data never makes it onto the disk.  
  803. X
  804. X*/
  805. X#if 0
  806. X#define USE_FSYNC
  807. X#endif
  808. X
  809. X#define MEGABYTES 1                     /* number of megabytes in file */
  810. X#define RECLEN 512                      /* number of bytes in a record */
  811. X#define FILESIZE 1048576                /*size of file in bytes*/
  812. X#define NUMRECS 2048                    /* number of records */
  813. X#define MAXBUFFERSIZE 16*1024           /*maximum buffer size*/
  814. X#define MINBUFFERSIZE 128
  815. X#define TOOFAST 10
  816. X#define IOZONE_USAGE \
  817. X"\tUsage:\tiozone [megabytes] [record_length_in_bytes] [[path]filename]\n\t\tiozone auto\n\t\tiozone help\n\n"
  818. X#define THISVERSION "V1.16"
  819. X#define RELEASEDATE "10/28/92"
  820. X  /* Define only one of the following two.  All modern operating systems
  821. X     have time functions so let TIME be defined */
  822. X#ifndef noclock
  823. X#define TIME 1
  824. X#endif
  825. X  
  826. X#define MAXNAMESIZE 1000                /* max # of characters in filename */
  827. X#define CONTROL_STRING1 "\t%-8ld%-8ld%-20ld%-20ld\n"
  828. X#define CONTROL_STRING2 "\t%-8s%-8s%-20s%-20s\n"
  829. X  /*
  830. X    For 'auto mode', these defines determine the number of iterations
  831. X    to perform for both the file size and the record length.
  832. X    I.e., if MEGABYTES_ITER_LIMIT = 5 use 1, 2, 4, 8 & 16 megabyte files
  833. X    if RECLEN_ITER_LIMIT = 5 use 512, 1024, 2048, 4096 & 8192 byte records
  834. X    */
  835. X#define MEGABYTES_ITER_LIMIT 5
  836. X#define RECLEN_ITER_LIMIT 5
  837. X/******************************************************************
  838. X  
  839. X  MACRO DEFINITIONS
  840. X  
  841. X  ******************************************************************/
  842. X#define abs(X) ( (X) < 0 ? (-(X)) : (X) )  /* Absolute value of X */
  843. X  /******************************************************************
  844. X    
  845. X    FUNCTION DECLARATIONS
  846. X    
  847. X
  848. X    ******************************************************************/
  849. Xvoid auto_test();               /* perform automatic test series */
  850. Xvoid show_help();               /* show development help*/
  851. Xdouble time_so_far();        /* time since start of program */
  852. Xvoid signal_handler();          /* clean up if user interrupts us */
  853. X/******************************************************************
  854. X  
  855. X  GLOBAL VARIABLES
  856. X  
  857. X  ******************************************************************/
  858. Xint auto_mode;
  859. Xchar filename [MAXNAMESIZE];            /* name of temporary file */
  860. X/******************************************************************
  861. X  
  862. X  MAIN -- entry point
  863. X  
  864. X  ******************************************************************/
  865. X#ifdef ANSI_MAIN
  866. Xint 
  867. Xmain(int argc, char *argv[], char *env[])    /* main body of code */
  868. X#else
  869. Xint
  870. X     main(argc,argv)
  871. X     int argc;
  872. X     char *argv[];
  873. X#endif
  874. X{
  875. X#ifdef ANSI_MAIN
  876. X  char *fooenv;
  877. X#endif
  878. X  int fd;
  879. X  char *default_filename;
  880. X  
  881. X#ifdef  usecalloc
  882. X  char *buffer;
  883. X#else
  884. X  char buffer [MAXBUFFERSIZE];            /*a temporary data buffer*/
  885. X#endif
  886. X  unsigned long i;
  887. X  unsigned long megabytes = MEGABYTES;
  888. X  unsigned long reclen = RECLEN;
  889. X  unsigned long filesize;
  890. X  unsigned long numrecs;
  891. X  unsigned long thisrec;
  892. X#ifdef TIME
  893. X  unsigned long filebytes;
  894. X  unsigned long readrate, writerate;
  895. X  unsigned long goodmegs;
  896. X  unsigned long goodrecl;
  897. X  double starttime;
  898. X  double writetime, readtime;
  899. X  double totaltime;
  900. X#endif
  901. X#ifdef usecalloc
  902. X    buffer = (char *) calloc(1, MAXBUFFERSIZE);
  903. X#endif
  904. X  
  905. X#if defined (ANSI_MAIN)
  906. X  fooenv= env[0];       /* dummy so we make some use of env (to avoid warnings) */
  907. X#endif
  908. X  
  909. X#if defined (__TANDEM)
  910. X  default_filename ="IOZONET"; /* TANDEM GUARDIAN 90 has max 8 char filenames */
  911. X#else
  912. X  default_filename ="iozone.tmp"; /*default name of temporary file*/
  913. X#endif
  914. X  if (!auto_mode)
  915. X    {
  916. X      printf("\n\tIOZONE: Performance Test of Sequential File I/O  --  %s (%s)\n",
  917. X         THISVERSION, RELEASEDATE);
  918. X      printf("\t\tBy Bill Norcott\n\n");
  919. X#ifdef USE_FSYNC
  920. X      printf("\tOperating System: %s -- using fsync()\n\n", OS_TYPE);
  921. X#else
  922. X      printf("\tOperating System: %s\n\n", OS_TYPE);
  923. X#endif
  924. X#ifndef nosignals
  925. X      signal(SIGINT, signal_handler);      /* handle user interrupt */
  926. X      signal(SIGTERM, signal_handler);     /* handle kill from shell */
  927. X#endif
  928. X    }
  929. X  strcpy(filename,default_filename);
  930. X  switch (argc) {
  931. X  case 1:     /* no args, take all defaults */ 
  932. X    printf(IOZONE_USAGE);
  933. X#ifdef AUTOTEST 
  934. X    auto_mode = 1;
  935. X    auto_test();
  936. X    printf("Completed series of tests\n");
  937. X    exit(0);
  938. X#endif
  939. X    break;
  940. X  case 2:     /* <megabytes|filename> */
  941. X    i = (unsigned) abs(atoi(argv[1])); 
  942. X    if (i) {
  943. X      megabytes = i;
  944. X    } else {
  945. X      /*
  946. X    'Auto mode' will be enabled if the first command line argument is
  947. X    the word 'auto'.  This will trigger a series of tests
  948. X    */
  949. X      if ( (strcmp(argv[1], "auto") == 0) ||
  950. X      (strcmp(argv[1], "AUTO") == 0) )
  951. X    {
  952. X      auto_mode = 1;
  953. X      auto_test();
  954. X      printf("Completed series of tests\n");
  955. X      exit(0);
  956. X    } else {
  957. X      auto_mode = 0;
  958. X    }
  959. X      if ( (strcmp(argv[1], "help") == 0) ||
  960. X      (strcmp(argv[1], "HELP") == 0) )
  961. X    {
  962. X      show_help();
  963. X      exit(0);
  964. X    }
  965. X      strcpy(filename,argv[1]);
  966. X    }
  967. X    break;
  968. X  case 3:     /* <megabytes> <reclen|filename> */
  969. X    megabytes = (unsigned) atoi(argv[1]);
  970. X    if (atoi(argv[2])) {
  971. X      reclen = atoi(argv[2]);
  972. X    } else {
  973. X      strcpy(filename,argv[2]);
  974. X    }
  975. X    break;
  976. X  case 4:     /* <megabytes> <reclen> <filename> */
  977. X    megabytes = (unsigned) atoi(argv[1]);
  978. X    reclen = atoi(argv[2]);
  979. X    strcpy(filename,argv[3]);
  980. X    break;
  981. X  default:
  982. X    printf("IOZONE: bad usage\n");
  983. X    printf(IOZONE_USAGE);
  984. X    exit(1);
  985. X    
  986. X  }
  987. X  if (!auto_mode)
  988. X    {
  989. X      printf("\tSend comments to:\tnorcott_bill@tandem.com\n\n");
  990. X    }
  991. X  filesize = (unsigned long) (1024L*1024L*megabytes);
  992. X  numrecs =  filesize/(unsigned long) reclen;
  993. X  if (reclen >  MAXBUFFERSIZE) {
  994. X    printf("<Error: Maximum record length is %d bytes\n", MAXBUFFERSIZE);
  995. X    exit(1);
  996. X  }
  997. X  if (reclen < MINBUFFERSIZE) {
  998. X    printf("Error: Minimum record length is %d bytes\n", MINBUFFERSIZE);
  999. X    exit(1);
  1000. X  }
  1001. X  if (!auto_mode)
  1002. X    {
  1003. X      printf("\tIOZONE writes a %ld Megabyte sequential file consisting of\n",
  1004. X         megabytes);
  1005. X      printf("\t%ld records which are each %ld bytes in length.\n",
  1006. X         numrecs, reclen);
  1007. X      printf("\tIt then reads the file.  It prints the bytes-per-second\n");
  1008. X      printf("\trate at which the computer can read and write files.\n\n");
  1009. X      printf("\nWriting the %ld Megabyte file, '%s'...", megabytes, filename);
  1010. X    }
  1011. X  
  1012. X#if defined (__TANDEM)
  1013. X  /*
  1014. X    Tandem's GUARDIAN preallocates file space based on primary- and secondary extents.
  1015. X    The last 2 parameters to open are the sizes of the primary- and secondary extents,
  1016. X    in blocks which are 2K bytes each.  After the primary extent is filled, GUARDIAN
  1017. X    allocates up to 15 additional extents, one at a time.
  1018. X    */
  1019. X#define SPECIAL_CREAT
  1020. X#define PRI_EXT_BLOCKS 1024
  1021. X#define SEC_EXT_BLOCKS 1024
  1022. X  if((fd = creat(filename, 0640,
  1023. X         PRI_EXT_BLOCKS, SEC_EXT_BLOCKS))<0){
  1024. X    printf("Cannot create temporary file: %s\n", filename);
  1025. X    exit(1);
  1026. X  }
  1027. X#endif
  1028. X#ifndef SPECIAL_CREAT
  1029. X  if((fd = creat(filename, 0640))<0){
  1030. X    printf("Cannot create temporary file: %s\n", filename);
  1031. X    exit(1);
  1032. X  }
  1033. X#endif
  1034. X#ifdef TIME
  1035. X  starttime = time_so_far();
  1036. X#endif
  1037. X#ifndef TIME
  1038. X  printf("\nstart timing\n");
  1039. X#endif
  1040. X  for(thisrec=0; thisrec<numrecs; thisrec++){
  1041. X#ifndef DEBUG_ME
  1042. X    if(write(fd, buffer, (unsigned) reclen) != reclen)
  1043. X      {
  1044. X    printf("Error writing block %d\n", thisrec);
  1045. X    perror("iozone");
  1046. X    close(fd);
  1047. X#ifndef VMS
  1048. X#ifndef NO_DELETE
  1049. X    unlink(filename);   /* delete the file */
  1050. X#endif
  1051. X    /*stop timer*/
  1052. X#endif
  1053. X    exit(1);
  1054. X      }
  1055. X#endif
  1056. X  }
  1057. X#ifdef USE_FSYNC
  1058. X  fsync(fd);
  1059. X#endif
  1060. X#ifdef TIME
  1061. X  writetime = time_so_far() - starttime;
  1062. X  if (!auto_mode)
  1063. X    {
  1064. X      printf("%f seconds", writetime);
  1065. X    }
  1066. X#endif
  1067. X#ifndef TIME
  1068. X  printf("\nstop timing\n");
  1069. X#endif
  1070. X  close(fd);
  1071. X#if defined (VMS)
  1072. X#define SPECIAL_OPEN_READ
  1073. X  if((fd = open(filename, O_RDONLY, 0640))<0){
  1074. X    printf("Cannot open temporary file for read\n");
  1075. X    exit(1);
  1076. X  }
  1077. X#endif
  1078. X  
  1079. X#ifdef MSDOS
  1080. X#define SPECIAL_OPEN_READ
  1081. X  if((fd = open(filename, O_RDONLY, 0640))<0){
  1082. X    printf("Cannot open temporary file for read\n");
  1083. X    exit(1);
  1084. X  }
  1085. X#endif
  1086. X  
  1087. X  /*
  1088. X    'Generic' case, compiled if no operating system-specific case was invoked
  1089. X    */
  1090. X#ifndef SPECIAL_OPEN_READ
  1091. X  if((fd = open(filename, O_RDONLY))<0){
  1092. X    printf("Cannot open temporary file for read\n");
  1093. X    exit(1);
  1094. X  }
  1095. X#endif
  1096. X  
  1097. X  
  1098. X  
  1099. X  /*start timing*/
  1100. X  if (!auto_mode)
  1101. X    {
  1102. X      printf("\nReading the file...");
  1103. X    }
  1104. X#ifndef TIME
  1105. X  printf("\nstart timing\n");
  1106. X#endif
  1107. X#ifdef TIME
  1108. X  starttime = time_so_far();
  1109. X#endif
  1110. X  for(thisrec=0; thisrec<numrecs; thisrec++) {
  1111. X#ifndef DEBUG_ME
  1112. X    if(read(fd, buffer, (unsigned) reclen) != reclen)
  1113. X      {
  1114. X    printf("Error reading block %d\n", thisrec);
  1115. X    exit(1);
  1116. X      }
  1117. X#endif
  1118. X  }
  1119. X#ifndef TIME
  1120. X  printf("\nstop timing\n");
  1121. X#endif
  1122. X#ifdef TIME
  1123. X  readtime = time_so_far() - starttime;
  1124. X  if (!auto_mode)
  1125. X    {
  1126. X      printf("%f seconds\n", readtime);
  1127. X    }
  1128. X#ifdef DEBUG_ME
  1129. X  readtime = 1;
  1130. X  writetime = 1;
  1131. X#endif
  1132. X  if(readtime!=0)
  1133. X    {
  1134. X      filebytes = numrecs* (unsigned long) reclen;
  1135. X      readrate = (unsigned long) ((double) filebytes / readtime);
  1136. X      writerate = (unsigned long) ((double) filebytes / writetime);
  1137. X      if (auto_mode)
  1138. X    {
  1139. X      printf(CONTROL_STRING1,
  1140. X         megabytes,
  1141. X         reclen,
  1142. X         writerate,
  1143. X         readrate);
  1144. X      
  1145. X    } else {
  1146. X      printf("\nIOZONE performance measurements:\n");
  1147. X      printf("\t%ld bytes/second for writing the file\n", writerate);
  1148. X      printf("\t%ld bytes/second for reading the file\n", readrate);
  1149. X      totaltime = readtime + writetime;
  1150. X      if (totaltime < TOOFAST)
  1151. X        {
  1152. X          goodmegs = (TOOFAST/totaltime)*2*megabytes;
  1153. X          printf("\nThe test completed too quickly to give a good result\n");
  1154. X          printf("You will get a more precise measure of this machine's\n");
  1155. X          printf("performance by re-running IOZONE using the command:\n");
  1156. X          printf("\n\tiozone %ld ", goodmegs);
  1157. X          printf("\t(i.e., file size = %ld megabytes)\n", goodmegs);
  1158. X        }
  1159. X    }
  1160. X    } else {
  1161. X      goodrecl = reclen/2;
  1162. X      printf("\nI/O error during read.  Try again with the command:\n");
  1163. X      printf("\n\tiozone %ld %ld ", megabytes,  goodrecl);
  1164. X      printf("\t(i.e. record size = %ld bytes)\n",  goodrecl);
  1165. X    }
  1166. X#endif
  1167. X  close(fd);
  1168. X#ifndef VMS
  1169. X#ifndef NO_DELETE
  1170. X  unlink(filename);   /* delete the file */
  1171. X#endif
  1172. X  /*stop timer*/
  1173. X#endif
  1174. X#ifdef  usecalloc
  1175. X  free(buffer);           /* deallocate the memory */
  1176. X#endif
  1177. X#ifdef VMS
  1178. X  return SS$_NORMAL;
  1179. X#else
  1180. X  return 0;
  1181. X#endif
  1182. X}
  1183. X/******************************************************************
  1184. X  
  1185. X  SHOW_HELP -- show development help of this program
  1186. X  
  1187. X  ******************************************************************/
  1188. Xvoid 
  1189. X  show_help()
  1190. X{
  1191. X  int i;
  1192. X  printf("IOZONE: help mode\n\n");
  1193. X  for(i=0; strlen(help[i]); i++)
  1194. X    {
  1195. X      printf("%s\n", help[i]);
  1196. X    }
  1197. X}
  1198. X/******************************************************************
  1199. X  
  1200. X  SIGNAL_HANDLER -- clean up if user interrupts the program
  1201. X  
  1202. X  ******************************************************************/
  1203. Xvoid 
  1204. X  signal_handler()
  1205. X{
  1206. X  printf("\nIOZONE: interrupted\n\n");
  1207. X#ifndef VMS
  1208. X#ifndef NO_DELETE
  1209. X  printf("deleting file: %s\n", filename);
  1210. X  unlink(filename);   /* delete the file */
  1211. X#endif
  1212. X#endif
  1213. X  printf("exiting IOzone\n\n");
  1214. X  exit(0);
  1215. X}
  1216. X/******************************************************************
  1217. X  
  1218. X  AUTO_TEST -- perform series of tests and tabulate results
  1219. X  
  1220. X  ******************************************************************/
  1221. Xvoid 
  1222. X  auto_test()
  1223. X{
  1224. X  
  1225. X  int megsi, recszi;
  1226. X  char megs[10];
  1227. X  char recsz[10];
  1228. X  int i,j;
  1229. X  int autoArgc = 3;
  1230. X  char *autoArgv[3];
  1231. X  
  1232. X  printf("IOZONE: auto-test mode\n\n");
  1233. X  printf(CONTROL_STRING2,
  1234. X     "MB",
  1235. X     "reclen",
  1236. X     "bytes/sec written",
  1237. X     "bytes/sec read");
  1238. X  autoArgv[0] = "IOzone auto-test";
  1239. X  autoArgv[1] = megs;
  1240. X  autoArgv[2] = recsz;
  1241. X  /*
  1242. X    Start with file size of 1 megabyte and repeat the test MEGABYTES_ITER_LIMIT
  1243. X    times.  Each time we run, the file size is doubled
  1244. X    */
  1245. X  for(i=0,megsi=1;i<MEGABYTES_ITER_LIMIT;i++,megsi*=2)
  1246. X    {
  1247. X      sprintf(megs, "%d", megsi);
  1248. X      /*
  1249. X    Start with record size of 512 bytes and repeat the test RECLEN_ITER_LIMIT
  1250. X    times.  Each time we run, the record size is doubled
  1251. X    */
  1252. X      for (j=0,recszi=512;j<RECLEN_ITER_LIMIT;j++,recszi*=2)
  1253. X        {
  1254. X      sprintf(recsz, "%d", recszi);
  1255. X#ifdef ANSI_MAIN
  1256. X      main(autoArgc, autoArgv, NULL);
  1257. X#else
  1258. X      main(autoArgc, autoArgv);
  1259. X#endif
  1260. X        }
  1261. X    }
  1262. X}
  1263. X
  1264. X#ifdef TIME
  1265. X/******************************************************************
  1266. X  
  1267. X  TIME_SO_FAR -- return elapsed time
  1268. X
  1269. X  5/17/91 Bill Norcott        V1.07 -- use time() for VMS
  1270. X  The times() function in VMS returns proc & user CPU time in 10-millisecond
  1271. X  ticks.  Instead, use time() which lacks the precision but gives clock
  1272. X  time in seconds.
  1273. X  V1.14 make val of type clock_t if we are dealing with POSIX
  1274. X  V1.15 first time this is called, set base to initial number of clock
  1275. X  ticks, then subtract this value from all subsequent calculations.  This
  1276. X  will fix a loss of precision when times returns very big numbers;
  1277. X  
  1278. X  Here is what we check for (in order).  Each returns so we do not
  1279. X  have to nest the #ifdefs -- should satisfy even the dumbest 
  1280. X  pre-processor.  Note that each has its own flavor of timekeeping
  1281. X  1. ANSI C
  1282. X  2. POSIX - with and without CLK_TCK defined
  1283. X  3. System V variants
  1284. X  4. MS-DOS
  1285. X  5. BSD variants
  1286. X  ******************************************************************/
  1287. Xdouble
  1288. X  time_so_far()
  1289. X{
  1290. X#if defined(ANSItime)
  1291. X  return (double) time(NULL);
  1292. X#endif
  1293. X
  1294. X#ifdef isposix
  1295. X  {
  1296. X    static clock_t base, val;
  1297. X    struct tms tms;
  1298. X    
  1299. X    if (base == 0)
  1300. X      {
  1301. X    base = times(&tms);
  1302. X    if (base == (clock_t) -1)
  1303. X      {
  1304. X        perror("times");
  1305. X      }
  1306. X      }
  1307. X    val = times(&tms);
  1308. X    if (val == (clock_t) -1)
  1309. X      {
  1310. X    perror("times");
  1311. X      }
  1312. X    val = val - base;
  1313. X#ifndef CLK_TCK
  1314. X    return ((double) val) / ((double) sysconf(_SC_CLK_TCK));
  1315. X#else
  1316. X    return ((double) val) / ((double) CLK_TCK);
  1317. X#endif
  1318. X  }
  1319. X#endif
  1320. X
  1321. X#ifdef SysVtime
  1322. X  {
  1323. X    static long base, val;
  1324. X    struct tms tms;
  1325. X    
  1326. X    if (base == 0)
  1327. X      {
  1328. X    if ((base = times(&tms)) == -1)
  1329. X      {
  1330. X        perror("times");
  1331. X      }
  1332. X      }
  1333. X    if ((val = times(&tms)) == -1)
  1334. X      {
  1335. X    perror("times");
  1336. X      }
  1337. X    val = val - base;
  1338. X    return ((double) val) / ((double) CLK_TCK);
  1339. X  }
  1340. X#endif
  1341. X
  1342. X#if defined(MSDOS)
  1343. X  return ((double) clock()) / ((double) CLK_TCK);
  1344. X#endif
  1345. X
  1346. X#ifdef BSDtime
  1347. X  {
  1348. X    struct timeval tp;
  1349. X    
  1350. X    if (gettimeofday(&tp, (struct timezone *) NULL) == -1)
  1351. X      perror("gettimeofday");
  1352. X    return ((double) (tp.tv_sec)) +
  1353. X      (((double) tp.tv_usec) / 1000000.0);
  1354. X  }
  1355. X#endif
  1356. X}
  1357. X#endif
  1358. END_OF_FILE
  1359.   if test 35038 -ne `wc -c <'iozone.c'`; then
  1360.     echo shar: \"'iozone.c'\" unpacked with wrong size!
  1361.   fi
  1362.   # end of 'iozone.c'
  1363. fi
  1364. echo shar: End of archive 1 \(of 1\).
  1365. cp /dev/null ark1isdone
  1366. MISSING=""
  1367. for I in 1 ; do
  1368.     if test ! -f ark${I}isdone ; then
  1369.     MISSING="${MISSING} ${I}"
  1370.     fi
  1371. done
  1372. if test "${MISSING}" = "" ; then
  1373.     echo You have the archive.
  1374.     rm -f ark[1-9]isdone
  1375. else
  1376.     echo You still must unpack the following archives:
  1377.     echo "        " ${MISSING}
  1378. fi
  1379. exit 0
  1380. exit 0 # Just in case...
  1381.