1 #undef G_DISABLE_ASSERT
9 #include <sys/resource.h>
13 static int n_children
= 3;
14 static int n_active_children
;
15 static int n_iters
= 10000;
16 static GMainLoop
*loop
;
19 io_pipe (GIOChannel
**channels
)
26 fprintf (stderr
, "Cannot create pipe %s\n", g_strerror (errsv
));
30 channels
[0] = g_io_channel_unix_new (fds
[0]);
31 channels
[1] = g_io_channel_unix_new (fds
[1]);
35 read_all (GIOChannel
*channel
, char *buf
, int len
)
41 while (bytes_read
< len
)
43 err
= g_io_channel_read (channel
, buf
+ bytes_read
, len
- bytes_read
, &count
);
46 if (err
!= G_IO_ERROR_AGAIN
)
59 write_all (GIOChannel
*channel
, char *buf
, int len
)
61 gsize bytes_written
= 0;
65 while (bytes_written
< len
)
67 err
= g_io_channel_write (channel
, buf
+ bytes_written
, len
- bytes_written
, &count
);
68 if (err
&& err
!= G_IO_ERROR_AGAIN
)
71 bytes_written
+= count
;
78 run_child (GIOChannel
*in_channel
, GIOChannel
*out_channel
)
82 GTimer
*timer
= g_timer_new();
84 for (i
= 0; i
< n_iters
; i
++)
86 write_all (out_channel
, (char *)&val
, sizeof (val
));
87 read_all (in_channel
, (char *)&val
, sizeof (val
));
91 write_all (out_channel
, (char *)&val
, sizeof (val
));
93 val
= g_timer_elapsed (timer
, NULL
) * 1000;
95 write_all (out_channel
, (char *)&val
, sizeof (val
));
96 g_timer_destroy (timer
);
102 input_callback (GIOChannel
*source
,
103 GIOCondition condition
,
107 GIOChannel
*dest
= (GIOChannel
*)data
;
109 if (!read_all (source
, (char *)&val
, sizeof(val
)))
111 fprintf (stderr
, "Unexpected EOF\n");
117 write_all (dest
, (char *)&val
, sizeof(val
));
123 g_io_channel_close (source
);
124 g_io_channel_close (dest
);
126 g_io_channel_unref (source
);
127 g_io_channel_unref (dest
);
130 if (n_active_children
== 0)
131 g_main_loop_quit (loop
);
141 GIOChannel
*in_channels
[2];
142 GIOChannel
*out_channels
[2];
144 io_pipe (in_channels
);
145 io_pipe (out_channels
);
150 if (pid
> 0) /* Parent */
152 g_io_channel_close (in_channels
[0]);
153 g_io_channel_unref (in_channels
[0]);
154 g_io_channel_close (out_channels
[1]);
155 g_io_channel_unref (out_channels
[1]);
157 g_io_add_watch (out_channels
[0], G_IO_IN
| G_IO_HUP
,
158 input_callback
, in_channels
[1]);
160 else if (pid
== 0) /* Child */
162 g_io_channel_close (in_channels
[1]);
163 g_io_channel_close (out_channels
[0]);
167 run_child (in_channels
[0], out_channels
[1]);
171 fprintf (stderr
, "Cannot fork: %s\n", g_strerror (errsv
));
177 difftimeval (struct timeval
*old
, struct timeval
*new)
180 (new->tv_sec
- old
->tv_sec
) * 1000. + (new->tv_usec
- old
->tv_usec
) / 1000;
184 main (int argc
, char **argv
)
187 struct rusage old_usage
;
188 struct rusage new_usage
;
191 n_children
= atoi(argv
[1]);
194 n_iters
= atoi(argv
[2]);
196 printf ("Children: %d Iters: %d\n", n_children
, n_iters
);
198 n_active_children
= n_children
;
199 for (i
= 0; i
< n_children
; i
++)
202 getrusage (RUSAGE_SELF
, &old_usage
);
203 loop
= g_main_loop_new (NULL
, FALSE
);
204 g_main_loop_run (loop
);
205 getrusage (RUSAGE_SELF
, &new_usage
);
207 printf ("Elapsed user: %g\n",
208 difftimeval (&old_usage
.ru_utime
, &new_usage
.ru_utime
));
209 printf ("Elapsed system: %g\n",
210 difftimeval (&old_usage
.ru_stime
, &new_usage
.ru_stime
));
211 printf ("Elapsed total: %g\n",
212 difftimeval (&old_usage
.ru_utime
, &new_usage
.ru_utime
) +
213 difftimeval (&old_usage
.ru_stime
, &new_usage
.ru_stime
));
214 printf ("total / iteration: %g\n",
215 (difftimeval (&old_usage
.ru_utime
, &new_usage
.ru_utime
) +
216 difftimeval (&old_usage
.ru_stime
, &new_usage
.ru_stime
)) /
217 (n_iters
* n_children
));
219 g_main_loop_unref (loop
);