SET(TARGET_RPC_PORT_UNITTESTS "rpc-port_unittests")
SET(TARGET_RPC_PORT_UTIL "rpc-port-util")
SET(TARGET_BENCHMARK_SERVER "rpc-port-benchmark-server")
+SET(TARGET_BENCHMARK_SERVER_DBUS "rpc-port-benchmark-server-dbus")
SET(TARGET_BENCHMARK_TOOL "rpc-port-benchmark-tool")
ENABLE_TESTING()
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BENCHMARK_SERVER_SRCS)
-
-ADD_EXECUTABLE(${TARGET_BENCHMARK_SERVER} ${BENCHMARK_SERVER_SRCS})
-
-TARGET_INCLUDE_DIRECTORIES(${TARGET_BENCHMARK_SERVER} PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/../../include/)
-
-APPLY_PKG_CONFIG(${TARGET_BENCHMARK_SERVER} PUBLIC
- AUL_DEPS
- DLOG_DEPS
- GLIB_DEPS
-)
-
-TARGET_LINK_LIBRARIES(${TARGET_BENCHMARK_SERVER} PUBLIC
- ${TARGET_RPC_PORT} "-lpthread")
-SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
- COMPILE_FLAGS "-fPIE")
-SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
- LINK_FLAGS "-pie")
-
-INSTALL(TARGETS ${TARGET_BENCHMARK_SERVER} DESTINATION bin)
+ADD_SUBDIRECTORY(tidl)
+ADD_SUBDIRECTORY(dbus)
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BENCHMARK_SERVER_DBUS_SRCS)
+
+ADD_EXECUTABLE(${TARGET_BENCHMARK_SERVER_DBUS} ${BENCHMARK_SERVER_DBUS_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_BENCHMARK_SERVER_DBUS} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/)
+
+APPLY_PKG_CONFIG(${TARGET_BENCHMARK_SERVER_DBUS} PUBLIC
+ DLOG_DEPS
+ GLIB_DEPS
+ GIO_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_BENCHMARK_SERVER_DBUS} PUBLIC
+ ${TARGET_RPC_PORT} "-lpthread")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER_DBUS} PROPERTIES
+ COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER_DBUS} PROPERTIES
+ LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_BENCHMARK_SERVER_DBUS} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/rpc-port-benchmark.conf DESTINATION /etc/dbus-1/system.d)
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LOG_PRIVATE_HH_
+#define LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "RPC_PORT_BENCHMARK_SERVER_DBUS"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif // LOG_PRIVATE_HH_
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <string_view>
+#include <string>
+
+#include "log-private.hh"
+
+namespace {
+
+constexpr const char BUS_NAME[] = "tizen.appfw.rpcport.benchmark.dbus";
+constexpr const char OBJECT_PATH[] = "/tizen/appfw/rpcport/benchmark/dbus";
+
+constexpr const char INTROSPECTION_XML[] = R"__dbus(
+<node>
+ <interface name='tizen.appfw.rpcport.benchmark.dbus'>
+ <method name='Test'>
+ <arg type='s' name='data' direction='in'/>
+ <arg type='i' name='ret' direction='out'/>
+ </method>
+ </interface>
+</node>
+)__dbus";
+
+class MainLoop {
+ public:
+ MainLoop() {
+ loop_ = g_main_loop_new(nullptr, FALSE);
+ }
+
+ ~MainLoop() {
+ g_main_loop_unref(loop_);
+ if (introspection_data_)
+ g_dbus_node_info_unref(introspection_data_);
+ }
+
+ int OnTest(std::string data) {
+ return 0;
+ }
+
+ void OnBusAcquired(GDBusConnection* connection, const gchar* name) {
+ _I("bus acquired(%s)", name);
+
+ static const GDBusInterfaceVTable interface_vtable = {
+ [](GDBusConnection *connection,
+ const gchar *sender, const gchar *object_path,
+ const gchar *interface_name, const gchar *method_name,
+ GVariant *parameters, GDBusMethodInvocation *invocation,
+ gpointer user_data) {
+ if (std::string_view(method_name) == "Test") {
+ char* data = nullptr;
+ g_variant_get(parameters, "(&s)", &data);
+ auto* obj = static_cast<MainLoop*>(user_data);
+ int ret = obj->OnTest(data);
+
+ GVariant* param = g_variant_new("(i)", ret);
+ g_dbus_method_invocation_return_value(invocation, param);
+ }
+ },
+ nullptr,
+ nullptr
+ };
+
+ GError* error = nullptr;
+ guint reg_id = g_dbus_connection_register_object(connection,
+ OBJECT_PATH,
+ introspection_data_->interfaces[0],
+ &interface_vtable,
+ this, nullptr, &error);
+ if (reg_id == 0) {
+ _E("g_dbus_connection_register_object error(%s)", error ? error->message : "");
+ g_error_free(error);
+ }
+ }
+
+ void Run() {
+ GError* error = nullptr;
+ introspection_data_ = g_dbus_node_info_new_for_xml(INTROSPECTION_XML,
+ &error);
+ if (!introspection_data_) {
+ _E("g_dbus_node_info_new_for_xml error(%s)", error ? error->message : "");
+ g_error_free(error);
+ return;
+ }
+
+ guint owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ BUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ [](GDBusConnection* connection, const gchar* name,
+ gpointer user_data) {
+ auto* obj = static_cast<MainLoop*>(user_data);
+ obj->OnBusAcquired(connection, name);
+ },
+ [](GDBusConnection* connection,
+ const gchar* name, gpointer user_data) {
+ _I("name acquired(%s)", name);
+ },
+ [](GDBusConnection* connection,
+ const gchar* name, gpointer user_data) {
+ _I("name lost(%s)", name);
+ },
+ this, nullptr);
+ if (!owner_id) {
+ _E("g_bus_own_name error");
+ g_dbus_node_info_unref(introspection_data_);
+ return;
+ }
+
+ g_main_loop_run(loop_);
+ }
+
+ void Quit() {
+ g_main_loop_quit(loop_);
+ }
+
+ private:
+ GMainLoop* loop_ = nullptr;
+ GDBusNodeInfo* introspection_data_ = nullptr;
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+ MainLoop loop;
+ loop.Run();
+ return 0;
+}
--- /dev/null
+<!DOCTYPE busconfig PUBLIC
+"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<busconfig>
+ <policy context="default">
+ <allow own="tizen.appfw.rpcport.benchmark.dbus" />
+ <allow send_destination="tizen.appfw.rpcport.benchmark.dbus"
+ send_interface="tizen.appfw.rpcport.benchmark.dbus" send_type="method_call" />
+ </policy>
+</busconfig>
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BENCHMARK_SERVER_SRCS)
+
+ADD_EXECUTABLE(${TARGET_BENCHMARK_SERVER} ${BENCHMARK_SERVER_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_BENCHMARK_SERVER} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/)
+
+APPLY_PKG_CONFIG(${TARGET_BENCHMARK_SERVER} PUBLIC
+ AUL_DEPS
+ DLOG_DEPS
+ GLIB_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_BENCHMARK_SERVER} PUBLIC
+ ${TARGET_RPC_PORT} "-lpthread")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
+ COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
+ LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_BENCHMARK_SERVER} DESTINATION bin)
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dbus-proxy.hh"
+#include "log-private.hh"
+
+namespace rpc_port {
+namespace benchmark {
+
+namespace {
+
+constexpr const char BUS_NAME[] = "tizen.appfw.rpcport.benchmark.dbus";
+constexpr const char OBJECT_PATH[] = "/tizen/appfw/rpcport/benchmark/dbus";
+constexpr const char INTERFACE_NAME[] = "tizen.appfw.rpcport.benchmark.dbus";
+
+}
+
+DbusProxy::DbusProxy() {
+}
+
+void DbusProxy::Connect() {
+ if (system_conn_ != nullptr)
+ return;
+
+ GError* error = nullptr;
+ system_conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
+ if (system_conn_ == nullptr) {
+ _E("g_bus_get_sync() is failed. error(%s)",
+ error ? error->message : "Unknown");
+ g_clear_error(&error);
+ }
+}
+
+int DbusProxy::Test(std::string data) const {
+ auto* msg = g_dbus_message_new_method_call(BUS_NAME,
+ OBJECT_PATH, INTERFACE_NAME, "Test");
+ if (msg == nullptr) {
+ _E("g_dbus_message_new_method_call() is failed");
+ return -1;
+ }
+ std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_auto(
+ msg, g_object_unref);
+
+ g_dbus_message_set_body(msg, g_variant_new("(s)", data.c_str()));
+ GError* error = nullptr;
+ auto* reply = g_dbus_connection_send_message_with_reply_sync(system_conn_, msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &error);
+ if (reply == nullptr || error != nullptr) {
+ _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
+ error ? error->message : "Unknown");
+ g_clear_error(&error);
+ return -1;
+ }
+ std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_auto(
+ reply, g_object_unref);
+
+ auto* body = g_dbus_message_get_body(reply);
+ if (body == nullptr) {
+ _E("g_dbus_message_get_body() is failed");
+ return -1;
+ }
+
+ int ret = -1;
+ g_variant_get(body, "(i)", &ret);
+ return ret;
+}
+
+} // namespace benchmark
+} // namespace rpc_port
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DBUS_PROXY_HH_
+#define DBUS_PROXY_HH_
+
+#include <string>
+#include <memory>
+
+#include <gio/gio.h>
+#include <glib.h>
+
+namespace rpc_port {
+namespace benchmark {
+
+class DbusProxy {
+ public:
+ DbusProxy();
+
+ void Connect();
+ int Test(std::string data) const;
+
+ private:
+ GDBusConnection* system_conn_ = nullptr;
+};
+
+} // namespace benchmark
+} // namespace rpc_port
+
+#endif // DBUS_PROXY_HH_
#include "log-private.hh"
#include "options.hh"
#include "BenchmarkProxy.h"
+#include "dbus-proxy.hh"
namespace {
#define SERVER_PROC_NAME "org.tizen.appfw.rpc_port.benchmark"
#define SERVER_BIN "/usr/bin/rpc-port-benchmark-server"
+#define SERVER_BIN_DBUS "/usr/bin/rpc-port-benchmark-server-dbus"
namespace bp = rpc_port::BenchmarkProxy::proxy;
return;
}
- ExecuteServer();
- proxy_.reset(new bp::Benchmark(&listener_, SERVER_PROC_NAME));
-
- try {
- proxy_->Connect(true);
- } catch (const bp::Exception& e) {
- std::cerr << "Connect() failed" << std::endl;
- return;
- } catch (const std::exception& e) {
- std::cerr << "Connect() failed. " << e.what() << std::endl;
- return;
+ ExecuteServer(options_->IsDbus());
+ if (options_->IsDbus()) {
+ dbus_proxy_.Connect();
+ } else {
+ proxy_.reset(new bp::Benchmark(&listener_, SERVER_PROC_NAME));
+
+ try {
+ proxy_->Connect(true);
+ } catch (const bp::Exception& e) {
+ std::cerr << "Connect() failed" << std::endl;
+ return;
+ } catch (const std::exception& e) {
+ std::cerr << "Connect() failed. " << e.what() << std::endl;
+ return;
+ }
}
printf("%15s\t%15s\t%15s\t\t%15s\t\t%15s\n", "Iterations", "Data size",
private:
void DoTest(int iters, int size) {
bool is_func = options_->IsFunction();
+ bool is_dbus = options_->IsDbus();
StartTime();
for (int i = 0; i < iters; i++) {
continue;
}
+ if (is_dbus) {
+ int ret = dbus_proxy_.Test(std::string(size, 'a'));
+ if (ret != 0) {
+ _E("Invalid return");
+ break;
+ }
+
+ continue;
+ }
+
int ret = proxy_->Test(std::string(size, 'a'));
if (ret != 0) {
_E("Invalid return");
sec.count(), t, l);
}
- void ExecuteServer() {
+ void ExecuteServer(bool is_dbus) {
server_pid_ = fork();
if (server_pid_ == 0) {
setsid();
-
- char bin[] = { SERVER_BIN };
- char* argv[] = { bin, nullptr, nullptr };
- int ret = execv(argv[0], argv);
+ int ret;
+ if (is_dbus) {
+ char bin[] = { SERVER_BIN_DBUS };
+ char* argv[] = { bin, nullptr, nullptr };
+ ret = execv(argv[0], argv);
+ } else {
+ char bin[] = { SERVER_BIN };
+ char* argv[] = { bin, nullptr, nullptr };
+ ret = execv(argv[0], argv);
+ }
if (ret < 0) {
std::cerr << "execv() is failed. errno: " << errno << std::endl;
exit(-1);
ConnectionListener listener_;
std::chrono::system_clock::time_point start_;
pid_t server_pid_ = -1;
+ rpc_port::benchmark::DbusProxy dbus_proxy_;
};
} // namespace
Additional Options:
-f, --funcation Use function call instead of RPC
+ -d, --dbus Use Dbus method instead of TIDL RPC
-a, --all Test pre-defined test-cases
-i, --interations=<Iterations> Iterations
-s, --size=<Data size> Data size (byte)
{"iterations", required_argument, nullptr, 'i'},
{"size", required_argument, nullptr, 's'},
{"function", no_argument, nullptr, 'f'},
+ {"dbus", no_argument, nullptr, 'd'},
{"all", no_argument, nullptr, 'a'},
{0, 0, 0, 0}
};
while (true) {
- int c = getopt_long(argc, argv, "vhfai:s:", long_options,
+ int c = getopt_long(argc, argv, "vhfdai:s:", long_options,
&option_index);
if (c == -1)
break;
options->is_function_ = true;
break;
+ case 'd':
+ opt[OPT_DBUS] = true;
+ options->is_dbus_ = true;
+ break;
+
case 'a':
opt[OPT_ALL] = true;
options->is_all_ = true;
return is_all_;
}
+ bool IsDbus() const {
+ return is_dbus_;
+ }
+
private:
enum Cmd {
CMD_VERSION,
OPT_SIZE,
OPT_ALL,
OPT_FUNCTION,
+ OPT_DBUS,
OPT_MAX
};
std::string help_;
bool is_function_ = false;
bool is_all_ = false;
+ bool is_dbus_ = false;
};
} // namespace benchmark
%files
%manifest %{name}.manifest
+%config %{_sysconfdir}/dbus-1/system.d/rpc-port-benchmark.conf
%attr(0644,root,root) %{_libdir}/lib%{name}.so.*
%license LICENSE.APLv2
%{_bindir}/rpc-port-util
%{_bindir}/rpc-port-benchmark-server
+%{_bindir}/rpc-port-benchmark-server-dbus
%{_bindir}/rpc-port-benchmark-tool
%config %{_sysconfdir}/dbus-1/system.d/rpc-port.conf
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <iostream>
+#include <rpc-port-parcel.h>
+
+#include "log-private.hh"
+
+namespace {
+
+constexpr const char SOCKET_PATH[] = "/run/.socket_test";
+
+class ClientSocket {
+ public:
+ ClientSocket() {
+ fd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ }
+
+ ~ClientSocket() {
+ if (!IsClosed())
+ Close();
+ }
+
+ void Close() {
+ if (fd_ > -1) {
+ close(fd_);
+ fd_ = -1;
+ }
+ }
+
+ int Connect(const std::string& endpoint) {
+ struct sockaddr_un sockaddr = { 0, };
+ sockaddr.sun_family = AF_UNIX;
+ snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s",
+ endpoint.c_str());
+ struct sockaddr* sockaddr_ptr = reinterpret_cast<struct sockaddr*>(&sockaddr);
+ socklen_t len = sizeof(sockaddr);
+ int ret = connect(fd_, sockaddr_ptr, len);
+ if (ret < 0) {
+ ret = -errno;
+ _E("connect() is failed. errno(%d)", errno);
+ return ret;
+ }
+
+ return 0;
+ }
+
+ int Send(const void* buf, unsigned int size) {
+ const unsigned char* buffer = static_cast<const unsigned char*>(buf);
+ size_t len = size;
+ while (len) {
+ ssize_t bytes = send(fd_, buffer, len, MSG_NOSIGNAL);
+ if (bytes < 0) {
+ int ret = -errno;
+ _E("send() is failed. fd(%d), errno(%d)", fd_, errno);
+ return ret;
+ }
+
+ len -= bytes;
+ buffer += bytes;
+ }
+
+ return 0;
+ }
+
+ int Receive(void* buf, unsigned int size) {
+ unsigned char* buffer = static_cast<unsigned char*>(buf);
+ size_t len = size;
+ while (len) {
+ ssize_t bytes = read(fd_, buffer, len);
+ if (bytes == 0) {
+ _W("EOF. fd(%d)", fd_);
+ return -EIO;
+ }
+
+ if (bytes < 0)
+ return -errno;
+
+ len -= bytes;
+ buffer += bytes;
+ }
+
+ return 0;
+ }
+
+ bool IsClosed() {
+ return fd_ < 0 ? true : false;
+ }
+
+ private:
+ int fd_ = -1;
+};
+
+std::chrono::system_clock::time_point start_;
+
+void StartTime() {
+ start_ = std::chrono::system_clock::now();
+}
+
+void EndTime(int iters, int size) {
+ std::chrono::duration<double> sec = std::chrono::system_clock::now() - start_;
+ double t = size * iters * 8 / sec.count() / 1024 / 1024;
+ double l = sec.count() * 1000 / iters;
+
+ printf("%10d\t%10dByte\t%15.4fs\t%15.4fMb/s\t%15.4fms\n", iters, size,
+ sec.count(), t, l);
+}
+
+void DoTest(ClientSocket& sk, int iters, int size) {
+ StartTime();
+ rpc_port_parcel_h p;
+ rpc_port_parcel_create(&p);
+ for (int i = 0; i < iters; i++) {
+
+
+ std::string data(size, 'a');
+ rpc_port_parcel_write_string(p, data.c_str());
+
+ int ret = -1;
+ sk.Send(&size, sizeof(size));
+ sk.Send(data.c_str(), size);
+ sk.Receive(&ret, sizeof(ret));
+ if (ret != 9216) {
+ _E("Invalid return");
+ exit(1);
+ }
+ }
+ rpc_port_parcel_destroy(p);
+ EndTime(iters, size);
+}
+
+}
+
+int main(int argc, char** argv) {
+ ClientSocket sk;
+ sk.Connect(SOCKET_PATH);
+
+ printf("%15s\t%15s\t%15s\t\t%15s\t\t%15s\n", "Iterations", "Data size",
+ "Time", "Throughput", "Latency");
+ DoTest(sk, 4000, 10);
+ DoTest(sk, 4000, 20);
+ DoTest(sk, 4000, 100);
+ DoTest(sk, 4000, 200);
+ DoTest(sk, 2000, 1000);
+ DoTest(sk, 2000, 2000);
+ DoTest(sk, 1000, 10000);
+ DoTest(sk, 1000, 20000);
+ DoTest(sk, 1000, 30000);
+ DoTest(sk, 1000, 40000);
+ DoTest(sk, 1000, 50000);
+ DoTest(sk, 1000, 60000);
+ DoTest(sk, 500, 100000);
+
+ return 0;
+}