]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/test-bus-benchmark.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
8 #include "alloc-util.h"
9 #include "bus-internal.h"
10 #include "bus-kernel.h"
11 #include "constants.h"
13 #include "missing_resource.h"
14 #include "string-util.h"
16 #include "time-util.h"
18 #define MAX_SIZE (2*1024*1024)
20 static usec_t arg_loop_usec
= 100 * USEC_PER_MSEC
;
27 static void server(sd_bus
*b
, size_t *result
) {
31 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
33 r
= sd_bus_process(b
, &m
);
37 assert_se(sd_bus_wait(b
, USEC_INFINITY
) >= 0);
41 if (sd_bus_message_is_method_call(m
, "benchmark.server", "Ping"))
42 assert_se(sd_bus_reply_method_return(m
, NULL
) >= 0);
43 else if (sd_bus_message_is_method_call(m
, "benchmark.server", "Work")) {
47 /* Make sure the mmap is mapped */
48 assert_se(sd_bus_message_read_array(m
, 'y', &p
, &sz
) > 0);
50 r
= sd_bus_reply_method_return(m
, NULL
);
52 } else if (sd_bus_message_is_method_call(m
, "benchmark.server", "Exit")) {
54 assert_se(sd_bus_message_read(m
, "t", &res
) > 0);
59 } else if (!sd_bus_message_is_signal(m
, NULL
, NULL
))
64 static void transaction(sd_bus
*b
, size_t sz
, const char *server_name
) {
65 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *reply
= NULL
;
68 assert_se(sd_bus_message_new_method_call(b
, &m
, server_name
, "/", "benchmark.server", "Work") >= 0);
69 assert_se(sd_bus_message_append_array_space(m
, 'y', sz
, (void**) &p
) >= 0);
73 assert_se(sd_bus_call(b
, m
, 0, NULL
, &reply
) >= 0);
76 static void client_bisect(const char *address
, const char *server_name
) {
77 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*x
= NULL
;
78 size_t lsize
, rsize
, csize
;
85 r
= sd_bus_set_address(b
, address
);
91 r
= sd_bus_call_method(b
, server_name
, "/", "benchmark.server", "Ping", NULL
, NULL
, NULL
);
97 printf("SIZE\tCOPY\tMEMFD\n");
101 unsigned n_copying
, n_memfd
;
103 csize
= (lsize
+ rsize
) / 2;
111 printf("%zu\t", csize
);
115 t
= now(CLOCK_MONOTONIC
);
116 for (n_copying
= 0;; n_copying
++) {
117 transaction(b
, csize
, server_name
);
118 if (now(CLOCK_MONOTONIC
) >= t
+ arg_loop_usec
)
121 printf("%u\t", (unsigned) ((n_copying
* USEC_PER_SEC
) / arg_loop_usec
));
125 t
= now(CLOCK_MONOTONIC
);
126 for (n_memfd
= 0;; n_memfd
++) {
127 transaction(b
, csize
, server_name
);
128 if (now(CLOCK_MONOTONIC
) >= t
+ arg_loop_usec
)
131 printf("%u\n", (unsigned) ((n_memfd
* USEC_PER_SEC
) / arg_loop_usec
));
133 if (n_copying
== n_memfd
)
136 if (n_copying
> n_memfd
)
143 assert_se(sd_bus_message_new_method_call(b
, &x
, server_name
, "/", "benchmark.server", "Exit") >= 0);
144 assert_se(sd_bus_message_append(x
, "t", csize
) >= 0);
145 assert_se(sd_bus_send(b
, x
, NULL
) >= 0);
150 static void client_chart(Type type
, const char *address
, const char *server_name
, int fd
) {
151 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*x
= NULL
;
159 if (type
== TYPE_DIRECT
) {
160 r
= sd_bus_set_fd(b
, fd
, fd
);
163 r
= sd_bus_set_address(b
, address
);
166 r
= sd_bus_set_bus_client(b
, true);
173 r
= sd_bus_call_method(b
, server_name
, "/", "benchmark.server", "Ping", NULL
, NULL
, NULL
);
178 printf("SIZE\tLEGACY\n");
181 printf("SIZE\tDIRECT\n");
185 for (csize
= 1; csize
<= MAX_SIZE
; csize
*= 2) {
189 printf("%zu\t", csize
);
191 t
= now(CLOCK_MONOTONIC
);
192 for (n_memfd
= 0;; n_memfd
++) {
193 transaction(b
, csize
, server_name
);
194 if (now(CLOCK_MONOTONIC
) >= t
+ arg_loop_usec
)
198 printf("%u\n", (unsigned) ((n_memfd
* USEC_PER_SEC
) / arg_loop_usec
));
202 assert_se(sd_bus_message_new_method_call(b
, &x
, server_name
, "/", "benchmark.server", "Exit") >= 0);
203 assert_se(sd_bus_message_append(x
, "t", csize
) >= 0);
204 assert_se(sd_bus_send(b
, x
, NULL
) >= 0);
209 int main(int argc
, char *argv
[]) {
213 } mode
= MODE_BISECT
;
214 Type type
= TYPE_LEGACY
;
215 int i
, pair
[2] = EBADF_PAIR
;
216 _cleanup_free_
char *address
= NULL
, *server_name
= NULL
;
217 _cleanup_close_
int bus_ref
= -EBADF
;
225 test_setup_logging(LOG_DEBUG
);
227 for (i
= 1; i
< argc
; i
++) {
228 if (streq(argv
[i
], "chart")) {
231 } else if (streq(argv
[i
], "legacy")) {
234 } else if (streq(argv
[i
], "direct")) {
239 assert_se(parse_sec(argv
[i
], &arg_loop_usec
) >= 0);
242 assert_se(arg_loop_usec
> 0);
244 if (type
== TYPE_LEGACY
) {
247 e
= secure_getenv("DBUS_SESSION_BUS_ADDRESS");
257 if (type
== TYPE_DIRECT
) {
258 assert_se(socketpair(AF_UNIX
, SOCK_STREAM
, 0, pair
) >= 0);
260 r
= sd_bus_set_fd(b
, pair
[0], pair
[0]);
263 r
= sd_bus_set_server(b
, true, SD_ID128_NULL
);
266 r
= sd_bus_set_address(b
, address
);
269 r
= sd_bus_set_bus_client(b
, true);
276 if (type
!= TYPE_DIRECT
) {
277 r
= sd_bus_get_unique_name(b
, &unique
);
280 server_name
= strdup(unique
);
281 assert_se(server_name
);
285 setpriority(PRIO_PROCESS
, 0, -19);
293 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t
), &cpuset
);
300 client_bisect(address
, server_name
);
304 client_chart(type
, address
, server_name
, pair
[1]);
313 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t
), &cpuset
);
317 if (mode
== MODE_BISECT
)
318 printf("Copying/memfd are equally fast at %zu bytes\n", result
);
320 assert_se(waitpid(pid
, NULL
, 0) == pid
);