home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume30 / iozone / part01 < prev    next >
Encoding:
Text File  |  1992-05-23  |  47.7 KB  |  1,389 lines

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