AHCI - Misc fixes
[dragonfly.git] / test / interbench / hackbench.c
blob641dd3d201abac7e7ec858b20cb9b47db0c32ee0
1 /* Test groups of 20 processes spraying to 20 receivers */
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <semaphore.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <sys/wait.h>
11 #include <sys/time.h>
12 #include <sys/poll.h>
13 #include "interbench.h"
15 #define DATASIZE 100
16 #define LOOPS 100
17 #define NUM_FDS 20
19 static inline void barf(const char *msg)
21 terminal_error(msg);
24 static void fdpair(int fds[2])
26 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1)
27 barf("Creating fdpair");
30 /* Block until we're ready to go */
31 static void ready(int ready_out, int wakefd)
33 char dummy;
34 struct pollfd pollfd = { .fd = wakefd, .events = POLLIN };
36 /* Tell them we're ready. */
37 if (write(ready_out, &dummy, 1) != 1)
38 barf("CLIENT: ready write");
40 /* Wait for "GO" signal */
41 if (poll(&pollfd, 1, -1) != 1)
42 barf("poll");
45 /* Sender sprays LOOPS messages down each file descriptor */
46 static void sender(int out_fd[NUM_FDS],
47 int ready_out,
48 int wakefd)
50 char data[DATASIZE];
51 unsigned int i, j;
53 ready(ready_out, wakefd);
55 /* Now pump to every receiver. */
56 for (i = 0; i < LOOPS; i++) {
57 for (j = 0; j < NUM_FDS; j++) {
58 int ret;
59 unsigned long done = 0;
61 again:
62 ret = write(out_fd[j], data + done, sizeof(data)-done);
63 if (ret < 0)
64 barf("SENDER: write");
65 done += ret;
66 if (done < sizeof(data))
67 goto again;
72 /* One receiver per fd */
73 static void receiver(unsigned int num_packets,
74 int in_fd,
75 int ready_out,
76 int wakefd)
78 unsigned int i;
80 /* Wait for start... */
81 ready(ready_out, wakefd);
83 /* Receive them all */
84 for (i = 0; i < num_packets; i++) {
85 char data[DATASIZE];
86 int ret, done = 0;
88 again:
89 ret = Read(in_fd, data + done, DATASIZE - done);
90 done += ret;
91 if (done < DATASIZE)
92 goto again;
96 /* One group of senders and receivers */
97 static unsigned int group(int ready_out,
98 int wakefd)
100 unsigned int i;
101 int out_fds[NUM_FDS];
103 for (i = 0; i < NUM_FDS; i++) {
104 int fds[2];
106 /* Create the pipe between client and server */
107 fdpair(fds);
109 /* Fork the receiver. */
110 switch (fork()) {
111 case -1: barf("fork()");
112 case 0:
113 close(fds[1]);
114 receiver(NUM_FDS*LOOPS, fds[0], ready_out, wakefd);
115 exit(0);
118 out_fds[i] = fds[1];
119 close(fds[0]);
122 /* Now we have all the fds, fork the senders */
123 for (i = 0; i < NUM_FDS; i++) {
124 switch (fork()) {
125 case -1: barf("fork()");
126 case 0:
127 sender(out_fds, ready_out, wakefd);
128 exit(0);
132 /* Close the fds we have left */
133 for (i = 0; i < NUM_FDS; i++)
134 close(out_fds[i]);
136 /* Return number of children to reap */
137 return NUM_FDS * 2;
140 void *hackbench_thread(void *t)
142 unsigned int i, num_groups, total_children;
143 int readyfds[2], wakefds[2];
144 char dummy;
146 num_groups = 50;
147 t = NULL;
149 fdpair(readyfds);
150 fdpair(wakefds);
152 while (1) {
153 total_children = 0;
154 for (i = 0; i < num_groups; i++)
155 total_children += group(readyfds[1], wakefds[0]);
157 /* Wait for everyone to be ready */
158 for (i = 0; i < total_children; i++)
159 if (Read(readyfds[0], &dummy, 1) != 1)
160 barf("Reading for readyfds");
162 /* Kick them off */
163 if (write(wakefds[1], &dummy, 1) != 1)
164 barf("Writing to start them");
166 /* Reap them all */
167 for (i = 0; i < total_children; i++) {
168 int status;
169 wait(&status);
170 if (!WIFEXITED(status))
171 exit(1);
173 if (!trywait_sem(&hackthread.sem.stop))
174 break;
177 post_sem(&hackthread.sem.complete);
178 return NULL;