hdparm: more robust (re overflows) code. +38 bytes.
This commit is contained in:
parent
a0ad43b80b
commit
920c52a5c8
@ -1353,35 +1353,34 @@ static void read_big_block(/*int fd,*/ char *buf)
|
|||||||
buf[i] &= 1;
|
buf[i] &= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long long dev_size_mb(/*int fd*/ void)
|
static unsigned dev_size_mb(/*int fd*/ void)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
unsigned long long blksize64;
|
unsigned long long blksize64;
|
||||||
unsigned blksize32;
|
unsigned blksize32;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // returns bytes
|
if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
|
||||||
return u.blksize64 / (1024 * 1024);
|
u.blksize64 /= (1024 * 1024);
|
||||||
|
} else {
|
||||||
|
xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
|
||||||
|
u.blksize64 = u.blksize32 / (2 * 1024);
|
||||||
}
|
}
|
||||||
xioctl(fd, BLKGETSIZE, &u.blksize32); // returns sectors
|
if (u.blksize64 > UINT_MAX)
|
||||||
return u.blksize32 / (2 * 1024);
|
return UINT_MAX;
|
||||||
|
return u.blksize64;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_timing(unsigned long m, unsigned elapsed_us)
|
static void print_timing(unsigned m, unsigned elapsed_us)
|
||||||
{
|
{
|
||||||
unsigned sec = elapsed_us / 1000000;
|
unsigned sec = elapsed_us / 1000000;
|
||||||
unsigned hs = (elapsed_us % 1000000) / 10000;
|
unsigned hs = (elapsed_us % 1000000) / 10000;
|
||||||
|
|
||||||
printf("%5lu MB in %u.%02u seconds = %lu kB/s\n",
|
printf("%5u MB in %u.%02u seconds = %u kB/s\n",
|
||||||
m, sec, hs,
|
m, sec, hs,
|
||||||
/* Trying to not overflow 32-bit arith in m * CONST
|
/* + 1 prevents div-by-0 */
|
||||||
* by keeping CONST not so big. But elapsed_us / CONST2
|
(unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us + 1))
|
||||||
* also should not introduce big errors. Currently,
|
// ~= (m * 1024) / (elapsed_us / 1000000)
|
||||||
* 16000us is ~1.6% of 1 second.
|
|
||||||
* "+ 1" prevents div-by-0. */
|
|
||||||
(m * (1024 * 1000000 / (16*1024))) / (elapsed_us / (16*1024) + 1)
|
|
||||||
// ~= (m * 1024 * 1000000) / elapsed_us
|
|
||||||
// = (m * 1024) / (elapsed_us / 1000000)
|
|
||||||
// = kb / elapsed_sec
|
// = kb / elapsed_sec
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1392,19 +1391,14 @@ static void do_time(int cache /*,int fd*/)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned max_iterations, iterations;
|
unsigned max_iterations, iterations;
|
||||||
unsigned start; /* don't need to be long long */
|
unsigned start; /* doesn't need to be long long */
|
||||||
unsigned elapsed, elapsed2;
|
unsigned elapsed, elapsed2;
|
||||||
unsigned long total_MB;
|
unsigned total_MB;
|
||||||
char *buf = xmalloc(TIMING_BUF_BYTES);
|
char *buf = xmalloc(TIMING_BUF_BYTES);
|
||||||
|
|
||||||
if (mlock(buf, TIMING_BUF_BYTES))
|
if (mlock(buf, TIMING_BUF_BYTES))
|
||||||
bb_perror_msg_and_die("mlock");
|
bb_perror_msg_and_die("mlock");
|
||||||
|
|
||||||
/* Don't want to read past the end! */
|
|
||||||
max_iterations = UINT_MAX;
|
|
||||||
if (!cache)
|
|
||||||
max_iterations = dev_size_mb() / TIMING_BUF_MB;
|
|
||||||
|
|
||||||
/* Clear out the device request queues & give them time to complete.
|
/* Clear out the device request queues & give them time to complete.
|
||||||
* NB: *small* delay. User is expected to have a clue and to not run
|
* NB: *small* delay. User is expected to have a clue and to not run
|
||||||
* heavy io in parallel with measurements. */
|
* heavy io in parallel with measurements. */
|
||||||
@ -1422,10 +1416,14 @@ static void do_time(int cache /*,int fd*/)
|
|||||||
/* Now do the timing */
|
/* Now do the timing */
|
||||||
iterations = 0;
|
iterations = 0;
|
||||||
/* Max time to run (small for cache, avoids getting
|
/* Max time to run (small for cache, avoids getting
|
||||||
* huge total_MB which can overlow on print_timing) */
|
* huge total_MB which can overlow unsigned type) */
|
||||||
elapsed2 = 510000; /* cache */
|
elapsed2 = 510000; /* cache */
|
||||||
if (!cache)
|
max_iterations = UINT_MAX;
|
||||||
|
if (!cache) {
|
||||||
elapsed2 = 3000000; /* not cache */
|
elapsed2 = 3000000; /* not cache */
|
||||||
|
/* Don't want to read past the end! */
|
||||||
|
max_iterations = dev_size_mb() / TIMING_BUF_MB;
|
||||||
|
}
|
||||||
start = monotonic_us();
|
start = monotonic_us();
|
||||||
do {
|
do {
|
||||||
if (cache)
|
if (cache)
|
||||||
@ -1434,7 +1432,7 @@ static void do_time(int cache /*,int fd*/)
|
|||||||
elapsed = (unsigned)monotonic_us() - start;
|
elapsed = (unsigned)monotonic_us() - start;
|
||||||
++iterations;
|
++iterations;
|
||||||
} while (elapsed < elapsed2 && iterations < max_iterations);
|
} while (elapsed < elapsed2 && iterations < max_iterations);
|
||||||
total_MB = (unsigned long)iterations * TIMING_BUF_MB;
|
total_MB = iterations * TIMING_BUF_MB;
|
||||||
//printf(" elapsed:%u iterations:%u ", elapsed, iterations);
|
//printf(" elapsed:%u iterations:%u ", elapsed, iterations);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
/* Cache: remove lseek() and monotonic_us() overheads
|
/* Cache: remove lseek() and monotonic_us() overheads
|
||||||
|
Loading…
x
Reference in New Issue
Block a user