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);
99 static void run_guest(void)
101 int completed_before;
104 int bufs = runcycles;
114 completed_before = completed;
116 if (started < bufs &&
117 started - completed < max_outstanding) {
118 r = add_inbuf(0, "Buffer\n", "Hello, world!");
119 if (__builtin_expect(r == 0, true)) {
131 /* Flush out completed bufs if any */
132 if (get_buf(&len, &buf)) {
134 if (__builtin_expect(completed == bufs, false))
139 if (completed == completed_before)
141 assert(completed <= bufs);
142 assert(started <= bufs);
152 static void run_host(void)
154 int completed_before;
157 int bufs = runcycles;
170 completed_before = completed;
171 while (__builtin_expect(use_buf(&len, &buf), true)) {
175 if (__builtin_expect(completed == bufs, false))
178 if (completed == completed_before)
180 assert(completed <= bufs);
181 if (completed == bufs)
186 void *start_guest(void *arg)
193 void *start_host(void *arg)
200 static const char optstring[] = "";
201 static const struct option longopts[] = {
204 .has_arg = no_argument,
208 .name = "host-affinity",
209 .has_arg = required_argument,
213 .name = "guest-affinity",
214 .has_arg = required_argument,
219 .has_arg = required_argument,
223 .name = "run-cycles",
224 .has_arg = required_argument,
228 .name = "outstanding",
229 .has_arg = required_argument,
234 .has_arg = required_argument,
239 .has_arg = no_argument,
244 .has_arg = no_argument,
249 .has_arg = no_argument,
256 static void help(void)
258 fprintf(stderr, "Usage: <test> [--help]"
259 " [--host-affinity H]"
260 " [--guest-affinity G]"
261 " [--ring-size R (default: %d)]"
262 " [--run-cycles C (default: %d)]"
273 int main(int argc, char **argv)
276 pthread_t host, guest;
278 char *host_arg = NULL;
279 char *guest_arg = NULL;
283 kickfd = eventfd(0, 0);
285 callfd = eventfd(0, 0);
289 int o = getopt_long(argc, argv, optstring, longopts, NULL);
303 ring_size = strtol(optarg, &endptr, 0);
304 assert(ring_size && !(ring_size & (ring_size - 1)));
308 c = strtol(optarg, &endptr, 0);
310 assert(c > 0 && c < INT_MAX);
314 c = strtol(optarg, &endptr, 0);
316 assert(c > 0 && c < INT_MAX);
320 c = strtol(optarg, &endptr, 0);
322 assert(c > 0 && c < INT_MAX);
341 /* does nothing here, used to make sure all smp APIs compile */
347 if (batch > max_outstanding)
348 batch = max_outstanding;
356 ret = pthread_create(&host, NULL, start_host, host_arg);
358 ret = pthread_create(&guest, NULL, start_guest, guest_arg);
361 ret = pthread_join(guest, &tret);
363 ret = pthread_join(host, &tret);