struct coreset {
GSList *cores;
char *name;
+ bool disclaimer_shown;
};
struct cpu_sched {
return RESOURCED_ERROR_NONE;
}
-static int cpu_sched_add_pid_to_cpuset(struct coreset *set, pid_t pid, bool move_pid)
+static int cpu_sched_add_pid_to_cpuset(struct coreset *set, pid_t pid)
{
- pid_t old_pid;
- char path[PATH_MAX];
- _cleanup_free_ char *buf = NULL;
- int r;
-
assert(set);
_D("cpu-sched: add pid %d to cpuset %s", pid, set->name);
- r = snprintf(path, sizeof path, "%s/%s", CPUSET_CGROUP, set->name);
+
+ char path[PATH_MAX];
+ int r = snprintf(path, sizeof path, "%s/%s", CPUSET_CGROUP, set->name);
if (r < 0) {
_E("cpu-sched: failed to setup path for cpuset (%s)", set->name);
return r;
}
- buf = (char *)calloc(1, PATH_MAX);
- if (NULL == buf)
- return RESOURCED_ERROR_OUT_OF_MEMORY;
+ r = cgroup_write_node_int32(path, "tasks", pid);
+ ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL, "Failed to attach pid %d to cgroup %s: %m", pid, path);
+ return RESOURCED_ERROR_NONE;
+}
- if (true == move_pid) { /* in case of foreground app previous pid needs to be moved to main cpuset first */
- /* read pid of previous foreground app, there can be only one */
- if (RESOURCED_ERROR_NONE == cgroup_read_node_int32(path, "tasks", &old_pid)) {
- /* and write it to default cpuset */
- r = cgroup_write_node_int32(CPUSET_CGROUP, "tasks", (u_int32_t)old_pid);
- ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL,
- "Failed to attach pid %d to cgroup %s : %m",
- old_pid, CPUSET_CGROUP);
- }
+static int cpu_sched_remove_pid_from_cpuset(struct coreset *set, pid_t pid)
+{
+ assert(set);
- r = snprintf(buf, PATH_MAX, "%d", pid);
- if (r < 0) {
- _E("cpu-sched: failed to create pid list for cpuset (%s)", set->name);
- return r;
- }
+ _D("cpu-sched: moving pid %d to toplevel cpuset (from %s cpuset)", pid, set->name);
- } else { /* in case of static apps new pid needs to be appended to existing pids */
- char path_full[PATH_MAX];
+ int r = cgroup_write_node_int32(CPUSET_CGROUP, "tasks", pid);
+ ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL, "Failed to attach pid %d to cgroup " CPUSET_CGROUP ": %m", pid);
- r = snprintf(path_full, sizeof path_full, "%s/tasks", path);
- if (r < 0) {
- _E("cpu-sched: failed to setup path for cpuset (%s)", set->name);
- return r;
- }
+ return RESOURCED_ERROR_NONE;
+}
- r = 0;
- /* read pid of previous apps in this cpuset, there can be more than one */
- if (RESOURCED_ERROR_NONE != fread_str(path_full, &buf)) {
- _I("cpu-sched: could not read old value of app's pids, adding first one");
- r = snprintf(buf, PATH_MAX, "%d", pid);
- } else {
- /* append new pid at the end */
- r = snprintf(buf + strlen(buf), PATH_MAX - strlen(buf), ",%d", pid);
- }
+/* if app is subject to static coreset config its coreset should not be changed */
+static bool cpu_sched_is_static_app(const char *appid)
+{
+ assert (appid);
- if (r < 0) {
- _E("cpu-sched: failed to create pid list for cpuset (%s)", set->name);
- return r;
- }
- _D("cpu-sched: add new pids to cpuset %s: %s (%d)", set->name, buf, r);
+ struct coreset *c = cpu_sched_find_coreset(appid);
+ if (!c)
+ return false;
+ if (false == c->disclaimer_shown) {
+ _D("cpu-sched: appid %s is statically configured - not subject to cpuset change", appid);
+ c->disclaimer_shown = true;
}
- /* write current foreground app to proper cpuset */
- r = cgroup_write_node_str(path, "tasks", buf);
- ret_value_msg_if(r < 0, RESOURCED_ERROR_FAIL,
- "Failed to attach pid %d to cgroup %s : %m",
- pid, path);
-
- return RESOURCED_ERROR_NONE;
+ return true;
}
static int cpu_sched_app_foreground(void *data)
{
+ struct proc_status *ps = (struct proc_status *)data;
+
assert(cs.fg);
+ assert(ps);
+ assert(ps->pai);
+
+ if (false == cs.is_initalized || true == cpu_sched_is_static_app(ps->pai->appid))
+ return RESOURCED_ERROR_NONE;
+
+ _D("cpu-sched: app %s moved to foreground; pid=%d", ps->pai->appid, ps->pid);
+ return cpu_sched_add_pid_to_cpuset(cs.fg, ps->pid);
+}
+
+static int cpu_sched_app_background(void *data)
+{
struct proc_status *ps = (struct proc_status *)data;
+ assert(cs.fg);
assert(ps);
assert(ps->pai);
- if (false == cs.is_initalized)
+ if (false == cs.is_initalized || true == cpu_sched_is_static_app(ps->pai->appid))
return RESOURCED_ERROR_NONE;
- /* if this app is subject to static coreset config don't change that */
- if (NULL != cpu_sched_find_coreset(ps->pai->appid))
- return 0;
+ _D("cpu-sched: app %s moved to background; pid=%d", ps->pai->appid, ps->pid);
- _D("cpu-sched: app %s moved to foreground; pid=%d", ps->pai->appid, ps->pid);
-
- return cpu_sched_add_pid_to_cpuset(cs.fg, ps->pid, true);
+ return cpu_sched_remove_pid_from_cpuset(cs.fg, ps->pid);
}
static int cpu_sched_app_launch(void *data)
if (NULL == c)
return 0;
- return cpu_sched_add_pid_to_cpuset(c, ps->pid, false);
+ return cpu_sched_add_pid_to_cpuset(c, ps->pid);
}
static void register_notifiers()
{
if (cs.fg) {
register_notifier(RESOURCED_NOTIFIER_APP_RESUME, cpu_sched_app_foreground);
+
register_notifier(RESOURCED_NOTIFIER_APP_FOREGRD, cpu_sched_app_foreground);
+ register_notifier(RESOURCED_NOTIFIER_APP_BACKGRD, cpu_sched_app_background);
+
register_notifier(RESOURCED_NOTIFIER_WIDGET_FOREGRD, cpu_sched_app_foreground);
+ register_notifier(RESOURCED_NOTIFIER_WIDGET_BACKGRD, cpu_sched_app_background);
}
register_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
{
if (cs.fg) {
unregister_notifier(RESOURCED_NOTIFIER_APP_RESUME, cpu_sched_app_foreground);
+
unregister_notifier(RESOURCED_NOTIFIER_APP_FOREGRD, cpu_sched_app_foreground);
+ unregister_notifier(RESOURCED_NOTIFIER_APP_BACKGRD, cpu_sched_app_background);
+
unregister_notifier(RESOURCED_NOTIFIER_WIDGET_FOREGRD, cpu_sched_app_foreground);
+ unregister_notifier(RESOURCED_NOTIFIER_WIDGET_BACKGRD, cpu_sched_app_background);
}
unregister_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
c = cpu_sched_find_coreset(pai->appid);
if (NULL != c) {
- cpu_sched_add_pid_to_cpuset(c, pai->main_pid, false);
+ cpu_sched_add_pid_to_cpuset(c, pai->main_pid);
continue;
}