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
;
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
);