summaryrefslogtreecommitdiff
path: root/miscutils
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-08-06 08:47:59 +0000
committerEric Andersen <andersen@codepoet.org>2003-08-06 08:47:59 +0000
commit50af12dbd6d79a7d9bec457ee452ea03d88be3aa (patch)
tree046c3d3c89dd105b56d4a51f9edd69f0be9d7d2e /miscutils
parent481772a4c2915bfca8099218d458bb22906e71b5 (diff)
downloadbusybox-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.c135
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
1031static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0; 1034static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0;
1032static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0; 1035static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0;
1033static int do_ctimings, do_timings = 0; 1036static 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
1306static void time_cache (int fd) 1309static double correction = 0.0;
1310
1311void 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
1393static void time_device (int fd) 1395void 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
1461quit: 1464quit:
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");