Add getpidopt case to docker benchmarks.

getpidopt is an important test case for the systrap platform,
so add it to our syscall test.

PiperOrigin-RevId: 513657968
This commit is contained in:
Zach Koopmans
2023-03-02 15:37:50 -08:00
committed by gVisor bot
parent ac84f9c963
commit 5a6447f491
3 changed files with 88 additions and 34 deletions
+44 -7
View File
@@ -20,21 +20,39 @@
static int loops = 10000000;
enum syscall_type { get_pid, get_pid_opt };
#ifdef __x86_64__
#define SYSNO_STR1(x) #x
#define SYSNO_STR(x) SYSNO_STR1(x)
void do_getpidopt() {
__asm__("movl $" SYSNO_STR(SYS_getpid) ", %%eax\n"
"syscall\n"
: : : "rax", "rcx", "r11");
}
#endif
static void show_usage(const char *cmd) {
fprintf(stderr,
"Usage: %s [options]\n"
"-l, --loops <num>\t\t Number of syscall loops, default 10000000\n",
cmd);
"-l, --loops <num>\t\t Number of syscall loops, default 10000000\n"
"-s, --syscall <num>\t\tSyscall to run (default getpid)\n"
"\tOptions:\n"
"\t%d) getpid\n"
"\t%d) getpidopt\n",
cmd, get_pid, get_pid_opt);
}
int main(int argc, char *argv[]) {
int i;
int c;
int i, c, sys_val = get_pid;
struct option long_options[] = {{"loops", required_argument, 0, 'l'},
{"syscall", required_argument, 0, 's'},
{0, 0, 0, 0}};
int option_index = 0;
while ((c = getopt_long(argc, argv, "l:", long_options, &option_index)) !=
while ((c = getopt_long(argc, argv, "l:s", long_options, &option_index)) !=
-1) {
switch (c) {
case 'l':
@@ -44,14 +62,33 @@ int main(int argc, char *argv[]) {
exit(1);
}
break;
case 's':
sys_val = atoi(optarg);
if (sys_val < 0) {
show_usage(argv[0]);
exit(1);
}
break;
default:
fprintf(stderr, "unknown option: '%c'\n", c);
show_usage(argv[0]);
exit(1);
}
}
for (i = 0; i < loops; i++) syscall(SYS_getpid);
switch (sys_val) {
case (int)get_pid:
for (i = 0; i < loops; i++) syscall(SYS_getpid);
break;
case (int)get_pid_opt:
for (i = 0; i < loops; i++) do_getpidopt();
break;
default:
fprintf(stderr, "unknown syscall option: %d\n", sys_val);
show_usage(argv[0]);
exit(1);
}
printf("# Executed %'d getpid() calls\n", loops);
printf("# Executed %'d calls\n", loops);
return 0;
}
+44 -27
View File
@@ -24,41 +24,58 @@ import (
"gvisor.dev/gvisor/test/benchmarks/tools"
)
// BenchmarSyscallbench runs syscallbench on the runtime.
// BenchmarSyscallbench runs a syscall b.N times on the runtime.
func BenchmarkSyscallbench(b *testing.B) {
ctx := context.Background()
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",
for _, tc := range []struct {
param tools.Parameter
syscallArg int
}{
{
param: tools.Parameter{
Name: "syscall",
Value: "getpid",
},
"sleep", "24h",
); err != nil {
b.Fatalf("run failed with: %v", err)
},
{
param: tools.Parameter{
Name: "syscall",
Value: "getpidopt",
},
syscallArg: 1,
},
} {
name, err := tools.ParametersToName(tc.param)
if err != nil {
b.Fatalf("Failed to parse params: %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)
}
})
func() {
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)
}
b.Run(name, func(b *testing.B) {
cmd := []string{"syscallbench", fmt.Sprintf("--loops=%d --syscall %d", b.N, tc.syscallArg)}
b.ResetTimer()
out, err := container.Exec(ctx, dockerutil.ExecOpts{}, cmd...)
if err != nil {
b.Fatalf("failed to run syscallbench: %v, logs:%s", err, out)
}
})
}()
}
}