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 (1*1024*1024)
37 static void server(sd_bus *b, size_t *result) {
41 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
43 r = sd_bus_process(b, &m);
47 assert_se(sd_bus_wait(b, (usec_t) -1) >= 0);
51 if (sd_bus_message_is_method_call(m, "benchmark.server", "Ping"))
52 assert_se(sd_bus_reply_method_return(b, m, NULL) >= 0);
53 else if (sd_bus_message_is_method_call(m, "benchmark.server", "Work")) {
57 /* Make sure the mmap is mapped */
58 assert_se(sd_bus_message_read_array(m, 'y', &p, &sz) > 0);
60 assert_se(sd_bus_reply_method_return(b, m, NULL) >= 0);
61 } else if (sd_bus_message_is_method_call(m, "benchmark.server", "Exit")) {
63 assert_se(sd_bus_message_read(m, "t", &res) > 0);
69 assert_not_reached("Unknown method");
73 static void transaction(sd_bus *b, size_t sz) {
74 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
78 assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Work", &m) >= 0);
79 assert_se(sd_bus_message_append_array_space(m, 'y', sz, (void**) &p) >= 0);
81 /* Touch every page */
82 /* psz = page_size(); */
83 /* for (i = 0; i < sz; i += psz) */
86 assert_se(sd_bus_send_with_reply_and_block(b, m, 0, NULL, &reply) >= 0);
89 static void client(const char *address) {
90 _cleanup_bus_message_unref_ sd_bus_message *x = NULL;
91 size_t lsize, rsize, csize;
98 r = sd_bus_set_address(b, address);
104 assert_se(sd_bus_call_method(b, ":1.1", "/", "benchmark.server", "Ping", NULL, NULL, NULL) >= 0);
110 usec_t copy, memfd, t;
113 csize = (lsize + rsize) / 2;
115 log_info("Trying size=%zu", csize);
123 log_info("copying...");
125 t = now(CLOCK_MONOTONIC);
126 for (i = 0; i < N_TRIES; i++)
127 transaction(b, csize);
128 copy = (now(CLOCK_MONOTONIC) - t);
129 log_info("%llu usec per copy transaction", (unsigned long long) (copy / N_TRIES));
131 log_info("sending memfd...");
133 t = now(CLOCK_MONOTONIC);
134 for (i = 0; i < N_TRIES; i++)
135 transaction(b, csize);
136 memfd = (now(CLOCK_MONOTONIC) - t);
137 log_info("%llu usec per memfd transaction", (unsigned long long) (memfd / N_TRIES));
148 assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &x) >= 0);
149 assert_se(sd_bus_message_append(x, "t", csize) >= 0);
150 assert_se(sd_bus_send(b, x, NULL) >= 0);
155 int main(int argc, char *argv[]) {
156 _cleanup_free_ char *bus_name = NULL, *address = NULL;
157 _cleanup_close_ int bus_ref = -1;
164 log_set_max_level(LOG_DEBUG);
166 bus_ref = bus_kernel_create("deine-mutter", &bus_name);
167 if (bus_ref == -ENOENT)
168 exit(EXIT_TEST_SKIP);
170 assert_se(bus_ref >= 0);
172 address = strappend("kernel:path=", bus_name);
178 r = sd_bus_set_address(b, address);
185 setpriority(PRIO_PROCESS, 0, -19);
193 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
195 close_nointr_nofail(bus_ref);
204 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
208 log_info("Copying/memfd are equally fast at %zu", result);
210 assert_se(waitpid(pid, NULL, 0) == pid);