1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <sys/syscall.h>
17 #include <cstring>
18 #include <sys/timex.h>
19 #include <csignal>
20 #include <sys/resource.h>
21 #include <cstdio>
22 #include <sys/types.h>
23 #include <fcntl.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/time.h>
27 #include <ctime>
28 #include <unistd.h>
29 #include <sys/utsname.h>
30 #if not defined __APPLE__
31 #include <sys/eventfd.h>
32 #endif
33 #include "util.h"
34
35 using namespace std;
36
37 constexpr int BYTES_WRITTEN = 8;
38 constexpr int BUFSIZE = 10;
39
40 // Gets the identification code of the current process
Bm_function_Syscall_getpid(benchmark::State & state)41 static void Bm_function_Syscall_getpid(benchmark::State &state)
42 {
43 pid_t pid;
44 for (auto _ : state) {
45 pid = syscall(SYS_getpid);
46 benchmark::DoNotOptimize(pid);
47 }
48 }
49
50 // The system call gets the current thread ID
Bm_function_Syscall_gettid(benchmark::State & state)51 static void Bm_function_Syscall_gettid(benchmark::State &state)
52 {
53 pid_t tid;
54 for (auto _ : state) {
55 tid = syscall(SYS_gettid);
56 benchmark::DoNotOptimize(tid);
57 }
58 }
59
60 // Used to read the kernel time
Bm_function_Syscall_adjtimex(benchmark::State & state)61 static void Bm_function_Syscall_adjtimex(benchmark::State &state)
62 {
63 struct timex timeInfo;
64 for (auto _ : state) {
65 benchmark::DoNotOptimize(syscall(SYS_adjtimex, &timeInfo));
66 }
67 }
68
69 // Writes the contents of the file of the user buffer to the corresponding location of the file on disk
Bm_function_Syscall_write(benchmark::State & state)70 static void Bm_function_Syscall_write(benchmark::State &state)
71 {
72 int fp = open("/dev/zero", O_RDWR, OPEN_MODE);
73 if (fp == -1) {
74 perror("open SYS_write");
75 }
76 for (auto _ : state) {
77 benchmark::DoNotOptimize(syscall(SYS_write, fp, "Bad Mind", BYTES_WRITTEN));
78 }
79 close(fp);
80 }
81
82 // Transfer 10 bytes into the BUFF in the open file
Bm_function_Syscall_read(benchmark::State & state)83 static void Bm_function_Syscall_read(benchmark::State &state)
84 {
85 char buf[BUFSIZE];
86 int fd = open("/dev/zero", O_RDONLY, OPEN_MODE);
87 if (fd == -1) {
88 perror("open SYS_read");
89 }
90 for (auto _ : state) {
91 ssize_t ret = syscall(SYS_read, fd, buf, BUFSIZE);
92 if (ret < 0) {
93 perror("STS_read");
94 }
95 benchmark::DoNotOptimize(ret);
96 }
97 close(fd);
98 }
99
100 // Manipulate the characteristics of a file based on the file descriptor
Bm_function_Syscall_fcntl(benchmark::State & state)101 static void Bm_function_Syscall_fcntl(benchmark::State &state)
102 {
103 long int ret;
104 int fd = open("/dev/zero", O_RDONLY, OPEN_MODE);
105 if (fd == -1) {
106 perror("open SYS_fcntl");
107 }
108 for (auto _ : state) {
109 ret = syscall(SYS_fcntl, fd, F_GETFL);
110 if (ret == -1) {
111 perror("SYS_fcntl");
112 }
113 benchmark::DoNotOptimize(ret);
114 }
115 close(fd);
116 }
117
118 // Obtain system resource usage status
Bm_function_Syscall_getrusage(benchmark::State & state)119 static void Bm_function_Syscall_getrusage(benchmark::State &state)
120 {
121 struct rusage usage;
122 long result;
123 for (auto _ : state) {
124 result = syscall(SYS_getrusage, RUSAGE_SELF, &usage);
125 benchmark::DoNotOptimize(result);
126 }
127 if (result != 0) {
128 printf("SYS_getrusage error\n");
129 }
130 }
131
132 // Obtain system information
Bm_function_Syscall_uname(benchmark::State & state)133 static void Bm_function_Syscall_uname(benchmark::State &state)
134 {
135 struct utsname buf;
136 long int ret;
137 for (auto _ : state) {
138 ret = syscall(SYS_uname, &buf);
139 benchmark::DoNotOptimize(ret);
140 }
141 if (ret != 0) {
142 printf("SYS_uname error\n");
143 }
144 }
145
Bm_function_Syscall_getpriority(benchmark::State & state)146 static void Bm_function_Syscall_getpriority(benchmark::State &state)
147 {
148 pid_t pid = getpid();
149 for (auto _ : state) {
150 benchmark::DoNotOptimize(getpriority(PRIO_PROCESS, pid));
151 }
152 }
153
Bm_function_Syscall_setpriority(benchmark::State & state)154 static void Bm_function_Syscall_setpriority(benchmark::State &state)
155 {
156 pid_t pid = getpid();
157 int prio = getpriority(PRIO_PROCESS, pid);
158 if (prio == -1) {
159 perror("getpriority failed");
160 }
161
162 for (auto _ : state) {
163 benchmark::DoNotOptimize(setpriority(PRIO_PROCESS, pid, prio));
164 }
165 }
166
Bm_function_Syscall_eventfd(benchmark::State & state)167 static void Bm_function_Syscall_eventfd(benchmark::State &state)
168 {
169 for (auto _ : state) {
170 int fd = eventfd(0, 0);
171 if (fd >= 0) {
172 state.PauseTiming();
173 close(fd);
174 state.ResumeTiming();
175 }
176 }
177 }
178
179 MUSL_BENCHMARK(Bm_function_Syscall_getpid);
180 MUSL_BENCHMARK(Bm_function_Syscall_gettid);
181 MUSL_BENCHMARK(Bm_function_Syscall_adjtimex);
182 MUSL_BENCHMARK(Bm_function_Syscall_write);
183 MUSL_BENCHMARK(Bm_function_Syscall_read);
184 MUSL_BENCHMARK(Bm_function_Syscall_fcntl);
185 MUSL_BENCHMARK(Bm_function_Syscall_getrusage);
186 MUSL_BENCHMARK(Bm_function_Syscall_uname);
187 MUSL_BENCHMARK(Bm_function_Syscall_getpriority);
188 MUSL_BENCHMARK(Bm_function_Syscall_setpriority);
189 MUSL_BENCHMARK(Bm_function_Syscall_eventfd);
190