diff --git a/images/benchmarks/syscallbench/Dockerfile b/images/benchmarks/syscallbench/Dockerfile new file mode 100644 index 000000000..26bc0c563 --- /dev/null +++ b/images/benchmarks/syscallbench/Dockerfile @@ -0,0 +1,10 @@ +FROM ubuntu:18.04 + +RUN set -x \ + && apt-get update \ + && apt-get install -y \ + gcc \ + && rm -rf /var/lib/apt/lists/* + +COPY ./syscallbench.c / +RUN gcc /syscallbench.c -o /usr/bin/syscallbench diff --git a/images/benchmarks/syscallbench/syscallbench.c b/images/benchmarks/syscallbench/syscallbench.c new file mode 100644 index 000000000..580d90252 --- /dev/null +++ b/images/benchmarks/syscallbench/syscallbench.c @@ -0,0 +1,58 @@ +// Copyright 2022 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include + +static int loops = 10000000; + +static void show_usage(const char *cmd) +{ + fprintf(stderr, "Usage: %s [options]\n" + "-l, --loops \t\t Number of syscall loops, default 10000000\n", cmd); +} + +int main(int argc, char *argv[]) +{ + int i; + int c; + struct option long_options[] = { + {"loops", required_argument, 0, 'l'}, + {0, 0, 0, 0}}; + int option_index = 0; + + while ((c = getopt_long(argc, argv, "l:", long_options, &option_index)) != -1) { + switch (c) { + case 'l': + loops = atoi(optarg); + if (loops <= 0) { + show_usage(argv[0]); + exit(1); + } + break; + default: + show_usage(argv[0]); + exit(1); + } + } + + for (i = 0; i < loops; i++) + syscall(SYS_getpid); + + printf("# Executed %'d getpid() calls\n", loops); + return 0; +} diff --git a/test/benchmarks/base/BUILD b/test/benchmarks/base/BUILD index a5a3cf2c1..16d25bd5f 100644 --- a/test/benchmarks/base/BUILD +++ b/test/benchmarks/base/BUILD @@ -48,3 +48,14 @@ benchmark_test( "//test/benchmarks/tools", ], ) + +benchmark_test( + name = "syscallbench_test", + srcs = ["syscallbench_test.go"], + visibility = ["//:sandbox"], + deps = [ + "//pkg/test/dockerutil", + "//test/benchmarks/harness", + "//test/benchmarks/tools", + ], +) diff --git a/test/benchmarks/base/syscallbench_test.go b/test/benchmarks/base/syscallbench_test.go new file mode 100644 index 000000000..092b76ef4 --- /dev/null +++ b/test/benchmarks/base/syscallbench_test.go @@ -0,0 +1,64 @@ +// Copyright 2022 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package syscallbench_test + +import ( + "context" + "fmt" + "testing" + + "gvisor.dev/gvisor/pkg/test/dockerutil" + "gvisor.dev/gvisor/test/benchmarks/harness" + "gvisor.dev/gvisor/test/benchmarks/tools" +) + +// BenchmarSyscallbench runs syscallbench on the runtime. +func BenchmarkSyscallbench(b *testing.B) { + machine, err := harness.GetMachine() + if err != nil { + b.Fatalf("failed to get machine: %v", err) + } + defer machine.CleanUp() + + param := tools.Parameter{ + Name: "syscall", + Value: "getpid", + } + name, err := tools.ParametersToName(param) + if err != nil { + b.Fatalf("Failed to parse params: %v", err) + } + b.Run(name, func(b *testing.B) { + ctx := context.Background() + container := machine.GetContainer(ctx, b) + defer container.CleanUp(ctx) + + if err := container.Spawn( + ctx, dockerutil.RunOpts{ + Image: "benchmarks/syscallbench", + }, + "sleep", "24h", + ); err != nil { + b.Fatalf("run failed with: %v", err) + } + + cmd := []string{"syscallbench", fmt.Sprintf("--loops=%d", b.N)} + b.ResetTimer() + out, err := container.Exec(ctx, dockerutil.ExecOpts{}, cmd...) + if err != nil { + b.Fatalf("failed to run syscallbench: %v, logs:%s", err, out) + } + }) +}