13 #include "../util/util.h"
14 #include "../util/parse-options.h"
15 #include "../builtin.h"
25 #include <sys/types.h>
26 #include <sys/socket.h>
34 static bool use_pipes =
false;
35 static unsigned int loops = 100;
36 static bool thread_mode =
false;
37 static unsigned int num_groups = 10;
53 static void barf(
const char *
msg)
59 static void fdpair(
int fds[2])
69 barf(use_pipes ?
"pipe()" :
"socketpair()");
73 static void ready(
int ready_out,
int wakefd)
79 if (
write(ready_out, &dummy, 1) != 1)
80 barf(
"CLIENT: ready write");
83 if (
poll(&pollfd, 1, -1) != 1)
96 for (i = 0; i < loops; i++) {
97 for (j = 0; j < ctx->
num_fds; j++) {
104 barf(
"SENDER: write");
134 barf(
"SERVER: read");
143 static pthread_t create_worker(
void *ctx,
void *(*
func)(
void *))
167 if (pthread_attr_init(&attr) != 0)
168 barf(
"pthread_attr_init:");
171 if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0)
172 barf(
"pthread_attr_setstacksize");
175 err = pthread_create(&childid, &attr,
func, ctx);
177 fprintf(stderr,
"pthread_create failed: %s (%d)\n",
184 static void reap_worker(pthread_t
id)
192 if (!WIFEXITED(proc_status))
195 pthread_join(
id, &thread_status);
200 static unsigned int group(pthread_t *pth,
201 unsigned int num_fds,
207 + num_fds *
sizeof(
int));
212 for (i = 0; i <
num_fds; i++) {
229 pth[
i] = create_worker(ctx, (
void *)
receiver);
237 for (i = 0; i < num_fds; i++) {
242 pth[num_fds+
i] = create_worker(snd_ctx, (
void *)sender);
247 for (i = 0; i < num_fds; i++)
256 "Use pipe() instead of socketpair()"),
258 "Be multi thread instead of multi process"),
259 OPT_UINTEGER(
'g',
"group", &num_groups,
"Specify number of groups"),
260 OPT_UINTEGER(
'l',
"loop", &loops,
"Specify number of loops"),
264 static const char *
const bench_sched_message_usage[] = {
265 "perf bench sched messaging <options>",
272 unsigned int i, total_children;
273 struct timeval start, stop, diff;
274 unsigned int num_fds = 20;
275 int readyfds[2], wakefds[2];
280 bench_sched_message_usage, 0);
282 pth_tab =
malloc(num_fds * 2 * num_groups *
sizeof(pthread_t));
284 barf(
"main:malloc()");
290 for (i = 0; i < num_groups; i++)
291 total_children +=
group(pth_tab+total_children, num_fds,
292 readyfds[1], wakefds[0]);
295 for (i = 0; i < total_children; i++)
296 if (
read(readyfds[0], &dummy, 1) != 1)
297 barf(
"Reading for readyfds");
302 if (
write(wakefds[1], &dummy, 1) != 1)
303 barf(
"Writing to start them");
306 for (i = 0; i < total_children; i++)
307 reap_worker(pth_tab[i]);
311 timersub(&stop, &start, &diff);
315 printf(
"# %d sender and receiver %s per group\n",
316 num_fds, thread_mode ?
"threads" :
"processes");
317 printf(
"# %d groups == %d %s run\n\n",
318 num_groups, num_groups * 2 * num_fds,
319 thread_mode ?
"threads" :
"processes");
320 printf(
" %14s: %lu.%03lu [sec]\n",
"Total time",
322 (
unsigned long) (diff.
tv_usec/1000));
326 (
unsigned long) (diff.
tv_usec/1000));