Add benchmark tool 23/316423/2
authorjh9216.park <jh9216.park@samsung.com>
Wed, 21 Aug 2024 06:39:33 +0000 (02:39 -0400)
committerjh9216.park <jh9216.park@samsung.com>
Fri, 23 Aug 2024 05:02:15 +0000 (01:02 -0400)
Change-Id: Id3590a2a39e591243a0cefd372b7a4cf86373b34
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
CMakeLists.txt
benchmark/CMakeLists.txt [new file with mode: 0644]
benchmark/log-private.hh [new file with mode: 0644]
benchmark/main.cc [new file with mode: 0644]
benchmark/options.cc [new file with mode: 0644]
benchmark/options.hh [new file with mode: 0644]
packaging/eventsystem.spec

index 7d21baed53eac028520f83b3769e9ec224e7d7f7..bf0370c3fbea3bc9f2c5cd68c71801d3ceb5166b 100644 (file)
@@ -25,6 +25,7 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
   "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
 
 SET(TARGET_EVENTSYSTEM "eventsystem")
+SET(TARGET_EVENTSYSTEM_BENCHMARK "eventsystem-benchmark")
 SET(TARGET_EVENTSYSTEM_UNITTESTS "eventsystem-unittests")
 
 INCLUDE(FindPkgConfig)
@@ -54,6 +55,7 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
 
 ADD_SUBDIRECTORY(src)
 ADD_SUBDIRECTORY(tests)
