Index: .bzrignore
===================================================================
--- .bzrignore	(revision d1ac0d7dbbabf578a769e9e9e5e525e6543f5319)
+++ .bzrignore	(revision 423f64f63d8c108939a35c61f253370da5f05380)
@@ -26,4 +26,5 @@
 uspace/app/bdsh/bdsh
 uspace/app/blkdump/blkdump
+uspace/app/bnchmark/bnchmark
 uspace/app/edit/edit
 uspace/app/ext2info/ext2info
@@ -53,4 +54,5 @@
 uspace/dist/app/bdsh
 uspace/dist/app/blkdump
+uspace/dist/app/bnchmark
 uspace/dist/app/edit
 uspace/dist/app/ext2info
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision d1ac0d7dbbabf578a769e9e9e5e525e6543f5319)
+++ boot/Makefile.common	(revision 423f64f63d8c108939a35c61f253370da5f05380)
@@ -137,4 +137,5 @@
 RD_APPS_NON_ESSENTIAL = \
 	$(USPACE_PATH)/app/blkdump/blkdump \
+	$(USPACE_PATH)/app/bnchmark/bnchmark \
 	$(USPACE_PATH)/app/dltest/dltest \
 	$(USPACE_PATH)/app/dltest2/dltest2 \
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision d1ac0d7dbbabf578a769e9e9e5e525e6543f5319)
+++ uspace/Makefile	(revision 423f64f63d8c108939a35c61f253370da5f05380)
@@ -36,4 +36,5 @@
 	app/bdsh \
 	app/blkdump \
+	app/bnchmark \
 	app/edit \
 	app/ext2info \
Index: uspace/app/bnchmark/Makefile
===================================================================
--- uspace/app/bnchmark/Makefile	(revision 423f64f63d8c108939a35c61f253370da5f05380)
+++ uspace/app/bnchmark/Makefile	(revision 423f64f63d8c108939a35c61f253370da5f05380)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2011 Martin Sucha
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+BINARY = bnchmark
+
+SOURCES = \
+	bnchmark.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/bnchmark/bnchmark.c
===================================================================
--- uspace/app/bnchmark/bnchmark.c	(revision 423f64f63d8c108939a35c61f253370da5f05380)
+++ uspace/app/bnchmark/bnchmark.c	(revision 423f64f63d8c108939a35c61f253370da5f05380)
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup test
+ * @{
+ */
+
+/**
+ * @file	bnchmark.c
+ * This program measures time for various actions and writes the results
+ * to a file.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mem.h>
+#include <devmap.h>
+#include <byteorder.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <time.h>
+#include <dirent.h>
+
+#define NAME	"bnchmark"
+#define BUFSIZE 8096
+#define MBYTE (1024*1024)
+
+typedef int(*measure_func_t)(void *);
+typedef unsigned long umseconds_t; /* milliseconds */
+
+static void syntax_print(void);
+
+static int measure(measure_func_t fn, void* data, umseconds_t *result)
+{
+	struct timeval start_time;
+	int rc;
+	rc = gettimeofday(&start_time, NULL);
+	if (rc != EOK) {
+		fprintf(stderr, "gettimeofday failed\n");
+		return rc;
+	}
+	
+	rc = fn(data);
+	if (rc != EOK) {
+		fprintf(stderr, "measured function failed\n");
+		return rc;
+	}
+
+	struct timeval final_time;
+	rc = gettimeofday(&final_time, NULL);
+	if (rc != EOK) {
+		fprintf(stderr, "gettimeofday failed\n");
+		return rc;
+	}
+	
+	/* Calculate time difference in milliseconds */
+	*result = ((final_time.tv_usec - start_time.tv_usec) / 1000) +
+	    ((final_time.tv_sec - start_time.tv_sec) * 1000);
+	return EOK;
+}
+
+static int sequential_read_file(void *data)
+{
+	char *path = (char *) data;
+	char *buf = malloc(BUFSIZE);
+
+	if (buf == NULL) {
+		return ENOMEM;
+	}
+	
+	FILE *file = fopen(path, "r");
+	if (file == NULL) {
+		fprintf(stderr, "Failed opening file: %s\n", path);
+		free(buf);
+		return EIO;
+	}
+	
+	while (!feof(file)) {
+		fread(buf, 1, BUFSIZE, file);
+		if (ferror(file)) {
+			fprintf(stderr, "Failed reading file\n");
+			fclose(file);
+			free(buf);
+			return EIO;
+		}
+	}
+	
+	fclose(file);
+	free(buf);
+	return EOK;
+}
+
+static int sequential_read_dir(void *data)
+{
+	char *path = (char *) data;
+	
+	DIR *dir = opendir(path);
+	if (dir == NULL) {
+		fprintf(stderr, "Failed opening directory: %s\n", path);
+		return EIO;
+	}
+
+	struct dirent *dp;
+	
+	while ((dp = readdir(dir))) {
+		/* Do nothing */
+	}
+	
+	closedir(dir);
+	return EOK;
+}
+
+int main(int argc, char **argv)
+{
+	int rc;
+	umseconds_t milliseconds_taken;
+	char *path = NULL;
+	measure_func_t fn = NULL;
+	int iteration;
+	int iterations;
+	char *log_str = NULL;
+	char *test_type = NULL;
+	char *endptr;
+	
+	if (argc < 5) {
+		fprintf(stderr, NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+	
+	if (argc > 5) {
+		fprintf(stderr, NAME ": Error, too many arguments.\n");
+		syntax_print();
+		return 1;
+	}
+	
+	// Skip program name
+	--argc; ++argv;
+
+	iterations = strtol(*argv, &endptr, 10);
+	if (*endptr != '\0') {
+		printf(NAME ": Error, invalid argument (iterations).\n");
+		syntax_print();
+		return 1;
+	}
+	
+	--argc; ++argv;
+	test_type = *argv;
+
+	--argc; ++argv;
+	log_str = *argv;
+
+	--argc; ++argv;
+	path = *argv;
+	
+	if (str_cmp(test_type, "sequential-file-read") == 0) {
+		fn = sequential_read_file;
+	}
+	else if (str_cmp(test_type, "sequential-dir-read") == 0) {
+		fn = sequential_read_dir;
+	}
+	else {
+		fprintf(stderr, "Error, unknown test type\n");
+		syntax_print();
+		return 1;
+	}
+
+	for (iteration = 0; iteration < iterations; iteration++) {
+		rc = measure(fn, path, &milliseconds_taken);
+		if (rc != EOK) {
+			fprintf(stderr, "Error %d\n", rc);
+			return 1;
+		}
+	
+		printf("%s;%s;%s;%lu;ms\n", test_type, path, log_str, milliseconds_taken);
+	}
+
+	return 0;
+}
+
+
+static void syntax_print(void)
+{
+	fprintf(stderr, "syntax: bnchmark <iterations> <test type> <log-str> <path>\n");
+	fprintf(stderr, "  <iterations>    number of times to run a given test");
+	fprintf(stderr, "  <test-type>     one of:");
+	fprintf(stderr, "                    sequential-file-read");
+	fprintf(stderr, "                    sequential-dir-read");
+	fprintf(stderr, "  <log-str>       a string to attach to results");
+	fprintf(stderr, "  <path>          file/directory to use for testing");
+}
+
+/**
+ * @}
+ */
