hdparm utilizes shared memory for no good reason ?
Tito
farmatito at tiscali.it
Tue May 16 12:18:10 UTC 2006
On Tuesday 16 May 2006 13:49, Tito wrote:
> On Tuesday 16 May 2006 08:19, Mike Frysinger wrote:
> > was trying to use `hdparm -t` on a uClinux host when it failed with:
> > could not allocate sharedmem buf
> >
> > this is because hdparm uses shm* functions to get a buffer of memory ... but
> > afaict, there's no reason a buffer created on the stack/heap wouldnt work
> > just as well
>
> > could someone enlighten me as to why the shm* stuff is needed ?
> > -mike
>
> It is what the real hdparm does, after Rob applies my pending shrinkage
> and bugfix patch I can try to write a fix for that ... if you haven't one already.
> Please notice that the patch contains an update for the timing functions
> to the code of hdparm 6.6+, but i'm sure it uses the shm* stuff the same.
>
>
> Ciao,
> Tito
Here one proposal new do_time() function, plus do_blkgetsize() and print_timing()
as in pending patch without shared mem stuff.
Tested, seems to work fine for me.
BTW: do you prefer the buffer static or malloced?
Ciao,
Tito
-------------- next part --------------
static void print_timing(int t, double e)
{
if (t >= e) /* more than 1MB/s */
printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n", t, e, t / e);
else
printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n", t, e, t / e * 1024);
}
static int do_blkgetsize (int fd, unsigned long long *blksize64)
{
int rc;
unsigned int blksize32 = 0;
if (0 == ioctl(fd, BLKGETSIZE64, blksize64)) { // returns bytes
*blksize64 /= 512;
return 0;
}
rc = ioctl(fd, BLKGETSIZE, &blksize32); // returns sectors
if (rc)
bb_perror_msg("BLKGETSIZE");
*blksize64 = blksize32;
return rc;
}
static void do_time(int flag, int fd)
/*
flag = 0 time_cache
flag = 1 time_device
*/
{
char *buf;
struct itimerval e1, e2;
double elapsed, elapsed2;
unsigned int max_iterations = 1024, total_MB, iterations;
unsigned long long blksize;
if (0 == do_blkgetsize(fd, &blksize)) {
max_iterations = blksize / (2 * 1024) / TIMING_BUF_MB;
}
/* Clear out the device request queues & give them time to complete */
buf = xmalloc(TIMING_BUF_BYTES);
sync();
sleep(3);
setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL);
if (flag == 0) /* Time cache */
{
if (seek_to_zero (fd)) return;
if (read_big_block (fd, buf)) return;
printf(" Timing cached reads: ");
fflush(stdout);
/* Now do the timing */
iterations = 0;
getitimer(ITIMER_REAL, &e1);
do {
++iterations;
if (seek_to_zero (fd) || read_big_block (fd, buf))
goto quit;
getitimer(ITIMER_REAL, &e2);
elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
} while (elapsed < 2.0);
total_MB = iterations * TIMING_BUF_MB;
elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
/* Now remove the lseek() and getitimer() overheads from the elapsed time */
getitimer(ITIMER_REAL, &e1);
do {
if (seek_to_zero (fd))
goto quit;
getitimer(ITIMER_REAL, &e2);
elapsed2 = (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
} while (--iterations);
elapsed -= elapsed2;
print_timing(BUFCACHE_FACTOR * total_MB, elapsed);
flush_buffer_cache(fd);
sleep(1);
}
else /* Time device */
{
printf(" Timing buffered disk reads: ");
fflush(stdout);
/*
* getitimer() is used rather than gettimeofday() because
* it is much more consistent (on my machine, at least).
*/
/* Now do the timings for real */
iterations = 0;
getitimer(ITIMER_REAL, &e1);
do {
++iterations;
if (read_big_block (fd, buf))
goto quit;
getitimer(ITIMER_REAL, &e2);
elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec)
+ ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
} while (elapsed < 3.0 && iterations < max_iterations);
total_MB = iterations * TIMING_BUF_MB;
print_timing(total_MB, elapsed);
}
quit:
free(buf);
return;
}
More information about the busybox
mailing list