diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-08-06 08:47:59 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-08-06 08:47:59 +0000 |
commit | 50af12dbd6d79a7d9bec457ee452ea03d88be3aa (patch) | |
tree | 046c3d3c89dd105b56d4a51f9edd69f0be9d7d2e /miscutils | |
parent | 481772a4c2915bfca8099218d458bb22906e71b5 (diff) | |
download | busybox-w32-50af12dbd6d79a7d9bec457ee452ea03d88be3aa.tar.gz busybox-w32-50af12dbd6d79a7d9bec457ee452ea03d88be3aa.tar.bz2 busybox-w32-50af12dbd6d79a7d9bec457ee452ea03d88be3aa.zip |
Sync hdparm -t and -T options with hdparm-5.3, which seems
to produce sensible results,
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/hdparm.c | 135 |
1 files changed, 69 insertions, 66 deletions
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index 1e34f4f4e..eb4991ef3 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
@@ -1023,11 +1023,14 @@ static void identify (uint16_t *id_supplied, const char *devname) | |||
1023 | 1023 | ||
1024 | #define VERSION "v5.4" | 1024 | #define VERSION "v5.4" |
1025 | 1025 | ||
1026 | #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */ | 1026 | #define TIMING_MB 64 |
1027 | #define TIMING_BUF_MB 2 | 1027 | #define TIMING_BUF_MB 1 |
1028 | #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024) | 1028 | #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024) |
1029 | #define TIMING_BUF_COUNT (timing_MB / TIMING_BUF_MB) | ||
1029 | #define BUFCACHE_FACTOR 2 | 1030 | #define BUFCACHE_FACTOR 2 |
1030 | 1031 | ||
1032 | #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */ | ||
1033 | |||
1031 | static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0; | 1034 | static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0; |
1032 | static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0; | 1035 | static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0; |
1033 | static int do_ctimings, do_timings = 0; | 1036 | static int do_ctimings, do_timings = 0; |
@@ -1303,13 +1306,15 @@ static int read_big_block (int fd, char *buf) | |||
1303 | return 0; | 1306 | return 0; |
1304 | } | 1307 | } |
1305 | 1308 | ||
1306 | static void time_cache (int fd) | 1309 | static double correction = 0.0; |
1310 | |||
1311 | void time_cache (int fd) | ||
1307 | { | 1312 | { |
1313 | int i; | ||
1308 | char *buf; | 1314 | char *buf; |
1309 | struct itimerval e1, e2; | 1315 | struct itimerval e1, e2; |
1310 | int shmid; | 1316 | int shmid; |
1311 | double elapsed, elapsed2; | 1317 | int timing_MB = TIMING_MB; |
1312 | unsigned int iterations, total_MB; | ||
1313 | 1318 | ||
1314 | if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { | 1319 | if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { |
1315 | bb_perror_msg ("could not allocate sharedmem buf"); | 1320 | bb_perror_msg ("could not allocate sharedmem buf"); |
@@ -1332,7 +1337,12 @@ static void time_cache (int fd) | |||
1332 | sync(); | 1337 | sync(); |
1333 | sleep(3); | 1338 | sleep(3); |
1334 | 1339 | ||
1335 | /* | 1340 | /* Calculate a correction factor for the basic |
1341 | * overhead of doing a read() from the buffer cache. | ||
1342 | * To do this, we read the data once to "cache it" and | ||
1343 | * to force full preallocation of our timing buffer, | ||
1344 | * and then we re-read it 10 times while timing it. | ||
1345 | * | ||
1336 | * getitimer() is used rather than gettimeofday() because | 1346 | * getitimer() is used rather than gettimeofday() because |
1337 | * it is much more consistent (on my machine, at least). | 1347 | * it is much more consistent (on my machine, at least). |
1338 | */ | 1348 | */ |
@@ -1346,42 +1356,34 @@ static void time_cache (int fd) | |||
1346 | sync(); | 1356 | sync(); |
1347 | sleep(1); | 1357 | sleep(1); |
1348 | 1358 | ||
1349 | /* Now do the timing */ | 1359 | /* Time re-reading from the buffer-cache */ |
1350 | iterations = 0; | ||
1351 | getitimer(ITIMER_REAL, &e1); | 1360 | getitimer(ITIMER_REAL, &e1); |
1352 | do { | 1361 | for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i) { |
1353 | ++iterations; | 1362 | if (seek_to_zero (fd)) goto quit; |
1354 | if (seek_to_zero (fd) || read_big_block (fd, buf)) | 1363 | if (read_big_block (fd, buf)) goto quit; |
1355 | goto quit; | 1364 | } |
1356 | getitimer(ITIMER_REAL, &e2); | 1365 | getitimer(ITIMER_REAL, &e2); |
1357 | elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) | 1366 | correction = (e1.it_value.tv_sec - e2.it_value.tv_sec) |
1358 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); | ||
1359 | } while (elapsed < 2.0); | ||
1360 | total_MB = iterations * TIMING_BUF_MB; | ||
1361 | |||
1362 | elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) | ||
1363 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); | 1367 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); |
1364 | 1368 | ||
1365 | /* Now remove the lseek() and getitimer() overheads from the elapsed time */ | 1369 | /* Now remove the lseek() from the correction factor */ |
1366 | getitimer(ITIMER_REAL, &e1); | 1370 | getitimer(ITIMER_REAL, &e1); |
1367 | do { | 1371 | for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i) { |
1368 | if (seek_to_zero (fd)) | 1372 | if (seek_to_zero (fd)) goto quit; |
1369 | goto quit; | 1373 | } |
1370 | getitimer(ITIMER_REAL, &e2); | 1374 | getitimer(ITIMER_REAL, &e2); |
1371 | elapsed2 = (e1.it_value.tv_sec - e2.it_value.tv_sec) | 1375 | correction -= (e1.it_value.tv_sec - e2.it_value.tv_sec) |
1372 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); | 1376 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); |
1373 | } while (--iterations); | 1377 | |
1374 | 1378 | if ((BUFCACHE_FACTOR * timing_MB) >= correction) /* more than 1MB/s */ | |
1375 | elapsed -= elapsed2; | 1379 | printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n", |
1376 | 1380 | (BUFCACHE_FACTOR * timing_MB), correction, | |
1377 | if ((BUFCACHE_FACTOR * total_MB) >= elapsed) /* more than 1MB/s */ | 1381 | (BUFCACHE_FACTOR * timing_MB) / correction); |
1378 | printf("%3u MB in %5.2f seconds = %6.2f MB/sec\n", | ||
1379 | (BUFCACHE_FACTOR * total_MB), elapsed, | ||
1380 | (BUFCACHE_FACTOR * total_MB) / elapsed); | ||
1381 | else | 1382 | else |
1382 | printf("%3u MB in %5.2f seconds = %6.2f kB/sec\n", | 1383 | printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n", |
1383 | (BUFCACHE_FACTOR * total_MB), elapsed, | 1384 | (BUFCACHE_FACTOR * timing_MB), correction, |
1384 | (BUFCACHE_FACTOR * total_MB) / elapsed * 1024); | 1385 | (BUFCACHE_FACTOR * timing_MB) / correction * 1024); |
1386 | correction /= BUFCACHE_FACTOR; | ||
1385 | 1387 | ||
1386 | flush_buffer_cache(fd); | 1388 | flush_buffer_cache(fd); |
1387 | sleep(1); | 1389 | sleep(1); |
@@ -1390,24 +1392,14 @@ quit: | |||
1390 | bb_perror_msg ("could not detach sharedmem buf"); | 1392 | bb_perror_msg ("could not detach sharedmem buf"); |
1391 | } | 1393 | } |
1392 | 1394 | ||
1393 | static void time_device (int fd) | 1395 | void time_device (int fd) |
1394 | { | 1396 | { |
1397 | int i; | ||
1395 | char *buf; | 1398 | char *buf; |
1396 | double elapsed; | 1399 | double elapsed; |
1397 | struct itimerval e1, e2; | 1400 | struct itimerval e1, e2; |
1398 | int shmid; | 1401 | int shmid; |
1399 | unsigned int max_iterations = 1024, total_MB, iterations; | 1402 | int timing_MB = TIMING_MB; |
1400 | static long parm; | ||
1401 | |||
1402 | // | ||
1403 | // get device size | ||
1404 | // | ||
1405 | if (do_ctimings || do_timings) { | ||
1406 | if (ioctl(fd, BLKGETSIZE, &parm)) | ||
1407 | bb_perror_msg(" BLKGETSIZE failed"); | ||
1408 | else | ||
1409 | max_iterations = parm / (2 * 1024) / TIMING_BUF_MB; | ||
1410 | } | ||
1411 | 1403 | ||
1412 | if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { | 1404 | if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { |
1413 | bb_perror_msg ("could not allocate sharedmem buf"); | 1405 | bb_perror_msg ("could not allocate sharedmem buf"); |
@@ -1440,24 +1432,35 @@ static void time_device (int fd) | |||
1440 | setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL); | 1432 | setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL); |
1441 | 1433 | ||
1442 | /* Now do the timings for real */ | 1434 | /* Now do the timings for real */ |
1443 | iterations = 0; | ||
1444 | getitimer(ITIMER_REAL, &e1); | 1435 | getitimer(ITIMER_REAL, &e1); |
1445 | do { | 1436 | for (i = TIMING_BUF_COUNT; i > 0; --i) { |
1446 | ++iterations; | 1437 | if (read_big_block (fd, buf)) goto quit; |
1447 | if (read_big_block (fd, buf)) | 1438 | } |
1448 | goto quit; | 1439 | getitimer(ITIMER_REAL, &e2); |
1449 | getitimer(ITIMER_REAL, &e2); | 1440 | |
1450 | elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) | 1441 | elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) |
1451 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); | 1442 | + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); |
1452 | } while (elapsed < 3.0 && iterations < max_iterations); | 1443 | if (timing_MB >= elapsed) /* more than 1MB/s */ |
1453 | 1444 | printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n", | |
1454 | total_MB = iterations * TIMING_BUF_MB; | 1445 | timing_MB, elapsed, timing_MB / elapsed); |
1455 | if ((total_MB / elapsed) > 1.0) /* more than 1MB/s */ | ||
1456 | printf("%3u MB in %5.2f seconds = %6.2f MB/sec\n", | ||
1457 | total_MB, elapsed, total_MB / elapsed); | ||
1458 | else | 1446 | else |
1459 | printf("%3u MB in %5.2f seconds = %6.2f kB/sec\n", | 1447 | printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n", |
1460 | total_MB, elapsed, total_MB / elapsed * 1024); | 1448 | timing_MB, elapsed, timing_MB / elapsed * 1024); |
1449 | |||
1450 | if (elapsed <= (correction * 2)) | ||
1451 | printf("Hmm.. suspicious results: probably not enough free memory for a proper test.\n"); | ||
1452 | #if 0 /* the "estimate" is just plain wrong for many systems.. */ | ||
1453 | else if (correction != 0.0) { | ||
1454 | printf(" Estimating raw driver speed: "); | ||
1455 | elapsed -= correction; | ||
1456 | if (timing_MB >= elapsed) /* more than 1MB/s */ | ||
1457 | printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n", | ||
1458 | timing_MB, elapsed, timing_MB / elapsed); | ||
1459 | else | ||
1460 | printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n", | ||
1461 | timing_MB, elapsed, timing_MB / elapsed * 1024); | ||
1462 | } | ||
1463 | #endif | ||
1461 | quit: | 1464 | quit: |
1462 | if (-1 == shmdt(buf)) | 1465 | if (-1 == shmdt(buf)) |
1463 | bb_perror_msg ("could not detach sharedmem buf"); | 1466 | bb_perror_msg ("could not detach sharedmem buf"); |