1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* test-profile.c Program that does basic message-response for timing; doesn't really use glib bindings
4 * Copyright (C) 2003, 2004 Red Hat Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <dbus/dbus-glib-lowlevel.h>
32 #include <sys/socket.h>
34 #include <netinet/in.h>
38 #ifndef HAVE_SOCKLEN_T
42 #define _DBUS_ZERO(object) (memset (&(object), '\0', sizeof ((object))))
43 #define _DBUS_MAX_SUN_PATH_LENGTH 99
45 /* Note that if you set threads > 1 you get a bogus profile since the
46 * clients start blocking on the server, so the client write() will go
47 * higher in the profile the larger the number of threads.
49 #define N_CLIENT_THREADS 1
50 /* It seems like at least 750000 or so iterations reduces the variability to sane levels */
51 #define N_ITERATIONS 750000
52 #define N_PROGRESS_UPDATES 20
53 /* Don't make PAYLOAD_SIZE too huge because it gets used as a static buffer size */
54 #define PAYLOAD_SIZE 0
56 #define ECHO_SERVICE "org.freedesktop.EchoTestServer"
57 #define ECHO_PATH "/org/freedesktop/EchoTest"
58 #define ECHO_INTERFACE "org.freedesktop.EchoTest"
59 #define ECHO_PING_METHOD "Ping"
61 static const char *messages_address;
62 static const char *plain_sockets_address;
63 static unsigned char *payload;
64 static int echo_call_size;
65 static int echo_return_size;
67 typedef struct ProfileRunVTable ProfileRunVTable;
71 const ProfileRunVTable *vtable;
78 const ProfileRunVTable *vtable;
84 struct ProfileRunVTable
87 gboolean fake_malloc_overhead;
88 void* (* init_server) (ServerData *sd);
89 void (* stop_server) (ServerData *sd,
91 void* (* client_thread_func) (void *data); /* Data has to be the vtable */
93 /* this is so different runs show up in the profiler with
96 void (* main_loop_run_func) (GMainLoop *loop);
99 /* Note, this is all crack-a-rific; it isn't using DBusGProxy and thus is
103 send_echo_method_call (DBusConnection *connection)
105 DBusMessage *message;
106 const char *hello = "Hello World!";
107 dbus_int32_t i32 = 123456;
109 message = dbus_message_new_method_call (ECHO_SERVICE,
113 dbus_message_append_args (message,
114 DBUS_TYPE_STRING, &hello,
115 DBUS_TYPE_INT32, &i32,
117 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
118 &payload, PAYLOAD_SIZE,
122 dbus_connection_send (connection, message, NULL);
123 dbus_message_unref (message);
124 dbus_connection_flush (connection);
128 send_echo_method_return (DBusConnection *connection,
129 DBusMessage *call_message)
131 DBusMessage *message;
133 message = dbus_message_new_method_return (call_message);
135 dbus_connection_send (connection, message, NULL);
136 dbus_message_unref (message);
137 dbus_connection_flush (connection);
140 static DBusHandlerResult
141 with_or_without_bus_client_filter (DBusConnection *connection,
142 DBusMessage *message,
145 if (dbus_message_is_signal (message,
146 DBUS_INTERFACE_LOCAL,
149 g_printerr ("Client thread disconnected\n");
152 else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
155 if (cd->iterations >= N_ITERATIONS)
157 g_printerr ("\nCompleted %d iterations\n", N_ITERATIONS);
158 g_main_loop_quit (cd->loop);
160 else if (cd->iterations % (N_ITERATIONS/N_PROGRESS_UPDATES) == 0)
162 g_printerr ("%d%% ", (int) (cd->iterations/(double)N_ITERATIONS * 100.0));
165 send_echo_method_call (connection);
166 return DBUS_HANDLER_RESULT_HANDLED;
169 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
172 static DBusHandlerResult
173 no_bus_client_filter (DBusConnection *connection,
174 DBusMessage *message,
177 ClientData *cd = user_data;
179 return with_or_without_bus_client_filter (connection, message, cd);
183 no_bus_thread_func (void *data)
186 GMainContext *context;
187 DBusConnection *connection;
190 g_printerr ("Starting client thread %p\n", g_thread_self());
192 dbus_error_init (&error);
193 connection = dbus_connection_open_private (messages_address, &error);
194 if (connection == NULL)
196 g_printerr ("could not open connection: %s\n", error.message);
197 dbus_error_free (&error);
201 context = g_main_context_new ();
204 cd.loop = g_main_loop_new (context, FALSE);
206 if (!dbus_connection_add_filter (connection,
207 no_bus_client_filter, &cd, NULL))
208 g_error ("no memory");
211 dbus_connection_setup_with_g_main (connection, context);
213 g_printerr ("Client thread sending message to prime pingpong\n");
214 send_echo_method_call (connection);
215 g_printerr ("Client thread sent message\n");
217 g_printerr ("Client thread entering main loop\n");
218 g_main_loop_run (cd.loop);
219 g_printerr ("Client thread %p exiting main loop\n",
222 dbus_connection_close (connection);
224 g_main_loop_unref (cd.loop);
225 g_main_context_unref (context);
230 static DBusHandlerResult
231 no_bus_server_filter (DBusConnection *connection,
232 DBusMessage *message,
235 ServerData *sd = user_data;
237 if (dbus_message_is_signal (message,
238 DBUS_INTERFACE_LOCAL,
241 g_printerr ("Client disconnected from server\n");
243 if (sd->n_clients == 0)
244 g_main_loop_quit (sd->loop);
246 else if (dbus_message_is_method_call (message,
251 send_echo_method_return (connection, message);
252 return DBUS_HANDLER_RESULT_HANDLED;
255 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
259 no_bus_new_connection_callback (DBusServer *server,
260 DBusConnection *new_connection,
263 ServerData *sd = user_data;
265 dbus_connection_ref (new_connection);
266 dbus_connection_setup_with_g_main (new_connection, NULL);
268 if (!dbus_connection_add_filter (new_connection,
269 no_bus_server_filter, sd, NULL))
270 g_error ("no memory");
274 /* FIXME we leak the handler */
278 no_bus_init_server (ServerData *sd)
283 dbus_error_init (&error);
284 server = dbus_server_listen ("unix:tmpdir="DBUS_TEST_SOCKET_DIR,
288 g_printerr ("Could not start server: %s\n",
293 messages_address = dbus_server_get_address (server);
295 dbus_server_set_new_connection_function (server,
296 no_bus_new_connection_callback,
299 dbus_server_setup_with_g_main (server, NULL);
305 no_bus_stop_server (ServerData *sd,
308 dbus_server_disconnect (server);
309 dbus_server_unref (server);
313 no_bus_main_loop_run (GMainLoop *loop)
315 g_main_loop_run (loop);
318 static const ProfileRunVTable no_bus_vtable = {
319 "dbus direct without bus",
329 const ProfileRunVTable *vtable;
331 GHashTable *client_names;
332 DBusConnection *connection;
335 static DBusHandlerResult
336 with_bus_client_filter (DBusConnection *connection,
337 DBusMessage *message,
340 ClientData *cd = user_data;
342 return with_or_without_bus_client_filter (connection, message, cd);
346 with_bus_thread_func (void *data)
349 DBusConnection *connection;
352 GMainContext *context;
354 g_printerr ("Starting client thread %p\n", g_thread_self());
356 address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
359 g_printerr ("DBUS_SESSION_BUS_ADDRESS not set\n");
363 dbus_error_init (&error);
364 connection = dbus_connection_open_private (address, &error);
365 if (connection == NULL)
367 g_printerr ("could not open connection to bus: %s\n", error.message);
368 dbus_error_free (&error);
372 if (!dbus_bus_register (connection, &error))
374 g_printerr ("could not register with bus: %s\n", error.message);
375 dbus_error_free (&error);
379 context = g_main_context_new ();
382 cd.loop = g_main_loop_new (context, FALSE);
384 if (!dbus_connection_add_filter (connection,
385 with_bus_client_filter, &cd, NULL))
386 g_error ("no memory");
388 dbus_connection_setup_with_g_main (connection, context);
390 g_printerr ("Client thread sending message to prime pingpong\n");
391 send_echo_method_call (connection);
392 g_printerr ("Client thread sent message\n");
394 g_printerr ("Client thread entering main loop\n");
395 g_main_loop_run (cd.loop);
396 g_printerr ("Client thread %p exiting main loop\n",
399 dbus_connection_close (connection);
401 g_main_loop_unref (cd.loop);
402 g_main_context_unref (context);
407 static DBusHandlerResult
408 with_bus_server_filter (DBusConnection *connection,
409 DBusMessage *message,
412 WithBusServer *server = user_data;
414 if (dbus_message_is_signal (message,
415 DBUS_INTERFACE_LOCAL,
418 g_printerr ("Server disconnected from message bus\n");
421 else if (dbus_message_has_sender (message,
422 DBUS_SERVICE_DBUS) &&
423 dbus_message_is_signal (message,
427 const char *name, *old_owner, *new_owner;
434 dbus_error_init (&error);
435 if (!dbus_message_get_args (message,
437 DBUS_TYPE_STRING, &name,
438 DBUS_TYPE_STRING, &old_owner,
439 DBUS_TYPE_STRING, &new_owner,
442 g_printerr ("dbus_message_get_args(): %s\n", error.message);
446 if (g_hash_table_lookup (server->client_names,
448 *old_owner != '\0' &&
451 g_hash_table_remove (server->client_names,
453 server->sd->n_clients -= 1;
454 if (server->sd->n_clients == 0)
455 g_main_loop_quit (server->sd->loop);
458 else if (dbus_message_is_method_call (message,
464 sender = dbus_message_get_sender (message);
466 if (!g_hash_table_lookup (server->client_names,
469 g_printerr ("First message from new client %s on bus\n", sender);
471 g_hash_table_replace (server->client_names,
473 GINT_TO_POINTER (1));
474 server->sd->n_clients += 1;
477 server->sd->handled += 1;
478 send_echo_method_return (connection, message);
479 return DBUS_HANDLER_RESULT_HANDLED;
482 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
486 with_bus_init_server (ServerData *sd)
488 DBusGConnection *gconnection;
489 DBusConnection *connection;
492 WithBusServer *server;
495 server = g_new0 (WithBusServer, 1);
497 server->vtable = sd->vtable;
500 s = g_getenv ("DBUS_TEST_GLIB_RUN_TEST_SCRIPT");
504 g_printerr ("You have to run with_bus mode with the run-test.sh script\n");
508 /* Note that we use the standard global bus connection for the
509 * server, and the clients open their own connections so they can
510 * have their own main loops and because I'm not sure "talking to
511 * yourself" really works yet
514 gconnection = dbus_g_bus_get (DBUS_BUS_SESSION, &gerror);
515 if (gconnection == NULL)
517 g_printerr ("could not open connection to bus: %s\n", gerror->message);
518 g_error_free (gerror);
522 server->client_names = g_hash_table_new_full (g_str_hash, g_str_equal,
525 connection = dbus_g_connection_get_connection (gconnection);
527 dbus_bus_request_name (connection,
529 0, NULL); /* ignore errors because we suck */
531 rule = g_strdup_printf ("type='signal',sender='%s',member='%s'",
535 /* ignore errors because we suck */
536 dbus_bus_add_match (connection, rule, NULL);
540 if (!dbus_connection_add_filter (connection,
541 with_bus_server_filter, server, NULL))
542 g_error ("no memory");
544 server->connection = connection;
545 server->client_names = g_hash_table_new_full (g_str_hash, g_str_equal,
552 with_bus_stop_server (ServerData *sd,
555 WithBusServer *server = serverv;
557 dbus_connection_remove_filter (server->connection,
558 with_bus_server_filter, server);
560 g_hash_table_destroy (server->client_names);
561 dbus_connection_unref (server->connection);
567 with_bus_main_loop_run (GMainLoop *loop)
569 g_main_loop_run (loop);
572 static const ProfileRunVTable with_bus_vtable = {
575 with_bus_init_server,
576 with_bus_stop_server,
577 with_bus_thread_func,
578 with_bus_main_loop_run
584 const ProfileRunVTable *vtable;
587 unsigned int source_id;
591 read_and_drop_on_floor (int fd,
593 gboolean fake_malloc_overhead)
599 char not_allocated[512+PAYLOAD_SIZE];
601 g_assert (count < (int) sizeof(not_allocated));
603 if (fake_malloc_overhead)
605 allocated = g_malloc (count);
616 while (bytes_read < count)
620 val = read (fd, buf + bytes_read, count - bytes_read);
628 g_printerr ("read() failed thread %p: %s\n",
629 g_thread_self(), strerror (errno));
639 if (fake_malloc_overhead)
643 g_printerr ("%p read %d bytes from fd %d\n",
644 g_thread_self(), bytes_read, fd);
651 gboolean fake_malloc_overhead)
657 char not_allocated[512+PAYLOAD_SIZE];
659 g_assert (count < (int) sizeof(not_allocated));
661 if (fake_malloc_overhead)
665 allocated = g_malloc (count);
668 /* Write some stuff into the allocated buffer to simulate
669 * creating some sort of data
674 allocated[i] = (char) i;
686 while (bytes_written < count)
690 val = write (fd, buf + bytes_written, count - bytes_written);
698 g_printerr ("write() failed thread %p: %s\n",
699 g_thread_self(), strerror (errno));
705 bytes_written += val;
709 if (fake_malloc_overhead)
713 g_printerr ("%p wrote %d bytes to fd %d\n",
714 g_thread_self(), bytes_written, fd);
719 plain_sockets_talk_to_client_watch (GIOChannel *source,
720 GIOCondition condition,
723 PlainSocketServer *server = data;
724 int client_fd = g_io_channel_unix_get_fd (source);
726 if (condition & G_IO_HUP)
728 g_printerr ("Client disconnected from server\n");
729 server->sd->n_clients -= 1;
730 if (server->sd->n_clients == 0)
731 g_main_loop_quit (server->sd->loop);
733 return FALSE; /* remove watch */
735 else if (condition & G_IO_IN)
737 server->sd->handled += 1;
739 read_and_drop_on_floor (client_fd, echo_call_size, server->vtable->fake_malloc_overhead);
740 write_junk (client_fd, echo_return_size, server->vtable->fake_malloc_overhead);
744 g_printerr ("Unexpected IO condition in server thread\n");
752 plain_sockets_new_client_watch (GIOChannel *source,
753 GIOCondition condition,
757 struct sockaddr addr;
760 PlainSocketServer *server = data;
762 if (!(condition & G_IO_IN))
764 g_printerr ("Unexpected IO condition on server socket\n");
768 addrlen = sizeof (addr);
771 client_fd = accept (server->listen_fd, &addr, &addrlen);
779 g_printerr ("Failed to accept() connection from client: %s\n",
785 channel = g_io_channel_unix_new (client_fd);
786 g_io_add_watch (channel,
787 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_PRI,
788 plain_sockets_talk_to_client_watch,
790 g_io_channel_unref (channel);
792 server->sd->n_clients += 1;
798 plain_sockets_init_server (ServerData *sd)
800 PlainSocketServer *server;
801 struct sockaddr_un addr;
802 static char path[] = "/tmp/dbus-test-profile-XXXXXX";
806 server = g_new0 (PlainSocketServer, 1);
808 server->vtable = sd->vtable; /* for convenience */
814 *p = 'a' + (int) (26.0*rand()/(RAND_MAX+1.0));
818 g_printerr ("Socket is %s\n", path);
820 server->listen_fd = socket (PF_UNIX, SOCK_STREAM, 0);
822 if (server->listen_fd < 0)
824 g_printerr ("Failed to create socket: %s",
830 addr.sun_family = AF_UNIX;
832 #ifdef HAVE_ABSTRACT_SOCKETS
833 /* remember that abstract names aren't nul-terminated so we rely
834 * on sun_path being filled in with zeroes above.
836 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
837 strncpy (&addr.sun_path[1], path, _DBUS_MAX_SUN_PATH_LENGTH - 2);
838 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
839 #else /* HAVE_ABSTRACT_SOCKETS */
843 if (stat (path, &sb) == 0 &&
844 S_ISSOCK (sb.st_mode))
848 strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
849 #endif /* ! HAVE_ABSTRACT_SOCKETS */
851 if (bind (server->listen_fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
853 g_printerr ("Failed to bind socket \"%s\": %s",
854 path, strerror (errno));
858 if (listen (server->listen_fd, 30 /* backlog */) < 0)
860 g_printerr ("Failed to listen on socket \"%s\": %s",
861 path, strerror (errno));
865 plain_sockets_address = path;
867 channel = g_io_channel_unix_new (server->listen_fd);
869 g_io_add_watch (channel,
870 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_PRI,
871 plain_sockets_new_client_watch,
873 g_io_channel_unref (channel);
879 plain_sockets_stop_server (ServerData *sd,
882 PlainSocketServer *server = server_v;
884 g_source_remove (server->source_id);
886 close (server->listen_fd);
892 if (stat (plain_sockets_address, &sb) == 0 &&
893 S_ISSOCK (sb.st_mode))
894 unlink (plain_sockets_address);
899 plain_sockets_client_side_watch (GIOChannel *source,
900 GIOCondition condition,
903 ClientData *cd = data;
904 int fd = g_io_channel_unix_get_fd (source);
906 if (condition & G_IO_IN)
908 read_and_drop_on_floor (fd, echo_return_size, cd->vtable->fake_malloc_overhead);
910 else if (condition & G_IO_OUT)
913 if (cd->iterations >= N_ITERATIONS)
915 g_printerr ("\nCompleted %d iterations\n", N_ITERATIONS);
916 g_main_loop_quit (cd->loop);
918 else if (cd->iterations % (N_ITERATIONS/N_PROGRESS_UPDATES) == 0)
920 g_printerr ("%d%% ", (int) (cd->iterations/(double)N_ITERATIONS * 100.0));
923 write_junk (fd, echo_call_size, cd->vtable->fake_malloc_overhead);
927 g_printerr ("Unexpected IO condition in client thread\n");
935 plain_sockets_thread_func (void *data)
937 GMainContext *context;
940 struct sockaddr_un addr;
944 g_printerr ("Starting client thread %p\n",
947 fd = socket (PF_UNIX, SOCK_STREAM, 0);
951 g_printerr ("Failed to create socket: %s",
957 addr.sun_family = AF_UNIX;
959 #ifdef HAVE_ABSTRACT_SOCKETS
960 /* remember that abstract names aren't nul-terminated so we rely
961 * on sun_path being filled in with zeroes above.
963 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
964 strncpy (&addr.sun_path[1], plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 2);
965 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
966 #else /* HAVE_ABSTRACT_SOCKETS */
967 strncpy (addr.sun_path, plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 1);
968 #endif /* ! HAVE_ABSTRACT_SOCKETS */
970 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
972 g_printerr ("Failed to connect to socket %s: %s",
973 plain_sockets_address, strerror (errno));
977 context = g_main_context_new ();
980 cd.loop = g_main_loop_new (context, FALSE);
982 channel = g_io_channel_unix_new (fd);
984 gsource = g_io_create_watch (channel,
986 G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_PRI);
988 g_source_set_callback (gsource,
989 (GSourceFunc)plain_sockets_client_side_watch,
992 g_source_attach (gsource, context);
994 g_io_channel_unref (channel);
996 g_printerr ("Client thread writing to prime pingpong\n");
997 write_junk (fd, echo_call_size, cd.vtable->fake_malloc_overhead);
998 g_printerr ("Client thread done writing primer\n");
1000 g_printerr ("Client thread entering main loop\n");
1001 g_main_loop_run (cd.loop);
1002 g_printerr ("Client thread %p exiting main loop\n",
1005 g_source_destroy (gsource);
1009 g_main_loop_unref (cd.loop);
1010 g_main_context_unref (context);
1016 plain_sockets_main_loop_run (GMainLoop *loop)
1018 g_main_loop_run (loop);
1021 static const ProfileRunVTable plain_sockets_vtable = {
1024 plain_sockets_init_server,
1025 plain_sockets_stop_server,
1026 plain_sockets_thread_func,
1027 plain_sockets_main_loop_run
1030 static const ProfileRunVTable plain_sockets_with_malloc_vtable = {
1031 "plain sockets with malloc overhead",
1033 plain_sockets_init_server,
1034 plain_sockets_stop_server,
1035 plain_sockets_thread_func,
1036 plain_sockets_main_loop_run
1040 do_profile_run (const ProfileRunVTable *vtable)
1048 g_printerr ("Profiling %s\n", vtable->name);
1052 sd.loop = g_main_loop_new (NULL, FALSE);
1055 server = (* vtable->init_server) (&sd);
1057 for (i = 0; i < N_CLIENT_THREADS; i++)
1059 g_thread_create (vtable->client_thread_func, (void*) vtable, FALSE, NULL);
1062 timer = g_timer_new ();
1064 g_printerr ("Server thread %p entering main loop\n",
1066 (* vtable->main_loop_run_func) (sd.loop);
1067 g_printerr ("Server thread %p exiting main loop\n",
1070 secs = g_timer_elapsed (timer, NULL);
1071 g_timer_destroy (timer);
1073 g_printerr ("%s: %g seconds, %d round trips, %f seconds per pingpong\n",
1074 vtable->name, secs, sd.handled, secs/sd.handled);
1076 (* vtable->stop_server) (&sd, server);
1078 g_main_loop_unref (sd.loop);
1084 print_result (const ProfileRunVTable *vtable,
1088 g_printerr (" %g times slower for %s (%g seconds, %f per iteration)\n",
1089 seconds/baseline, vtable->name,
1090 seconds, seconds / N_ITERATIONS);
1094 main (int argc, char *argv[])
1096 g_thread_init (NULL);
1097 dbus_g_thread_init ();
1099 #ifndef DBUS_DISABLE_ASSERT
1100 g_printerr ("You should probably --disable-asserts before you profile as they have noticeable overhead\n");
1103 #if DBUS_ENABLE_VERBOSE_MODE
1104 g_printerr ("You should probably --disable-verbose-mode before you profile as verbose has noticeable overhead\n");
1107 payload = g_malloc (PAYLOAD_SIZE);
1109 /* The actual size of the DBusMessage on the wire, as of Nov 23 2004,
1110 * without the payload
1112 echo_call_size = 140 + PAYLOAD_SIZE;
1113 echo_return_size = 32;
1115 if (argc > 1 && strcmp (argv[1], "plain_sockets") == 0)
1116 do_profile_run (&plain_sockets_vtable);
1117 else if (argc > 1 && strcmp (argv[1], "plain_sockets_with_malloc") == 0)
1118 do_profile_run (&plain_sockets_with_malloc_vtable);
1119 else if (argc > 1 && strcmp (argv[1], "no_bus") == 0)
1120 do_profile_run (&no_bus_vtable);
1121 else if (argc > 1 && strcmp (argv[1], "with_bus") == 0)
1122 do_profile_run (&with_bus_vtable);
1123 else if (argc > 1 && strcmp (argv[1], "all") == 0)
1125 double e1, e2, e3, e4;
1127 e1 = do_profile_run (&plain_sockets_vtable);
1128 e2 = do_profile_run (&plain_sockets_with_malloc_vtable);
1129 e3 = do_profile_run (&no_bus_vtable);
1130 e4 = do_profile_run (&with_bus_vtable);
1132 g_printerr ("Baseline plain sockets time %g seconds for %d iterations\n",
1134 print_result (&plain_sockets_vtable, e1, e1);
1135 print_result (&plain_sockets_with_malloc_vtable, e2, e1);
1136 print_result (&no_bus_vtable, e3, e1);
1137 print_result (&with_bus_vtable, e4, e1);
1141 g_printerr ("Specify profile type plain_sockets, plain_sockets_with_malloc, no_bus, with_bus, all\n");
1145 /* Make valgrind happy */