1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2016 Red Hat, Inc.
4 * Author: Michael S. Tsirkin <mst@redhat.com>
6 * Command line processing and common functions for ring benchmarking.
14 #include <sys/eventfd.h>
20 int runcycles = 10000000;
21 int max_outstanding = INT_MAX;
25 bool do_sleep = false;
26 bool do_relax = false;
29 unsigned ring_size = 256;
31 static int kickfd = -1;
32 static int callfd = -1;
36 unsigned long long v = 1;
40 r = write(fd, &v, sizeof v);
41 assert(r == sizeof v);
45 void wait_for_notify(int fd)
47 unsigned long long v = 1;
51 r = read(fd, &v, sizeof v);
52 assert(r == sizeof v);
61 void wait_for_kick(void)
63 wait_for_notify(kickfd);
71 void wait_for_call(void)
73 wait_for_notify(callfd);
76 void set_affinity(const char *arg)
87 cpu = strtol(arg, &endptr, 0);
90 assert(cpu >= 0 && cpu < CPU_SETSIZE);
92 self = pthread_self();
94 CPU_SET(cpu, &cpuset);
96 ret = pthread_setaffinity_np(self, sizeof(cpu_set_t), &cpuset);
106 static void __attribute__((__flatten__)) run_guest(void)
108 int completed_before;
111 int bufs = runcycles;
121 completed_before = completed;
123 if (started < bufs &&
124 started - completed < max_outstanding) {
125 r = add_inbuf(0, "Buffer\n", "Hello, world!");
126 if (__builtin_expect(r == 0, true)) {
138 /* Flush out completed bufs if any */
139 if (get_buf(&len, &buf)) {
141 if (__builtin_expect(completed == bufs, false))
146 if (completed == completed_before)
148 assert(completed <= bufs);
149 assert(started <= bufs);
151 if (used_empty() && enable_call())
159 void poll_avail(void)
161 while (avail_empty())
165 static void __attribute__((__flatten__)) run_host(void)
167 int completed_before;
170 int bufs = runcycles;
176 if (avail_empty() && enable_kick())
183 completed_before = completed;
184 while (__builtin_expect(use_buf(&len, &buf), true)) {
188 if (__builtin_expect(completed == bufs, false))
191 if (completed == completed_before)
193 assert(completed <= bufs);
194 if (completed == bufs)
199 void *start_guest(void *arg)
206 void *start_host(void *arg)
213 static const char optstring[] = "";
214 static const struct option longopts[] = {
217 .has_arg = no_argument,
221 .name = "host-affinity",
222 .has_arg = required_argument,
226 .name = "guest-affinity",
227 .has_arg = required_argument,
232 .has_arg = required_argument,
236 .name = "run-cycles",
237 .has_arg = required_argument,
241 .name = "outstanding",
242 .has_arg = required_argument,
247 .has_arg = required_argument,
252 .has_arg = required_argument,
257 .has_arg = no_argument,
262 .has_arg = no_argument,
267 .has_arg = no_argument,
274 static void help(void)
276 fprintf(stderr, "Usage: <test> [--help]"
277 " [--host-affinity H]"
278 " [--guest-affinity G]"
279 " [--ring-size R (default: %d)]"
280 " [--run-cycles C (default: %d)]"
292 int main(int argc, char **argv)
295 pthread_t host, guest;
297 char *host_arg = NULL;
298 char *guest_arg = NULL;
302 kickfd = eventfd(0, 0);
304 callfd = eventfd(0, 0);
308 int o = getopt_long(argc, argv, optstring, longopts, NULL);
322 ring_size = strtol(optarg, &endptr, 0);
323 assert(ring_size && !(ring_size & (ring_size - 1)));
327 c = strtol(optarg, &endptr, 0);
329 assert(c > 0 && c < INT_MAX);
333 c = strtol(optarg, &endptr, 0);
335 assert(c > 0 && c < INT_MAX);
339 c = strtol(optarg, &endptr, 0);
341 assert(c > 0 && c < INT_MAX);
345 c = strtol(optarg, &endptr, 0);
347 assert(c > 0 && c < INT_MAX);
366 /* does nothing here, used to make sure all smp APIs compile */
372 if (batch > max_outstanding)
373 batch = max_outstanding;
381 ret = pthread_create(&host, NULL, start_host, host_arg);
383 ret = pthread_create(&guest, NULL, start_guest, guest_arg);
386 ret = pthread_join(guest, &tret);
388 ret = pthread_join(host, &tret);