Add CPUChecker and AppInfo classes 39/290339/6
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 23 Mar 2023 08:48:27 +0000 (08:48 +0000)
committerHwanKyu Jhun <h.jhun@samsung.com>
Thu, 23 Mar 2023 09:21:33 +0000 (09:21 +0000)
The new claases are for refactoring the launchpad.

Adds:
 - CPUChecker
 - AppInfo

Change-Id: I1cb745057d34fc092783c172b3369ebd4bc39d9c
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/launchpad-process-pool/app_info.cc [new file with mode: 0644]
src/launchpad-process-pool/app_info.hh [new file with mode: 0644]
src/launchpad-process-pool/cpu_checker.cc [new file with mode: 0644]
src/launchpad-process-pool/cpu_checker.hh [new file with mode: 0644]

diff --git a/src/launchpad-process-pool/app_info.cc b/src/launchpad-process-pool/app_info.cc
new file mode 100644 (file)
index 0000000..d7e7c19
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "launchpad-process-pool/app_info.hh"
+
+#include <utility>
+
+#include "lib/common/inc/key.h"
+
+namespace launchpad {
+
+AppInfo::Builder& AppInfo::Builder::SetAppId(const tizen_base::Bundle& b) {
+  app_id_ = b.GetString(AUL_K_APPID);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetAppPath(const tizen_base::Bundle& b) {
+  app_path_ = b.GetString(AUL_K_EXEC);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetOriginalAppPath(
+    const tizen_base::Bundle& b) {
+  original_app_path_ = b.GetString(AUL_K_EXEC);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetPkgType(const tizen_base::Bundle& b) {
+  pkg_type_ = b.GetString(AUL_K_PACKAGETYPE);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetAppType(const tizen_base::Bundle& b) {
+  app_type_ = b.GetString(AUL_K_APP_TYPE);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetHwacc(const tizen_base::Bundle& b) {
+  hwacc_ = b.GetString(AUL_K_HWACC);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetTaskmanage(const tizen_base::Bundle& b) {
+  taskmanage_ = b.GetString(AUL_K_TASKMANAGE);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetPkgId(const tizen_base::Bundle& b) {
+  pkg_id_ = b.GetString(AUL_K_PKGID);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetCompType(const tizen_base::Bundle& b) {
+  comp_type_ = b.GetString(AUL_K_COMP_TYPE);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetInternalPool(
+    const tizen_base::Bundle& b) {
+  internal_pool_ = b.GetString(AUL_K_INTERNAL_POOL);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetRootPath(const tizen_base::Bundle& b) {
+  root_path_ = b.GetString(AUL_K_ROOT_PATH);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetLoaderName(const tizen_base::Bundle& b) {
+  loader_name_ = b.GetString(AUL_K_LOADER_NAME);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetGlobal(const tizen_base::Bundle& b) {
+  if (b.GetString(AUL_K_IS_GLOBAL) == "true")
+    global_ = true;
+  else
+    global_ = false;
+
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetBundle(tizen_base::Bundle b) {
+  b_ = std::move(b);
+  return *this;
+}
+
+AppInfo::Builder::operator AppInfo*() {
+  return new (std::nothrow) AppInfo(std::move(app_id_), std::move(app_path_),
+      std::move(original_app_path_), std::move(pkg_type_), std::move(app_type_),
+      std::move(hwacc_), std::move(taskmanage_), std::move(pkg_id_),
+      std::move(comp_type_), std::move(internal_pool_), std::move(root_path_),
+      std::move(loader_name_), global_, std::move(b_));
+}
+
+std::unique_ptr<AppInfo> AppInfo::Create(tizen_base::Bundle b) {
+  return std::unique_ptr<AppInfo>(Builder().SetAppId(b)
+      .SetAppPath(b)
+      .SetOriginalAppPath(b)
+      .SetPkgType(b)
+      .SetAppType(b)
+      .SetHwacc(b)
+      .SetTaskmanage(b)
+      .SetPkgId(b)
+      .SetCompType(b)
+      .SetInternalPool(b)
+      .SetRootPath(b)
+      .SetLoaderName(b)
+      .SetGlobal(b)
+      .SetBundle(std::move(b)));
+}
+
+const std::string& AppInfo::GetAppId() const {
+  return app_id_;
+}
+
+const std::string& AppInfo::GetAppPath() const {
+  return app_path_;
+}
+
+const std::string& AppInfo::GetOriginalAppPath() const {
+  return original_app_path_;
+}
+
+const std::string& AppInfo::GetPkgType() const {
+  return pkg_type_;
+}
+
+const std::string& AppInfo::GetAppType() const {
+  return app_type_;
+}
+
+const std::string& AppInfo::GetHwacc() const {
+  return hwacc_;
+}
+
+const std::string& AppInfo::GetTaskmanage() const {
+  return taskmanage_;
+}
+
+const std::string& AppInfo::GetPkgId() const {
+  return pkg_id_;
+}
+
+const std::string& AppInfo::GetCompType() const {
+  return comp_type_;
+}
+
+const std::string& AppInfo::GetInternalPool() const {
+  return internal_pool_;
+}
+
+const std::string& AppInfo::GetRootPath() const {
+  return root_path_;
+}
+
+const std::string& AppInfo::GetLoaderName() const {
+  return loader_name_;
+}
+
+const bool AppInfo::IsGlobal() const {
+  return global_;
+}
+
+const tizen_base::Bundle& AppInfo::GetBundle() const {
+  return b_;
+}
+
+AppInfo::AppInfo(std::string app_id, std::string app_path,
+    std::string original_app_path, std::string pkg_type, std::string app_type,
+    std::string hwacc, std::string taskmanage, std::string pkg_id,
+    std::string comp_type, std::string internal_pool, std::string root_path,
+    std::string loader_name, bool global, tizen_base::Bundle b)
+    : app_id_(std::move(app_id)),
+      app_path_(std::move(app_path)),
+      original_app_path_(std::move(original_app_path)),
+      pkg_type_(std::move(pkg_type)),
+      app_type_(std::move(app_type)),
+      hwacc_(std::move(hwacc)),
+      taskmanage_(std::move(taskmanage)),
+      pkg_id_(std::move(pkg_id)),
+      comp_type_(std::move(comp_type)),
+      internal_pool_(std::move(internal_pool)),
+      root_path_(std::move(root_path)),
+      loader_name_(std::move(loader_name)),
+      global_(global),
+      b_(std::move(b)) {}
+
+}  // namespace launchpad
diff --git a/src/launchpad-process-pool/app_info.hh b/src/launchpad-process-pool/app_info.hh
new file mode 100644 (file)
index 0000000..32c1675
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LAUNCHPAD_PROCESS_POOL_APP_INFO_HH_
+#define LAUNCHPAD_PROCESS_POOL_APP_INFO_HH_
+
+#include <bundle_cpp.h>
+
+#include <memory>
+#include <string>
+
+namespace launchpad {
+
+class AppInfo {
+ public:
+  class Builder {
+   public:
+    Builder& SetAppId(const tizen_base::Bundle& b);
+    Builder& SetAppPath(const tizen_base::Bundle& b);
+    Builder& SetOriginalAppPath(const tizen_base::Bundle& b);
+    Builder& SetPkgType(const tizen_base::Bundle& b);
+    Builder& SetAppType(const tizen_base::Bundle& b);
+    Builder& SetHwacc(const tizen_base::Bundle& b);
+    Builder& SetTaskmanage(const tizen_base::Bundle& b);
+    Builder& SetPkgId(const tizen_base::Bundle& b);
+    Builder& SetCompType(const tizen_base::Bundle& b);
+    Builder& SetInternalPool(const tizen_base::Bundle& b);
+    Builder& SetRootPath(const tizen_base::Bundle& b);
+    Builder& SetLoaderName(const tizen_base::Bundle& b);
+    Builder& SetGlobal(const tizen_base::Bundle& b);
+    Builder& SetBundle(tizen_base::Bundle b);
+    operator AppInfo*();
+
+   private:
+    std::string app_id_;
+    std::string app_path_;
+    std::string original_app_path_;
+    std::string pkg_type_;
+    std::string app_type_;
+    std::string hwacc_;
+    std::string taskmanage_;
+    std::string pkg_id_;
+    std::string comp_type_;
+    std::string internal_pool_;
+    std::string root_path_;
+    std::string loader_name_;
+    bool global_;
+    tizen_base::Bundle b_;
+  };
+
+  virtual ~AppInfo() = default;
+
+  static std::unique_ptr<AppInfo> Create(tizen_base::Bundle b);
+
+  const std::string& GetAppId() const;
+  const std::string& GetAppPath() const;
+  const std::string& GetOriginalAppPath() const;
+  const std::string& GetPkgType() const;
+  const std::string& GetAppType() const;
+  const std::string& GetHwacc() const;
+  const std::string& GetTaskmanage() const;
+  const std::string& GetPkgId() const;
+  const std::string& GetCompType() const;
+  const std::string& GetInternalPool() const;
+  const std::string& GetRootPath() const;
+  const std::string& GetLoaderName() const;
+  const bool IsGlobal() const;
+  const tizen_base::Bundle& GetBundle() const;
+
+ private:
+  AppInfo(std::string app_id, std::string app_path,
+      std::string original_app_path, std::string pkg_type, std::string app_type,
+      std::string hwacc, std::string taskmanage, std::string pkg_id,
+      std::string comp_type, std::string internal_pool, std::string root_path,
+      std::string loader_name, bool global, tizen_base::Bundle b);
+
+ private:
+  std::string app_id_;
+  std::string app_path_;
+  std::string original_app_path_;
+  std::string pkg_type_;
+  std::string app_type_;
+  std::string hwacc_;
+  std::string taskmanage_;
+  std::string pkg_id_;
+  std::string comp_type_;
+  std::string internal_pool_;
+  std::string root_path_;
+  std::string loader_name_;
+  bool global_;
+  tizen_base::Bundle b_;
+};
+
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_APP_INFO_HH_
diff --git a/src/launchpad-process-pool/cpu_checker.cc b/src/launchpad-process-pool/cpu_checker.cc
new file mode 100644 (file)
index 0000000..3777f1c
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "launchpad-process-pool/cpu_checker.hh"
+
+#include <algorithm>
+#include <cmath>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include "launchpad-process-pool/log_private.hh"
+
+namespace launchpad {
+namespace {
+
+constexpr const float PI = 3.14159265;
+
+void GetCPUIdle(uint64_t* total, uint64_t* idle) {
+  std::ifstream stat_file("/proc/stat");
+  if (!stat_file) {
+    _E("Failed to open /proc/stat");
+    return;
+  }
+
+  std::string cpu_label;
+  stat_file >> cpu_label;
+  if (cpu_label != "cpu") {
+    _E("Unexpected label in /proc/stat");
+    return;
+  }
+
+  uint64_t sum = 0;
+  uint64_t value;
+  uint64_t idle_value = 0;
+  for (int i = 0; i < 10; ++i) {
+    if (!(stat_file >> value)) {
+      _E("Failed to read /proc/stat");
+      return;
+    }
+
+    if (sum + value < sum) {
+      _E("Overflow in /proc/stat");
+      return;
+    }
+
+    sum += value;
+    if (i == 3)
+      idle_value = value;
+  }
+
+  *total = sum;
+  *idle = idle_value;
+}
+
+float Interpolator(float input, int cpu_max, int cpu_min) {
+  const float min_percent = cpu_min / 100.0f;
+  const float max_percent = cpu_max / 100.0f;
+  const float input_clamped = std::clamp(input, 0.0f, 1.0f);
+  const float result = (std::cos(input_clamped * PI) / 2.0f) + 0.5f;
+  return (result * (max_percent - min_percent)) - min_percent;
+}
+
+}  // namespace
+
+CPUChecker::CPUChecker(int threshold_max, int threshold_min)
+    : threshold_max_(threshold_max),
+      threshold_min_(threshold_min) {
+}
+
+bool CPUChecker::IsIdle() {
+  uint64_t total;
+  uint64_t idle;
+  GetCPUIdle(&total, &idle);
+
+  if (total == cpu_total_time_)
+    total++;
+
+  auto percentage = CalculatePercentage(idle, total);
+  if (percentage >= threshold_) {
+    UpdateThreshold(-0.02f * (percentage - threshold_));
+    return true;
+  }
+
+  UpdateCPUIdleTime(idle);
+  UpdateCPUTotalTime(total);
+  UpdateThreshold(0.05f);
+  return false;
+}
+
+float CPUChecker::CalculatePercentage(uint64_t idle, uint64_t total) {
+  return (idle - cpu_idle_time_) * 100 / (total - cpu_total_time_);
+}
+
+void CPUChecker::UpdateCPUIdleTime(uint64_t idle) {
+  cpu_idle_time_ = idle;
+}
+
+void CPUChecker::UpdateCPUTotalTime(uint64_t total) {
+  cpu_total_time_ = total;
+}
+
+void CPUChecker::UpdateThreshold(float delta) {
+  pos_ = std::clamp(pos_ + delta, 0.0f, 1.0f);
+  threshold_ = Interpolator(pos_, threshold_max_, threshold_min_) * 100;
+  _D("[CPU] delta: %f, input cursor: %f, threshold: %f",
+      delta, pos_, threshold_);
+}
+
+}  // namespace launchpad
diff --git a/src/launchpad-process-pool/cpu_checker.hh b/src/launchpad-process-pool/cpu_checker.hh
new file mode 100644 (file)
index 0000000..6e23ed8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LAUNCHPAD_PROCESS_POOL_CPU_CHECKER_HH_
+#define LAUNCHPAD_PROCESS_POOL_CPU_CHECKER_HH_
+
+#include <cstdint>
+
+namespace launchpad {
+
+class CPUChecker {
+ public:
+  CPUChecker(int threshold_max, int threshold_min);
+
+  bool IsIdle();
+
+ private:
+  float CalculatePercentage(uint64_t idle, uint64_t total);
+  void UpdateCPUIdleTime(uint64_t idle);
+  void UpdateCPUTotalTime(uint64_t total);
+  void UpdateThreshold(float delta);
+
+ private:
+  int threshold_max_;
+  int threshold_min_;
+  uint64_t cpu_idle_time_ = 0;
+  uint64_t cpu_total_time_ = 0;
+  float threshold_ = 0;
+  float pos_ = 0.0f;
+};
+
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_CPU_CHECKER_HH_