glib/tests/timeloop.c
branchRCL_3
changeset 56 acd3cd4aaceb
equal deleted inserted replaced
54:4332f0f7be53 56:acd3cd4aaceb
       
     1 /* Portion Copyright © 2008-09 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.*/
       
     2 #undef G_DISABLE_ASSERT
       
     3 #undef G_LOG_DOMAIN
       
     4 
       
     5 #include <errno.h>
       
     6 #include <stdlib.h>
       
     7 #include <unistd.h>
       
     8 #include <stdio.h>
       
     9 #include <sys/time.h>
       
    10 #include <sys/resource.h>
       
    11 
       
    12 #include <glib.h>
       
    13 
       
    14 #ifdef __SYMBIAN32__
       
    15 #include <glib_global.h>
       
    16 #include "mrt2_glib2_test.h"
       
    17 #endif /*__SYMBIAN32__*/
       
    18 
       
    19 
       
    20 static int n_children = 3;
       
    21 static int n_active_children;
       
    22 static int n_iters = 10000;
       
    23 static GMainLoop *loop;
       
    24 
       
    25 static void
       
    26 io_pipe (GIOChannel **channels)
       
    27 {
       
    28   int fds[2];
       
    29 
       
    30   if (pipe(fds) < 0)
       
    31     {
       
    32       g_print ("Cannot create pipe %s\n", g_strerror (errno));
       
    33       g_assert(FALSE && "timeloop failed");  
       
    34 #ifdef __SYMBIAN32__
       
    35   testResultXml("timeloop");
       
    36 #endif /* EMULATOR */
       
    37       exit (1);
       
    38     }
       
    39 
       
    40   channels[0] = g_io_channel_unix_new (fds[0]);
       
    41   channels[1] = g_io_channel_unix_new (fds[1]);
       
    42 }
       
    43 
       
    44 static gboolean
       
    45 read_all (GIOChannel *channel, char *buf, int len)
       
    46 {
       
    47   gsize bytes_read = 0;
       
    48   gsize count;
       
    49   GIOError err;
       
    50 
       
    51   while (bytes_read < len)
       
    52     {
       
    53       err = g_io_channel_read (channel, buf + bytes_read, len - bytes_read, &count);
       
    54       if (err)
       
    55 	{
       
    56 	  if (err != G_IO_ERROR_AGAIN)
       
    57 	  {
       
    58 	  	g_assert(FALSE && "timeloop failed");
       
    59 	    return FALSE;
       
    60 	  }
       
    61 	}
       
    62       else if (count == 0)
       
    63 	return FALSE;
       
    64 
       
    65       bytes_read += count;
       
    66     }
       
    67 
       
    68   return TRUE;
       
    69 }
       
    70 
       
    71 static gboolean
       
    72 write_all (GIOChannel *channel, char *buf, int len)
       
    73 {
       
    74   gsize bytes_written = 0;
       
    75   gsize count;
       
    76   GIOError err;
       
    77 
       
    78   while (bytes_written < len)
       
    79     {
       
    80       err = g_io_channel_write (channel, buf + bytes_written, len - bytes_written, &count);
       
    81       if (err && err != G_IO_ERROR_AGAIN)
       
    82 	return FALSE;
       
    83 
       
    84       bytes_written += count;
       
    85     }
       
    86 
       
    87   return TRUE;
       
    88 }
       
    89 
       
    90 #ifndef __SYMBIAN32__
       
    91 static void
       
    92 run_child (GIOChannel *in_channel, GIOChannel *out_channel)
       
    93 #else
       
    94 gpointer
       
    95 run_child (gpointer data)
       
    96 #endif//__SYMBIAN32__
       
    97 {
       
    98   int i;
       
    99   int val = 1;
       
   100 #ifdef __SYMBIAN32__
       
   101 GIOChannel *in_channel,*out_channel;
       
   102 #endif//__SYMBIAN32__
       
   103   GTimer *timer = g_timer_new();
       
   104 #ifdef __SYMBIAN32__  
       
   105   GIOChannel **channels = data;  
       
   106   in_channel = channels[0];
       
   107   out_channel = channels[1];
       
   108 #endif//__SYMBIAN32__
       
   109   for (i = 0; i < n_iters; i++)
       
   110     {
       
   111       write_all (out_channel, (char *)&val, sizeof (val));
       
   112       read_all (in_channel, (char *)&val, sizeof (val));
       
   113     }
       
   114 
       
   115   val = 0;
       
   116   write_all (out_channel, (char *)&val, sizeof (val));
       
   117 
       
   118   val = g_timer_elapsed (timer, NULL) * 1000;
       
   119   
       
   120   write_all (out_channel, (char *)&val, sizeof (val));
       
   121   g_timer_destroy (timer);
       
   122 #ifndef __SYMBIAN32__ 
       
   123   exit (0);
       
   124 #else
       
   125   return NULL;
       
   126 #endif//__SYMBIAN32__  
       
   127 }
       
   128 
       
   129 static gboolean
       
   130 input_callback (GIOChannel   *source,
       
   131 		GIOCondition  condition,
       
   132 		gpointer      data)
       
   133 {
       
   134   int val;
       
   135   GIOChannel *dest = (GIOChannel *)data;
       
   136   
       
   137   if (!read_all (source, (char *)&val, sizeof(val)))
       
   138     {
       
   139       g_print("Unexpected EOF\n");
       
   140       g_assert(FALSE && "timeloop failed");
       
   141 #ifdef __SYMBIAN32__
       
   142   testResultXml("timeloop");
       
   143 #endif /* EMULATOR */
       
   144       exit (1);
       
   145     }
       
   146 
       
   147   if (val)
       
   148     {
       
   149       write_all (dest, (char *)&val, sizeof(val));
       
   150       
       
   151       return TRUE;
       
   152     }
       
   153   else
       
   154     {
       
   155       g_io_channel_close (source);
       
   156       g_io_channel_close (dest);
       
   157       
       
   158       g_io_channel_unref (source);
       
   159       g_io_channel_unref (dest);
       
   160 
       
   161       n_active_children--;
       
   162       if (n_active_children == 0)
       
   163 	g_main_loop_quit (loop);
       
   164       
       
   165       return FALSE;
       
   166     }
       
   167 }
       
   168 
       
   169 static void
       
   170 create_child (void)
       
   171 {
       
   172 #ifndef __SYMBIAN32__
       
   173   int pid;
       
   174 #else  
       
   175   GError *err = NULL;
       
   176 #endif//__SYMBIAN32__    
       
   177   GIOChannel *in_channels[2];
       
   178   GIOChannel *out_channels[2];
       
   179 #ifdef __SYMBIAN32__  
       
   180   GIOChannel **sub_channels;
       
   181   
       
   182   sub_channels = g_new (GIOChannel *, 2);
       
   183   
       
   184   io_pipe (in_channels);
       
   185   io_pipe (out_channels);
       
   186   sub_channels[0] = in_channels[0];
       
   187   sub_channels[1] = out_channels[1];
       
   188 
       
   189   g_io_add_watch (out_channels[0], G_IO_IN | G_IO_HUP,
       
   190 		      input_callback, in_channels[1]);
       
   191   
       
   192   g_thread_create(run_child,sub_channels,FALSE,&err);
       
   193 #else
       
   194   pid = fork ();
       
   195 
       
   196   if (pid > 0)			/* Parent */
       
   197     {
       
   198       g_io_channel_close (in_channels[0]);
       
   199       g_io_channel_close (out_channels[1]);
       
   200 
       
   201       g_io_add_watch (out_channels[0], G_IO_IN | G_IO_HUP,
       
   202 		      input_callback, in_channels[1]);
       
   203     }
       
   204   else if (pid == 0)		/* Child */
       
   205     {
       
   206       g_io_channel_close (in_channels[1]);
       
   207       g_io_channel_close (out_channels[0]);
       
   208 
       
   209       setsid ();
       
   210 
       
   211       run_child (in_channels[0], out_channels[1]);
       
   212     }
       
   213   else				/* Error */
       
   214     {
       
   215       fprintf (stderr, "Cannot fork: %s\n", g_strerror (errno));
       
   216       exit (1);
       
   217     }
       
   218 #endif//__SYMBIAN32__	
       
   219 }
       
   220 
       
   221 static double 
       
   222 difftimeval (struct timeval *old, struct timeval *new)
       
   223 {
       
   224   return
       
   225     (new->tv_sec - old->tv_sec) * 1000. + (new->tv_usec - old->tv_usec) / 1000;
       
   226 }
       
   227 
       
   228 int 
       
   229 main (int argc, char **argv)
       
   230 {
       
   231   int i;
       
   232   
       
   233   #ifdef __SYMBIAN32__
       
   234   g_log_set_handler (NULL,  G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL);
       
   235   g_set_print_handler(mrtPrintHandler);
       
   236   g_thread_init(NULL);
       
   237   #endif /*__SYMBIAN32__*/
       
   238 	  
       
   239   
       
   240   if (argc > 1)
       
   241     n_children = atoi(argv[1]);
       
   242 
       
   243   if (argc > 2)
       
   244     n_iters = atoi(argv[2]);
       
   245 
       
   246   printf ("Children: %d     Iters: %d\n", n_children, n_iters);
       
   247 
       
   248   n_active_children = n_children;
       
   249   for (i = 0; i < n_children; i++)
       
   250     create_child ();
       
   251 #ifndef __SYMBIAN32__
       
   252   getrusage (RUSAGE_SELF, &old_usage);
       
   253 #endif  
       
   254   loop = g_main_loop_new (NULL, FALSE);
       
   255   g_main_loop_run (loop);
       
   256 #ifndef __SYMBIAN32__   
       
   257   getrusage (RUSAGE_SELF, &new_usage);
       
   258 
       
   259   printf ("Elapsed user: %g\n",
       
   260 	  difftimeval (&old_usage.ru_utime, &new_usage.ru_utime));
       
   261   printf ("Elapsed system: %g\n",
       
   262 	  difftimeval (&old_usage.ru_stime, &new_usage.ru_stime));
       
   263   printf ("Elapsed total: %g\n",
       
   264 	  difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) +	   
       
   265 	  difftimeval (&old_usage.ru_stime, &new_usage.ru_stime));
       
   266   printf ("total / iteration: %g\n",
       
   267 	  (difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) +	   
       
   268 	   difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)) /
       
   269 	  (n_iters * n_children));
       
   270 #endif	  
       
   271   #ifdef __SYMBIAN32__
       
   272   testResultXml("timeloop");
       
   273   #endif /* EMULATOR */
       
   274 
       
   275   return 0;
       
   276 }