The "Always Loader With Low Priority" mode is added to the LaunchMode.
If it's set, an application will be executed using the loader process.
And, the loader process is executed with the low priority.
When getting the launch request, the launchpad-process-pool sets the high
priority to the process using the boosting API.
Change-Id: I46a6eef78c263c01f4a757717cbb069f4b8b28f5
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
## Mode=Always_Loader_Without_CPUChecker
## - This mode is the modified version of "Mode=Always_Loader".
## - After processing the launch request, the launchpad executes a new loader process without CPU Checker.
+## Mode=Always_Loader_With_Low_Priority
+## - This mode is the modified version of "Mode=Always_Loader_Without_CPUChecker".
+## - When the loader process is executed, the launchpad sets the low scheduling priority to the running process.
+## - And then, the launchpad sets the normal priority to the running process if the launch request is delivered.
[LaunchMode]
Mode=Default_Operation
constexpr const char kValueModeAlwaysLoader[] = "ALWAYS_LOADER";
constexpr const char kValueModeAlwaysLoaderWithoutCPUChecker[] =
"ALWAYS_LOADER_WITHOUT_CPUCHECKER";
+constexpr const char kValueModeAlwaysLoaderWithLowPriority[] =
+ "ALWAYS_LOADER_WITH_LOW_PRIORITY";
} // namespace
mode_ = LaunchMode::Mode::AlwaysLoader;
else if (mode == kValueModeAlwaysLoaderWithoutCPUChecker)
mode_ = LaunchMode::Mode::AlwaysLoaderWithoutCPUChecker;
+ else if (mode == kValueModeAlwaysLoaderWithLowPriority)
+ mode_ = LaunchMode::Mode::AlwaysLoaderWithLowPriority;
}
_W("[LaunchMode] mode: %d(%s)", static_cast<int>(mode_), mode.c_str());
DefaultOperation = 1,
AlwaysLoader = 2,
AlwaysLoaderWithoutCPUChecker = 3,
+ AlwaysLoaderWithLowPriority = 4,
};
explicit LaunchMode(const IniParser& parser);
#include <exception.hh>
#include <executor.hh>
#include <procfs.hh>
+#include <sched_priority.hh>
#include <types.hh>
#include <user_tracer.hh>
#include <util.hh>
// Config::LaunchMode::Mode::AlwaysLoader
// Config::LaunchMode::Mode::AlwaysLoaderWithoutCPUChecker
+ // Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority
if (context->GetPid() > 0)
return true;
Launchpad::LaunchResult Launchpad::LaunchRequestPend(
std::shared_ptr<Request> request) {
auto loader_context = request->GetAvailableLoaderContext();
- if (loader_context->IsPrepared())
+ if (loader_context->IsPrepared()) {
+ SchedPriority::Set(loader_context->GetPid(), 0);
return LaunchResult::Continue;
+ }
_W("Loader context is not prepared");
loader_context->Ref();
request->SetPid(loader_context->Deploy(app_info));
if ((mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithoutCPUChecker) ||
+ (mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority) ||
(mode_ == Config::LaunchMode::Mode::AlwaysLoader &&
loader_context->RefCount() > 0))
loader_context->Prepare();
void Launchpad::OnLoaderLaunched(LoaderContext* loader_context) {
_W("Loader is launched. name(%s), pid(%d)",
loader_context->GetLoaderName().c_str(), loader_context->GetPid());
- if (loader_context->RefCount() == 0)
+ if (loader_context->RefCount() == 0) {
+ if (mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority)
+ SchedPriority::Set(loader_context->GetPid(), 19);
+
return;
+ }
for (auto& request : pending_requests_) {
auto context = request->GetAvailableLoaderContext();
#include <types.hh>
#include "launchpad-process-pool/app_labels_monitor.hh"
+#include "launchpad-process-pool/config.hh"
#include "launchpad-process-pool/loader_executor.hh"
#include "launchpad-process-pool/log.hh"
#include "launchpad-process-pool/log_private.hh"
}
pid_t LoaderContext::Prepare() {
+ bool set_priority = (Config::GetInst().GetLaunchMode().GetMode() !=
+ Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority);
pid_ = LoaderExecutor::GetInst().Execute(this,
- loader_info_->GetSchedPriority());
+ set_priority ? loader_info_->GetSchedPriority() : 0);
_W("Prepare. type(%d), name(%s), pid(%d)",
GetType(), GetLoaderName().c_str(), pid_);
if (pid_ == -1) {
namespace launchpad {
int SchedPriority::Set(int priority) {
- int ret = setpriority(PRIO_PGRP, 0, priority);
+ return Set(0, priority);
+}
+
+int SchedPriority::Set(pid_t pid, int priority) {
+ int ret = setpriority(PRIO_PGRP, pid, priority);
if (ret != 0) {
- _E("Failed to set process priority. priority(%d), errno(%d)",
- priority, errno);
+ _E("Failed to set priority proriority. who(%d), priority(%d), errno(%d)",
+ pid, priority, errno);
} else {
- _D("Setting priority(%d) is sucessful", priority);
+ _D("Setting priority(%d) is sucessful. who(%d)", priority, pid);
}
return ret;
#ifndef LIB_LAUNCHPAD_COMMON_SCHED_PRIORITY_HH_
#define LIB_LAUNCHPAD_COMMON_SCHED_PRIORITY_HH_
+#include <sys/types.h>
+
#undef EXPORT_API
#define EXPORT_API __attribute__((visibility("default")))
class EXPORT_API SchedPriority {
public:
static int Set(int priority);
+ static int Set(pid_t pid, int priority);
static int Get();
};
candidate_pid_ = executor_->Execute(argc_, argv_);
_D("Candidate process(%d)", candidate_pid_);
socket_->Send(&candidate_pid_, sizeof(candidate_pid_));
- SchedPriority::Set(0);
EventLoop::GetInst().Run();
OnTerminate();
return -1;
}
- SchedPriority::Set(0);
OnAdapterLoopBegin();
return OnTerminate();
}