~ubuntu-branches/ubuntu/utopic/glib2.0/utopic

« back to all changes in this revision

Viewing changes to tests/timeloop-basic.c

Tags: upstream-2.12.12
ImportĀ upstreamĀ versionĀ 2.12.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <sys/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