5 #include <sys/resource.h>
10 static int n_children
= 3;
11 static int n_active_children
;
12 static int n_iters
= 10000;
13 static GMainLoop
*loop
;
16 io_pipe (GIOChannel
**channels
)
22 fprintf (stderr
, "Cannot create pipe %s\n", g_strerror (errno
));
26 channels
[0] = g_io_channel_unix_new (fds
[0]);
27 channels
[1] = g_io_channel_unix_new (fds
[1]);
31 read_all (GIOChannel
*channel
, char *buf
, int len
)
37 while (bytes_read
< len
)
39 err
= g_io_channel_read (channel
, buf
+ bytes_read
, len
- bytes_read
, &count
);
42 if (err
!= G_IO_ERROR_AGAIN
)
55 write_all (GIOChannel
*channel
, char *buf
, int len
)
57 int bytes_written
= 0;
61 while (bytes_written
< len
)
63 err
= g_io_channel_write (channel
, buf
+ bytes_written
, len
- bytes_written
, &count
);
64 if (err
&& err
!= G_IO_ERROR_AGAIN
)
67 bytes_written
+= count
;
74 run_child (GIOChannel
*in_channel
, GIOChannel
*out_channel
)
78 GTimer
*timer
= g_timer_new();
80 for (i
= 0; i
< n_iters
; i
++)
82 write_all (out_channel
, (char *)&val
, sizeof (val
));
83 read_all (in_channel
, (char *)&val
, sizeof (val
));
87 write_all (out_channel
, (char *)&val
, sizeof (val
));
89 val
= g_timer_elapsed (timer
, NULL
) * 1000;
91 write_all (out_channel
, (char *)&val
, sizeof (val
));
92 g_timer_destroy (timer
);
98 input_callback (GIOChannel
*source
,
99 GIOCondition condition
,
103 GIOChannel
*dest
= (GIOChannel
*)data
;
105 if (!read_all (source
, (char *)&val
, sizeof(val
)))
107 fprintf (stderr
, "Unexpected EOF\n");
113 write_all (dest
, (char *)&val
, sizeof(val
));
119 g_io_channel_close (source
);
120 g_io_channel_close (dest
);
122 g_io_channel_unref (source
);
123 g_io_channel_unref (dest
);
126 if (n_active_children
== 0)
137 GIOChannel
*in_channels
[2];
138 GIOChannel
*out_channels
[2];
140 io_pipe (in_channels
);
141 io_pipe (out_channels
);
145 if (pid
> 0) /* Parent */
147 g_io_channel_close (in_channels
[0]);
148 g_io_channel_close (out_channels
[1]);
150 g_io_add_watch (out_channels
[0], G_IO_IN
| G_IO_HUP
,
151 input_callback
, in_channels
[1]);
153 else if (pid
== 0) /* Child */
155 g_io_channel_close (in_channels
[1]);
156 g_io_channel_close (out_channels
[0]);
160 run_child (in_channels
[0], out_channels
[1]);
164 fprintf (stderr
, "Cannot fork: %s\n", g_strerror (errno
));
170 difftimeval (struct timeval
*old
, struct timeval
*new)
173 (new->tv_sec
- old
->tv_sec
) * 1000. + (new->tv_usec
- old
->tv_usec
) / 1000;
177 main (int argc
, char **argv
)
180 struct rusage old_usage
;
181 struct rusage new_usage
;
184 n_children
= atoi(argv
[1]);
187 n_iters
= atoi(argv
[2]);
189 printf ("Children: %d Iters: %d\n", n_children
, n_iters
);
191 n_active_children
= n_children
;
192 for (i
= 0; i
< n_children
; i
++)
195 getrusage (RUSAGE_SELF
, &old_usage
);
196 loop
= g_main_new (FALSE
);
198 getrusage (RUSAGE_SELF
, &new_usage
);
200 printf ("Elapsed user: %g\n",
201 difftimeval (&old_usage
.ru_utime
, &new_usage
.ru_utime
));
202 printf ("Elapsed system: %g\n",
203 difftimeval (&old_usage
.ru_stime
, &new_usage
.ru_stime
));
204 printf ("Elapsed total: %g\n",
205 difftimeval (&old_usage
.ru_utime
, &new_usage
.ru_utime
) +
206 difftimeval (&old_usage
.ru_stime
, &new_usage
.ru_stime
));
207 printf ("total / iteration: %g\n",
208 (difftimeval (&old_usage
.ru_utime
, &new_usage
.ru_utime
) +
209 difftimeval (&old_usage
.ru_stime
, &new_usage
.ru_stime
)) /
210 (n_iters
* n_children
));