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