#include "config-parser.h"
#include "trace.h"
#include "cgroup.h"
+#include "notifier.h"
+#include "cpu-hotplug.h"
#define CPU_SCHED_CONF_FILE RD_CONFIG_FILE(cpu-sched)
#define CPU_SCHED_FG_NAME "foreground"
return RESOURCED_ERROR_NONE;
}
+static int cpu_sched_write_coreset(struct coreset *set)
+{
+ GSList *i;
+ struct core *c;
+ char path[128], coreset[128];
+ int r;
+
+ assert(set);
+
+
+ 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;
+ }
+
+ r = 0;
+ gslist_for_each_item(i, set->cores) {
+ c = (struct core *)i->data;
+ if (NULL == c || false == c->on)
+ continue;
+
+ r += snprintf(coreset + r, sizeof coreset - r, "%d,", c->id);
+ }
+
+ if (r > 0)
+ coreset[--r] = '\0';
+
+ return cgroup_write_node_str(path, "cpuset.cpus", coreset);
+}
+
+static int cpu_sched_cpu_on_for_coreset(struct coreset *set, int core_id)
+{
+ GSList *i;
+ struct core *c;
+ bool refresh = false;
+
+ assert(set);
+ assert(core_id >= 0);
+
+ if (NULL == set->cores)
+ return 0;
+
+ gslist_for_each_item(i, set->cores) {
+ c = (struct core *)i->data;
+ if (NULL == c || c->id != core_id)
+ continue;
+
+ _D("cpu-sched: core %d on for coreset %s", core_id, set->name);
+ c->on = true;
+ refresh = true;
+ break;
+ }
+
+ if (false == refresh)
+ return 0;
+
+ return cpu_sched_write_coreset(set);
+}
+
+static int cpu_sched_cpu_off_for_coreset(struct coreset *set, int core_id)
+{
+ GSList *i;
+ struct core *c;
+ bool refresh = false;
+
+ assert(set);
+ assert(core_id >= 0);
+
+ if (NULL == set->cores)
+ return 0;
+
+ gslist_for_each_item(i, set->cores) {
+ c = (struct core *)i->data;
+ if (NULL == c || c->id != core_id)
+ continue;
+
+ _D("cpu-sched: core %d off for coreset %s", core_id, set->name);
+ c->on = false;
+ refresh = true;
+ break;
+ }
+
+ if (false == refresh)
+ return 0;
+
+ return cpu_sched_write_coreset(set);
+}
+
+static int cpu_sched_cpu_on(void *data)
+{
+ int id;
+
+ assert(data);
+
+ id = *(int*)(data);
+
+ _D("cpu-sched: core %d plugged in", id);
+ cpu_sched_cpu_on_for_coreset(&cs.fg, id);
+
+ return RESOURCED_ERROR_NONE;
+}
+
+static int cpu_sched_cpu_off(void *data)
+{
+ int id;
+
+ assert(data);
+
+ id = *(int*)(data);
+
+ _D("cpu-sched: core %d plugged out", id);
+ cpu_sched_cpu_off_for_coreset(&cs.fg, id);
+
+ return RESOURCED_ERROR_NONE;
+}
+
+static void register_notifiers()
+{
+ register_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
+ register_notifier(RESOURCED_NOTIFIER_CPU_OFF, cpu_sched_cpu_off);
+}
+
+static void unregister_notifiers()
+{
+ unregister_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
+ unregister_notifier(RESOURCED_NOTIFIER_CPU_OFF, cpu_sched_cpu_off);
+}
+
static int cpu_sched_init(void *data)
{
int r;
if (r < 0)
goto init_failed;
+ register_notifiers();
+ if (cpu_hotplug_init() != 0) {
+ _E("cpu_sched: could not setup cpu hotplugging");
+ return RESOURCED_ERROR_FAIL;
+ }
+
cs.is_initalized = true;
return RESOURCED_ERROR_NONE;
init_failed:
+ unregister_notifiers();
+ cpu_hotplug_finalize();
cpu_sched_free_cpuset(&cs.fg);
cs.is_initalized = false;
return RESOURCED_ERROR_FAIL;
static int cpu_sched_finalize(void *data)
{
_D("cpu-sched: deinit module");
+ unregister_notifiers();
+ cpu_hotplug_finalize();
cpu_sched_free_cpuset(&cs.fg);
cs.is_initalized = false;
return RESOURCED_ERROR_NONE;