+ADD_SUBDIRECTORY(benchmark)
 
 ENABLE_TESTING()
 ADD_TEST(NAME ${TARGET_EVENTSYSTEM_UNITTESTS}
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f0c1245
--- /dev/null
@@ -0,0 +1,26 @@
+ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BENCHMARK_SRCS)
+
+ADD_EXECUTABLE(${TARGET_EVENTSYSTEM_BENCHMARK}
+  ${BENCHMARK_SRCS}
+)
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_EVENTSYSTEM_BENCHMARK} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+
+APPLY_PKG_CONFIG(${TARGET_EVENTSYSTEM_BENCHMARK} PUBLIC
+  AUL_DEPS
+  BUNDLE_DEPS
+  DLOG_DEPS
+  GLIB_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_EVENTSYSTEM_BENCHMARK} PUBLIC
+  ${TARGET_EVENTSYSTEM})
+SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM_BENCHMARK} PROPERTIES
+  COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_EVENTSYSTEM_BENCHMARK} PROPERTIES
+  LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_EVENTSYSTEM_BENCHMARK} DESTINATION bin)
diff --git a/benchmark/log-private.hh b/benchmark/log-private.hh
new file mode 100644 (file)
index 0000000..23f9337
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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 LOG_PRIVATE_HH_
+#define LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "EVENTSYSTEM_BENCHMARK"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // LOG_PRIVATE_HH_
diff --git a/benchmark/main.cc b/benchmark/main.cc
new file mode 100644 (file)
index 0000000..384e8b0
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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 <bundle_cpp.h>
+#include <glib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <ctime>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "eventsystem.h"
+#include "log-private.hh"
+#include "options.hh"
+
+namespace {
+
+class Tester {
+ public:
+  Tester() { loop_ = g_main_loop_new(nullptr, FALSE); }
+
+  ~Tester() { g_main_loop_unref(loop_); }
+
+  void Run(int argc, char** argv) {
+    options_ = eventsystem::benchmark::Options::Parse(argc, argv);
+    if (!options_) {
+      std::cerr << "options is unllptr" << std::endl;
+      return;
+    }
+
+    if (options_->ShouldPrintTime()) PrintStartTime();
+
+    printf("%15s\t%15s\t%15s\t\t%15s\t\t%15s\n", "Iterations", "Data size",
+           "Time", "Throughput", "Latency");
+
+    try {
+      if (options_->IsAll()) {
+        DoTest(4000, 10);
+        DoTest(4000, 20);
+        DoTest(4000, 100);
+        DoTest(4000, 200);
+        DoTest(2000, 1000);
+        DoTest(2000, 2000);
+        DoTest(1000, 10000);
+        DoTest(1000, 20000);
+        DoTest(1000, 30000);
+        DoTest(1000, 40000);
+        DoTest(1000, 50000);
+        DoTest(1000, 60000);
+        DoTest(500, 100000);
+      } else {
+        DoTest(options_->GetIters(), options_->GetSize());
+      }
+    } catch (...) {
+      std::cerr << "test failed" << std::endl;
+    }
+  }
+
+ private:
+  void DoTest(int iters, int size) {
+    StartTime();
+    unsigned int id;
+    static int g_iters;
+    static int g_iters_org;
+    static int g_size;
+
+    g_iters = iters;
+    g_iters_org = iters;
+    g_size = size;
+    eventsystem_register_event(
+        "tizen.system.event.benchmarktest", &id,
+        [](const char* event_name, bundle* data, void* user_data) {
+          auto* tester = static_cast<Tester*>(user_data);
+          g_iters--;
+          if (g_iters <= 0) {
+            g_main_loop_quit(tester->loop_);
+            tester->EndTime(g_iters_org, g_size);
+          } else {
+            tizen_base::Bundle d = {{"ITER", std::to_string(g_iters)},
+                                    {"DATA", std::string(g_size, 'a')}};
+            eventsystem_send_system_event("tizen.system.event.benchmarktest",
+                                          d.GetHandle());
+          }
+        },
+        this);
+    tizen_base::Bundle d = {{"ITER", std::to_string(g_iters)},
+                            {"DATA", std::string(size, 'a')}};
+    eventsystem_send_system_event("tizen.system.event.benchmarktest",
+                                  d.GetHandle());
+    g_main_loop_run(loop_);
+    eventsystem_unregister_event(id);
+  }
+
+  int FakeFunction(std::string str) { return 0; }
+
+  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 * static_cast<double>(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 PrintStartTime() {
+    std::ifstream stat_file("/proc/self/stat");
+    if (!stat_file) {
+      _E("Failed to open stat");
+      return;
+    }
+
+    std::string line;
+    getline(stat_file, line);
+    std::istringstream iss(line);
+
+    std::string value;
+    int pos = 21;
+    for (int i = 0; i < pos; ++i) iss >> value;
+
+    iss >> value;
+    stat_file.close();
+
+    long start_time = std::stol(value) / sysconf(_SC_CLK_TCK);
+    time_t start_time_seconds = start_time;
+    long start_time_microseconds = (start_time - start_time_seconds) * 1000000;
+
+    std::time_t start_time_utc = std::time(nullptr) - start_time_seconds;
+    std::tm* start_time_tm = std::localtime(&start_time_utc);
+
+    char buffer[26];
+    std::strftime(buffer, sizeof(buffer), "%Y-%m %H:%M:%S", start_time_tm);
+
+    std::string result = buffer;
+    result += ".";
+    result += std::to_string(start_time_microseconds);
+    result += " UTC";
+
+    std::cout << "Program start time: [" << value << "] " << result
+              << std::endl;
+  }
+
+ private:
+  std::unique_ptr<eventsystem::benchmark::Options> options_;
+  std::chrono::system_clock::time_point start_;
+  GMainLoop* loop_ = nullptr;
+};
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  try {
+    Tester tester;
+    tester.Run(argc, argv);
+  } catch (...) {
+    _E("Exception occurs");
+    return -1;
+  }
+
+  return 0;
+}
diff --git a/benchmark/options.cc b/benchmark/options.cc
new file mode 100644 (file)
index 0000000..dac0b77
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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 <getopt.h>
+
+#include <iostream>
+#include <cstring>
+#include <memory>
+
+#include "options.hh"
+
+namespace eventsystem {
+namespace benchmark {
+
+Options::Options() {
+  help_ = R"__option_cb(
+Usage:
+  eventsystem-benchmark [OPTION...]
+
+Help Options:
+  -h, --help                  Show help options
+
+Additional Options:
+  -a, --all                           Test pre-defined test-cases
+  -i, --interations=<Iterations>      Iterations
+  -s, --size=<Data size>              Data size (byte)
+  -t, --time                          Print starting time of this tool
+
+Application Options:
+  -v, --version               Show version information
+)__option_cb";
+}
+
+void Options::PrintUsage() {
+  std::cerr << help_ << std::endl;
+}
+
+void Options::PrintVersion() {
+  std::cerr << "rpc-port-benchmark-tool " << FULLVER << std::endl;
+}
+
+void Options::PrintSample() {
+  std::cerr << "rpc-port-benchmark-tool -i 1000 -s 10000" << std::endl;
+}
+
+std::unique_ptr<Options> Options::Parse(int argc, char** argv) {
+  bool cmd[CMD_MAX] = { false, };
+  bool opt[OPT_MAX] = { false, };
+  auto options = std::unique_ptr<Options>(new Options());
+  int option_index = 0;
+
+  struct option long_options[] = {
+    {"version", no_argument, nullptr, 'v'},
+    {"help", no_argument, nullptr, 'h'},
+    {"iterations", required_argument, nullptr, 'i'},
+    {"size", required_argument, nullptr, 's'},
+    {"all", no_argument, nullptr, 'a'},
+    {"time", no_argument, nullptr, 't'},
+    {0, 0, 0, 0}
+  };
+
+  while (true) {
+    int c = getopt_long(argc, argv, "vhati:s:", long_options,
+        &option_index);
+    if (c == -1)
+      break;
+
+    switch (c) {
+      case 0:
+        break;
+
+      case 'v':
+        cmd[CMD_VERSION] = true;
+        break;
+
+      case 'h':
+        cmd[CMD_HELP] = true;
+        break;
+
+      case 'i':
+        opt[OPT_ITER] = true;
+        options->iters_ = std::stoi(optarg);
+        break;
+
+      case 's':
+        opt[OPT_SIZE] = true;
+        options->size_ = std::stoi(optarg);
+        break;
+
+      case 'a':
+        opt[OPT_ALL] = true;
+        options->is_all_ = true;
+        break;
+
+      case 't':
+        opt[OPT_TIME] = true,
+        options->should_print_time_ = true;
+        break;
+
+      default:
+        cmd[CMD_HELP] = true;
+    }
+  }
+
+  if (cmd[CMD_VERSION]) {
+    options->PrintVersion();
+    return std::unique_ptr<Options>(nullptr);
+  }
+
+  if (cmd[CMD_HELP]) {
+    options->PrintUsage();
+    return std::unique_ptr<Options>(nullptr);
+  } else if (opt[OPT_ALL]) {
+    return options;
+  } else if (!opt[OPT_ITER] || !opt[OPT_SIZE]) {
+    options->PrintSample();
+    return std::unique_ptr<Options>(nullptr);
+  }
+
+  return options;
+}
+
+}  // namespace benchmark
+}  // namespace eventsystem
diff --git a/benchmark/options.hh b/benchmark/options.hh
new file mode 100644 (file)
index 0000000..5b049ee
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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 OPTIONS_HH_
+#define OPTIONS_HH_
+
+#include <string>
+#include <memory>
+
+namespace eventsystem {
+namespace benchmark {
+
+class Options {
+ public:
+  Options();
+  ~Options() = default;
+
+  static std::unique_ptr<Options> Parse(int argc, char** argv);
+
+  int GetIters() const {
+    return iters_;
+  }
+
+  int GetSize() const {
+    return size_;
+  }
+
+  bool IsAll() const {
+    return is_all_;
+  }
+
+  bool ShouldPrintTime() const {
+    return should_print_time_;
+  }
+
+ private:
+  enum Cmd {
+    CMD_VERSION,
+    CMD_HELP,
+    CMD_MAX
+  };
+
+  enum Opt {
+    OPT_ITER,
+    OPT_SIZE,
+    OPT_ALL,
+    OPT_TIME,
+    OPT_MAX
+  };
+
+  void PrintUsage();
+  void PrintVersion();
+  void PrintSample();
+
+ private:
+  int iters_ = 0;
+  int size_ = 0;
+  std::string help_;
+  bool is_function_ = false;
+  bool is_all_ = false;
+  bool is_dbus_ = false;
+  bool is_grpc_ = false;
+  bool should_print_time_ = false;
+};
+
+}  // namespace benchmark
+}  // namespace eventsystem
+
+#endif  // OPTIONS_HH_
index ba76812cab055693f6f3064da26a483df299d491..3e035bf28c88e2c4d3224005367ac5b244a50cf4 100644 (file)
@@ -46,6 +46,18 @@ Requires:   %{name}
 %description -n %{name}-unittests
 GTest for EventSystem API
 
+#################################################
+# eventsystem-benchmark
+#################################################
+%package -n %{name}-benchmark
+Summary:    Benchmark for EventySystem API
+Group:      Application Framework/Testing
+Requires:   %{name}
+
+%description -n %{name}-benchmark
+Benchmark for EventySystem API
+
+
 #################################################
 # gcov
 #################################################
@@ -150,6 +162,12 @@ install -m 0755 run-unittest.sh %{buildroot}%{_bindir}/tizen-unittests/%{name}/
 %{_bindir}/%{name}-unittests
 %{_bindir}/tizen-unittests/%{name}/run-unittest.sh
 
+#################################################
+# eventsystem-benchmark
+#################################################
+%files -n %{name}-benchmark
+%{_bindir}/%{name}-benchmark
+
 #################################################
 # eventsystem-gcov
 #################################################