diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 18 | ||||
-rw-r--r-- | test/benchmark-common.c | 193 | ||||
-rw-r--r-- | test/benchmark-gvfs-big-files.c | 170 | ||||
-rw-r--r-- | test/benchmark-gvfs-small-files.c | 170 | ||||
-rw-r--r-- | test/benchmark-posix-big-files.c | 176 | ||||
-rw-r--r-- | test/benchmark-posix-small-files.c | 176 |
6 files changed, 903 insertions, 0 deletions
diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 00000000..143d50ee --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,18 @@ +NULL = + +AM_CFLAGS = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(GLIB_CFLAGS) \ + -DG_DISABLE_DEPRECATED + +AM_LDFLAGS = \ + $(top_builddir)/gio/libgio.la \ + $(GLIB_LIBS) + +noinst_PROGRAMS = \ + benchmark-gvfs-small-files \ + benchmark-gvfs-big-files \ + benchmark-posix-small-files \ + benchmark-posix-big-files \ + $(NULL) diff --git a/test/benchmark-common.c b/test/benchmark-common.c new file mode 100644 index 00000000..46d6f7b1 --- /dev/null +++ b/test/benchmark-common.c @@ -0,0 +1,193 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* This file should be included directly in each benchmark program */ + +#define __USE_GNU 1 + +#include "config.h" +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/time.h> +#include <glib/gprintf.h> + +static GMainLoop *main_loop; + +typedef struct +{ + gdouble x; + gdouble y; +} +BenchmarkDataPoint; + +typedef struct +{ + /* Array of BenchmarkDataPoints */ + GArray *points; +} +BenchmarkDataSet; + +typedef struct +{ + gchar *name; + gchar *x_unit; + gchar *y_unit; + + GList *data_sets; +} +BenchmarkDataPlot; + +static gint benchmark_run (gint argc, gchar *argv []); + +GList *benchmark_data_plots = NULL; +gboolean benchmark_is_running = FALSE; + +static void +benchmark_begin_data_plot (const gchar *name, const gchar *x_unit, const gchar *y_unit) +{ + BenchmarkDataPlot *data_plot; + + data_plot = g_new0 (BenchmarkDataPlot, 1); + + data_plot->name = g_strdup (name); + data_plot->x_unit = g_strdup (x_unit); + data_plot->y_unit = g_strdup (y_unit); + + data_plot->data_sets = NULL; + + benchmark_data_plots = g_list_prepend (benchmark_data_plots, data_plot); +} + +static void +benchmark_begin_data_set (void) +{ + BenchmarkDataPlot *data_plot; + BenchmarkDataSet *data_set; + + if (!benchmark_data_plots) + g_error ("Must begin a data plot before adding data sets!"); + + data_plot = benchmark_data_plots->data; + + data_set = g_new0 (BenchmarkDataSet, 1); + data_set->points = g_array_new (FALSE, FALSE, sizeof (BenchmarkDataPoint)); + + data_plot->data_sets = g_list_prepend (data_plot->data_sets, data_set); +} + +static void +benchmark_add_data_point (gdouble x, gdouble y) +{ + BenchmarkDataPlot *data_plot; + BenchmarkDataSet *data_set; + BenchmarkDataPoint data_point; + + if (!benchmark_data_plots) + g_error ("Must begin a data plot before adding data sets!"); + + data_plot = benchmark_data_plots->data; + + if (!data_plot->data_sets) + g_error ("Must begin a data set before adding data points!"); + + data_set = data_plot->data_sets->data; + + data_point.x = x; + data_point.y = y; + + g_array_append_val (data_set->points, data_point); +} + +static void +benchmark_end (void) +{ + BenchmarkDataPlot *plot; + GList *l; + + /* Dump plots */ + + if (!benchmark_data_plots) + exit (1); + + plot = benchmark_data_plots->data; + if (!plot) + exit (1); + + for (l = plot->data_sets; l; l = g_list_next (l)) + { + BenchmarkDataSet *set = l->data; + guint i; + + for (i = 0; i < set->points->len; i++) + { + BenchmarkDataPoint *point = &g_array_index (set->points, BenchmarkDataPoint, i); + + g_print ("%20lf %20lf\n", point->x, point->y); + } + } + + exit (0); +} + +static void +benchmark_begin (const gchar *name) +{ + g_type_init (); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR); + main_loop = g_main_loop_new (NULL, FALSE); +} + +G_GNUC_UNUSED static void +benchmark_run_main_loop (void) +{ + g_main_loop_run (main_loop); +} + +G_GNUC_UNUSED static void +benchmark_quit_main_loop (void) +{ + g_main_loop_quit (main_loop); +} + +static void +benchmark_timeout (void) +{ + benchmark_is_running = FALSE; +} + +G_GNUC_UNUSED static void +benchmark_start_wallclock_timer (gint n_seconds) +{ + benchmark_is_running = TRUE; + signal (SIGALRM, (sig_t) benchmark_timeout); + alarm (n_seconds); +} + +G_GNUC_UNUSED static void +benchmark_start_cpu_timer (gint n_seconds) +{ + struct itimerval itv; + + benchmark_is_running = TRUE; + + memset (&itv, 0, sizeof (itv)); + itv.it_value.tv_sec = n_seconds; + + signal (SIGPROF, (sig_t) benchmark_timeout); + setitimer (ITIMER_PROF, &itv, NULL); +} + +gint +main (gint argc, gchar *argv []) +{ + gint result; + + benchmark_begin (BENCHMARK_UNIT_NAME); + result = benchmark_run (argc, argv); + benchmark_end (); + + return result; +} diff --git a/test/benchmark-gvfs-big-files.c b/test/benchmark-gvfs-big-files.c new file mode 100644 index 00000000..3fcc1fc1 --- /dev/null +++ b/test/benchmark-gvfs-big-files.c @@ -0,0 +1,170 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <locale.h> +#include <errno.h> +#include <string.h> + +#include <glib.h> +#include <gio/gfile.h> + +#define BENCHMARK_UNIT_NAME "gvfs-big-file" + +#include "benchmark-common.c" + +#define FILE_SIZE (1024 * 1024 * 50) /* 50 MiB */ +#define BUFFER_SIZE 4096 +#define ITERATIONS_NUM 1 + +static gboolean +is_dir (GFile *file) +{ + GFileInfo *info; + gboolean res; + + info = g_file_get_info (file, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL); + res = info && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY; + if (info) + g_object_unref (info); + return res; +} + +static GFile * +create_file (GFile *base_dir) +{ + GFile *scratch_file; + gchar *scratch_name; + GOutputStream *output_stream; + gint pid; + GError *error = NULL; + gchar buffer [BUFFER_SIZE]; + gint i; + + pid = getpid (); + scratch_name = g_strdup_printf ("gvfs-benchmark-scratch-%d", pid); + scratch_file = g_file_resolve_relative (base_dir, scratch_name); + g_free (scratch_name); + + if (!scratch_file) + return NULL; + + output_stream = G_OUTPUT_STREAM (g_file_replace (scratch_file, 0, FALSE, NULL, &error)); + if (!output_stream) + { + g_printerr ("Failed to create scratch file: %s\n", error->message); + g_object_unref (scratch_file); + return NULL; + } + + memset (buffer, 0xaa, BUFFER_SIZE); + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + if (g_output_stream_write (output_stream, buffer, BUFFER_SIZE, NULL, &error) < BUFFER_SIZE) + { + g_printerr ("Failed to populate scratch file: %s\n", error->message); + g_output_stream_close (output_stream, NULL, NULL); + g_object_unref (output_stream); + g_object_unref (scratch_file); + return NULL; + } + } + + g_output_stream_close (output_stream, NULL, NULL); + g_object_unref (output_stream); + return scratch_file; +} + +static void +read_file (GFile *scratch_file) +{ + GInputStream *input_stream; + GError *error = NULL; + gint i; + + input_stream = (GInputStream *) g_file_read (scratch_file, NULL, &error); + if (!input_stream) + { + g_printerr ("Failed to open scratch file: %s\n", error->message); + return; + } + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + gchar buffer [BUFFER_SIZE]; + gsize bytes_read; + + if (!g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &bytes_read, NULL, &error) || + bytes_read < BUFFER_SIZE) + { + g_printerr ("Failed to read back scratch file: %s\n", error->message); + g_input_stream_close (input_stream, NULL, NULL); + g_object_unref (input_stream); + } + } + + g_object_unref (input_stream); +} + +static void +delete_file (GFile *scratch_file) +{ + GError *error = NULL; + +#if 0 + /* Enable when GDaemonFile supports delete */ + + if (!g_file_delete (scratch_file, NULL, &error)) + { + g_printerr ("Failed to delete scratch file: %s\n", error->message); + } +#endif +} + +static gint +benchmark_run (gint argc, gchar *argv []) +{ + GFile *base_dir; + GFile *scratch_file; + gint i; + + setlocale (LC_ALL, ""); + + g_type_init (); + + if (argc < 2) + { + g_printerr ("Usage: %s <scratch URI>\n", argv [0]); + return 1; + } + + base_dir = g_file_get_for_commandline_arg (argv [1]); + + if (!is_dir (base_dir)) + { + g_printerr ("Scratch URI %s is not a directory\n", argv [1]); + g_object_unref (base_dir); + return 1; + } + + for (i = 0; i < ITERATIONS_NUM; i++) + { + scratch_file = create_file (base_dir); + if (!scratch_file) + { + g_object_unref (base_dir); + return 1; + } + + read_file (scratch_file); + delete_file (scratch_file); + + g_object_unref (scratch_file); + } + + g_object_unref (base_dir); + return 0; +} diff --git a/test/benchmark-gvfs-small-files.c b/test/benchmark-gvfs-small-files.c new file mode 100644 index 00000000..f0b0adcd --- /dev/null +++ b/test/benchmark-gvfs-small-files.c @@ -0,0 +1,170 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <locale.h> +#include <errno.h> +#include <string.h> + +#include <glib.h> +#include <gio/gfile.h> + +#define BENCHMARK_UNIT_NAME "gvfs-big-file" + +#include "benchmark-common.c" + +#define FILE_SIZE 4096 +#define BUFFER_SIZE 4096 +#define ITERATIONS_NUM 65536 + +static gboolean +is_dir (GFile *file) +{ + GFileInfo *info; + gboolean res; + + info = g_file_get_info (file, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL); + res = info && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY; + if (info) + g_object_unref (info); + return res; +} + +static GFile * +create_file (GFile *base_dir) +{ + GFile *scratch_file; + gchar *scratch_name; + GOutputStream *output_stream; + gint pid; + GError *error = NULL; + gchar buffer [BUFFER_SIZE]; + gint i; + + pid = getpid (); + scratch_name = g_strdup_printf ("gvfs-benchmark-scratch-%d", pid); + scratch_file = g_file_resolve_relative (base_dir, scratch_name); + g_free (scratch_name); + + if (!scratch_file) + return NULL; + + output_stream = G_OUTPUT_STREAM (g_file_replace (scratch_file, 0, FALSE, NULL, &error)); + if (!output_stream) + { + g_printerr ("Failed to create scratch file: %s\n", error->message); + g_object_unref (scratch_file); + return NULL; + } + + memset (buffer, 0xaa, BUFFER_SIZE); + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + if (g_output_stream_write (output_stream, buffer, BUFFER_SIZE, NULL, &error) < BUFFER_SIZE) + { + g_printerr ("Failed to populate scratch file: %s\n", error->message); + g_output_stream_close (output_stream, NULL, NULL); + g_object_unref (output_stream); + g_object_unref (scratch_file); + return NULL; + } + } + + g_output_stream_close (output_stream, NULL, NULL); + g_object_unref (output_stream); + return scratch_file; +} + +static void +read_file (GFile *scratch_file) +{ + GInputStream *input_stream; + GError *error = NULL; + gint i; + + input_stream = (GInputStream *) g_file_read (scratch_file, NULL, &error); + if (!input_stream) + { + g_printerr ("Failed to open scratch file: %s\n", error->message); + return; + } + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + gchar buffer [BUFFER_SIZE]; + gsize bytes_read; + + if (!g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &bytes_read, NULL, &error) || + bytes_read < BUFFER_SIZE) + { + g_printerr ("Failed to read back scratch file: %s\n", error->message); + g_input_stream_close (input_stream, NULL, NULL); + g_object_unref (input_stream); + } + } + + g_object_unref (input_stream); +} + +static void +delete_file (GFile *scratch_file) +{ + GError *error = NULL; + +#if 0 + /* Enable when GDaemonFile supports delete */ + + if (!g_file_delete (scratch_file, NULL, &error)) + { + g_printerr ("Failed to delete scratch file: %s\n", error->message); + } +#endif +} + +static gint +benchmark_run (gint argc, gchar *argv []) +{ + GFile *base_dir; + GFile *scratch_file; + gint i; + + setlocale (LC_ALL, ""); + + g_type_init (); + + if (argc < 2) + { + g_printerr ("Usage: %s <scratch URI>\n", argv [0]); + return 1; + } + + base_dir = g_file_get_for_commandline_arg (argv [1]); + + if (!is_dir (base_dir)) + { + g_printerr ("Scratch URI %s is not a directory\n", argv [1]); + g_object_unref (base_dir); + return 1; + } + + for (i = 0; i < ITERATIONS_NUM; i++) + { + scratch_file = create_file (base_dir); + if (!scratch_file) + { + g_object_unref (base_dir); + return 1; + } + + read_file (scratch_file); + delete_file (scratch_file); + + g_object_unref (scratch_file); + } + + g_object_unref (base_dir); + return 0; +} diff --git a/test/benchmark-posix-big-files.c b/test/benchmark-posix-big-files.c new file mode 100644 index 00000000..3c4dbfbf --- /dev/null +++ b/test/benchmark-posix-big-files.c @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <locale.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <glib.h> +#include <gio/gfile.h> + +#define BENCHMARK_UNIT_NAME "posix-big-file" + +#include "benchmark-common.c" + +#define FILE_SIZE (1024 * 1024 * 50) /* 50 MiB */ +#define BUFFER_SIZE 4096 +#define ITERATIONS_NUM 1 + +static gboolean +is_dir (const gchar *dir) +{ + struct stat sbuf; + + if (stat (dir, &sbuf) < 0) + return FALSE; + + if (S_ISDIR (sbuf.st_mode)) + return TRUE; + + return FALSE; +} + +static gchar * +create_file (const gchar *base_dir) +{ + gchar *scratch_file; + gchar *scratch_name; + gint output_fd; + gint pid; + GError *error = NULL; + gchar buffer [BUFFER_SIZE]; + gint i; + + pid = getpid (); + scratch_file = g_strdup_printf ("%s/posix-benchmark-scratch-%d", base_dir, pid); + + output_fd = open (scratch_file, O_WRONLY | O_CREAT | O_TRUNC, 0777); + if (output_fd < 0) + { + g_printerr ("Failed to create scratch file: %s\n", strerror (errno)); + g_free (scratch_file); + return NULL; + } + + memset (buffer, 0xaa, BUFFER_SIZE); + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + gint bytes_written; + + bytes_written = write (output_fd, buffer, BUFFER_SIZE); + if (bytes_written < BUFFER_SIZE) + { + if (errno == EINTR) + { + i -= BUFFER_SIZE - bytes_written; + continue; + } + + g_printerr ("Failed to populate scratch file: %s\n", strerror (errno)); + close (output_fd); + g_free (scratch_file); + return NULL; + } + } + + close (output_fd); + return scratch_file; +} + +static void +read_file (const gchar *scratch_file) +{ + gint input_fd; + GError *error = NULL; + gint i; + + input_fd = open (scratch_file, O_RDONLY); + if (input_fd < 0) + { + g_printerr ("Failed to read back scratch file: %s\n", strerror (errno)); + return; + } + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + gchar buffer [BUFFER_SIZE]; + gsize bytes_read; + + bytes_read = read (input_fd, buffer, BUFFER_SIZE); + if (bytes_read < BUFFER_SIZE) + { + if (errno == EINTR) + { + i -= BUFFER_SIZE - bytes_read; + continue; + } + + g_printerr ("Failed to read back scratch file: %s\n", strerror (errno)); + close (input_fd); + return; + } + } + + close (input_fd); +} + +static void +delete_file (const gchar *scratch_file) +{ + GError *error = NULL; + + if (unlink (scratch_file) < 0) + { + g_printerr ("Failed to delete scratch file: %s\n", strerror (errno)); + } +} + +static gint +benchmark_run (gint argc, gchar *argv []) +{ + gchar *base_dir; + gchar *scratch_file; + gint i; + + setlocale (LC_ALL, ""); + + g_type_init (); + + if (argc < 2) + { + g_printerr ("Usage: %s <scratch path>\n", argv [0]); + return 1; + } + + base_dir = argv [1]; + + if (!is_dir (base_dir)) + { + g_printerr ("Scratch path %s is not a directory\n", argv [1]); + return 1; + } + + for (i = 0; i < ITERATIONS_NUM; i++) + { + scratch_file = create_file (base_dir); + if (!scratch_file) + { + g_free (base_dir); + return 1; + } + + read_file (scratch_file); + delete_file (scratch_file); + + g_free (scratch_file); + } + + return 0; +} diff --git a/test/benchmark-posix-small-files.c b/test/benchmark-posix-small-files.c new file mode 100644 index 00000000..01d801ae --- /dev/null +++ b/test/benchmark-posix-small-files.c @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <locale.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <glib.h> +#include <gio/gfile.h> + +#define BENCHMARK_UNIT_NAME "posix-big-file" + +#include "benchmark-common.c" + +#define FILE_SIZE 4096 +#define BUFFER_SIZE 4096 +#define ITERATIONS_NUM 65536 + +static gboolean +is_dir (const gchar *dir) +{ + struct stat sbuf; + + if (stat (dir, &sbuf) < 0) + return FALSE; + + if (S_ISDIR (sbuf.st_mode)) + return TRUE; + + return FALSE; +} + +static gchar * +create_file (const gchar *base_dir) +{ + gchar *scratch_file; + gchar *scratch_name; + gint output_fd; + gint pid; + GError *error = NULL; + gchar buffer [BUFFER_SIZE]; + gint i; + + pid = getpid (); + scratch_file = g_strdup_printf ("%s/posix-benchmark-scratch-%d", base_dir, pid); + + output_fd = open (scratch_file, O_WRONLY | O_CREAT | O_TRUNC, 0777); + if (output_fd < 0) + { + g_printerr ("Failed to create scratch file: %s\n", strerror (errno)); + g_free (scratch_file); + return NULL; + } + + memset (buffer, 0xaa, BUFFER_SIZE); + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + gint bytes_written; + + bytes_written = write (output_fd, buffer, BUFFER_SIZE); + if (bytes_written < BUFFER_SIZE) + { + if (errno == EINTR) + { + i -= BUFFER_SIZE - bytes_written; + continue; + } + + g_printerr ("Failed to populate scratch file: %s\n", strerror (errno)); + close (output_fd); + g_free (scratch_file); + return NULL; + } + } + + close (output_fd); + return scratch_file; +} + +static void +read_file (const gchar *scratch_file) +{ + gint input_fd; + GError *error = NULL; + gint i; + + input_fd = open (scratch_file, O_RDONLY); + if (input_fd < 0) + { + g_printerr ("Failed to read back scratch file: %s\n", strerror (errno)); + return; + } + + for (i = 0; i < FILE_SIZE; i += BUFFER_SIZE) + { + gchar buffer [BUFFER_SIZE]; + gsize bytes_read; + + bytes_read = read (input_fd, buffer, BUFFER_SIZE); + if (bytes_read < BUFFER_SIZE) + { + if (errno == EINTR) + { + i -= BUFFER_SIZE - bytes_read; + continue; + } + + g_printerr ("Failed to read back scratch file: %s\n", strerror (errno)); + close (input_fd); + return; + } + } + + close (input_fd); +} + +static void +delete_file (const gchar *scratch_file) +{ + GError *error = NULL; + + if (unlink (scratch_file) < 0) + { + g_printerr ("Failed to delete scratch file: %s\n", strerror (errno)); + } +} + +static gint +benchmark_run (gint argc, gchar *argv []) +{ + gchar *base_dir; + gchar *scratch_file; + gint i; + + setlocale (LC_ALL, ""); + + g_type_init (); + + if (argc < 2) + { + g_printerr ("Usage: %s <scratch path>\n", argv [0]); + return 1; + } + + base_dir = argv [1]; + + if (!is_dir (base_dir)) + { + g_printerr ("Scratch path %s is not a directory\n", argv [1]); + return 1; + } + + for (i = 0; i < ITERATIONS_NUM; i++) + { + scratch_file = create_file (base_dir); + if (!scratch_file) + { + g_free (base_dir); + return 1; + } + + read_file (scratch_file); + delete_file (scratch_file); + + g_free (scratch_file); + } + + return 0; +} |