1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "bus-message.h"
30 #include "bus-error.h"
31 #include "bus-kernel.h"
32 #include "bus-internal.h"
35 #define MAX_SIZE (5*1024*1024)
37 static void server(sd_bus *b, usec_t *result) {
42 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
44 r = sd_bus_process(b, &m);
48 assert_se(sd_bus_wait(b, (usec_t) -1) >= 0);
53 /* log_error("huhu %s from %s", sd_bus_message_get_member(m), sd_bus_message_get_sender(m)); */
55 if (sd_bus_message_is_method_call(m, "benchmark.server", "Work")) {
56 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
61 assert_se(sd_bus_message_read_array(m, 'y', (const void**) &p, &sz) > 0);
62 assert_se(sd_bus_message_new_method_return(b, m, &reply) >= 0);
63 assert_se(sd_bus_message_append_array_space(reply, 'y', sz, (void**) &q) >= 0);
65 x = now(CLOCK_MONOTONIC);
67 for (i = 0; i < sz; i++)
70 x = now(CLOCK_MONOTONIC) - x;
72 assert_se(sd_bus_send(b, reply, NULL) >= 0);
73 } else if (sd_bus_message_is_method_call(m, "benchmark.server", "Exit")) {
76 assert_se(sd_bus_message_read(m, "t", &t) > 0);
81 } else if (sd_bus_message_is_method_call(m, "benchmark.server", "Ping")) {
82 assert_se(sd_bus_reply_method_return(b, m, "y", 1) >= 0);
84 assert_not_reached("Unknown method");
88 static void client(sd_bus *b, size_t sz) {
89 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
95 assert_se(sd_bus_call_method(b, ":1.1", "/", "benchmark.server", "Ping", NULL, NULL, NULL) >= 0);
97 assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Work", &m) >= 0);
98 assert_se(sd_bus_message_append_array_space(m, 'y', sz, (void**) &p) >= 0);
100 for (i = 0; i < sz; i++)
101 p[i] = 'a' + (char) (i % 26);
103 t = now(CLOCK_MONOTONIC);
104 assert_se(sd_bus_send_with_reply_and_block(b, m, 0, NULL, &reply) >= 0);
105 t = now(CLOCK_MONOTONIC) - t;
107 assert_se(sd_bus_message_read_array(reply, 'y', (const void**) &q, &l) > 0);
110 for (i = 0; i < sz; i++) {
111 assert_se(q[i] == 'A' + (char) (i % 26));
114 sd_bus_message_unref(m);
116 assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &m) >= 0);
117 assert_se(sd_bus_message_append(m, "t", t) >= 0);
118 assert_se(sd_bus_send(b, m, NULL) >= 0);
121 static void run_benchmark(size_t sz, bool force_copy, usec_t *result) {
123 _cleanup_close_ int bus_ref = -1;
124 _cleanup_free_ char *bus_name = NULL, *address = NULL;
129 bus_ref = bus_kernel_create("deine-mutter", &bus_name);
130 if (bus_ref == -ENOENT)
131 exit(EXIT_TEST_SKIP);
133 assert_se(bus_ref >= 0);
135 address = strappend("kernel:path=", bus_name);
141 b->use_memfd = force_copy ? 0 : -1;
143 r = sd_bus_set_address(b, address);
153 close_nointr_nofail(bus_ref);
159 b->use_memfd = force_copy ? 0 : -1;
161 r = sd_bus_set_address(b, address);
174 assert_se(waitpid(pid, NULL, 0) == pid);
177 int main(int argc, char *argv[]) {
178 size_t lsize, rsize, csize;
180 log_set_max_level(LOG_DEBUG);
186 usec_t copy = 0, memfd = 0;
189 csize = (lsize + rsize) / 2;
191 log_info("Trying size=%zu", csize);
196 for (i = 0; i < N_TRIES; i++) {
199 run_benchmark(csize, true, &t);
203 for (i = 0; i < N_TRIES; i++) {
206 run_benchmark(csize, false, &t);
222 log_info("Copying/memfd are equally fast at %zu", csize);