Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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