Improve benchmark systems and add create/destroy session
authorDavid Goulet <david.goulet@polymtl.ca>
Tue, 23 Aug 2011 17:19:29 +0000 (13:19 -0400)
committerDavid Goulet <david.goulet@polymtl.ca>
Tue, 23 Aug 2011 17:19:29 +0000 (13:19 -0400)
Signed-off-by: David Goulet <david.goulet@polymtl.ca>
13 files changed:
.gitignore
benchmark/Makefile.am
benchmark/bench-sessions.c [new file with mode: 0644]
benchmark/benchmark.c
benchmark/benchmark.h
benchmark/cpu.c
benchmark/measures.h
benchmark/run-boot-time.sh [new file with mode: 0755]
benchmark/run-sessions.sh [new file with mode: 0755]
benchmark/runall.sh
benchmark/utils.h [new file with mode: 0644]
configure.ac
ltt-sessiond/main.c

index 08d44e8e8fcbc53c0f94776e2efd896e3605a5f8..37f95a4022dcf35e6b384a1bbdedc2c5495b9bbb 100644 (file)
@@ -34,3 +34,5 @@ tests/test_sessions
 tests/test_kernel_data_trace
 tests/kernel_all_events_basic
 tests/kernel_event_basic
+
+benchmark/bench_sessions
index d1a353df0d37ef85f0e29c6b529fc84f6a7d3920..59c88fe2fd45bf418b6a0293d504032413379aec 100644 (file)
@@ -2,7 +2,15 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
 
 noinst_LTLIBRARIES = liblttng-benchmark.la
 
+noinst_PROGRAMS = bench_sessions
+
+UTILS=utils.h
+SESSIONS=$(top_srcdir)/ltt-sessiond/session.c
+
 liblttng_benchmark_la_SOURCES = benchmark.c benchmark.h cpu.c cpu.h
 
+bench_sessions_SOURCES = bench-sessions.c $(SESSIONS) $(UTILS)
+bench_sessions_LDADD = $(top_builddir)/benchmark/liblttng-benchmark.la
+
 bench:
        ./runall.sh
