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