2 * Copyright (C) 2016 Red Hat, Inc.
3 * Author: Michael S. Tsirkin <mst@redhat.com>
4 * This work is licensed under the terms of the GNU GPL, version 2.
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;
24 bool do_sleep = false;
25 bool do_relax = false;
28 unsigned ring_size = 256;
30 static int kickfd = -1;
31 static int callfd = -1;
35 unsigned long long v = 1;
39 r = write(fd, &v, sizeof v);
40 assert(r == sizeof v);
44 void wait_for_notify(int fd)
46 unsigned long long v = 1;
50 r = read(fd, &v, sizeof v);
51 assert(r == sizeof v);
60 void wait_for_kick(void)
62 wait_for_notify(kickfd);
70 void wait_for_call(void)
72 wait_for_notify(callfd);
75 void set_affinity(const char *arg)
86 cpu = strtol(arg, &endptr, 0);
89 assert(cpu >= 0 || cpu < CPU_SETSIZE);
91 self = pthread_self();
93 CPU_SET(cpu, &cpuset);
95 ret = pthread_setaffinity_np(self, sizeof(cpu_set_t), &cpuset);
105 static void __attribute__((__flatten__)) run_guest(void)
107 int completed_before;
110 int bufs = runcycles;
120 completed_before = completed;
122 if (started < bufs &&
123 started - completed < max_outstanding) {
124 r = add_inbuf(0, "Buffer\n", "Hello, world!");
125 if (__builtin_expect(r == 0, true)) {
137 /* Flush out completed bufs if any */
138 if (get_buf(&len, &buf)) {
140 if (__builtin_expect(completed == bufs, false))
145 if (completed == completed_before)
147 assert(completed <= bufs);
148 assert(started <= bufs);
150 if (used_empty() && enable_call())
158 void poll_avail(void)
160 while (avail_empty())
164 static void __attribute__((__flatten__)) run_host(void)
166 int completed_before;
169 int bufs = runcycles;
175 if (avail_empty() && enable_kick())
182 completed_before = completed;
183 while (__builtin_expect(use_buf(&len, &buf), true)) {
187 if (__builtin_expect(completed == bufs, false))
190 if (completed == completed_before)
192 assert(completed <= bufs);
193 if (completed == bufs)
198 void *start_guest(void *arg)
205 void *start_host(void *arg)
212 static const char optstring[] = "";
213 static const struct option longopts[] = {
216 .has_arg = no_argument,
220 .name = "host-affinity",
221 .has_arg = required_argument,
225 .name = "guest-affinity",
226 .has_arg = required_argument,
231 .has_arg = required_argument,
235 .name = "run-cycles",
236 .has_arg = required_argument,
240 .name = "outstanding",
241 .has_arg = required_argument,
246 .has_arg = required_argument,
251 .has_arg = no_argument,
256 .has_arg = no_argument,
261 .has_arg = no_argument,
268 static void help(void)
270 fprintf(stderr, "Usage: <test> [--help]"
271 " [--host-affinity H]"
272 " [--guest-affinity G]"
273 " [--ring-size R (default: %d)]"
274 " [--run-cycles C (default: %d)]"
285 int main(int argc, char **argv)
288 pthread_t host, guest;
290 char *host_arg = NULL;
291 char *guest_arg = NULL;
295 kickfd = eventfd(0, 0);
297 callfd = eventfd(0, 0);
301 int o = getopt_long(argc, argv, optstring, longopts, NULL);
315 ring_size = strtol(optarg, &endptr, 0);
316 assert(ring_size && !(ring_size & (ring_size - 1)));
320 c = strtol(optarg, &endptr, 0);
322 assert(c > 0 && c < INT_MAX);
326 c = strtol(optarg, &endptr, 0);
328 assert(c > 0 && c < INT_MAX);
332 c = strtol(optarg, &endptr, 0);
334 assert(c > 0 && c < INT_MAX);
353 /* does nothing here, used to make sure all smp APIs compile */
359 if (batch > max_outstanding)
360 batch = max_outstanding;
368 ret = pthread_create(&host, NULL, start_host, host_arg);
370 ret = pthread_create(&guest, NULL, start_guest, guest_arg);
373 ret = pthread_join(guest, &tret);
375 ret = pthread_join(host, &tret);