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