git » libjio » commit 5802eb0

tests/performance: Add a random writes test

author Alberto Bertogli
2009-04-03 04:31:00 UTC
committer Alberto Bertogli
2009-04-12 13:51:04 UTC
parent 1bd4aa9aa3943a1bbdf6b26466b1697c6cca499b

tests/performance: Add a random writes test

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

.gitignore +1 -0
tests/performance/Makefile +5 -1
tests/performance/random.c +144 -0

diff --git a/.gitignore b/.gitignore
index 2f09c27..2a82b46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,5 +8,6 @@ samples/jio1
 samples/jio2
 samples/jio3
 tests/performance/performance
+tests/performance/random
 *.pyc
 *.pyo
diff --git a/tests/performance/Makefile b/tests/performance/Makefile
index 11ddd33..8dae8a5 100644
--- a/tests/performance/Makefile
+++ b/tests/performance/Makefile
@@ -5,16 +5,20 @@ LIBS = -ljio
 
 default: all
 
-all: performance
+all: performance random
 
 performance: performance.o
 	$(CC) $(LIBS) performance.o -o performance
 
+random: random.o
+	$(CC) $(LIBS) random.o -o random
+
 .c.o:
 	$(CC) $(CFLAGS) -c $< -o $@
 
 clean:
 	rm -f performance.o performance
+	rm -f random.o random
 	rm -f *.bb *.bbg *.da *.gcov gmon.out
 	rm -f test_file
 	rm -rf .test_file.jio
diff --git a/tests/performance/random.c b/tests/performance/random.c
new file mode 100644
index 0000000..4af4bed
--- /dev/null
+++ b/tests/performance/random.c
@@ -0,0 +1,144 @@
+
+/*
+ * random.c - A program to test speed of random writes using libjio.
+ * Alberto Bertogli (albertito@blitiri.com.ar)
+ *
+ * It creates a big file, extends it using truncate, and forks N threads which
+ * write the file in chunks (ie. if we have three threads, the first one
+ * writes the first 1/3rd of the file, and so on).
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <libjio.h>
+
+#define FILENAME "test_file"
+
+/* These are shared among threads, to make the code simpler */
+static struct jfs fs;
+static unsigned long mb;
+static ssize_t blocksize, towrite;
+
+
+static void help(void)
+{
+	printf("Use: performance towrite blocksize nthreads\n");
+	printf("\n");
+	printf(" - towrite: how many MB to write per thread\n");
+	printf(" - blocksize: size of blocks written, in KB\n");
+	printf(" - nthreads: number of threads to use\n");
+}
+
+static void *worker(void *tno)
+{
+	void *buf;
+	unsigned long tid;
+	ssize_t work_done, rv;
+	off_t localoffset, offset;
+	long secs, usecs;
+	double seconds, mb_per_sec;
+	struct timeval tv1, tv2;
+
+	tid = (unsigned long) tno;
+
+	localoffset = tid * towrite;
+
+	buf = malloc(blocksize);
+	if (buf == NULL) {
+		perror("malloc()");
+		return NULL;
+	}
+
+	work_done = 0;
+
+	srandom(time(NULL));
+
+	gettimeofday(&tv1, NULL);
+
+	while (work_done < towrite) {
+		offset = random() % (towrite - blocksize);
+		rv = jpwrite(&fs, buf, blocksize, localoffset + offset);
+		if (rv != blocksize) {
+			perror("jpwrite()");
+			break;
+		}
+
+		work_done += blocksize;
+	}
+
+	gettimeofday(&tv2, NULL);
+
+	secs = tv2.tv_sec - tv1.tv_sec;
+	usecs = tv2.tv_usec - tv1.tv_usec;
+
+	if (usecs < 0) {
+		secs -= 1;
+		usecs = 1000000 + usecs;
+	}
+
+	seconds = secs + (usecs / 1000000.0);
+	mb_per_sec = mb / seconds;
+
+	printf("%lu %zd %zd %f %f\n", tid, mb, blocksize, seconds, mb_per_sec);
+
+	return NULL;
+}
+
+int main(int argc, char **argv)
+{
+	int rv, nthreads;
+	unsigned long i;
+	pthread_t *threads;
+	struct jfsck_result ckres;
+
+	if (argc != 4) {
+		help();
+		return 1;
+	}
+
+	mb = atoi(argv[1]);
+	blocksize = atoi(argv[2]) * 1024;
+	nthreads = atoi(argv[3]);
+	towrite = mb * 1024 * 1024;
+
+	threads = malloc(sizeof(pthread_t) * nthreads);
+	if (threads == NULL) {
+		perror("malloc()");
+		return 1;
+	}
+
+	rv = jopen(&fs, FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0600, 0);
+	if (rv < 0) {
+		perror("jopen()");
+		return 1;
+	}
+
+	jtruncate(&fs, towrite * nthreads);
+
+	for (i = 0; i < nthreads; i++) {
+		pthread_create(threads + i, NULL, &worker, (void *) i);
+	}
+
+	for (i = 0; i < nthreads; i++) {
+		pthread_join(*(threads + i), NULL);
+	}
+
+	jclose(&fs);
+	jfsck(FILENAME, NULL, &ckres);
+	if (ckres.total != 0) {
+		fprintf(stderr, "There were %d errors during the test\n",
+				ckres.total);
+		fprintf(stderr, "jfsck() was used to fix them, but that ");
+		fprintf(stderr, "shouldn't happen.\n");
+		return 1;
+	}
+
+	jfsck_cleanup(FILENAME, NULL);
+	return 0;
+}
+