]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/test-bus-benchmark.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
7 #include "alloc-util.h"
8 #include "bus-internal.h"
9 #include "bus-kernel.h"
13 #include "missing_resource.h"
14 #include "time-util.h"
17 #define MAX_SIZE (2*1024*1024)
19 static usec_t arg_loop_usec
= 100 * USEC_PER_MSEC
;
26 static void server(sd_bus
*b
, size_t *result
) {
30 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
32 r
= sd_bus_process(b
, &m
);
36 assert_se(sd_bus_wait(b
, USEC_INFINITY
) >= 0);
40 if (sd_bus_message_is_method_call(m
, "benchmark.server", "Ping"))
41 assert_se(sd_bus_reply_method_return(m
, NULL
) >= 0);
42 else if (sd_bus_message_is_method_call(m
, "benchmark.server", "Work")) {
46 /* Make sure the mmap is mapped */
47 assert_se(sd_bus_message_read_array(m
, 'y', &p
, &sz
) > 0);
49 r
= sd_bus_reply_method_return(m
, NULL
);
51 } else if (sd_bus_message_is_method_call(m
, "benchmark.server", "Exit")) {
53 assert_se(sd_bus_message_read(m
, "t", &res
) > 0);
58 } else if (!sd_bus_message_is_signal(m
, NULL
, NULL
))
59 assert_not_reached("Unknown method");
63 static void transaction(sd_bus
*b
, size_t sz
, const char *server_name
) {
64 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *reply
= NULL
;
67 assert_se(sd_bus_message_new_method_call(b
, &m
, server_name
, "/", "benchmark.server", "Work") >= 0);
68 assert_se(sd_bus_message_append_array_space(m
, 'y', sz
, (void**) &p
) >= 0);
72 assert_se(sd_bus_call(b
, m
, 0, NULL
, &reply
) >= 0);
75 static void client_bisect(const char *address
, const char *server_name
) {
76 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*x
= NULL
;
77 size_t lsize
, rsize
, csize
;
84 r
= sd_bus_set_address(b
, address
);
90 r
= sd_bus_call_method(b
, server_name
, "/", "benchmark.server", "Ping", NULL
, NULL
, NULL
);
96 printf("SIZE\tCOPY\tMEMFD\n");
100 unsigned n_copying
, n_memfd
;
102 csize
= (lsize
+ rsize
) / 2;
110 printf("%zu\t", csize
);
114 t
= now(CLOCK_MONOTONIC
);
115 for (n_copying
= 0;; n_copying
++) {
116 transaction(b
, csize
, server_name
);
117 if (now(CLOCK_MONOTONIC
) >= t
+ arg_loop_usec
)
120 printf("%u\t", (unsigned) ((n_copying
* USEC_PER_SEC
) / arg_loop_usec
));
124 t
= now(CLOCK_MONOTONIC
);
125 for (n_memfd
= 0;; n_memfd
++) {
126 transaction(b
, csize
, server_name
);
127 if (now(CLOCK_MONOTONIC
) >= t
+ arg_loop_usec
)
130 printf("%u\n", (unsigned) ((n_memfd
* USEC_PER_SEC
) / arg_loop_usec
));
132 if (n_copying
== n_memfd
)
135 if (n_copying
> n_memfd
)
142 assert_se(sd_bus_message_new_method_call(b
, &x
, server_name
, "/", "benchmark.server", "Exit") >= 0);
143 assert_se(sd_bus_message_append(x
, "t", csize
) >= 0);
144 assert_se(sd_bus_send(b
, x
, NULL
) >= 0);
149 static void client_chart(Type type
, const char *address
, const char *server_name
, int fd
) {
150 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*x
= NULL
;
158 if (type
== TYPE_DIRECT
) {
159 r
= sd_bus_set_fd(b
, fd
, fd
);
162 r
= sd_bus_set_address(b
, address
);
165 r
= sd_bus_set_bus_client(b
, true);
172 r
= sd_bus_call_method(b
, server_name
, "/", "benchmark.server", "Ping", NULL
, NULL
, NULL
);
177 printf("SIZE\tLEGACY\n");
180 printf("SIZE\tDIRECT\n");
184 for (csize
= 1; csize
<= MAX_SIZE
; csize
*= 2) {
188 printf("%zu\t", csize
);
190 t
= now(CLOCK_MONOTONIC
);
191 for (n_memfd
= 0;; n_memfd
++) {
192 transaction(b
, csize
, server_name
);
193 if (now(CLOCK_MONOTONIC
) >= t
+ arg_loop_usec
)
197 printf("%u\n", (unsigned) ((n_memfd
* USEC_PER_SEC
) / arg_loop_usec
));
201 assert_se(sd_bus_message_new_method_call(b
, &x
, server_name
, "/", "benchmark.server", "Exit") >= 0);
202 assert_se(sd_bus_message_append(x
, "t", csize
) >= 0);
203 assert_se(sd_bus_send(b
, x
, NULL
) >= 0);
208 int main(int argc
, char *argv
[]) {
212 } mode
= MODE_BISECT
;
213 Type type
= TYPE_LEGACY
;
214 int i
, pair
[2] = { -1, -1 };
215 _cleanup_free_
char *address
= NULL
, *server_name
= NULL
;
216 _cleanup_close_
int bus_ref
= -1;
224 for (i
= 1; i
< argc
; i
++) {
225 if (streq(argv
[i
], "chart")) {
228 } else if (streq(argv
[i
], "legacy")) {
231 } else if (streq(argv
[i
], "direct")) {
236 assert_se(parse_sec(argv
[i
], &arg_loop_usec
) >= 0);
239 assert_se(arg_loop_usec
> 0);
241 if (type
== TYPE_LEGACY
) {
244 e
= secure_getenv("DBUS_SESSION_BUS_ADDRESS");
254 if (type
== TYPE_DIRECT
) {
255 assert_se(socketpair(AF_UNIX
, SOCK_STREAM
, 0, pair
) >= 0);
257 r
= sd_bus_set_fd(b
, pair
[0], pair
[0]);
260 r
= sd_bus_set_server(b
, true, SD_ID128_NULL
);
263 r
= sd_bus_set_address(b
, address
);
266 r
= sd_bus_set_bus_client(b
, true);
273 if (type
!= TYPE_DIRECT
) {
274 r
= sd_bus_get_unique_name(b
, &unique
);
277 server_name
= strdup(unique
);
278 assert_se(server_name
);
282 setpriority(PRIO_PROCESS
, 0, -19);
290 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t
), &cpuset
);
297 client_bisect(address
, server_name
);
301 client_chart(type
, address
, server_name
, pair
[1]);
310 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t
), &cpuset
);
314 if (mode
== MODE_BISECT
)
315 printf("Copying/memfd are equally fast at %zu bytes\n", result
);
317 assert_se(waitpid(pid
, NULL
, 0) == pid
);