diff --git a/benchmark/bench-sessions.c b/benchmark/bench-sessions.c
new file mode 100644 (file)
index 0000000..872b596
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c)  2011 David Goulet <david.goulet@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * as published by the Free Software Foundation; only version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "ltt-sessiond/session.h"
+#include "utils.h"
+#include "benchmark.h"
+
+#define SESSION1 "test1"
+
+/* This path will NEVER be created in this test */
+#define PATH1 "/tmp/.test-junk-lttng"
+
+/* For lttngerr.h */
+int opt_quiet = 1;
+int opt_verbose = 0;
+
+static const char alphanum[] =
+       "0123456789"
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+       "abcdefghijklmnopqrstuvwxyz";
+
+/*
+ * Return random string of 10 characters.
+ */
+static char *get_random_string(void)
+{
+       int i;
+       char *str = malloc(11);
+
+       for (i = 0; i < 10; i++) {
+               str[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
+       }
+
+       str[10] = '\0';
+
+       return str;
+}
+
+int main(int argc, char **argv)
+{
+       int ret, i, nb_iter;
+       char **names;
+       double value, total = 0;
+
+       if (getuid() != 0) {
+               printf("Aborting test. Must be uid 0 to drop_caches\n");
+               return 1;
+       }
+
+       if (argc < 2) {
+               printf("Missing arguments\n");
+               return 1;
+       }
+
+       nb_iter = atoi(argv[1]);
+
+       names = malloc(sizeof(char*) * nb_iter);
+
+       srand(time(NULL));
+       bench_init();
+
+       fprintf(fp, "--- Create tracing session ---\n");
+       for (i = 0; i < nb_iter; i++) {
+               names[i] = get_random_string();
+               ret = system("echo 3 >/proc/sys/vm/drop_caches");
+               tracepoint(create_session_start);
+               ret = create_session(names[i], PATH1);
+               tracepoint(create_session_end);
+               if (ret < 0) {
+                       printf("Create session went wrong. Aborting\n");
+                       goto error;
+               }
+               value = bench_get_create_session();
+               fprintf(fp, "%.20f\n", value);
+               total += value;
+       }
+
+       fprintf(fp, "--> Average: %.20f\n\n", total/nb_iter);
+       total = 0;
+
+       fprintf(fp, "--- Destroy tracing session ---\n");
+       for (i = 0; i < nb_iter; i++) {
+               ret = system("echo 3 >/proc/sys/vm/drop_caches");
+               tracepoint(destroy_session_start);
+               ret = destroy_session(names[i]);
+               tracepoint(destroy_session_end);
+               if (ret < 0) {
+                       printf("Destroy session went wrong. Aborting\n");
+                       goto error;
+               }
+               value = bench_get_destroy_session();
+               fprintf(fp, "%.20f\n", value);
+               total += value;
+               free(names[i]);
+       }
+       fprintf(fp, "--> Average: %.20f\n\n", total/nb_iter);
+
+       /* Success */
+       bench_close();
+       return 0;
+
+error:
+       bench_close();
+       free(names);
+
+       return 1;
+}
index 72a75c6198e5f948bb3728b8e7fcac81b2c2ecd0..eda40b2156737ae83e19c20f2611179a9e341f86 100644 (file)
 
 #include "benchmark.h"
 
-static FILE *fp;
+FILE *fp;
+static double g_freq;
 
-void benchmark_print_boot_results(void)
+static double calibrate_cpu_freq(void)
 {
-       uint64_t freq = 0;
-       double res;
        int i, nb_calib = 10;
-       double global_boot_time = 0.0;
+       double freq;
+
+       printf("CPU frequency calibration, this should take 10 seconds\n");
+
+       /* CPU Frequency calibration */
+       for (i = 0; i < nb_calib; i++) {
+               freq += (double) get_cpu_freq();
+       }
+       return (freq / (double)nb_calib);
+}
+
+static void close_logs(void)
+{
+       fclose(fp);
+}
 
-       fp = fopen(RESULTS_FILE_NAME, "w");
+static void open_logs(void)
+{
+       fp = fopen(RESULTS_FILE_NAME, "a");
        if (fp == NULL) {
                perror("fopen benchmark");
-               return;
        }
+}
 
-       /* CPU Frequency calibration */
-       for (i = 0; i < nb_calib; i++) {
-               freq += get_cpu_freq();
+static double get_bench_time(cycles_t before, cycles_t after)
+{
+       double ret;
+
+       ret = (((double)(after - before) / (g_freq / 1000.0)) / 1000000000.0);
+
+       return ret;
+}
+
+void bench_init(void)
+{
+       open_logs();
+       if (g_freq == 0) {
+               g_freq = calibrate_cpu_freq();
+               //fprintf(fp, "CPU frequency %f Ghz\n\n", g_freq);
+       }
+}
+
+void bench_close(void)
+{
+       close_logs();
+       printf("Benchmark results in %s\n", RESULTS_FILE_NAME);
+}
+
+double bench_get_create_session(void)
+{
+       if ((time_create_session_start == 0) &&
+                       (time_create_session_end == 0)) {
+               fprintf(fp, "NO DATA\n");
+               return 0;
+       }
+
+       return get_bench_time(time_create_session_start, time_create_session_end);
+}
+
+double bench_get_destroy_session(void)
+{
+       if ((time_destroy_session_start == 0) &&
+                       (time_destroy_session_end == 0)) {
+               fprintf(fp, "NO DATA\n");
+               return 0;
        }
-       freq = freq / nb_calib;
 
-       fprintf(fp, "CPU frequency %lu Ghz\n\n", freq);
+       return get_bench_time(time_destroy_session_start, time_destroy_session_end);
+}
 
-       fprintf(fp, "Results:\n----------\n");
+/*
+ * Log results of the sessiond boot process.
+ *
+ * Uses all time_sessiond_* values (see measures.h)
+ */
+void bench_print_boot_process(void)
+{
+       double res;
+       double global_boot_time = 0.0;
+
+       fprintf(fp, "--- Session daemon boot process ---\n");
 
-       res = (double) (((double)(time_sessiond_boot_end - time_sessiond_boot_start)
-                               / (((double)freq) / 1000)) / 1000000000);
+       res = get_bench_time(time_sessiond_boot_start, time_sessiond_boot_end);
 
        fprintf(fp, "Boot time inside main() from start to first pthread_join (blocking state)\n");
        fprintf(fp, "Time: %.20f sec.\n", res);
 
        global_boot_time += res;
 
-       res = (double) (((double)(time_sessiond_th_kern_poll - time_sessiond_th_kern_start)
-                               / (((double)freq) / 1000)) / 1000000000);
+       res = get_bench_time(time_sessiond_th_kern_start, time_sessiond_th_kern_poll);
 
        fprintf(fp, "Boot time of the kernel thread from start to poll() (ready state)\n");
        fprintf(fp, "Time: %.20f sec.\n", res);
 
        global_boot_time += res;
 
-       res = (double) (((double)(time_sessiond_th_apps_poll - time_sessiond_th_apps_start)
-                               / (((double)freq) / 1000)) / 1000000000);
+       res = get_bench_time(time_sessiond_th_apps_start, time_sessiond_th_apps_poll);
 
        fprintf(fp, "Boot time of the application thread from start to poll() (ready state)\n");
        fprintf(fp, "Time: %.20f sec.\n", res);
 
        global_boot_time += res;
 
-       res = (double) (((double)(time_sessiond_th_cli_poll - time_sessiond_th_cli_start)
-                               / (((double)freq) / 1000)) / 1000000000);
+       res = get_bench_time(time_sessiond_th_cli_start, time_sessiond_th_cli_poll);
 
        fprintf(fp, "Boot time of the client thread from start to poll() (ready state)\n");
        fprintf(fp, "Time: %.20f sec.\n", res);
@@ -81,6 +140,4 @@ void benchmark_print_boot_results(void)
        global_boot_time += res;
 
        fprintf(fp, "Global Boot Time of ltt-sessiond: %0.20f sec.\n", global_boot_time);
-
-       fclose(fp);
 }
index 6232dee8c51aa46f87a97086496248c005d3878f..c02822e80ff722db5fc4b417edfcfbbe515f3f5c 100644 (file)
 
 #define RESULTS_FILE_NAME "/tmp/lttng-bench-results.txt"
 
-void benchmark_print_boot_results(void);
+extern FILE *fp;
 
-#define record_cycles(name) \
-       time_##name = get_cycles();
+void bench_init(void);
+void bench_close(void);
+void bench_print_boot_process(void);
+double bench_get_create_session(void);
+double bench_get_destroy_session(void);
 
-#define tracepoint(name, args...)              \
-       do {                                                            \
-               record_cycles(name);                    \
+#define record_cycles(name)             \
+       do {                                \
+               time_##name = get_cycles();     \
+       } while (0)
+
+#define tracepoint(name, args...)       \
+       do {                                \
+               record_cycles(name);            \
        } while (0)
 
 #endif /* _BENCHMARK_H */
index efaea387874eef4dff3db4065d6328824d9677ff..02a8d99d3545af818cb1ffeeca1841d0d3b826be 100644 (file)
 
 #include "cpu.h"
 
+/*
+ * Return cpu cycle counter
+ */
 cycles_t get_cycles(void)
 {
        return caa_get_cycles();
 }
 
+/*
+ * Calculate CPU frequency.
+ */
 uint64_t get_cpu_freq(void)
 {
        struct timezone tz;
index 80cb16780f60482ab556472524a8db100fd4ddb5..f67f1c49b2dc0dd6a0633a0002ab413256b10de7 100644 (file)
@@ -39,4 +39,12 @@ cycles_t time_sessiond_th_apps_poll;
 cycles_t time_sessiond_th_cli_start;
 cycles_t time_sessiond_th_cli_poll;
 
+/* Create tracing session values */
+cycles_t time_create_session_start;
+cycles_t time_create_session_end;
+
+/* Destroy tracing session values */
+cycles_t time_destroy_session_start;
+cycles_t time_destroy_session_end;
+
 #endif /* _MEASURES_H */
diff --git a/benchmark/run-boot-time.sh b/benchmark/run-boot-time.sh
new file mode 100755 (executable)
index 0000000..dabb707
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+SESSIOND_BIN="ltt-sessiond"
+RESULTS_PATH="/tmp/lttng-bench-results.txt"
+BASEDIR=`dirname $0`
+
+echo "Session daemon boot process benchmark"
+
+$BASEDIR/../ltt-sessiond/$SESSIOND_BIN --daemonize --quiet
+if [ $? -ne 0 ]; then
+       echo -e '\e[1;31mFAILED\e[0m'
+       exit 1
+else
+       echo -e "\e[1;32mOK\e[0m"
+fi
+
+PID_SESSIOND=`pidof lt-$SESSIOND_BIN`
+
+# Wait for the benchmark to run
+echo -n "Waiting."
+sleep 1
+echo -n "."
+sleep 1
+echo -n "."
+sleep 1
+
+kill $PID_SESSIOND
+
+echo -e "\nResults will be available shortly in $RESULTS_PATH"
+echo ""
+
+tail -F $RESULTS_PATH --pid $PID_SESSIOND 2>/dev/null
+
+exit 0
diff --git a/benchmark/run-sessions.sh b/benchmark/run-sessions.sh
new file mode 100755 (executable)
index 0000000..6db0c85
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+RESULTS_PATH="/tmp/lttng-bench-results.txt"
+BASEDIR=`dirname $0`
+NR_ITER=100
+
+echo "Create/Destroy benchmarking..."
+
+$BASEDIR/bench_sessions $NR_ITER
+
+exit 0
index 51e9f4d53997d13fa04869486becc6060c41ea79..eaf4980b8540e41e76f2360f69297610685a4221 100755 (executable)
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #
 
-SESSIOND_BIN="ltt-sessiond"
+#### ADD TESTS HERE ####
+
+test_suite=( "run-boot-time.sh" "run-sessions.sh" )
+
+#### END TESTS HERE ####
+
 RESULTS_PATH="/tmp/lttng-bench-results.txt"
 BASEDIR=`dirname $0`
 
 if [ -e $RESULTS_PATH ]; then
-       mv $RESULTS_PATH $RESULTS_PATH.`date +%s`
-fi
-
-echo -n "Starting session daemon... "
-$BASEDIR/../ltt-sessiond/$SESSIOND_BIN --daemonize --quiet
-if [ $? -ne 0 ]; then
-       echo -e '\e[1;31mFAILED\e[0m'
-       exit 1
-else
-       echo -e "\e[1;32mOK\e[0m"
+       mv -v $RESULTS_PATH $RESULTS_PATH.`date +%s`
 fi
 
-PID_SESSIOND=`pidof lt-$SESSIOND_BIN`
-
-# Wait for the benchmark to run
-echo -n "Waiting."
-sleep 1
-echo -n "."
-sleep 1
-echo -n "."
-sleep 1
-
-kill $PID_SESSIOND
-
-echo -e "\nResults will be available shortly in $RESULTS_PATH"
 echo ""
 
-tail -F $RESULTS_PATH --pid $PID_SESSIOND 2>/dev/null
+for bin in ${test_suite[@]};
+do
+       $BASEDIR/$bin
+       # Test must return 0 to pass.
+       if [ $? -ne 0 ]; then
+               echo -e '\e[1;31mFAIL\e[0m'
+               echo ""
+               exit 1
+       fi
+       echo ""
+done
+
+mv -v $RESULTS_PATH results-`date +%d%m%Y.%H%M%S`.txt
 
 exit 0
diff --git a/benchmark/utils.h b/benchmark/utils.h
new file mode 100644 (file)
index 0000000..52893b2
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c)  2011 David Goulet <david.goulet@polymtl.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * as published by the Free Software Foundation; only version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+
+#define BRIGHT 1
+#define GREEN 32
+#define RED 31
+
+#define PRINT_OK() printf("%c[%d;%dmOK%c[%dm\n", 0x1B, BRIGHT, GREEN, 0x1B, 0);
+#define PRINT_FAIL() printf("%c[%d;%dmFAIL%c[%dm\n", 0x1B, BRIGHT, RED, 0x1B, 0);
index 24c1b7cb10aed70bcda670869b85a0eac469afda..7af39997a47de01d8e0488757da01b23bcbd9fc1 100644 (file)
@@ -27,6 +27,11 @@ AC_CHECK_DECL([cds_list_add], [],
        [AC_MSG_ERROR([liburcu 0.5.4 or newer is needed])], [[#include <urcu/list.h>]]
 )
 
+# Check liburcu
+AC_CHECK_DECL([caa_get_cycles], [],
+       [AC_MSG_ERROR([liburcu 0.5.4 or newer is needed])], [[#include <urcu/arch.h>]]
+)
+
 AC_PROG_CC
 AC_PROG_LIBTOOL
 
index ab6d315f317fc8965675d1e6962b8b35d55fd75c..8d9cfdfbcf31535aa2ee8b7127471fef07247116 100644 (file)
@@ -234,7 +234,13 @@ static void cleanup(void)
        DBG("Unloading kernel modules");
        modprobe_remove_kernel_modules();
 
-       benchmark_print_boot_results();
+       /* OUTPUT BENCHMARK RESULTS */
+       bench_init();
+
+       bench_print_boot_process();
+
+       bench_close();
+       /* END BENCHMARK */
 }
 
 /*
@@ -2073,7 +2079,9 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                        goto setup_error;
                }
 
+               tracepoint(create_session_start);
                ret = create_session(cmd_ctx->lsm->session.name, cmd_ctx->lsm->session.path);
+               tracepoint(create_session_end);
                if (ret < 0) {
                        if (ret == -EEXIST) {
                                ret = LTTCOMM_EXIST_SESS;
@@ -2097,7 +2105,9 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                /* Clean kernel session teardown */
                teardown_kernel_session(cmd_ctx->session);
 
+               tracepoint(destroy_session_start);
                ret = destroy_session(cmd_ctx->lsm->session.name);
+               tracepoint(destroy_session_end);
                if (ret < 0) {
                        ret = LTTCOMM_FATAL;
                        goto error;
This page took 0.035828 seconds and 4 git commands to generate.