Browse Source

qlock entry for regression device #Z

if you cat #Z/qlock, it will lock and unlock a lock, always returning
1.

Pipe ring regression test and lock test

This test shows a few things:
how to set up a pipe ring
How to print detailed errors on error

While it's running, you can hit ^C and it will print stats and continue.
If you hit ^C 16 times, it will exit.

This program has not found issues with harvey pipe IO.

lockdeath opens #Z/qlock, forks lots of kids, and reads over and over.

The ^c thing works with lockdeath too. It makes no attempts to be fair and balanced.

Change-Id: I78248b653f6a8a5931e7da6383cfa1b2fd7cea84
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Ronald G. Minnich 8 years ago
parent
commit
b7766b7264
4 changed files with 139 additions and 0 deletions
  1. 10 0
      sys/src/9/port/devregress.c
  2. 59 0
      sys/src/regress/lockdeath.c
  3. 68 0
      sys/src/regress/pipering.c
  4. 2 0
      sys/src/regress/regress.json

+ 10 - 0
sys/src/9/port/devregress.c

@@ -12,6 +12,7 @@ enum {
 	Qctl = 1,
 	Qmalloc,
 	Qtsleep,
+	Qlock,
 	Qmax,
 };
 
@@ -20,9 +21,11 @@ static Dirtab regressdir[Qmax] = {
 	"regressctl",	{ Qctl, 0 },	0,	0666,
 	"malloc",	{ Qmalloc, 0 },	0,	0666,
 	"tsleep",	{ Qtsleep, 0 },	0,	0666,
+	"qlock",	{ Qlock, 0 },	0,	0666,
 };
 
 int verbose = 0;
+static QLock testlock;
 
 static Chan*
 regressattach(char* spec)
@@ -65,6 +68,13 @@ regressread(Chan *c, void *a, int32_t n, int64_t offset)
 	case Qtsleep:
 		break;
 
+	case Qlock:
+		qlock(&testlock);
+		// sanity test code here.
+		qunlock(&testlock);
+		n = 1;
+		break;
+
 	default:
 		error(Eperm);
 		break;

+ 59 - 0
sys/src/regress/lockdeath.c

@@ -0,0 +1,59 @@
+#include <u.h>
+#include <libc.h>
+
+int np = 32;
+int niter = 65536;
+int debug = 0;
+char data[8192];
+int i;
+int id;
+int intr = 0;
+
+void
+handler(void *v, char *s)
+{
+	print("%d: %d iterations\n", id, i);
+	if (intr++ < 16)
+		noted(NCONT);
+	exits("too many interrupts");
+}
+
+void
+main(int argc, char *argv[])
+{
+	int pid;
+	int fd;
+
+	if (notify(handler)){
+		sysfatal("notify: %r");
+	}
+
+	if (argc > 1)
+		np = strtoull(argv[1], 0, 0);
+
+	if (argc > 2)
+		niter = strtoull(argv[2], 0, 0);
+
+	debug = argc > 3;
+
+	fd = open("#Z/qlock", ORDWR);
+	if (fd < 0)
+		sysfatal("qlock: %r");
+
+	print("Running with %d kids %d times\n", np, niter);
+
+	for(i = 0, id = 0; i < np-1; i++, id++) {
+		pid = fork();
+		if (pid == 0)
+			break;
+		if (pid < 0)
+			sysfatal("fork");
+	}
+
+	if (debug) print("Forked. pid %d\n", getpid());
+
+	for(i = 0; i < niter; i++) {
+		if (read(fd, data, 1) < 1)
+			print("%d: iter %d: %r", id, i);
+	}
+}

+ 68 - 0
sys/src/regress/pipering.c

@@ -0,0 +1,68 @@
+#include <u.h>
+#include <libc.h>
+
+int nring = 32;
+int niter = 65536;
+int debug = 0;
+char data[8192];
+int i;
+int id;
+int intr = 0;
+
+void
+handler(void *v, char *s)
+{
+	print("%d: %d iterations\n", id, i);
+	if (intr++ < 16)
+		noted(NCONT);
+	exits("too many interrupts");
+}
+
+void
+main(int argc, char *argv[])
+{
+	int pid;
+
+	if (notify(handler)){
+		sysfatal("notify: %r");
+	}
+
+	if (argc > 1)
+		nring = strtoull(argv[1], 0, 0);
+
+	if (argc > 2)
+		niter = strtoull(argv[2], 0, 0);
+	debug = argc > 3;
+
+	print("Running with %d pipes %d times\n", nring, niter);
+	int *pfd = malloc(sizeof(*pipe)* nring * 2);
+
+	if (pfd == nil)
+		sysfatal(smprint("alloc %d pipes: %r", nring*2));
+
+	for(i = 0; i < nring; i++)
+		if (pipe(&pfd[i*2]) < 0)
+			sysfatal(smprint("create pipe pair %d of %d: %r", i, nring));
+
+	for(i = 0; debug && i < nring; i++ ) print("pfd[%d,%d]\n", pfd[i*2],pfd[i*2+1]);
+	for(i = 0, id = 0; i < nring-1; i++, id++) {
+		pid = fork();
+		if (pid == 0)
+			break;
+		if (pid < 0)
+			sysfatal("fork");
+	}
+
+	if (debug) print("Forked. pid %d\n", getpid());
+	for(i = 0; debug && i < nring; i++ ) print("pfd[%d,%d]\n", pfd[i*2],pfd[i*2+1]);
+	for(i = 0; i < niter; i++) {
+		if (debug) print("%d: write %d\n", id, pfd[(id%nring)*2+1]);
+		int amt = write(pfd[(id%nring)*2+1], data, sizeof(data));
+		if (amt < sizeof(data))
+			sysfatal(smprint("%d: write only got %d of %d: %r", id, amt, sizeof(data)));
+		if (debug) print("%d: read %d\n", id, pfd[(id%nring)*2]);
+		amt = read(pfd[(id%nring)*2], data, sizeof(data));
+		if (amt < sizeof(data))
+			sysfatal(smprint("%d: read only got %d of %d: %r", id, amt, sizeof(data)));
+	}
+}

+ 2 - 0
sys/src/regress/regress.json

@@ -12,12 +12,14 @@
 		"frexp.c",
 		"idseg.c",
 		"iphash.c",
+		"lockdeath.c",
 		"longjmp.c",
 		"mixedfloat.c",
 		"mmap.c",
 		"nanotime.c",
 		"notify.c",
 		"nx.c",
+		"pipering.c",
 		"privates.c",
 		"psx.c",
 		"syscall.c",