#!/bin/bash

P=perfbuild-install
DEFAULT_VERSION=4.1
. $SHELLPACK_INCLUDE/common.sh
TIME_CMD=`which time`
if [ "$TIME_CMD" = "" ]; then
        TIMEFORMAT="%2Uuser %2Ssystem %Relapsed %P%%CPU"
        TIME_CMD="time"
fi
WEB_LOCATION="https://www.kernel.org/pub/linux/kernel/v4.x"
MIRROR_LOCATION="$WEBROOT/linux/"

install-depends python3-devel bison flex

# Basic argument parser
TASKSET_SERVER=
TASKSET_CLIENT=
TASKSET_ALL=
SERVERSIDE_COMMAND=none
SERVERSIDE_NAME=`date +%Y%m%d-%H%M-%S`

while [ "$1" != "" ]; do
	case "$1" in
	-v)
		VERSION=$2
		shift 2
		;;
	--serverside-command)
		SERVERSIDE_COMMAND=$2
		shift 2
		;;
	--serverside-name)
		SERVERSIDE_NAME=$2
		shift 2
		;;
	--install-only)
		INSTALL_ONLY=yes
		shift
		;;
	--install-force)
		INSTALL_FORCE=yes
		shift
		;;
	*)
		echo Unrecognised option: $1
		shift
	esac
done
if [ "$TASKSET_SERVER" != "" ]; then
	echo TASKSET_SERVER: $TASKSET_SERVER
	echo TASKSET_CLIENT: $TASKSET_CLIENT
fi
if [ -z "$VERSION" ]; then
	VERSION=$DEFAULT_VERSION
fi

# Unconditionally fetch the tar to find out the real version number
TARFILE=linux-${VERSION}.tar.xz
sources_fetch $WEB_LOCATION/$TARFILE $MIRROR_LOCATION/$TARFILE $SHELLPACK_SOURCES/$TARFILE $WEB_LOCATION_ALT/$TARFILE
cd $SHELLPACK_SOURCES
tar -xf $TARFILE
if [ $? -ne 0 ]; then
	error "$P: tar xf linux-${VERSION}.tar.xz failed"
	popd > /dev/null
	exit $SHELLPACK_ERROR
fi

# Rename directory to something we expect.
DST_DIR=`tar tf $TARFILE | head -n 1 | awk -F / '{print $1}'`
mv $DST_DIR perfbuild-${VERSION}
pushd perfbuild-${VERSION} > /dev/null || die Failed to rename tar
pushd $SHELLPACK_SOURCES/perfbuild-${VERSION} || die Failed to change to source directory
for FILE in `find -name "*"`; do
	touch $FILE
done

if [ "$PERFBUILD_ADD_SYSCALL" = "yes" ]; then
LINESTART=`grep -n "==== BEGIN 0001-perf-add-syscall-benchmark.patch" $0 | tail -1 | awk -F : '{print $1}'`
LINEEND=`grep -n "==== END 0001-perf-add-syscall-benchmark.patch" $0 | tail -1 | awk -F : '{print $1}'`
if [ "$LINEEND" = "" ]; then
	LINECOUNT=`wc -l $0 | awk '{print $1}'`
fi
if [ "$LINESTART" = "" ]; then
	die Failed to find start of file 0001-perf-add-syscall-benchmark.patch
fi
echo Extracting $SHELLPACK_TEMP/0001-perf-add-syscall-benchmark.patch
sed -n $((LINESTART+1)),$((LINEEND-1))p $0 > $SHELLPACK_TEMP/0001-perf-add-syscall-benchmark.patch
	patch -p1 < $SHELLPACK_TEMP/0001-perf-add-syscall-benchmark.patch || die "Failed to apply perf add syscall patch"
fi

pushd $SHELLPACK_SOURCES/perfbuild-${VERSION}/tools/perf || die Failed to change to source directory
for FILE in `find -name "*"`; do
	touch $FILE
done
make -j$NUMCPUS prefix=$SHELLPACK_SOURCES/perfbuild-${VERSION}-installed
if [ $? -ne 0 ]; then
	error "$P: make failed"
	popd > /dev/null
	exit $SHELLPACK_ERROR
fi
make -j$NUMCPUS prefix=$SHELLPACK_SOURCES/perfbuild-${VERSION}-installed install
if [ $? -ne 0 ]; then
	error "$P: make failed"
	popd > /dev/null
	exit $SHELLPACK_ERROR
fi

exit $SHELLPACK_SUCCESS

==== BEGIN 0001-perf-add-syscall-benchmark.patch ====
diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
index eafce1a130a1..abc461b16ff0 100644
--- a/tools/perf/bench/Build
+++ b/tools/perf/bench/Build
@@ -1,5 +1,6 @@
 perf-y += sched-messaging.o
 perf-y += sched-pipe.o
+perf-y += syscall.o
 perf-y += mem-functions.o
 perf-y += futex-hash.o
 perf-y += futex-wake.o
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
index 6c9fcd757f31..128823ab0a2d 100644
--- a/tools/perf/bench/bench.h
+++ b/tools/perf/bench/bench.h
@@ -29,6 +29,7 @@
 int bench_numa(int argc, const char **argv);
 int bench_sched_messaging(int argc, const char **argv);
 int bench_sched_pipe(int argc, const char **argv);
