Merge branch 'master' of https://github.sec.samsung.net/appfw/united-service into...
authorSukhyungKang <shine.kang@samsung.com>
Tue, 13 May 2025 10:48:26 +0000 (19:48 +0900)
committerSukhyungKang <shine.kang@samsung.com>
Tue, 13 May 2025 10:48:26 +0000 (19:48 +0900)
Signed-off-by: SukhyungKang <shine.kang@samsung.com>
1  2 
src/service.hh
src/service_loader.cc
src/service_loader.hh
src/watchdog/inspector.cc
src/watchdog/watchdog_manager.cc

diff --cc src/service.hh
Simple merge
index f3f26166ca3d54e045d363ba18171a8e5f637052,b39819b1c64a80e3b8b25086adc7922517f9ebd6..1ca8856016a2c447b8a1f8af2ae6a4bfefad9788
mode 100755,100644..100755
@@@ -32,25 -32,13 +32,32 @@@ namespace 
  constexpr const char kPathUnitedService[] = "/usr/share/united-service/";
  constexpr const char kConf[] = "/conf/";
  
 +bool ComparePriority(const std::pair<std::string, unsigned int>& pair1,
 +    const std::pair<std::string, unsigned int>& pair2) {
 +  return pair1.second > pair2.second;
 +}
 +
 +std::string ServiceStateToString(tizen_base::Service::State state) {
 +  switch(state) {
 +    case tizen_base::Service::State::Initialized:
 +      return std::string("Initialized");
 +    case tizen_base::Service::State::Created:
 +      return std::string("Created");
 +    case tizen_base::Service::State::Running:
 +      return std::string("Running");
 +    case tizen_base::Service::State::Destroyed:
 +      return std::string("Destroyed");
 +  }
 +  return "";
 +}
 +
