Date: Sun, 29 Oct 2006 17:07:16 +0300 From: Yar Tikhiy <yar@comp.chem.msu.su> To: hackers@freebsd.org Subject: File trees: the deeper, the weirder Message-ID: <20061029140716.GA12058@comp.chem.msu.su>
index | next in thread | raw e-mail
Folks,
Here's a funny observation. A program essentially doing:
for (;;) {
mkdir("foo");
chdir("foo");
}
starts as fast as the system permits, but settles to *exactly* one
cycle per second at some depth that seems to depend only on the
amount of RAM in the machine. An array sized at boot time seems
to play a role there: for 128M the depth is ~7800, for 512M it's
~35000. The system feels very slow then, but only due to the fact
that fs-related syscalls often take *exactly* one second to complete.
As for the said program, it keeps its 1 Hz pace, mostly waiting on
"vlruwk". It's killable, after a delay. The system doesn't show
any signs of instability, and it's mostly idle according to top or
systat!
Weird, eh? Any ideas what's going on?
--
Yar
P.S. Here's the test program generalised and enhanced with timing
diagnostics (-v). By setting several -v options, you'll get the
diagnostics more often, exponentially.
/*
* Usage:
*
* xdir [-v -v ...] name-length tree-depth
*
* This program will create a chain of subdirectories rooted
* in the current directory. Each subdir's name will be:
*
* 000 ... [ name-lenght times ] ... 000
*
* The total depth will be tree-depth:
*
* 000+/000+/ ... [ tree-depth times] ... /000+/000+
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <err.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int verbose;
int
main(int argc, char **argv)
{
int i, n, m, r;
double dt;
struct timeval tv0, tv;
char buf[NAME_MAX + 1];
while ((i = getopt(argc, argv, "v")) != -1)
switch (i) {
case 'v':
verbose++;
break;
default:
errx(2, "bad option");
}
argc -= optind;
argv += optind;
if (argv[0] == NULL || (n = atoi(argv[0])) <= 0)
errx(2, "bad length");
if (argv[1] == NULL || (m = atoi(argv[1])) <= 0)
errx(2, "bad depth");
if (n > NAME_MAX)
errx(2, "too long");
sprintf(buf, "%0*d", n, 0);
r = 1000; /* fool gcc */
if (verbose) {
for (i = 1; i < verbose && r > 9; i++)
r /= 10;
gettimeofday(&tv0, NULL);
}
for (i = 1; i <= m; i++) {
if (mkdir(buf, 0700) == -1)
err(2, "mkdir %s", buf);
if (chdir(buf) == -1)
err(2, "chdir %s", buf);
if (verbose && (i % r) == 0) {
gettimeofday(&tv, NULL);
dt = tv.tv_usec - tv0.tv_usec;
dt /= 1000000;
dt += tv.tv_sec - tv0.tv_sec;
printf("%d (%.1lf)... ", i, r / dt);
fflush(stdout);
tv0 = tv;
}
}
return (0);
}
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061029140716.GA12058>
