fsbenchmark
Xiang Cui
medivhc at gmail.com
Thu Jul 12 11:53:56 UTC 2012
Hi
The best way to evaluate the bdbuf is to get the trace of the I/O of
the application. But I can't get a typical embedded system application
trace. So the basic concept of the test is to parse strings contains
the I/O operation meta data and carry out these operation. Using this
method the test can do some kind of simulating the read/write sequence
and some random operation.
diff --git a/testsuites/fstests/fsbenchmark/fsbenchmark.doc
b/testsuites/fstests/fsbenchmark/fsbenchmark.doc
new file mode 100644
index 0000000..44a97ea
--- /dev/null
+++ b/testsuites/fstests/fsbenchmark/fsbenchmark.doc
@@ -0,0 +1,28 @@
+# COPYRIGHT (c) 1989-2011.
+# On-Line Applications Research Corporation (OAR).
+#
+# The license and distribution terms for this file may be
+# found in the file LICENSE in this distribution or at
+# http://www.rtems.com/license/LICENSE.
+#
+
+This file describes the directives and concepts tested by this test set.
+
+test set name: fsbenchmark
+
+directives:
+
++ open
++ read
++ write
++ lseek
+
+
+concepts:
++ This test could be a benchmark for bdbuf. The basic concept of the test is
+ to prase strings contains the I/O operation meta data and carry out these
+ operation.
+
+
+
+
diff --git a/testsuites/fstests/fsbenchmark/init.c
b/testsuites/fstests/fsbenchmark/init.c
new file mode 100644
index 0000000..d3c906d
--- /dev/null
+++ b/testsuites/fstests/fsbenchmark/init.c
@@ -0,0 +1,475 @@
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+
+
+
+/*
+ * Every operation divided by '\n'. Reading 4 bytes from file 2 starting
+ * at 3 could be expressed as "1 R 2 3 4". The order of the parameters
+ * is index operation file_name start size. index here have no meaning now.
+ * operation could be R W L C U which mean read write lseek close and
+ * unlink respectively. file_name could be [0-MAX_FILE_NUM-1] or L which
+ * means last opened file. start and size could be positive integer or r
+ * which means random. If start is 0, it will do nothing, else I will call
+ * lseek SEEK_SET before read or write. If file with file_name does not exists,
+ * W R L will create file with O_WRONLY O_RDONLY O_RDWR respectively.
+ * The test will not handle any error or check any data integrity. If error
+ * occurs, it just use perror() to print them.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/blkdev.h>
+#include <rtems/bdbuf.h>
+
+#include "fstest.h"
+#include "pmacros.h"
+#include "ramdisk_support.h"
+
+#define MAX_OPEN_FILE (10)
+#define MAX_LEN 1024*64
+
+static int fd_array[MAX_OPEN_FILE];
+const static int RUN_TIMES = 5;
+
+const static mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
+char workload_input[] = {
+ "1 W 0 0 r\n"
+ "1 W L r r\nn"
+ "1 W L 0 r\n"
+ "1 W L 0 r\n"
+ "1 W L 0 1024\n"
+ "1 W L 0 1024\n"
+ "1 L L r 1024\n"
+ "1 C L 0 1024\n"
+ "1 R 0 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 r\n"
+ "1 L L r 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L r r\n"
+ "1 R L 0 1024\n"
+ "1 R L r 1024\n"
+ "1 R L 0 r\n"
+ "1 L L r r\n"
+ "1 R L 0 r\n"
+ "1 C L 0 1024\n"
+ "1 W 0 0 r\n"
+ "1 W L r r\nn"
+ "1 L L r 1024\n"
+ "1 W L 0 r\n"
+ "1 W L 0 r\n"
+ "1 W L 0 1024\n"
+ "1 W L 0 1024\n"
+ "1 C L 0 r\n"
+ "1 L L r r\n"
+ "1 L 1 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 r\n"
+ "1 W L 0 r\n"
+ "1 W L 0 r\n"
+ "1 L L r 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 r\n"
+ "1 R L 0 1024\n"
+ "1 R L r r\n"
+ "1 R L 0 1024\n"
+ "1 L 0 0 1024\n"
+ "1 R L 0 r\n"
+ "1 R L 0 r\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 r\n"
+ "1 R L 0 1024\n"
+ "1 R L 0 r\n"
+ "1 R L 0 1024\n"
+ "1 L 3 0 1024\n"
+ "1 L L r 1024\n"
+ "1 W L 0 1024\n"
+ "1 W L 0 1024\n"
+ "1 W L 0 1024\n"
+ "1 W L 0 r\n"
+ "1 L L r 1024\n"
+ "1 W L 0 1024\n"
+ "1 W L 0 r\n"
+ "1 L L 0 r\n"
+ "1 L L 0 1024\n"
+ "1 C 3\n"
+};
+
+ static void
+check_status (char *message, int result)
+{
+ if (!result)
+ {
+ perror (message);
+ }
+}
+
+
+
+typedef struct benchmark_test_state
+{
+ int is_colsed;
+ int previous_fd;
+ int previous_name;
+ off_t pos;
+} benchmark_test_state;
+benchmark_test_state state;
+
+typedef enum test_arg_type
+{
+ INDEX,
+ OPERATION,
+ FILE_NAME,
+ START,
+ SIZE,
+ OTHER
+} test_arg_type;
+
+struct test_item
+{
+ int index;
+ char name[3];
+ char op;
+ off_t begin;
+ size_t size;
+ int fd;
+};
+
+ static long
+prase_long (const char*str)
+{
+ if (isdigit ((int) *str))
+ {
+ return atol (str);
+ }
+ else
+ {
+ switch (*str)
+ {
+ case 'l':
+ return state.pos;
+ break;
+ case 'r':
+ return (lrand48 () % (long)MAX_LEN)+1;
+ case 'u':
+ return 0;
+ }
+ return 0;
+
+ }
+}
+ static void
+fill_test_entry (test_arg_type arg, char *pch, struct test_item * it)
+{
+
+ switch (arg)
+ {
+ case INDEX:
+ it->index = atoi (pch);
+ break;
+ case OPERATION:
+ it->op = *pch;
+ break;
+ case FILE_NAME:
+ strncpy (it->name, pch, strlen (pch));
+ it->name[strlen (pch)] = '\0';
+ break;
+ case START:
+ it->begin = prase_long (pch);
+ break;
+ case SIZE:
+ it->size = prase_long (pch);
+ break;
+ case OTHER:
+ break;
+ default:
+ exit (1);
+ }
+}
+static void do_common_before (struct test_item *it)
+{
+ int fd;
+ int rv = 0;
+ char first_char = it->name[0];
+ if (isdigit ((int )first_char))
+ { /* file name */
+ if (state.previous_fd != -1)
+ {
+ rv = close (state.previous_fd);
+ check_status ("close ", rv == 0);
+ fd_array[state.previous_name] = -1;
+ }
+
+ switch (it->op)
+ {
+ case 'R':
+ fd = open (it->name, O_CREAT | O_RDONLY, mode);
+ break;
+ case 'W':
+ fd = open (it->name, O_CREAT | O_WRONLY, mode);
+ break;
+ case 'L':
+ fd = open (it->name, O_CREAT | O_RDWR, mode);
+ }
+ check_status ("create ", fd != -1);
+
+ state.previous_name = atoi (it->name);
+ }
+ else
+ {
+ fd = state.previous_fd;
+ }
+ it->fd = fd;
+ if (it->begin != 0)
+ {
+ lseek (fd, it->begin, SEEK_SET);
+ }
+}
+
+static void do_common_afer (struct test_item *it)
+{
+
+ state.previous_fd = it->fd;
+ fd_array[state.previous_name] = it->fd;
+}
+
+static off_t
+do_read (struct test_item *it)
+{
+ do_common_before (it);
+
+
+ void * buffer = malloc (it->size);
+
+ size_t n;
+ size_t actual = 0;
+
+ while ((n = read (it->fd, buffer, it->size - actual)) != -1)
+ {
+ if (n == 0)
+ break;
+ else
+ {
+ actual += n;
+ }
+ }
+ check_status ("read ", n != -1);
+
+ printf ("read file: %d size: %d\n", state.previous_name,actual);
+
+ free (buffer);
+ do_common_afer (it);
+ return actual;
+}
+
+
+static off_t
+do_write (struct test_item *it)
+{
+ size_t n;
+ size_t actual = 0;
+
+ do_common_before (it);
+ void * buffer = malloc (it->size);
+ while ((n = write (it->fd, buffer, it->size - actual)) != -1)
+ {
+ if (n == 0)
+ break;
+ else
+ {
+ actual += n;
+ }
+ }
+ free (buffer);
+ check_status ("write", n != -1);
+ printf ("write file: %d size: %d\n", state.previous_name,actual);
+ do_common_afer (it);
+ return actual;
+
+}
+
+static off_t
+do_lseek (struct test_item *it)
+{
+ do_common_before (it);
+ do_common_afer (it);
+ return it->begin;
+}
+
+static void
+do_unlink (struct test_item *it)
+{
+ int rv = unlink (it->name);
+ check_status ("unlink", rv == 0);
+}
+static void
+do_close (struct test_item *it)
+{
+ int rv = 0;
+ char first_char = it->name[0];
+ if (isdigit ((int)first_char))
+ { /* file name */
+ rv = close (fd_array[atoi (it->name)]);
+ check_status ("close", rv == 0);
+
+ fd_array[atoi (it->name)] = -1;
+ }
+ else
+ { /* last file */
+ rv = close (state.previous_fd);
+ check_status ("close", rv == 0);
+ }
+ it->fd = -1;
+
+ do_common_afer(it);
+
+}
+
+static void
+execute_entry (struct test_item *it)
+{
+ off_t result;
+ switch (it->op)
+ {
+ case 'R':
+ result = do_read (it);
+ break;
+ case 'W':
+ result = do_write (it);
+ break;
+ case 'L':
+ result = do_lseek (it);
+ break;
+ case 'U':
+ do_unlink (it);
+ break;
+ case 'C':
+ do_close (it);
+ break;
+ }
+ state.pos = result;
+}
+
+static void parse (char *str)
+{
+ char *pch;
+ pch = strtok (str, " ");
+ test_arg_type arg = INDEX;
+ struct test_item it;
+ while (pch != NULL)
+ {
+ fill_test_entry (arg, pch, &it);
+ pch = strtok (NULL, " ");
+ arg++;
+ }
+ execute_entry (&it);
+}
+
+static void process (const char* str)
+{
+ char * pch;
+ const char * start = str;
+ char buffer[256];
+ /*
+ * separate the string by '\n'
+ */
+ while (strlen (start))
+ {
+ pch = (char*) memchr (start, '\n', strlen (start));
+ size_t len = pch - start;
+
+ strncpy (buffer, start, len);
+ buffer[len] = '\0';
+ parse (buffer);
+ start = pch + 1;
+ }
+}
+
+static void init (void )
+{
+ int i = 1;
+ seed48 ((short unsigned int*) &i);
+ state.previous_name = 0;
+ state.pos = 0;
+ state.previous_fd =-1;
+}
+
+
+
+static void print_dev_stats(void)
+{
+ int status;
+ rtems_status_code sc;
+ int fd;
+ rtems_blkdev_stats stats;
+ rtems_disk_device *dd;
+
+
+ status = chroot("/");
+ rtems_test_assert (status == 0);
+
+ fd = open(RAMDISK_PATH, O_RDWR);
+ rtems_test_assert (fd != 0);
+ sc = rtems_disk_fd_get_disk_device(fd, &dd);
+ rtems_test_assert (sc == 0);
+ status = rtems_bdbuf_syncdev (dd);
+ rtems_test_assert (status == 0);
+ rtems_bdbuf_get_device_stats (dd, &stats);
+ rtems_blkdev_print_stats(&stats, rtems_printf_plugin, NULL);
+}
+
+static void reset_dev_stats(void )
+{
+
+ /*
+ * We have to chroot to get the ramdisk fd
+ */
+ int rv;
+ int fd;
+ rtems_status_code sc;
+ rv = chroot("/");
+ rtems_test_assert (rv == 0);
+ fd = open( RAMDISK_PATH,O_RDWR);
+ rtems_test_assert (fd != 0);
+ sc = rtems_disk_fd_reset_device_stats(fd);
+ rtems_test_assert (sc == 0);
+ rv = close (fd);
+ rtems_test_assert (rv == 0);
+ rv = chroot(BASE_FOR_TEST);
+ rtems_test_assert (rv == 0);
+}
+
+void test ()
+{
+ int i =0;
+ reset_dev_stats();
+ init ();
+ for ( i = 0; i < RUN_TIMES; i++){
+ process (workload_input);
+ }
+ sync();
+ print_dev_stats();
+}
diff --git a/testsuites/fstests/imfs_support/fs_support.c
b/testsuites/fstests/imfs_support/fs_support.c
index f623d9b..d54cab6 100644
--- a/testsuites/fstests/imfs_support/fs_support.c
+++ b/testsuites/fstests/imfs_support/fs_support.c
@@ -13,6 +13,9 @@
#include <sys/stat.h>
+#include <rtems/blkdev.h>
+#include <rtems/libio.h>
+#include "fs_config.h"
#include "fstest.h"
#include "fstest_support.h"
@@ -40,5 +43,7 @@ test_shutdown_filesystem (void)
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 40
#define CONFIGURE_INIT_TASK_STACK_SIZE (16 * 1024)
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
diff --git a/testsuites/fstests/mdosfs_fsbenchmark/Makefile.am
b/testsuites/fstests/mdosfs_fsbenchmark/Makefile.am
new file mode 100644
index 0000000..c0970a9
--- /dev/null
+++ b/testsuites/fstests/mdosfs_fsbenchmark/Makefile.am
@@ -0,0 +1,33 @@
+
+rtems_tests_PROGRAMS = mdosfs_fsbenchmark
+mdosfs_fsbenchmark_SOURCES = ../fsbenchmark/init.c
+mdosfs_fsbenchmark_SOURCES += ../support/ramdisk_support.c
+mdosfs_fsbenchmark_SOURCES += ../support/fstest_support.c
+mdosfs_fsbenchmark_SOURCES += ../support/fstest_support.h
+mdosfs_fsbenchmark_SOURCES += ../support/ramdisk_support.h
+mdosfs_fsbenchmark_SOURCES += ../support/fstest.h
+mdosfs_fsbenchmark_SOURCES += ../../psxtests/include/pmacros.h
+mdosfs_fsbenchmark_SOURCES += ../mdosfs_support/fs_support.c
+mdosfs_fsbenchmark_SOURCES += ../mdosfs_support/fs_config.h
+
+#dist_rtems_tests_DATA = mdosfs_fsbenchmark.scn
+#dist_rtems_tests_DATA += mdosfs_fsbenchmark.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+
+AM_CPPFLAGS += -I$(top_srcdir)/support
+AM_CPPFLAGS += -I$(top_srcdir)/mdosfs_support
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+AM_CPPFLAGS += -I$(top_srcdir)/../psxtests/include
+
+LINK_OBJS = $(mdosfs_fsbenchmark_OBJECTS)
+LINK_LIBS = $(mdosfs_fsbenchmark_LDLIBS)
+
+mdosfs_fsbenchmark$(EXEEXT): $(mdosfs_fsbenchmark_OBJECTS)
$(mdosfs_fsbenchmark_DEPENDENCIES)
+ @rm -f mdosfs_fsbenchmark$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/fstests/mimfs_support/fs_support.c
b/testsuites/fstests/mimfs_support/fs_support.c
index 2ac1e6c..a3a9ca0 100644
--- a/testsuites/fstests/mimfs_support/fs_support.c
+++ b/testsuites/fstests/mimfs_support/fs_support.c
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include <rtems/libio.h>
+#include <rtems/blkdev.h>
#include "fstest.h"
#include "fstest_support.h"
@@ -57,5 +58,7 @@ test_shutdown_filesystem (void)
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 40
#define CONFIGURE_INIT_TASK_STACK_SIZE (16 * 1024)
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
diff --git a/testsuites/fstests/mrfs_fsbenchmark/Makefile.am
b/testsuites/fstests/mrfs_fsbenchmark/Makefile.am
new file mode 100644
index 0000000..7d4831c
--- /dev/null
+++ b/testsuites/fstests/mrfs_fsbenchmark/Makefile.am
@@ -0,0 +1,33 @@
+
+rtems_tests_PROGRAMS = mrfs_fsbenchmark
+mrfs_fsbenchmark_SOURCES = ../fsbenchmark/init.c
+mrfs_fsbenchmark_SOURCES += ../support/ramdisk_support.c
+mrfs_fsbenchmark_SOURCES += ../support/fstest_support.c
+mrfs_fsbenchmark_SOURCES += ../support/fstest_support.h
+mrfs_fsbenchmark_SOURCES += ../support/ramdisk_support.h
+mrfs_fsbenchmark_SOURCES += ../support/fstest.h
+mrfs_fsbenchmark_SOURCES += ../../psxtests/include/pmacros.h
+mrfs_fsbenchmark_SOURCES += ../mrfs_support/fs_support.c
+mrfs_fsbenchmark_SOURCES += ../mrfs_support/fs_config.h
+
+#dist_rtems_tests_DATA = mrfs_fsbenchmark.scn
+#dist_rtems_tests_DATA += mrfs_fsbenchmark.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+
+AM_CPPFLAGS += -I$(top_srcdir)/support
+AM_CPPFLAGS += -I$(top_srcdir)/mrfs_support
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+AM_CPPFLAGS += -I$(top_srcdir)/../psxtests/include
+
+LINK_OBJS = $(mrfs_fsbenchmark_OBJECTS)
+LINK_LIBS = $(mrfs_fsbenchmark_LDLIBS)
+
+mrfs_fsbenchmark$(EXEEXT): $(mrfs_fsbenchmark_OBJECTS)
$(mrfs_fsbenchmark_DEPENDENCIES)
+ @rm -f mrfs_fsbenchmark$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
More information about the devel
mailing list