+ static const std::string kTagServiceLoader = "service-loader";
+ static const std::string kWatchdogSec = kTagServiceLoader + ":watchdogsec";
+ static const std::string kCpuTimeSec = kTagServiceLoader + ":cputimesec";
+ static const std::string kMemoryMonitor = kTagServiceLoader + ":memorymonitor";
+ static const std::string kCpuMonitor = kTagServiceLoader + ":cpumonitor";
+ static const std::string kBacktrace = kTagServiceLoader + ":backtrace";
  }  // namespace
  
  namespace tizen_base {
Simple merge
index 0000000000000000000000000000000000000000,4980f306588668ee99b314317b34f28bf0b084d3..861729431fb9caebee10a6a41ed32d4a8fd2b4e2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,98 +1,98 @@@
 -            _W("(PSS %-4ld kb) %s\n", pss, libinfo.c_str());
+ /*
+  * Copyright (c) 2025 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 "inspector.hh"
+ #include "cpu_time.hh"
+ #include <filesystem>
+ #include <string>
+ #include <iostream>
+ #include <fstream>
+ #include <aul_backtrace.h>
+ #include <sys/ptrace.h>
+ #include <sys/wait.h>
+ namespace tizen_base::Inspector {
+   void PrintBacktrace(pid_t tid, std::string name) {
+     int ret = aul_send_backtrace_request(tid);
+     if (ret != AUL_R_OK) {
+       _E("Fail to print bt for %d (%d)", tid, ret);
+     }
+   }
+   void MemoryMonitor(std::string loader_name) {
+     if (loader_name.empty()) {
+       _E("Invalid parameter");
+       return;
+     }
+     std::filesystem::path smaps_path = "/proc/" + std::to_string(getpid()) +
+         "/smaps";
+     if (!std::filesystem::exists(smaps_path)) {
+       _E("%s does not exist", smaps_path.c_str());
+       return;
+     }
+     std::ifstream file(smaps_path);
+     if (!file) {
+       _E("Failed to open %s", smaps_path.c_str());
+       return;
+     }
+     _W("[Loader %d(%s)] Memory monitor", getpid(), loader_name.c_str());
+     uint64_t total_pss = 0;
+     std::string line;
+     std::string libinfo;
+     while (std::getline(file, line)) {
+       std::stringstream stream(line);
+       std::string tag;
+       if (stream >> tag) {
+         if (!tag.ends_with(":")) {
+           std::string area = std::move(tag);
+           std::string perm;
+           std::string dummy;
+           std::string filename;
+           stream >> perm;
+           stream >> dummy >> dummy >> dummy;
+           stream >> filename;
+           libinfo = area + " " + perm + " " +  filename;
+         } else if (tag == "Pss:") {
+           uint64_t pss = 0;
+           stream >> pss;
+           total_pss += pss;
+           if (pss > 0) {
 -    _W("[%d] Total PSS %-4ld kB", getpid(), total_pss);
++            _W("(PSS %-4llu kb) %s\n", pss, libinfo.c_str());
+           }
+         }
+       }
+     }
++    _W("[%d] Total PSS %-4llu kB", getpid(), total_pss);
+     return;
+   }
+   void CpuMonitor(std::shared_ptr<CpuTime> cpu_time) {
+     double cpu_usage = cpu_time->CalculateCpuUsage();
+     _W("[%d:%d] CPU usage = %.4f%%", getpid(), cpu_time->GetTid(), cpu_usage);
+     return;
+   }
+ } // namespace tizen_base
index 0000000000000000000000000000000000000000,069b190f2c6b9b64383e75314370d1535bfecf56..b7b3c1667e37b0f3ab473bc8c6d7c5e0ef509332
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,169 +1,169 @@@
 -    _I("[%d/%ld] %s Interval",
+ /*
+  * Copyright (c) 2025 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 "watchdog_manager.hh"
+ #include "log_private.hh"
+ namespace tizen_base {
+ WatchdogManager& WatchdogManager::GetInst() {
+   static WatchdogManager inst;
+   return inst;
+ }
+ WatchdogManager::~WatchdogManager() {
+   int ret = tizen_core_task_destroy(task_);
+   if (ret != TIZEN_CORE_ERROR_NONE)
+     _E("Cannot destroy watchdog task");
+ }
+ bool WatchdogManager::Init(std::shared_ptr<WatchdogConf> conf) {
+   if (init_)
+     _W("Reinitialize manager instance");
+   conf_ = std::move(conf);
+   int ret = tizen_core_task_create("watchdog", true, &task_);
+   if (ret != TIZEN_CORE_ERROR_NONE) {
+     _E("Cannot create watchdog task(%d)", ret);
+     return false;
+   }
+   ret = tizen_core_task_get_tizen_core(task_, &core_);
+   if (ret != TIZEN_CORE_ERROR_NONE) {
+     _E("Cannot find core from watchdog task(%d)", ret);
+     return false;
+   }
+   if (!StartWatchdog())
+     return false;
+   _D("Manager instance initialied done");
+   init_ = true;
+   return true;
+ }
+ void WatchdogManager::RegisterService(pid_t tid, std::string name,
+     tizen_core_h core) {
+   _I("Loader(%s) register tid %d(%s)",
+       conf_->GetLoaderName().c_str(), tid, name.c_str());
+   std::shared_ptr<CpuTime> cputime = nullptr;
+   std::shared_ptr<Heartbeat> heartbeat = nullptr;
+   if (conf_->IsCpuMonitor())
+     cputime = std::make_shared<CpuTime>(tid);
+   if (conf_->GetWatchdogSec() > 0)
+     heartbeat = std::make_shared<Heartbeat>(tid, core);
+   auto ctx = WatchdogContext::Builder()
+       .SetLoaderName(conf_->GetLoaderName())
+       .SetCpuMonitorFlag(conf_->IsCpuMonitor())
+       .SetCpuTime(cputime)
+       .SetHeartbeat(heartbeat)
+       .SetServiceName(std::move(name))
+       .SetTid(std::move(tid))
+       .SetMemoryMonitorFlag(conf_->IsMemoryMonitor())
+       .SetBacktraceFlag(conf_->IsBacktrace())
+       .Build();
+   std::unique_lock<std::mutex> lock(context_list_mutex_);
+   contexts_.emplace_back(std::move(ctx));
+ }
+ void WatchdogManager::UnregisterService(pid_t tid) {
+   std::unique_lock<std::mutex> lock(context_list_mutex_);
+   int ret = contexts_.remove_if([tid](auto context) {
+       return context->GetTid() == tid;
+     });
+   if (ret == 1)
+     _I("Loader(%s) unregister tid %d", conf_->GetLoaderName().c_str(), tid);
+   else
+     _E("Loader(%s) unregister tid %d return %d",
+         conf_->GetLoaderName().c_str(), tid, ret);
+ }
+ void WatchdogManager::Interval() {
+   std::unique_lock<std::mutex> lock(context_list_mutex_);
+   int count = 1;
+   for (auto& context : contexts_) {
++    _I("[%d/%u] %s Interval",
+         count++, contexts_.size(), context->GetServiceName().c_str());
+     if (!context->CpuTimeInterval())
+       _W("Failed to update CpuTime of tid %d", context->GetTid());
+     if (!context->HeartbeatInterval()) {
+       _E("Failed to verify Heartbeat of tid %d", context->GetTid());
+       context->OnWatchdogTimeout();
+     }
+   }
+ }
+ bool WatchdogManager::StartWatchdog() {
+   int ret = 0;
+   tizen_core_source_h oneshot_source;
+   if (conf_->GetWatchdogSec() == 0) {
+     _W("Watchdog is disabled (WatchdogSec 0)");
+     return true;
+   }
+   // Initial logging
+   ret = tizen_core_add_idle_job(core_, [](void* user_data) -> bool {
+     _I("Watchdog Manager Job Thread %d", gettid());
+     return false;
+   }, nullptr, &oneshot_source);
+   if (ret != TIZEN_CORE_ERROR_NONE) {
+     _E("Cannot add idle job to watchdog %d", ret);
+     return false;
+   }
+   // Interval
+   ret = tizen_core_add_timer(core_, conf_->GetWatchdogSec() * 1000,
+     [](void* user_data) -> bool {
+       WatchdogManager::GetInst().Interval();
+       return true;
+     }, nullptr, &source_);
+   if (ret != TIZEN_CORE_ERROR_NONE) {
+     _E("Cannot add watchdog interval %d", ret);
+     return false;
+   }
+   // Run
+   ret = tizen_core_task_run(task_);
+   if (ret != TIZEN_CORE_ERROR_NONE) {
+     _E("Cannot run watchdog task %d", ret);
+     return false;
+   }
+   return true;
+ }
+ bool WatchdogManager::StopWatchdog() {
+   int ret = 0;
+   int result = true;
+   ret = tizen_core_remove_source(core_, source_);
+   if (ret != TIZEN_CORE_ERROR_NONE) {
+     _E("Cannot Stop Watchdog Monitor %d", ret);
+     result = false;
+   }
+   return result;
+ }
+ } // namespace tizen_base