1e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* 2e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 3e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * sched-messaging.c 4e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 5e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * messaging: Benchmark for scheduler and IPC mechanisms 6e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 7e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Based on hackbench by Rusty Russell <rusty@rustcorp.com.au> 8e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> 9e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 10e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 11e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 12e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../perf.h" 13e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../util/util.h" 14e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../util/parse-options.h" 15e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../builtin.h" 16e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "bench.h" 17e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 18e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* Test groups of 20 processes spraying to 20 receivers */ 19e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* ANDROID_CHANGE_BEGIN */ 20e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#ifdef __BIONIC__ 21e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <asm/page.h> 22e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif 23e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* ANDROID_CHANGE_END */ 24e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <pthread.h> 25e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <stdio.h> 26e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <stdlib.h> 27e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <string.h> 28e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <errno.h> 29e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <unistd.h> 30e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/types.h> 31e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/socket.h> 32e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/wait.h> 33e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/time.h> 34e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/poll.h> 35e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <limits.h> 36e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 37e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define DATASIZE 100 38e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 39e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic bool use_pipes = false; 40e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned int loops = 100; 41e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic bool thread_mode = false; 42e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned int num_groups = 10; 43e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 44e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct sender_context { 45e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int num_fds; 46e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ready_out; 47e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int wakefd; 48e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int out_fds[0]; 49e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 50e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 51e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct receiver_context { 52e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int num_packets; 53e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int in_fds[2]; 54e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ready_out; 55e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int wakefd; 56e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 57e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 58e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void barf(const char *msg) 59e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 60e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno)); 61e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng exit(1); 62e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 63e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 64e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void fdpair(int fds[2]) 65e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 66e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (use_pipes) { 67e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (pipe(fds) == 0) 68e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 69e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 70e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0) 71e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 72e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 73e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 74e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf(use_pipes ? "pipe()" : "socketpair()"); 75e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 76e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 77e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* Block until we're ready to go */ 78e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void ready(int ready_out, int wakefd) 79e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 80e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char dummy; 81e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct pollfd pollfd = { .fd = wakefd, .events = POLLIN }; 82e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 83e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Tell them we're ready. */ 84e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (write(ready_out, &dummy, 1) != 1) 85e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("CLIENT: ready write"); 86e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 87e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Wait for "GO" signal */ 88e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (poll(&pollfd, 1, -1) != 1) 89e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("poll"); 90e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 91e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 92e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* Sender sprays loops messages down each file descriptor */ 93e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void *sender(struct sender_context *ctx) 94e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 95e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char data[DATASIZE]; 96e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int i, j; 97e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 98e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ready(ctx->ready_out, ctx->wakefd); 99e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Now pump to every receiver. */ 101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < loops; i++) { 102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (j = 0; j < ctx->num_fds; j++) { 103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ret, done = 0; 104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengagain: 106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = write(ctx->out_fds[j], data + done, 107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sizeof(data)-done); 108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (ret < 0) 109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("SENDER: write"); 110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng done += ret; 111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (done < DATASIZE) 112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto again; 113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return NULL; 117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* One receiver per fd */ 121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void *receiver(struct receiver_context* ctx) 122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int i; 124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!thread_mode) 126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng close(ctx->in_fds[1]); 127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Wait for start... */ 129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ready(ctx->ready_out, ctx->wakefd); 130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Receive them all */ 132e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < ctx->num_packets; i++) { 133e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char data[DATASIZE]; 134e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ret, done = 0; 135e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 136e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengagain: 137e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = read(ctx->in_fds[0], data + done, DATASIZE - done); 138e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (ret < 0) 139e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("SERVER: read"); 140e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng done += ret; 141e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (done < DATASIZE) 142e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto again; 143e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 144e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 145e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return NULL; 146e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 147e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 148e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic pthread_t create_worker(void *ctx, void *(*func)(void *)) 149e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 150e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_attr_t attr; 151e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_t childid; 152e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int err; 153e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 154e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!thread_mode) { 155e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* process mode */ 156e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Fork the receiver. */ 157e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng switch (fork()) { 158e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case -1: 159e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("fork()"); 160e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 161e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case 0: 162e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (*func) (ctx); 163e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng exit(0); 164e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 165e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng default: 166e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 167e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 168e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 169e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return (pthread_t)0; 170e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 171e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 172e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (pthread_attr_init(&attr) != 0) 173e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("pthread_attr_init:"); 174e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 175e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#ifndef __ia64__ 176e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0) 177e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("pthread_attr_setstacksize"); 178e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif 179e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 180e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = pthread_create(&childid, &attr, func, ctx); 181e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (err != 0) { 182e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fprintf(stderr, "pthread_create failed: %s (%d)\n", 183e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng strerror(err), err); 184e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng exit(-1); 185e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 186e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return childid; 187e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 188e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 189e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void reap_worker(pthread_t id) 190e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 191e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int proc_status; 192e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void *thread_status; 193e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 194e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!thread_mode) { 195e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* process mode */ 196e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wait(&proc_status); 197e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!WIFEXITED(proc_status)) 198e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng exit(1); 199e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 200e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_join(id, &thread_status); 201e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 202e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 203e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 204e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* One group of senders and receivers */ 205e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic unsigned int group(pthread_t *pth, 206e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int num_fds, 207e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ready_out, 208e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int wakefd) 209e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 210e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int i; 211e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sender_context *snd_ctx = malloc(sizeof(struct sender_context) 212e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng + num_fds * sizeof(int)); 213e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 214e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!snd_ctx) 215e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("malloc()"); 216e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 217e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < num_fds; i++) { 218e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int fds[2]; 219e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct receiver_context *ctx = malloc(sizeof(*ctx)); 220e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 221e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!ctx) 222e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("malloc()"); 223e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 224e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 225e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Create the pipe between client and server */ 226e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fdpair(fds); 227e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 228e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ctx->num_packets = num_fds * loops; 229e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ctx->in_fds[0] = fds[0]; 230e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ctx->in_fds[1] = fds[1]; 231e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ctx->ready_out = ready_out; 232e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ctx->wakefd = wakefd; 233e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 234e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pth[i] = create_worker(ctx, (void *)receiver); 235e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 236e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng snd_ctx->out_fds[i] = fds[1]; 237e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!thread_mode) 238e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng close(fds[0]); 239e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 240e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 241e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Now we have all the fds, fork the senders */ 242e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < num_fds; i++) { 243e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng snd_ctx->ready_out = ready_out; 244e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng snd_ctx->wakefd = wakefd; 245e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng snd_ctx->num_fds = num_fds; 246e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 247e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pth[num_fds+i] = create_worker(snd_ctx, (void *)sender); 248e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 249e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 250e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Close the fds we have left */ 251e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!thread_mode) 252e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < num_fds; i++) 253e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng close(snd_ctx->out_fds[i]); 254e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 255e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Return number of children to reap */ 256e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return num_fds * 2; 257e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 258e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 259e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const struct option options[] = { 260e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_BOOLEAN('p', "pipe", &use_pipes, 261e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "Use pipe() instead of socketpair()"), 262e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_BOOLEAN('t', "thread", &thread_mode, 263e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "Be multi thread instead of multi process"), 264e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"), 265e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"), 266e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng OPT_END() 267e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 268e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 269e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char * const bench_sched_message_usage[] = { 270e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "perf bench sched messaging <options>", 271e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng NULL 272e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 273e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 274e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint bench_sched_messaging(int argc, const char **argv, 275e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *prefix __used) 276e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 277e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int i, total_children; 278e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct timeval start, stop, diff; 279e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int num_fds = 20; 280e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int readyfds[2], wakefds[2]; 281e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char dummy; 282e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_t *pth_tab; 283e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 284e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng argc = parse_options(argc, argv, options, 285e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng bench_sched_message_usage, 0); 286e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 287e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t)); 288e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!pth_tab) 289e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("main:malloc()"); 290e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 291e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fdpair(readyfds); 292e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fdpair(wakefds); 293e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 294e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng total_children = 0; 295e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < num_groups; i++) 296e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng total_children += group(pth_tab+total_children, num_fds, 297e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng readyfds[1], wakefds[0]); 298e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 299e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Wait for everyone to be ready */ 300e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < total_children; i++) 301e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (read(readyfds[0], &dummy, 1) != 1) 302e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("Reading for readyfds"); 303e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 304e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng gettimeofday(&start, NULL); 305e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 306e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Kick them off */ 307e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (write(wakefds[1], &dummy, 1) != 1) 308e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng barf("Writing to start them"); 309e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 310e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Reap them all */ 311e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < total_children; i++) 312e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng reap_worker(pth_tab[i]); 313e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 314e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng gettimeofday(&stop, NULL); 315e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 316e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng timersub(&stop, &start, &diff); 317e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 318e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng switch (bench_format) { 319e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case BENCH_FORMAT_DEFAULT: 320e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("# %d sender and receiver %s per group\n", 321e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng num_fds, thread_mode ? "threads" : "processes"); 322e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("# %d groups == %d %s run\n\n", 323e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng num_groups, num_groups * 2 * num_fds, 324e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_mode ? "threads" : "processes"); 325e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf(" %14s: %lu.%03lu [sec]\n", "Total time", 326e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng diff.tv_sec, 327e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (unsigned long) (diff.tv_usec/1000)); 328e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 329e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case BENCH_FORMAT_SIMPLE: 330e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng printf("%lu.%03lu\n", diff.tv_sec, 331e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (unsigned long) (diff.tv_usec/1000)); 332e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 333e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng default: 334e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* reaching here is something disaster */ 335e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fprintf(stderr, "Unknown format:%d\n", bench_format); 336e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng exit(1); 337e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 338e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 339e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 340e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 341e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 342