source: trunk/minix/commands/simple/rawspeed.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 6.0 KB
Line 
1/* rawspeed 1.15 - Measure speed of a device. Author: Kees J. Bot
2 * 26 Apr 1992
3 */
4#define nil 0
5#include <sys/types.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <errno.h>
10#include <signal.h>
11#include <string.h>
12#include <time.h>
13#if !__minix
14#include <sys/time.h>
15#endif
16#include <fcntl.h>
17#include <limits.h>
18#include <sys/stat.h>
19
20#define SECTOR_SIZE 512
21#define BLK_MAX_SECTORS (sizeof(int) == 2 ? 32 : 64)
22#define CHR_MAX_SECTORS (sizeof(int) == 2 ? 63 : 512)
23#define ABS_MAX_SECTORS (INT_MAX / SECTOR_SIZE)
24
25#define USEC (!__minix || __minix_vmd)
26
27/* Any good random number generator around? */
28#if __minix_vmd || __linux
29#define rand random
30#define srand srandom
31#endif
32
33#if __sun && __svr4__
34#define rand lrand48
35#define srand srand48
36#endif
37
38void report(const char *label)
39{
40 fprintf(stderr, "rawspeed: %s: %s\n", label, strerror(errno));
41}
42
43void fatal(const char *label)
44{
45 report(label);
46 exit(1);
47}
48
49void usage(void)
50{
51 fprintf(stderr,
52"Usage: rawspeed [-u unit] [-m max] [-t seconds] [-c] [-r limit] device\n");
53 fprintf(stderr,
54" -u unit = best sector multiple (default 2)\n");
55 fprintf(stderr,
56" -m max = read multiples of unit upto 'max' (default %d raw, %d file)\n",
57 CHR_MAX_SECTORS, BLK_MAX_SECTORS);
58 fprintf(stderr,
59" -t seconds = time to run test (default 10)\n");
60 fprintf(stderr,
61" -c = cache test: rewind after each read or write of max size\n");
62 fprintf(stderr,
63" -r limit = random seeks upto sector 'limit' before reading or writing\n");
64 exit(1);
65}
66
67int done= 0;
68
69void timeout(int sig)
70{
71 done= 1;
72}
73
74int main(int argc, char **argv)
75{
76 int i, fd, n= 0, unit= -1, max= -1, cache= 0;
77 int size, seconds= 10;
78 long tenthsec;
79#if USEC
80 struct timeval start_time, end_time;
81 struct timezone dummy;
82#else
83 time_t start_time;
84#endif
85 off_t nbytes= 0, wbytes= 0, randlimit= 0;
86 char *device, *chunk;
87 struct stat st;
88 off_t nseeks= 0;
89
90 for (i= 1; i < argc && argv[i][0] == '-' && argv[i][1] != 0; i++) {
91 char *opt;
92
93 if (argv[i][1] == '-' && argv[i][2] == 0) { i++; break; }
94
95 for (opt= argv[i]+1; *opt != 0; opt++) {
96 switch (*opt) {
97 case 'w':
98 if (i == argc) usage();
99 wbytes= atol(argv[++i]) * 1024;
100 if (wbytes <= 0) usage();
101 break;
102 case 'm':
103 if (i == argc) usage();
104 max= atoi(argv[++i]);
105 if (max <= 0 || max > ABS_MAX_SECTORS)
106 usage();
107 break;
108 case 'u':
109 if (i == argc) usage();
110 unit= atoi(argv[++i]);
111 if (unit <= 0 || unit > ABS_MAX_SECTORS)
112 usage();
113 break;
114 case 't':
115 if (i == argc) usage();
116 seconds= atoi(argv[++i]);
117 if (seconds <= 0) usage();
118 break;
119 case 'c':
120 cache= 1;
121 break;
122 case 'r':
123 if (i == argc) usage();
124 randlimit= atol(argv[++i]);
125 if (randlimit <= 0) usage();
126 break;
127 default:
128 usage();
129 }
130 }
131 }
132
133 if (i != argc - 1) usage();
134
135 if (strcmp(argv[i], "-") == 0) {
136 fd= wbytes == 0 ? 0 : 1;
137 device= "";
138 } else {
139 device= argv[i];
140 if ((fd= open(device,
141 wbytes == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666)) < 0)
142 fatal(device);
143 }
144 if (max < 0) {
145 if (fstat(fd, &st) >= 0 && S_ISCHR(st.st_mode))
146 max= CHR_MAX_SECTORS;
147 else
148 max= BLK_MAX_SECTORS;
149 }
150
151 if (unit < 0) unit= max > 1 ? 2 : 1;
152 unit*= max / unit;
153 if (unit == 0) usage();
154 size= unit * SECTOR_SIZE;
155 randlimit/= unit;
156
157 if ((chunk= malloc((size_t) size)) == nil) {
158 fprintf(stderr, "rawspeed: can't grab %d bytes: %s\n",
159 size, strerror(errno));
160 exit(1);
161 }
162
163 /* Touch the pages to get real memory sending other processes to swap.
164 */
165 memset((void *) chunk, 0, (size_t) size);
166
167 /* Clean the cache. */
168 sync();
169
170 signal(SIGALRM, timeout);
171 signal(SIGINT, timeout);
172#if USEC
173 gettimeofday(&start_time, &dummy);
174 if (randlimit != 0) srand((int) (start_time.tv_sec & INT_MAX));
175#else
176 start_time= time((time_t *) nil);
177 if (randlimit != 0) srand((int) (start_time & INT_MAX));
178#endif
179 alarm(seconds);
180
181 if (wbytes > 0) {
182 while (!done && (n= write(fd, chunk, size)) > 0
183 && (nbytes+= n) < wbytes) {
184 if (cache && lseek(fd, (off_t) 0, SEEK_SET) == -1)
185 fatal(device);
186 if (randlimit != 0) {
187 if (lseek(fd, (off_t)
188 (rand() % randlimit * size),
189 SEEK_SET) == -1)
190 fatal(device);
191 nseeks++;
192 }
193 }
194 sync();
195 } else {
196 while (!done && (n= read(fd, chunk, size)) > 0) {
197 nbytes+= n;
198 if (cache && lseek(fd, (off_t) 0, SEEK_SET) == -1)
199 fatal(device);
200 if (randlimit != 0) {
201 if (lseek(fd, (off_t)
202 (rand() % randlimit * size),
203 SEEK_SET) == -1)
204 fatal(device);
205 nseeks++;
206 }
207 }
208 }
209
210#if USEC
211 gettimeofday(&end_time, &dummy);
212 tenthsec= (end_time.tv_sec - start_time.tv_sec) * 10
213 + (end_time.tv_usec - start_time.tv_usec) / 100000;
214#else
215 tenthsec= (time((time_t *) 0) - start_time) * 10;
216#endif
217 if (n < 0 && errno == EINTR) n= 0;
218 if (n < 0) report(device);
219
220 if (nbytes > 0) {
221 off_t kBpts;
222
223 fprintf(stderr, "%ld kB / %d.%d s = ",
224 (nbytes + 512) / 1024,
225 tenthsec / 10, tenthsec % 10);
226 if (tenthsec < 5)
227 fprintf(stderr, "infinite\n");
228 else {
229 if (nbytes > LONG_MAX / 100) {
230 seconds = (tenthsec + 5) / 10;
231 kBpts= (nbytes + 512L * seconds)
232 / (1024L * seconds);
233 fprintf(stderr, "%ld kB/s\n", kBpts);
234 } else {
235 kBpts= (100 * nbytes + 512L * tenthsec)
236 / (1024L * tenthsec);
237 fprintf(stderr, "%ld.%ld kB/s\n",
238 kBpts/10, kBpts%10);
239 }
240 }
241 }
242 if (randlimit != 0 && tenthsec >= 5) {
243 int rpm, disc= 0;
244 off_t tenthms;
245
246 tenthms= (tenthsec * 1000 + nseeks/2) / nseeks;
247
248 fprintf(stderr,
249 "%ld seeks / %d.%d s = %ld seeks/s = %ld.%ld ms/seek\n",
250 nseeks, tenthsec / 10, tenthsec % 10,
251 (nseeks * 10 + tenthsec/2) / tenthsec,
252 tenthms / 10, tenthms % 10);
253
254 for (rpm= 3600; rpm <= 7200; rpm+= 1800) {
255 int rotms = (10000L / 2 * 60 + rpm/2) / rpm;
256
257 if (tenthms <= rotms) continue;
258
259 if (!disc) {
260 fprintf(stderr,
261 "discarding av. rotational delay:\n ");
262 disc= 1;
263 } else {
264 fprintf(stderr, ", ");
265 }
266 fprintf(stderr, "%ld.%ld ms (%d rpm)",
267 (tenthms - rotms) / 10, (tenthms - rotms) % 10,
268 rpm);
269 }
270 if (disc) fputc('\n', stdout);
271 }
272 return n < 0 ? 1 : 0;
273}
Note: See TracBrowser for help on using the repository browser.