Facilitates the creation of histograms from a large number of samples.
Latencies are saved in a simple CSV file.
Change-Id: I5d98289787a6f352f4998d421e87164e2145c901
bool lt_on, bw_on;
+bool raw_data_on; /* dump raw data (every possible result) */
+FILE *raw_data_fd;
+
static void server_name_acquired_handler (GDBusConnection *conn, const gchar *name, gpointer user_data)
{ }
#ifdef DEBUG_ON
printf("latency: %0.4f\n", lt);
#endif
+ if (raw_data_on)
+ fprintf(raw_data_fd, "%0.4f\n", lt);
if(lt > 0) {
lt_cnt++;
perror("fork");
return;
default:
+ if (raw_data_on) {
+ raw_data_fd = fopen("gdbus-latency.csv", "w");
+ if (raw_data_fd == NULL) {
+ perror("fopen");
+ return;
+ }
+ fprintf(raw_data_fd, "Latency\n");
+ }
+
Receive(msize, "org.gdbus.server", "/org/gdbus/server", true);
printf("min: %0.4f(us), max: %0.4f(us), avg: %0.4f(us)\n", min, max, total/lt_cnt);
waitpid(pid, NULL, 0);
+ if (raw_data_on)
+ fclose(raw_data_fd);
return;
}
}
msize = 3;
lt_on = bw_on = false;
- while((opt = getopt(argc, argv, "m:p:blh")) != -1) {
+ while((opt = getopt(argc, argv, "m:p:blhr")) != -1) {
switch(opt) {
case 'm':
msize = atoi(optarg);
case 'l':
lt_on = true;
break;
+ case 'r':
+ raw_data_on = true; /* dump raw data */
+ break;
case 'h':
print_help(argv);
exit(0);
#include <csignal>
#include <functional>
#include <iostream>
+#include <fstream>
+#include <iomanip>
#include <limits>
#include <memory>
#include <tuple>
*
* Good for %-based comparisons, but avoid for time measurements. */
bool busy_wait = false;
+
+ /* When enabled, the server collects all method call times and
+ * writes them out to a CSV file. Useful for distribution charts. */
+ bool raw_data_on = false;
};
run_opts get_opt (int argc, char ** argv)
run_opts ret;
int opt;
- while ((opt = getopt(argc, argv, "wit:p:h")) != -1)
+ while ((opt = getopt(argc, argv, "wit:p:rh")) != -1)
switch (opt) {
case 't':
case 'p':
ret.sock_path = optarg;
break;
+ case 'r':
+ ret.raw_data_on = true;
+ break;
case 'h':
default:
ret.show_help = true;
size_t warmup_tries;
+ bool raw_data_on;
+
+ std::ofstream &raw_data_out_file;
+
std::unique_ptr <DBusConnection, DBusConnection_destructor> conn;
bool finished;
static DBusObjectPathVTable vtable;
- conn_with_metadata (const run_opts & ro, DBusConnection * c)
+ conn_with_metadata (const run_opts & ro, DBusConnection * c, std::ofstream & rdof)
: total_time (0)
, total_count (0)
, min_time (std::numeric_limits <uint64_t> :: max ())
, max_time (std::numeric_limits <uint64_t> :: min ())
, warmup_tries (ro.warmup_tries)
+ , raw_data_on(ro.raw_data_on)
+ , raw_data_out_file(rdof)
, conn (c)
, finished (false)
{
, min_time (std::move(x.min_time))
, max_time (std::move(x.max_time))
, warmup_tries (std::move(x.warmup_tries))
+ , raw_data_on (std::move(x.raw_data_on))
+ , raw_data_out_file (x.raw_data_out_file)
, conn (std::move(x.conn))
, finished (std::move(x.finished))
{
min_time = std::move(x.min_time);
max_time = std::move(x.max_time);
warmup_tries = std::move(x.warmup_tries);
+ raw_data_on = std::move(x.raw_data_on);
+ raw_data_out_file = std::move(x.raw_data_out_file);
conn = std::move(x.conn);
finished = std::move(x.finished);
THIS->min_time = std::min (THIS->min_time, diff);
THIS->max_time = std::max (THIS->max_time, diff);
+
+ if (THIS->raw_data_on) {
+ THIS->raw_data_out_file << std::setprecision(4);
+ THIS->raw_data_out_file << (double)diff << std::endl;
+ }
} else {
-- THIS->warmup_tries;
}
<< " [-p sock_path] "
<< " [-i (infinite listening)] "
<< " [-w (busy wait)] "
+ << " [-r (raw data dump)] "
<< std::endl
;
}
int main (int argc, char ** argv)
{
run_opts opt = get_opt (argc, argv);
+ std::ofstream raw_data_out_file;
if (opt.show_help) {
show_help (argv[0]);
return EXIT_FAILURE;
}
+ if (opt.raw_data_on) {
+ raw_data_out_file.open("libdbus-p2p-latency.csv");
+ if (!raw_data_out_file.is_open()) {
+ std::cerr << "cannot create raw data output file" << std::endl;
+ return EXIT_FAILURE;
+ }
+ raw_data_out_file << "Latency" << std::endl;
+ raw_data_out_file << std::fixed;
+ }
+
// Set up cleanup functions for `server`
std::atexit (exit_func);
std::signal (SIGINT , sig_handler);
std::signal (SIGTERM, sig_handler);
std::vector <conn_with_metadata> conns;
- auto ud = std::make_pair (std::ref(opt), std::ref (conns));
+ auto ud = std::make_tuple (std::ref(opt), std::ref (conns), std::ref(raw_data_out_file));
dbus_server_set_new_connection_function (server
, [] (DBusServer * s, DBusConnection * c, void * data) {
- auto [opts, connz] = *(reinterpret_cast <decltype (&ud)> (data));
- connz.emplace_back (opts, c);
+ auto [opts, connz, rdof] = *(reinterpret_cast <decltype (&ud)> (data));
+ connz.emplace_back (opts, c, rdof);
}
, & ud // userdata
, nullptr // userdata free func
bool lt_on, bw_on;
bool stop;
+bool raw_data_on; /* dump raw data (every possible result) */
+FILE *raw_data_fd;
+
static void unregistered_func (DBusConnection *connection, void *user_data)
{ }
double lt = (double)(end - start) / 1000;
+ if (raw_data_on)
+ fprintf(raw_data_fd, "%0.4f\n", lt);
+
if(lt) {
lt_cnt++;
total += lt;
perror("fork");
return;
default:
+ if (raw_data_on) {
+ raw_data_fd = fopen("libdbus-latency.csv", "w");
+ if (raw_data_fd == NULL) {
+ perror("fopen");
+ return;
+ }
+ fprintf(raw_data_fd, "Latency\n");
+ }
+
Receive(msize, "org.libdbus.server", "/org/libdbus/server", true);
printf("min: %0.4f(us), max: %0.4f(us), avg: %0.4f(us)\n", min, max, total/lt_cnt);
waitpid(pid, NULL, 0);
+
+ if (raw_data_on)
+ fclose(raw_data_fd);
return;
}
}
msize = 3;
lt_on = bw_on = false;
- while((opt = getopt(argc, argv, "m:p:blh")) != -1) {
+ while((opt = getopt(argc, argv, "m:p:blhr")) != -1) {
switch(opt) {
case 'm':
msize = atoi(optarg);
case 'l':
lt_on = true;
break;
+ case 'r':
+ raw_data_on = true; /* dump raw data */
+ break;
case 'h':
print_help(argv);
exit(0);
bool lt_on, /* latency test */
bw_on; /* bandwidth test */
+bool raw_data_on; /* dump raw data (every possible result) */
+FILE *raw_data_fd;
+
static GDBusNodeInfo *introspection_data = NULL;
typedef struct _state {
double lt = (double)(end - start) / 1000;
if (state->verbose)
g_print("latency: %0.4f\n", lt);
+ if (raw_data_on)
+ fprintf(raw_data_fd, "%0.4f\n", lt);
if (lt > 0) { /* latency */
lt_cnt++;
total += lt;
Send(msize, "org.gtk.GDBus.TestPeerInterface", "/org/gtk/GDBus/TestObject", "0", true, verbose);
exit(0);
default: /* parent process */
+ if (raw_data_on) {
+ raw_data_fd = fopen("p2pgdbus-latency.csv", "w");
+ if (raw_data_fd == NULL) {
+ perror("fopen");
+ return;
+ }
+ fprintf(raw_data_fd, "Latency\n");
+ }
Receive(msize, "org.gtk.GDBus.TestPeerInterface", "/org/gtk/GDBus/TestObject", "0", true, verbose);
g_print("min: %0.4f(us), max: %0.4f(us), avg: %0.4f(us)\n", min, max, total/lt_cnt);
waitpid(pid, NULL, 0); /* wait for the child */
+ if (raw_data_on)
+ fclose(raw_data_fd);
}
}
n_real_tries = REAL_TRY;
cpu_pin_to_same_core = false;
- while ((opt = getopt(argc, argv, "m:p:blht:cv")) != -1) {
+ while ((opt = getopt(argc, argv, "m:p:blhrt:cv")) != -1) {
switch(opt) {
case 'm':
msize = atoi(optarg);
case 'v':
verbose = true;
break;
+ case 'r':
+ raw_data_on = true; /* dump raw data */
+ break;
case 'h':
print_help(argv);
exit(0);
bool lt_on, bw_on;
+bool raw_data_on; /* dump raw data (every possible result) */
+FILE *raw_data_fd;
+
void Receive(int rfd1, int rfd2, register int size, bool is_lt)
{
static int bw_cnt = 0;
#ifdef DEBUG_ON
printf("latency: %0.4f\n", lt);
#endif
-
+ if (raw_data_on)
+ fprintf(raw_data_fd, "%0.4f\n", lt);
if(lt > 0) {
lt_cnt++;
total += lt;
perror("fork");
return;
default:
+ if (raw_data_on) {
+ raw_data_fd = fopen("pipe-latency.csv", "w");
+ if (raw_data_fd == NULL) {
+ perror("fopen");
+ return;
+ }
+ fprintf(raw_data_fd, "Latency\n");
+ }
close(p1[1]);
close(p2[1]);
Receive(p1[0], p2[0], msize, true);
close(p2[0]);
printf("min: %0.4f(us), max: %0.4f(us), avg: %0.4f(us)\n", min, max, total/lt_cnt);
waitpid(pid, NULL, 0);
+ if (raw_data_on)
+ fclose(raw_data_fd);
return;
}
}
msize = 3;
lt_on = bw_on = false;
- while((opt = getopt(argc, argv, "m:p:blh")) != -1) {
+ while((opt = getopt(argc, argv, "m:p:blhr")) != -1) {
switch(opt) {
case 'm':
msize = atoi(optarg);
case 'l':
lt_on = true;
break;
+ case 'r':
+ raw_data_on = true; /* dump raw data */
+ break;
case 'h':
print_help(argv);
exit(0);
bool lt_on, bw_on;
+bool raw_data_on; /* dump raw data (every possible result) */
+FILE *raw_data_fd;
+
void Receive(void *r1, register char *r2, register int size, bool is_lt)
{
static int bw_cnt = 0;
#ifdef DEBUG_ON
printf("latency: %0.4f\n", lt);
#endif
-
+ if (raw_data_on)
+ fprintf(raw_data_fd, "%0.4f\n", lt);
if(lt > 0) {
lt_cnt++;
total += lt;
perror("fork");
return;
default:
+ if (raw_data_on) {
+ raw_data_fd = fopen("sharedmem-latency.csv", "w");
+ if (raw_data_fd == NULL) {
+ perror("fopen");
+ return;
+ }
+ fprintf(raw_data_fd, "Latency\n");
+ }
Receive(shm_ptr[SHM1], shm_ptr[SHM2], msize, true);
printf("min: %0.4f(us), max: %0.4f(us), avg: %0.4f(us)\n", min, max, total/lt_cnt);
waitpid(pid, NULL, 0);
+ if (raw_data_on)
+ fclose(raw_data_fd);
ret = munmap(shm_ptr[SHM1], sizeof(unsigned long long));
if (ret != 0) {
perror("munmap");
msize = 3;
lt_on = bw_on = false;
- while((opt = getopt(argc, argv, "m:p:blh")) != -1) {
+ while((opt = getopt(argc, argv, "m:p:blrh")) != -1) {
switch(opt) {
case 'm':
msize = atoi(optarg);
case 'l':
lt_on = true;
break;
+ case 'r':
+ raw_data_on = true; /* dump raw data */
+ break;
case 'h':
print_help(argv);
exit(0);
bool lt_on, bw_on;
+bool raw_data_on; /* dump raw data (every possible result) */
+FILE *raw_data_fd;
+
void Receive(int rfd1, int rfd2, register int size, bool is_lt)
{
static int bw_cnt = 0;
#ifdef DEBUG_ON
printf("latency: %0.4f\n", lt);
#endif
-
+ if (raw_data_on)
+ fprintf(raw_data_fd, "%0.4f\n", lt);
if(lt > 0) {
lt_cnt++;
total += lt;
perror("fork");
return;
default:
+ if (raw_data_on) {
+ raw_data_fd = fopen("socket-latency.csv", "w");
+ if (raw_data_fd == NULL) {
+ perror("fopen");
+ return;
+ }
+ fprintf(raw_data_fd, "Latency\n");
+ }
Receive(fd1[1], fd2[1], msize, true);
close(fd1[1]);
close(fd2[1]);
printf("min: %0.4f(us), max: %0.4f(us), avg: %0.4f(us)\n", min, max, total/lt_cnt);
waitpid(pid, NULL, 0);
+ if (raw_data_on)
+ fclose(raw_data_fd);
return;
}
}
msize = 3;
lt_on = bw_on = false;
- while((opt = getopt(argc, argv, "m:p:blh")) != -1) {
+ while((opt = getopt(argc, argv, "m:p:blrh")) != -1) {
switch(opt) {
case 'm':
msize = atoi(optarg);
case 'l':
lt_on = true;
break;
+ case 'r':
+ raw_data_on = true; /* dump raw data */
+ break;
case 'h':
print_help(argv);
exit(0);