From: David Goulet Date: Tue, 6 Sep 2011 21:14:47 +0000 (-0400) Subject: Merge branch 'master' into benchmark X-Git-Url: http://git.lttng.org./?a=commitdiff_plain;h=73c251ae38aee62c5f71e26a62db54d69b4b9269;hp=28ba3f4e591845d044b329db5ac80e9558ed1fc8;p=lttng-tools.git Merge branch 'master' into benchmark --- diff --git a/.gitignore b/.gitignore index 08d44e8e8..37f95a402 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ tests/test_sessions tests/test_kernel_data_trace tests/kernel_all_events_basic tests/kernel_event_basic + +benchmark/bench_sessions diff --git a/Makefile.am b/Makefile.am index ec8b7fe95..8815acebe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ ACLOCAL_AMFLAGS = -I config -SUBDIRS = liblttng-sessiond-comm \ +SUBDIRS = benchmark \ + liblttng-sessiond-comm \ libkernelctl \ liblttngkconsumerd \ liblttngctl \ @@ -12,3 +13,6 @@ SUBDIRS = liblttng-sessiond-comm \ tests \ include \ doc + +bench: + ./benchmark/runall.sh diff --git a/benchmark/Makefile.am b/benchmark/Makefile.am new file mode 100644 index 000000000..59c88fe2f --- /dev/null +++ b/benchmark/Makefile.am @@ -0,0 +1,16 @@ +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 index 000000000..872b596b6 --- /dev/null +++ b/benchmark/bench-sessions.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011 David Goulet + * + * 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 +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/benchmark/benchmark.c b/benchmark/benchmark.c new file mode 100644 index 000000000..8fbe8ad78 --- /dev/null +++ b/benchmark/benchmark.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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. + */ + +#include +#include +#include +#include + +#include "benchmark.h" + +FILE *fp; +static double g_freq; + +static double calibrate_cpu_freq(void) +{ + int i, nb_calib = 10; + 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); +} + +static void open_logs(void) +{ + fp = fopen(RESULTS_FILE_NAME, "a"); + if (fp == NULL) { + perror("fopen benchmark"); + } +} + +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; + } + + return get_bench_time(time_destroy_session_start, time_destroy_session_end); +} + +/* + * Complete UST notification process time break down in different actions. + */ +void bench_print_ust_notification(void) +{ + double res, total = 0; + + fprintf(fp, "--- UST notification time ---\n"); + + if (time_ust_notify_mmap_start == 0 || time_ust_notify_mmap_stop == 0) { + goto no_data; + } + + res = get_bench_time(time_ust_notify_mmap_start, + time_ust_notify_mmap_stop); + fprintf(fp, "mmap() call time\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + if (time_ust_notify_perms_start == 0 || time_ust_notify_perms_stop == 0) { + goto no_data; + } + + res = get_bench_time(time_ust_notify_perms_start, + time_ust_notify_perms_stop); + fprintf(fp, "Setting permissions (chown/chmod)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + if (time_ust_notify_shm_start == 0 || time_ust_notify_shm_stop == 0) { + goto no_data; + } + + res = get_bench_time(time_ust_notify_shm_start, + time_ust_notify_shm_stop); + fprintf(fp, "shm_open/ftruncate/fchmod\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + fprintf(fp, "Global UST nonification time\n"); + fprintf(fp, "Time: %.20f sec.\n", total); + return; + +no_data: + fprintf(fp, "NO DATA\n"); + return; +} + +/* + * This time value is only coherent is an UST application registered. + */ +void bench_print_ust_register(void) +{ + double res, total = 0; + + fprintf(fp, "--- UST registration time ---\n"); + + if (time_ust_register_start == 0 || time_ust_register_stop == 0) { + goto no_data; + } + + res = get_bench_time(time_ust_register_start, time_ust_register_stop); + fprintf(fp, "UST registration received and send to dispatch time\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + if (time_ust_dispatch_register_start == 0 || + time_ust_dispatch_register_stop == 0) { + goto no_data; + } + + res = get_bench_time(time_ust_dispatch_register_start, + time_ust_dispatch_register_stop); + fprintf(fp, "Dispatch UST registration request time\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + fprintf(fp, "--> Manage registration breakdown\n"); + + res = get_bench_time(time_ust_register_read_start, + time_ust_register_read_stop); + fprintf(fp, "read() from pipe time\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + res = get_bench_time(time_ust_register_add_start, + time_ust_register_add_stop); + fprintf(fp, "register_traceable_app time\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + res = get_bench_time(time_ust_register_done_start, + time_ust_register_done_stop); + fprintf(fp, "send register done command time\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + total += res; + + fprintf(fp, "Global time of an UST application registration\n"); + fprintf(fp, "Time: %.20f sec.\n", total); + return; + +no_data: + fprintf(fp, "NO DATA\n"); + return; +} + + +/* + * 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 = get_bench_time(time_sessiond_boot_start, time_sessiond_boot_end); + + fprintf(fp, "Inside main() from start to first pthread_join" + "(blocking state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + res = get_bench_time(time_sessiond_th_kern_start, + time_sessiond_th_kern_poll); + + fprintf(fp, "Kernel thread from start to poll() (ready state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + res = get_bench_time(time_sessiond_th_apps_start, + time_sessiond_th_apps_poll); + + fprintf(fp, "Application thread from start to poll() (ready state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + res = get_bench_time(time_sessiond_th_cli_start, + time_sessiond_th_cli_poll); + + fprintf(fp, "Client thread from start to poll() (ready state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + res = get_bench_time(time_sessiond_th_dispatch_start, + time_sessiond_th_dispatch_block); + + fprintf(fp, "Dispatch registration thread from start to poll()" + "(ready state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + fprintf(fp, "Global Boot Time\n"); + fprintf(fp, "Time: %0.20f sec.\n", global_boot_time); +} diff --git a/benchmark/benchmark.h b/benchmark/benchmark.h new file mode 100644 index 000000000..2a23fd97e --- /dev/null +++ b/benchmark/benchmark.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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. + */ + +#ifndef _BENCHMARK_H +#define _BENCHMARK_H + +#include +#include + +#include "cpu.h" +#include "measures.h" + +#define RESULTS_FILE_NAME "/tmp/lttng-bench-results.txt" + +extern FILE *fp; + +void bench_init(void); +void bench_close(void); +void bench_print_boot_process(void); +void bench_print_ust_register(void); +void bench_print_ust_notification(void); +double bench_get_create_session(void); +double bench_get_destroy_session(void); + +#define record_cycles(name) \ + do { \ + time_##name = get_cycles(); \ + } while (0) + +#define tracepoint(name, args...) \ + do { \ + record_cycles(name); \ + } while (0) + +#endif /* _BENCHMARK_H */ diff --git a/benchmark/cpu.c b/benchmark/cpu.c new file mode 100644 index 000000000..02a8d99d3 --- /dev/null +++ b/benchmark/cpu.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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. + */ + +#include +#include +#include +#include + +#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; + struct timeval tvstart, tvstop; + cycles_t c_before, c_after; + unsigned long microseconds; + + memset(&tz, 0, sizeof(tz)); + + gettimeofday(&tvstart, &tz); + c_before = get_cycles(); + gettimeofday(&tvstart, &tz); + + sleep(1); + + gettimeofday(&tvstop, &tz); + c_after = get_cycles(); + gettimeofday(&tvstop, &tz); + + microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) + + (tvstop.tv_usec - tvstart.tv_usec); + + return (uint64_t) ((c_after - c_before) / microseconds); +} diff --git a/benchmark/cpu.h b/benchmark/cpu.h new file mode 100644 index 000000000..799ccdf30 --- /dev/null +++ b/benchmark/cpu.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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. + */ + +#ifndef _CPU_H +#define _CPU_H + +#include +#include + +uint64_t get_cpu_freq(void); +cycles_t get_cycles(void); + +#endif /* _CPU_H */ diff --git a/benchmark/hello b/benchmark/hello new file mode 100755 index 000000000..adbc00f14 --- /dev/null +++ b/benchmark/hello @@ -0,0 +1,148 @@ +#! /bin/bash + +# hello - temporary wrapper script for .libs/hello +# Generated by ltmain.sh (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1 +# +# The hello program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='/bin/sed -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command="(cd /home/dave/Documents/git/ust/tests/hello; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/home/dave/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/NX/bin; export PATH; gcc -Wall -g -O2 -o \$progdir/\$file hello.o tp.o ../../libust/.libs/libust.so -lurcu-bp -lpthread -ldl -Wl,-rpath -Wl,/home/dave/Documents/git/ust/libust/.libs)" + +# This environment variable determines our operation mode. +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then + # install mode needs the following variables: + generated_by_libtool_version='2.2.6b' + notinst_deplibs=' ../../libust/libust.la' +else + # When we are sourced in execute mode, $file and $ECHO are already set. + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + ECHO="echo" + file="$0" + # Make sure echo works. + if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then + # Yippee, $ECHO works! + : + else + # Restart under the correct shell, and then maybe $ECHO will work. + exec /bin/bash "$0" --no-reexec ${1+"$@"} + fi + fi + + # Find the directory that this script lives in. + thisdir=`$ECHO "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "x$thisdir" = "x$file" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'` + while test -n "$file"; do + destdir=`$ECHO "X$file" | $Xsed -e 's%/[^/]*$%%'` + + # If there was a directory component, then change thisdir. + if test "x$destdir" != "x$file"; then + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; + *) thisdir="$thisdir/$destdir" ;; + esac + fi + + file=`$ECHO "X$file" | $Xsed -e 's%^.*/%%'` + file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'` + done + + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no + if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then + # special case for '.' + if test "$thisdir" = "."; then + thisdir=`pwd` + fi + # remove .libs from thisdir + case "$thisdir" in + *[\\/].libs ) thisdir=`$ECHO "X$thisdir" | $Xsed -e 's%[\\/][^\\/]*$%%'` ;; + .libs ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=`cd "$thisdir" && pwd` + test -n "$absdir" && thisdir="$absdir" + + program=lt-'hello' + progdir="$thisdir/.libs" + + if test ! -f "$progdir/$program" || + { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \ + test "X$file" != "X$progdir/$program"; }; then + + file="$$-$program" + + if test ! -d "$progdir"; then + mkdir "$progdir" + else + rm -f "$progdir/$file" + fi + + # relink executable if necessary + if test -n "$relink_command"; then + if relink_command_output=`eval $relink_command 2>&1`; then : + else + echo "$relink_command_output" >&2 + rm -f "$progdir/$file" + exit 1 + fi + fi + + mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null || + { rm -f "$progdir/$program"; + mv -f "$progdir/$file" "$progdir/$program"; } + rm -f "$progdir/$file" + fi + + if test -f "$progdir/$program"; then + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + # Run the actual program with our arguments. + + exec "$progdir/$program" ${1+"$@"} + + $ECHO "$0: cannot exec $program $*" 1>&2 + exit 1 + fi + else + # The program doesn't exist. + $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2 + $ECHO "This script is just a wrapper for $program." 1>&2 + echo "See the libtool documentation for more information." 1>&2 + exit 1 + fi +fi diff --git a/benchmark/main.c b/benchmark/main.c new file mode 100644 index 000000000..1c176f84c --- /dev/null +++ b/benchmark/main.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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. + */ + +#include +#include +#include + +#include "benchmark.h" + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/benchmark/measures.h b/benchmark/measures.h new file mode 100644 index 000000000..91809e1ac --- /dev/null +++ b/benchmark/measures.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * 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. + */ + +#ifndef _MEASURES_H +#define _MEASURES_H + +/* Session daemon main() time */ +cycles_t time_sessiond_boot_start; +cycles_t time_sessiond_boot_end; + +/* Session daemon thread manage kconsumerd time */ +cycles_t time_sessiond_th_kcon_start; +cycles_t time_sessiond_th_kcon_poll; + +/* Session daemon thread manage kernel time */ +cycles_t time_sessiond_th_kern_start; +cycles_t time_sessiond_th_kern_poll; + +/* Session daemon thread manage apps time */ +cycles_t time_sessiond_th_apps_start; +cycles_t time_sessiond_th_apps_poll; + +/* Session daemon thread registration apps time */ +cycles_t time_sessiond_th_reg_start; +cycles_t time_sessiond_th_reg_poll; + +/* Session daemon thread registration apps time */ +cycles_t time_sessiond_th_dispatch_start; +cycles_t time_sessiond_th_dispatch_block; + +/* Session daemon thread manage client time */ +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; + +/* + * UST registration time + * + * Start time is taken *after* the poll() has detected activity on the apps + * socket and right *before* the accept(). There is a malloc() after that + * accept and then we recv() the request from the client. We need to measure + * the complete process. + */ +cycles_t time_ust_register_start; +/* + * The stop time is measured right after the futex() wake up. + */ +cycles_t time_ust_register_stop; + +/* + * UST dispatch registration request time + * + * Start time taken *after* the dequeue which is a blocking call. + */ +cycles_t time_ust_dispatch_register_start; +/* + * Stop time taken *before* the futex() wait so at this point, the registration + * was sent to the manage apps thread. + */ +cycles_t time_ust_dispatch_register_stop; + +/* + * UST managing registration time + */ +/* read() from pipe */ +cycles_t time_ust_register_read_start; +cycles_t time_ust_register_read_stop; +/* register_traceable_app() time */ +cycles_t time_ust_register_add_start; +cycles_t time_ust_register_add_stop; +/* send register done command */ +cycles_t time_ust_register_done_start; +cycles_t time_ust_register_done_stop; + +/* + * UST notification time (using the shm/futex scheme). Those times were break + * down in seperate time for each big action step. + * + * Start time taken *before* we create/get the SHM mmap. + */ +cycles_t time_ust_notify_apps_start; +/* + * Stop time taken after waiting all processes (futex_wait_update()). + */ +cycles_t time_ust_notify_apps_stop; +/* mmap() call */ +cycles_t time_ust_notify_mmap_start; +cycles_t time_ust_notify_mmap_stop; +/* Permissions time (chmod/chown) */ +cycles_t time_ust_notify_perms_start; +cycles_t time_ust_notify_perms_stop; +/* Fork process */ +cycles_t time_ust_notify_fork_start; +cycles_t time_ust_notify_fork_stop; +/* shm_open call */ +cycles_t time_ust_notify_shm_start; +cycles_t time_ust_notify_shm_stop; + +#endif /* _MEASURES_H */ diff --git a/benchmark/run-boot-time.sh b/benchmark/run-boot-time.sh new file mode 100755 index 000000000..bbf0edca0 --- /dev/null +++ b/benchmark/run-boot-time.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright (C) 2011 - David Goulet +# +# 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 "Starting session daemon" + +BENCH_BOOT_PROCESS=1 $BASEDIR/../ltt-sessiond/$SESSIOND_BIN -v >/dev/null 2>&1 & + +PID_SESSIOND=$! +if [ -z $PID_SESSIOND ]; then + echo -e '\e[1;31mFAILED\e[0m' + exit 1 +else + echo -e "\e[1;32mOK\e[0m" + echo "PID session daemon: $PID_SESSIOND" +fi + +# Wait for the benchmark to run +echo -n "Waiting." +sleep 1 +echo -n "." +sleep 1 +echo "." +sleep 1 + +kill $PID_SESSIOND + +wait $PID_SESSIOND + +echo "Benchmarks done in $RESULTS_PATH" + +exit 0 diff --git a/benchmark/run-sessions.sh b/benchmark/run-sessions.sh new file mode 100755 index 000000000..6db0c855c --- /dev/null +++ b/benchmark/run-sessions.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Copyright (C) 2011 - David Goulet +# +# 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 diff --git a/benchmark/run-ust-notify.sh b/benchmark/run-ust-notify.sh new file mode 100755 index 000000000..0759398d7 --- /dev/null +++ b/benchmark/run-ust-notify.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# +# Copyright (C) 2011 - David Goulet +# +# 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" + +BENCH_UST_NOTIFY=1 $BASEDIR/../ltt-sessiond/$SESSIOND_BIN -v >/dev/null 2>&1 & + +PID_SESSIOND=$! +if [ -z $PID_SESSIOND ]; then + echo -e '\e[1;31mFAILED\e[0m' + exit 1 +else + echo -e "\e[1;32mOK\e[0m" + echo "PID session daemon: $PID_SESSIOND" +fi + +kill $PID_SESSIOND + +wait $PID_SESSIOND + +exit 0 diff --git a/benchmark/run-ust-register.sh b/benchmark/run-ust-register.sh new file mode 100755 index 000000000..0640cfd72 --- /dev/null +++ b/benchmark/run-ust-register.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# +# Copyright (C) 2011 - David Goulet +# +# 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" +BENCH_UST_REGISTER=1 $BASEDIR/../ltt-sessiond/$SESSIOND_BIN -v >/dev/null 2>&1 & + +PID_SESSIOND=$! +if [ -z $PID_SESSIOND ]; then + echo -e '\e[1;31mFAILED\e[0m' + exit 1 +else + echo -e "\e[1;32mOK\e[0m" + echo "PID session daemon: $PID_SESSIOND" +fi + +# Wait for sessiond to settle +sleep 2 + +# Start libust instrumented application to register. +UST_AUTOPROBE=1 UST_TRACE=1 ./$BASEDIR/hello + +kill $PID_SESSIOND + +wait $PID_SESSIOND + +exit 0 diff --git a/benchmark/runall.sh b/benchmark/runall.sh new file mode 100755 index 000000000..037ac9e3e --- /dev/null +++ b/benchmark/runall.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Copyright (C) 2011 - David Goulet +# +# 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. +# + +#### ADD TESTS HERE #### + +test_suite=( "run-boot-time.sh" "run-sessions.sh" "run-ust-register.sh" \ + "run-ust-notify.sh" ) + +#### END TESTS HERE #### + +RESULTS_PATH="/tmp/lttng-bench-results.txt" +BASEDIR=`dirname $0` + +if [ -e $RESULTS_PATH ]; then + mv -v $RESULTS_PATH "$RESULTS_PATH.`date +%s`.txt" +fi + +echo "" + +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 index 000000000..52893b207 --- /dev/null +++ b/benchmark/utils.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 David Goulet + * + * 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 + +#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); diff --git a/configure.ac b/configure.ac index f30b8329d..c1bff453f 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,11 @@ AC_CHECK_DECL([cds_list_add], [], [AC_MSG_ERROR([liburcu $liburcu_version or newer is needed])], [[#include ]] ) +# Check liburcu +AC_CHECK_DECL([caa_get_cycles], [], + [AC_MSG_ERROR([liburcu liburcu_version or newer is needed])], [[#include ]] +) + AC_CHECK_DECL([cds_wfq_init], [], [AC_MSG_ERROR([liburcu $liburcu_version or newer is needed])], [[#include ]] ) @@ -53,6 +58,7 @@ AC_SUBST(DEFAULT_INCLUDES) AC_CONFIG_FILES([ Makefile include/Makefile + benchmark/Makefile libkernelctl/Makefile liblttngkconsumerd/Makefile liblttngctl/Makefile diff --git a/ltt-sessiond/Makefile.am b/ltt-sessiond/Makefile.am index d19fe3caa..2109fbf52 100644 --- a/ltt-sessiond/Makefile.am +++ b/ltt-sessiond/Makefile.am @@ -1,5 +1,5 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -DINSTALL_BIN_PATH=\""$(bindir)"\" +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/benchmark \ + -DINSTALL_BIN_PATH=\"$(bindir)\" AM_CFLAGS = -fno-strict-aliasing @@ -23,4 +23,5 @@ ltt_sessiond_LDADD = -lrt \ $(top_builddir)/liblttng-sessiond-comm/liblttng-sessiond-comm.la \ $(top_builddir)/libkernelctl/libkernelctl.la \ $(top_builddir)/libustctl/libustctl.la \ - $(top_builddir)/liblttngctl/liblttngctl.la + $(top_builddir)/liblttngctl/liblttngctl.la \ + $(top_builddir)/benchmark/liblttng-benchmark.la diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index c9522d697..3395d4cf8 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -54,6 +54,8 @@ #include "utils.h" #include "ust-ctl.h" +#include "benchmark.h" + /* Const values */ const char default_home_dir[] = DEFAULT_HOME_DIR; const char default_tracing_group[] = LTTNG_DEFAULT_TRACING_GROUP; @@ -297,6 +299,24 @@ static void cleanup(void) DBG("Unloading kernel modules"); modprobe_remove_kernel_modules(); } + + /* OUTPUT BENCHMARK RESULTS */ + bench_init(); + + if (getenv("BENCH_UST_NOTIFY")) { + bench_print_ust_notification(); + } + + if (getenv("BENCH_UST_REGISTER")) { + bench_print_ust_register(); + } + + if (getenv("BENCH_BOOT_PROCESS")) { + bench_print_boot_process(); + } + + bench_close(); + /* END BENCHMARK */ } /* @@ -455,6 +475,8 @@ static int notify_ust_apps(int active) DBG("Notifying applications of session daemon state: %d", active); + tracepoint(ust_notify_apps_start); + /* See shm.c for this call implying mmap, shm and futex calls */ wait_shm_mmap = shm_ust_get_mmap(wait_shm_path, is_root); if (wait_shm_mmap == NULL) { @@ -464,6 +486,8 @@ static int notify_ust_apps(int active) /* Wake waiting process */ futex_wait_update((int32_t *) wait_shm_mmap, active); + tracepoint(ust_notify_apps_stop); + /* Apps notified successfully */ return 0; @@ -647,6 +671,8 @@ static void *thread_manage_kernel(void *data) char tmp; int update_poll_flag = 1; + tracepoint(sessiond_th_kern_start); + DBG("Thread manage kernel started"); while (1) { @@ -660,6 +686,8 @@ static void *thread_manage_kernel(void *data) DBG("Polling on %d fds", nb_fd); + tracepoint(sessiond_th_kern_poll); + /* Poll infinite value of time */ ret = poll(kernel_pollfd, nb_fd, -1); if (ret < 0) { @@ -728,6 +756,8 @@ static void *thread_manage_kconsumerd(void *data) enum lttcomm_return_code code; struct pollfd pollfd[2]; + tracepoint(sessiond_th_kcon_start); + DBG("[thread] Manage kconsumerd started"); ret = lttcomm_listen_unix_sock(kconsumerd_err_sock); @@ -742,6 +772,8 @@ static void *thread_manage_kconsumerd(void *data) pollfd[1].fd = kconsumerd_err_sock; pollfd[1].events = POLLIN; + tracepoint(sessiond_th_kcon_poll); + /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, 2, -1); if (ret < 0) { @@ -905,6 +937,8 @@ static void *thread_manage_apps(void *data) struct pollfd *pollfd = NULL; struct ust_command ust_cmd; + tracepoint(sessiond_th_apps_start); + DBG("[thread] Manage application started"); ust_cmd.sock = -1; @@ -936,6 +970,8 @@ static void *thread_manage_apps(void *data) DBG("Apps thread polling on %d fds", nb_fd); + tracepoint(sessiond_th_apps_poll); + /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, nb_fd, -1); if (ret < 0) { @@ -953,6 +989,8 @@ static void *thread_manage_apps(void *data) ERR("Apps command pipe poll error"); goto error; case POLLIN: + tracepoint(ust_register_read_start); + /* Empty pipe */ ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd)); if (ret < 0 || ret < sizeof(ust_cmd)) { @@ -960,13 +998,18 @@ static void *thread_manage_apps(void *data) goto error; } + tracepoint(ust_register_read_stop); + + tracepoint(ust_register_add_start); /* Register applicaton to the session daemon */ ret = register_traceable_app(&ust_cmd.reg_msg, ust_cmd.sock); if (ret < 0) { /* Only critical ENOMEM error can be returned here */ goto error; } + tracepoint(ust_register_add_stop); + tracepoint(ust_register_done_start); ret = ustctl_register_done(ust_cmd.sock); if (ret < 0) { /* @@ -975,6 +1018,8 @@ static void *thread_manage_apps(void *data) */ unregister_traceable_app(ust_cmd.sock); } + + tracepoint(ust_register_done_stop); break; } } @@ -1020,6 +1065,8 @@ static void *thread_dispatch_ust_registration(void *data) struct cds_wfq_node *node; struct ust_command *ust_cmd = NULL; + tracepoint(sessiond_th_dispatch_start); + DBG("[thread] Dispatch UST command started"); while (!dispatch_thread_exit) { @@ -1027,6 +1074,8 @@ static void *thread_dispatch_ust_registration(void *data) futex_nto1_prepare(&ust_cmd_queue.futex); do { + tracepoint(sessiond_th_dispatch_block); + /* Dequeue command for registration */ node = cds_wfq_dequeue_blocking(&ust_cmd_queue.queue); if (node == NULL) { @@ -1035,6 +1084,8 @@ static void *thread_dispatch_ust_registration(void *data) break; } + tracepoint(ust_dispatch_register_start); + ust_cmd = caa_container_of(node, struct ust_command, node); DBG("Dispatching UST registration pid:%d ppid:%d uid:%d" @@ -1065,6 +1116,8 @@ static void *thread_dispatch_ust_registration(void *data) free(ust_cmd); } while (node != NULL); + tracepoint(ust_dispatch_register_stop); + /* Futex wait on queue. Blocking call on futex() */ futex_nto1_wait(&ust_cmd_queue.futex); } @@ -1087,6 +1140,8 @@ static void *thread_registration_apps(void *data) */ struct ust_command *ust_cmd = NULL; + tracepoint(sessiond_th_reg_start); + DBG("[thread] Manage application registration started"); ret = lttcomm_listen_unix_sock(apps_sock); @@ -1112,6 +1167,8 @@ static void *thread_registration_apps(void *data) while (1) { DBG("Accepting application registration"); + tracepoint(sessiond_th_reg_poll); + /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, 2, -1); if (ret < 0) { @@ -1127,6 +1184,9 @@ static void *thread_registration_apps(void *data) goto error; } + /* Registration starts here. Recording cycles */ + tracepoint(ust_register_start); + sock = lttcomm_accept_unix_sock(apps_sock); if (sock < 0) { goto error; @@ -1175,6 +1235,8 @@ static void *thread_registration_apps(void *data) * Implicit memory barrier with the exchange in cds_wfq_enqueue. */ futex_nto1_wake(&ust_cmd_queue.futex); + + tracepoint(ust_register_stop); } error: @@ -2341,7 +2403,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; @@ -2365,7 +2429,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; @@ -2601,6 +2667,8 @@ static void *thread_manage_clients(void *data) struct command_ctx *cmd_ctx = NULL; struct pollfd pollfd[2]; + tracepoint(sessiond_th_cli_start); + DBG("[thread] Manage client started"); ret = lttcomm_listen_unix_sock(client_sock); @@ -2625,6 +2693,8 @@ static void *thread_manage_clients(void *data) while (1) { DBG("Accepting client command ..."); + tracepoint(sessiond_th_cli_poll); + /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, 2, -1); if (ret < 0) { @@ -3104,6 +3174,8 @@ int main(int argc, char **argv) void *status; const char *home_path; + tracepoint(sessiond_boot_start); + /* Create thread quit pipe */ if ((ret = init_thread_quit_pipe()) < 0) { goto error; @@ -3287,6 +3359,8 @@ int main(int argc, char **argv) goto exit_kernel; } + tracepoint(sessiond_boot_end); + ret = pthread_join(kernel_thread, &status); if (ret != 0) { perror("pthread_join"); diff --git a/ltt-sessiond/shm.c b/ltt-sessiond/shm.c index 7dac1659f..1ccaec5d8 100644 --- a/ltt-sessiond/shm.c +++ b/ltt-sessiond/shm.c @@ -28,6 +28,8 @@ #include +#include "benchmark.h" +#include "measures.h" #include "shm.h" /* @@ -43,6 +45,8 @@ static int get_wait_shm(char *shm_path, size_t mmap_size, int global) int wait_shm_fd, ret; mode_t mode; + tracepoint(ust_notify_perms_start); + /* Default permissions */ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; @@ -88,6 +92,9 @@ static int get_wait_shm(char *shm_path, size_t mmap_size, int global) */ umask(~mode); + tracepoint(ust_notify_perms_stop); + + tracepoint(ust_notify_shm_start); /* * Try creating shm (or get rw access). We don't do an exclusive open, * because we allow other processes to create+ftruncate it concurrently. @@ -110,6 +117,8 @@ static int get_wait_shm(char *shm_path, size_t mmap_size, int global) exit(EXIT_FAILURE); } + tracepoint(ust_notify_shm_stop); + DBG("Got the wait shm fd %d", wait_shm_fd); return wait_shm_fd; @@ -139,9 +148,12 @@ char *shm_ust_get_mmap(char *shm_path, int global) goto error; } + tracepoint(ust_notify_mmap_start); + wait_shm_mmap = mmap(NULL, mmap_size, PROT_WRITE | PROT_READ, MAP_SHARED, wait_shm_fd, 0); + tracepoint(ust_notify_mmap_stop); /* close shm fd immediately after taking the mmap reference */ ret = close(wait_shm_fd); if (ret) {