+int bench_syscall_basic(int argc, const char **argv);
 int bench_mem_memcpy(int argc, const char **argv);
 int bench_mem_memset(int argc, const char **argv);
 int bench_futex_hash(int argc, const char **argv);
diff --git a/tools/perf/bench/syscall.c b/tools/perf/bench/syscall.c
new file mode 100644
index 000000000000..149129cca639
--- /dev/null
+++ b/tools/perf/bench/syscall.c
@@ -0,0 +1,80 @@
+/*
+ *
+ * syscall.c
+ *
+ * syscall: Benchmark for system call performance
+ */
+#include "../perf.h"
+#include "../util/util.h"
+#include <subcmd/parse-options.h>
+#include "../builtin.h"
+#include "bench.h"
+
+#include <stdio.h>
+#include <locale.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#define LOOPS_DEFAULT 10000000
+static	int loops = LOOPS_DEFAULT;
+
+static const struct option options[] = {
+	OPT_INTEGER('l', "loop",	&loops,		"Specify number of loops"),
+	OPT_END()
+};
+
+static const char * const bench_syscall_usage[] = {
+	"perf bench syscall <options>",
+	NULL
+};
+
+int bench_syscall_basic(int argc, const char **argv)
+{
+	struct timeval start, stop, diff;
+	unsigned long long result_usec = 0;
+	int i;
+
+	argc = parse_options(argc, argv, options, bench_syscall_usage, 0);
+
+	gettimeofday(&start, NULL);
+
+	for (i = 0; i < loops; i++)
+		getppid();
+
+	gettimeofday(&stop, NULL);
+	timersub(&stop, &start, &diff);
+
+	switch (bench_format) {
+	case BENCH_FORMAT_DEFAULT:
+		setlocale(LC_NUMERIC, "");
+		printf("# Executed %'d getppid() calls\n", loops);
+
+		result_usec = diff.tv_sec * 1000000;
+		result_usec += diff.tv_usec;
+
+		printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
+		       diff.tv_sec,
+		       (unsigned long) (diff.tv_usec/1000));
+
+		printf(" %14lf usecs/op\n",
+		       (double)result_usec / (double)loops);
+		printf(" %'14d ops/sec\n",
+		       (int)((double)loops /
+			     ((double)result_usec / (double)1000000)));
+		break;
+
+	case BENCH_FORMAT_SIMPLE:
+		printf("%lu.%03lu\n",
+		       diff.tv_sec,
+		       (unsigned long) (diff.tv_usec / 1000));
+		break;
+
+	default:
+		/* reaching here is something disaster */
+		fprintf(stderr, "Unknown format:%d\n", bench_format);
+		exit(1);
+		break;
+	}
+
+	return 0;
+}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index 17a6bcd01aa6..66a4cce0b18d 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -10,10 +10,11 @@
 /*
  * Available benchmark collection list:
  *
- *  sched ... scheduler and IPC performance
- *  mem   ... memory access performance
- *  numa  ... NUMA scheduling and MM performance
- *  futex ... Futex performance
+ *  sched   ... Scheduler and IPC performance
+ *  syscall ... System call performance
+ *  mem     ... Memory access performance
+ *  numa    ... NUMA scheduling and MM performance
+ *  futex   ... Futex performance
  */
 #include "perf.h"
 #include "util/util.h"
@@ -45,10 +46,16 @@ static struct bench numa_benchmarks[] = {
 static struct bench sched_benchmarks[] = {
 	{ "messaging",	"Benchmark for scheduling and IPC",		bench_sched_messaging	},
 	{ "pipe",	"Benchmark for pipe() between two processes",	bench_sched_pipe	},
-	{ "all",	"Run all scheduler benchmarks",		NULL			},
+	{ "all",	"Run all scheduler benchmarks",			NULL			},
 	{ NULL,		NULL,						NULL			}
 };
 
+static struct bench syscall_benchmarks[] = {
+	{ "basic",	"Benchmark for basic getppid() system calls",	bench_syscall_basic	},
+	{ "all",	"Run all syscall benchmarks",			NULL			},
+	{ NULL,		NULL,						NULL			},
+};
+
 static struct bench mem_benchmarks[] = {
 	{ "memcpy",	"Benchmark for memcpy() functions",		bench_mem_memcpy	},
 	{ "memset",	"Benchmark for memset() functions",		bench_mem_memset	},
@@ -75,6 +82,7 @@ struct collection {
 
 static struct collection collections[] = {
 	{ "sched",	"Scheduler and IPC benchmarks",			sched_benchmarks	},
+	{ "syscall",	"System call benchmarks",			syscall_benchmarks	},
 	{ "mem",	"Memory access benchmarks",			mem_benchmarks		},
 #ifdef HAVE_LIBNUMA_SUPPORT
 	{ "numa",	"NUMA scheduling and MM benchmarks",		numa_benchmarks		},
==== END 0001-perf-add-syscall-benchmark.patch ====
#### Description perfbuild
#### Details perfbuild 13
