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