nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #undef G_DISABLE_ASSERT |
2 | #undef G_LOG_DOMAIN |
||
3 | |||
4 | #include <errno.h> |
||
5 | #include <stdlib.h> |
||
6 | #include <stdio.h> |
||
7 | #include <string.h> |
||
8 | #include <unistd.h> |
||
9 | #include <sys/resource.h> |
||
10 | #include <sys/time.h> |
||
11 | #include <poll.h> |
||
12 | |||
13 | #define TRUE 1 |
||
14 | #define FALSE 0 |
||
15 | |||
16 | static int n_children = 3; |
||
17 | static int n_active_children; |
||
18 | static int n_iters = 10000; |
||
19 | |||
20 | static int write_fds[1024]; |
||
21 | static struct pollfd poll_fds[1024]; |
||
22 | |||
23 | void |
||
24 | my_pipe (int *fds) |
||
25 | { |
||
26 | if (pipe(fds) < 0) |
||
27 | { |
||
28 | fprintf (stderr, "Cannot create pipe %s\n", strerror (errno)); |
||
29 | exit (1); |
||
30 | } |
||
31 | } |
||
32 | |||
33 | int |
||
34 | read_all (int fd, char *buf, int len) |
||
35 | { |
||
36 | size_t bytes_read = 0; |
||
37 | ssize_t count; |
||
38 | |||
39 | while (bytes_read < len) |
||
40 | { |
||
41 | count = read (fd, buf + bytes_read, len - bytes_read); |
||
42 | if (count < 0) |
||
43 | { |
||
44 | if (errno != EAGAIN) |
||
45 | return FALSE; |
||
46 | } |
||
47 | else if (count == 0) |
||
48 | return FALSE; |
||
49 | |||
50 | bytes_read += count; |
||
51 | } |
||
52 | |||
53 | return TRUE; |
||
54 | } |
||
55 | |||
56 | int |
||
57 | write_all (int fd, char *buf, int len) |
||
58 | { |
||
59 | size_t bytes_written = 0; |
||
60 | ssize_t count; |
||
61 | |||
62 | while (bytes_written < len) |
||
63 | { |
||
64 | count = write (fd, buf + bytes_written, len - bytes_written); |
||
65 | if (count < 0) |
||
66 | { |
||
67 | if (errno != EAGAIN) |
||
68 | return FALSE; |
||
69 | } |
||
70 | |||
71 | bytes_written += count; |
||
72 | } |
||
73 | |||
74 | return TRUE; |
||
75 | } |
||
76 | |||
77 | void |
||
78 | run_child (int in_fd, int out_fd) |
||
79 | { |
||
80 | int i; |
||
81 | int val = 1; |
||
82 | |||
83 | for (i = 0; i < n_iters; i++) |
||
84 | { |
||
85 | write_all (out_fd, (char *)&val, sizeof (val)); |
||
86 | read_all (in_fd, (char *)&val, sizeof (val)); |
||
87 | } |
||
88 | |||
89 | val = 0; |
||
90 | write_all (out_fd, (char *)&val, sizeof (val)); |
||
91 | |||
92 | exit (0); |
||
93 | } |
||
94 | |||
95 | int |
||
96 | input_callback (int source, int dest) |
||
97 | { |
||
98 | int val; |
||
99 | |||
100 | if (!read_all (source, (char *)&val, sizeof(val))) |
||
101 | { |
||
102 | fprintf (stderr,"Unexpected EOF\n"); |
||
103 | exit (1); |
||
104 | } |
||
105 | |||
106 | if (val) |
||
107 | { |
||
108 | write_all (dest, (char *)&val, sizeof(val)); |
||
109 | return TRUE; |
||
110 | } |
||
111 | else |
||
112 | { |
||
113 | close (source); |
||
114 | close (dest); |
||
115 | |||
116 | n_active_children--; |
||
117 | return FALSE; |
||
118 | } |
||
119 | } |
||
120 | |||
121 | void |
||
122 | create_child (int pos) |
||
123 | { |
||
124 | int pid; |
||
125 | int in_fds[2]; |
||
126 | int out_fds[2]; |
||
127 | |||
128 | my_pipe (in_fds); |
||
129 | my_pipe (out_fds); |
||
130 | |||
131 | pid = fork (); |
||
132 | |||
133 | if (pid > 0) /* Parent */ |
||
134 | { |
||
135 | close (in_fds[0]); |
||
136 | close (out_fds[1]); |
||
137 | |||
138 | write_fds[pos] = in_fds[1]; |
||
139 | poll_fds[pos].fd = out_fds[0]; |
||
140 | poll_fds[pos].events = POLLIN; |
||
141 | } |
||
142 | else if (pid == 0) /* Child */ |
||
143 | { |
||
144 | close (in_fds[1]); |
||
145 | close (out_fds[0]); |
||
146 | |||
147 | setsid (); |
||
148 | |||
149 | run_child (in_fds[0], out_fds[1]); |
||
150 | } |
||
151 | else /* Error */ |
||
152 | { |
||
153 | fprintf (stderr,"Cannot fork: %s\n", strerror (errno)); |
||
154 | exit (1); |
||
155 | } |
||
156 | } |
||
157 | |||
158 | static double |
||
159 | difftimeval (struct timeval *old, struct timeval *new) |
||
160 | { |
||
161 | return |
||
162 | (new->tv_sec - old->tv_sec) * 1000. + (new->tv_usec - old->tv_usec) / 1000; |
||
163 | } |
||
164 | |||
165 | int |
||
166 | main (int argc, char **argv) |
||
167 | { |
||
168 | int i, j; |
||
169 | struct rusage old_usage; |
||
170 | struct rusage new_usage; |
||
171 | |||
172 | if (argc > 1) |
||
173 | n_children = atoi(argv[1]); |
||
174 | |||
175 | if (argc > 2) |
||
176 | n_iters = atoi(argv[2]); |
||
177 | |||
178 | printf ("Children: %d Iters: %d\n", n_children, n_iters); |
||
179 | |||
180 | n_active_children = n_children; |
||
181 | for (i = 0; i < n_children; i++) |
||
182 | create_child (i); |
||
183 | |||
184 | getrusage (RUSAGE_SELF, &old_usage); |
||
185 | |||
186 | while (n_active_children > 0) |
||
187 | { |
||
188 | int old_n_active_children = n_active_children; |
||
189 | |||
190 | poll (poll_fds, n_active_children, -1); |
||
191 | |||
192 | for (i=0; i<n_active_children; i++) |
||
193 | { |
||
194 | if (poll_fds[i].events & (POLLIN | POLLHUP)) |
||
195 | { |
||
196 | if (!input_callback (poll_fds[i].fd, write_fds[i])) |
||
197 | write_fds[i] = -1; |
||
198 | } |
||
199 | } |
||
200 | |||
201 | if (old_n_active_children > n_active_children) |
||
202 | { |
||
203 | j = 0; |
||
204 | for (i=0; i<old_n_active_children; i++) |
||
205 | { |
||
206 | if (write_fds[i] != -1) |
||
207 | { |
||
208 | if (j < i) |
||
209 | { |
||
210 | poll_fds[j] = poll_fds[i]; |
||
211 | write_fds[j] = write_fds[i]; |
||
212 | } |
||
213 | j++; |
||
214 | } |
||
215 | } |
||
216 | } |
||
217 | } |
||
218 | |||
219 | getrusage (RUSAGE_SELF, &new_usage); |
||
220 | |||
221 | printf ("Elapsed user: %g\n", |
||
222 | difftimeval (&old_usage.ru_utime, &new_usage.ru_utime)); |
||
223 | printf ("Elapsed system: %g\n", |
||
224 | difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)); |
||
225 | printf ("Elapsed total: %g\n", |
||
226 | difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) + |
||
227 | difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)); |
||
228 | printf ("total / iteration: %g\n", |
||
229 | (difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) + |
||
230 | difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)) / |
||
231 | (n_iters * n_children)); |
||
232 | |||
233 | return 0; |
||
234 | } |
||
235 |