GSList *child_cgroups;
};
+struct cgroup_oom {
+ int fixed_oom;
+ enum cgroup_type mem_type;
+ enum cgroup_type cpu_type;
+};
+
/**
* @desc Get cgroup type according to oom_score_adj
* @param oom_score_adj - oom_score_adj
free(namelist);
}
+void remove_app_conf_info_list(void)
+{
+ GSList *iter, *next;
+ struct proc_conf_info *pci;
+
+ gslist_for_each_safe(app_conf_info_list, iter, next, pci) {
+ app_conf_info_list = g_slist_remove(app_conf_info_list, pci);
+ free(pci);
+ }
+}
+
+void remove_service_conf_info_list(void)
+{
+ GSList *iter, *next;
+ struct proc_conf_info *pci;
+
+ gslist_for_each_safe(service_conf_info_list, iter, next, pci) {
+ service_conf_info_list = g_slist_remove(service_conf_info_list, pci);
+ free(pci);
+ }
+}
+
+GSList *get_app_conf_info_list(void)
+{
+ return app_conf_info_list;
+}
+
+GSList *get_service_conf_info_list(void)
+{
+ return app_conf_info_list;
+}
+
void resourced_parse_vendor_configs(void)
{
int config_type;
int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
+void remove_app_conf_info_list(void);
+void remove_service_conf_info_list(void);
+GSList *get_app_conf_info_list(void);
+GSList *get_service_conf_info_list(void);
void resourced_parse_vendor_configs(void);
#ifdef __cplusplus
}
void d_bus_init(void)
{
- owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, RESOURCED_DBUS_BUS_NAME,
+ owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, RESOURCED_BUS_NAME,
G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL, NULL);
if (owner_id == 0) {
_E("Failed to get gdbus own name");
/*
* Deviced
*/
-#define DEVICED_BUS_NAME "org.tizen.system.deviced"
+/*#define DEVICED_BUS_NAME "org.tizen.system.deviced"
#define DEVICED_OBJECT_PATH "/Org/Tizen/System/DeviceD"
#define DEVICED_PATH_PROCESS DEVICED_OBJECT_PATH"/Process"
#define DEVICED_INTERFACE_POWEROFF DEVICED_BUS_NAME".PowerOff"
#define DEVICED_PATH_TIME DEVICED_OBJECT_PATH"/Time"
-#define DEVICED_INTERFACE_TIME DEVICED_BUS_NAME".Time"
+#define DEVICED_INTERFACE_TIME DEVICED_BUS_NAME".Time"*/
#define SIGNAL_DEVICED_LCDON "LCDOn"
#ifndef DBUS_NAMES_LOCAL_H_INCLUDE_GUARD
#define DBUS_NAMES_LOCAL_H_INCLUDE_GUARD
-#define RESOURCED_DBUS_BUS_NAME "org.tizen.resourced"
+#include <libsyscommon/libsystemd.h>
+
+/*#define RESOURCED_DBUS_BUS_NAME "org.tizen.resourced"
#define RESOURCED_DBUS_OBJECT_PATH "/Org/Tizen/ResourceD"
-#define RESOURCED_DBUS_INTERFACE_NAME RESOURCED_DBUS_BUS_NAME
+#define RESOURCED_DBUS_INTERFACE_NAME RESOURCED_DBUS_BUS_NAME*/
/*
* Core service
* get/set swap status
* operations about swap
*/
-#define RESOURCED_PATH_SWAP RESOURCED_DBUS_OBJECT_PATH"/Swap"
-#define RESOURCED_INTERFACE_SWAP RESOURCED_DBUS_INTERFACE_NAME".swap"
+#define RESOURCED_PATH_SWAP RESOURCED_OBJECT_PATH"/Swap"
+#define RESOURCED_INTERFACE_SWAP RESOURCED_INTERFACE_NAME".swap"
-#define RESOURCED_PATH_FREEZER RESOURCED_DBUS_OBJECT_PATH"/Freezer"
-#define RESOURCED_INTERFACE_FREEZER RESOURCED_DBUS_INTERFACE_NAME".freezer"
+/*#define RESOURCED_PATH_FREEZER RESOURCED_DBUS_OBJECT_PATH"/Freezer"
+#define RESOURCED_INTERFACE_FREEZER RESOURCED_DBUS_INTERFACE_NAME".freezer"*/
-#define RESOURCED_PATH_OOM RESOURCED_DBUS_OBJECT_PATH"/Oom"
-#define RESOURCED_INTERFACE_OOM RESOURCED_DBUS_INTERFACE_NAME".oom"
+#define RESOURCED_PATH_OOM RESOURCED_OBJECT_PATH"/Oom"
+#define RESOURCED_INTERFACE_OOM RESOURCED_INTERFACE_NAME".oom"
-#define RESOURCED_PATH_PROCESS RESOURCED_DBUS_OBJECT_PATH"/Process"
-#define RESOURCED_INTERFACE_PROCESS RESOURCED_DBUS_INTERFACE_NAME".process"
+/*#define RESOURCED_PATH_PROCESS RESOURCED_DBUS_OBJECT_PATH"/Process"
+#define RESOURCED_INTERFACE_PROCESS RESOURCED_DBUS_INTERFACE_NAME".process"*/
-#define RESOURCED_PATH_WATCHDOG RESOURCED_DBUS_OBJECT_PATH"/Watchdog"
-#define RESOURCED_INTERFACE_WATCHDOG RESOURCED_DBUS_INTERFACE_NAME".watchdog"
+#define RESOURCED_PATH_WATCHDOG RESOURCED_OBJECT_PATH"/Watchdog"
+#define RESOURCED_INTERFACE_WATCHDOG RESOURCED_INTERFACE_NAME".watchdog"
#define SIGNAL_PROC_ACTIVE "Active"
/*
* Logging
*/
-#define RESOURCED_PATH_LOGGING RESOURCED_DBUS_OBJECT_PATH"/Logging"
-#define RESOURCED_INTERFACE_LOGGING RESOURCED_DBUS_INTERFACE_NAME".logging"
+/*#define RESOURCED_PATH_LOGGING RESOURCED_DBUS_OBJECT_PATH"/Logging"
+#define RESOURCED_INTERFACE_LOGGING RESOURCED_DBUS_INTERFACE_NAME".logging"*/
#endif
static const char resourced_module_methods_xml[] =
"<node>"
-" <interface name ='"RESOURCED_DBUS_INTERFACE_NAME"'>"
+" <interface name ='"RESOURCED_INTERFACE_NAME"'>"
" <method name='ListActiveModuels'>"
" <arg type='as' name='ActiveModules' direction='out'/>"
" </method>"
int modules_add_methods(void)
{
- return d_bus_register_methods(RESOURCED_DBUS_OBJECT_PATH, resourced_module_methods_xml,
+ return d_bus_register_methods(RESOURCED_OBJECT_PATH, resourced_module_methods_xml,
resourced_module_methods, ARRAY_SIZE(resourced_module_methods));
}
#include "resourced.h"
#include "trace.h"
-#define PRIORITY_CONF_FILE RD_CONFIG_FILE(limiter)
-
-#define FIXED_OOM_CONF_SECTION "OOM_FIXED_APPS"
-
-#define FIXED_OOM_MIN OOMADJ_SERVICE_MIN
-#define FIXED_OOM_MAX OOMADJ_BACKGRD_LOCKED
-
-static GHashTable *oom_fixed_app_list;
+static GHashTable *cgroup_oom_fixed_app_list;
static GHashTable *oom_fixed_pid_list;
+static GHashTable *cpu_cgroup_fixed_pid_list;
int proc_priority_set_fixed_oom(void *data)
{
int ret;
- int *fixed_oom = NULL;
+ struct cgroup_oom *cgroup_oom;
gint *key, *val;
struct proc_status *ps = (struct proc_status *)data;
- if (!ps)
+ if (!ps || !ps->pai)
return RESOURCED_ERROR_INVALID_PARAMETER;
- fixed_oom = (int *)g_hash_table_lookup(oom_fixed_app_list, ps->pai->appid);
+ cgroup_oom = (struct cgroup_oom *)g_hash_table_lookup(cgroup_oom_fixed_app_list, ps->pai->appid);
/* Make another hashtable for fast searching during proc_set_oom_score_adj */
- if (fixed_oom) {
- ret = proc_set_oom_score_adj(ps->pid, *fixed_oom, ps->pai);
+ if (cgroup_oom &&
+ cgroup_oom->mem_type != CGROUP_TOP) {
+ ret = proc_set_oom_score_adj(ps->pid, cgroup_oom->fixed_oom, ps->pai);
if (ret != RESOURCED_ERROR_NONE) {
_E("Failed to set the fixed oom for %s", ps->pai->appid);
return ret;
}
- _D("Set the fixed oom of %s with %d", ps->pai->appid, *fixed_oom);
+ _D("Set the fixed oom of %s with %d", ps->pai->appid, cgroup_oom->fixed_oom);
key = g_new(gint, 1);
val = g_new(gint, 1);
*key = ps->pid;
- *val = *fixed_oom;
+ *val = cgroup_oom->fixed_oom;
g_hash_table_insert(oom_fixed_pid_list, (gpointer)key, (gpointer)val);
}
return g_hash_table_contains(oom_fixed_pid_list, &pid);
}
-static int load_fixed_oom_config(struct parse_result *result, void *user_data)
+static void register_fixed_oom_apps(void)
{
- int score;
- gint *fixed_oom;
-
- if (!result)
- return RESOURCED_ERROR_INVALID_PARAMETER;
-
- if (!strncmp(result->section, FIXED_OOM_CONF_SECTION, strlen(FIXED_OOM_CONF_SECTION) + 1)) {
-
- /* Set predefined OOM score */
- score = atoi(result->value);
-
- switch (score) {
- case OOMADJ_SERVICE_MIN:
- case OOMADJ_SU:
- case OOMADJ_INIT:
- case OOMADJ_FOREGRD_LOCKED:
- case OOMADJ_FOREGRD_UNLOCKED:
- case OOMADJ_BACKGRD_PERCEPTIBLE:
- case OOMADJ_BACKGRD_LOCKED:
- _E("You can't set the fixed oom for %s with predefined value %d", result->name, score);
- return RESOURCED_ERROR_INVALID_PARAMETER;
- default:
- if (score < FIXED_OOM_MIN || score > FIXED_OOM_MAX) {
- _E("You can't set the fixed oom for %s with the out of range %d", result->name, score);
- return RESOURCED_ERROR_INVALID_PARAMETER;
- }
- }
-
- fixed_oom = g_new(gint, 1);
- *fixed_oom = score;
- g_hash_table_insert(oom_fixed_app_list,
- g_strndup(result->name, strlen(result->name)),
- (gpointer)fixed_oom);
+ GSList *iter;
+ GSList *app_conf_info_list = get_app_conf_info_list();
+ struct proc_conf_info *pci = NULL;
+ struct cgroup_oom *cgroup_oom;
+
+ gslist_for_each_item(iter, app_conf_info_list) {
+ pci = (struct proc_conf_info *)iter->data;
+
+ if (pci->mem_type == CGROUP_TOP && pci->cpu_type == CGROUP_TOP)
+ continue;
+
+ cgroup_oom = g_new(struct cgroup_oom, 1);
+ cgroup_oom->cpu_type = pci->cpu_type;
+ cgroup_oom->mem_type = pci->mem_type;
+
+ if (cgroup_oom->mem_type != CGROUP_TOP)
+ cgroup_oom->fixed_oom = cgroup_get_lowest_oom_score_adj(pci->mem_type);
+ g_hash_table_insert(cgroup_oom_fixed_app_list,
+ g_strndup(pci->name, strlen(pci->name)),
+ (gpointer)cgroup_oom);
}
-
- return RESOURCED_ERROR_NONE;
}
static int proc_priority_init(void *data)
{
- oom_fixed_app_list = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ cgroup_oom_fixed_app_list = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
oom_fixed_pid_list = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
- g_assert(oom_fixed_app_list && oom_fixed_pid_list);
+ g_assert(cgroup_oom_fixed_app_list && oom_fixed_pid_list);
- config_parse(PRIORITY_CONF_FILE, load_fixed_oom_config, NULL);
+ register_fixed_oom_apps();
register_notifier(RESOURCED_NOTIFIER_APP_TERMINATED, proc_priority_remove_pid);
return RESOURCED_ERROR_NONE;
static int proc_priority_exit(void *data)
{
- if (oom_fixed_app_list)
- g_hash_table_destroy(oom_fixed_app_list);
+ if (cgroup_oom_fixed_app_list)
+ g_hash_table_destroy(cgroup_oom_fixed_app_list);
if (oom_fixed_pid_list)
g_hash_table_destroy(oom_fixed_pid_list);
unregister_notifier(RESOURCED_NOTIFIER_APP_TERMINATED, proc_priority_remove_pid);
#include "file-helper.h"
#include "watchdog-cgroup.h"
+#include <libsyscommon/libsystemd.h>
+
#define WATCHDOG_LAUNCHING_PARAM "PopupLaunch"
#define WATCHDOG_KEY1 "_SYSPOPUP_CONTENT_"
#define WATCHDOG_KEY2 "_APP_NAME_"
}
cgroup_write_tid_fullpath(cgroup_name, pid);
-/* r = cgroup_write_node_uint32(cgroup_name, TASK_FILE_NAME, pid);
- if (r < 0) {
- _E("[WATCHDOG] failed to write pid '%d' to '%s': %m",
- pid, cgroup_name);
- return r;
- }*/
_D("[WATCHDOG] PID(%d) is registered as %s sub cgroup(%s)", pid, PROC_WATCHDOGCG_NAME, name);
#define CPU_BACKGROUND_PRI 1
#define CPU_CONTROL_PRI 10
-static GSource *cpu_predefined_timer;
+//static GSource *cpu_predefined_timer;
static bool bCPUQuota;
static inline int ioprio_set(int which, int who, int ioprio)
#define IOPRIO_CLASS_SHIFT 13
-enum cpu_control_type {
+/*enum cpu_control_type {
SET_NONE,
SET_DEFAULT,
SET_BOOTING,
return def_list.control[i].type;
}
return SET_NONE;
-}
+}*/
static int cpu_move_cgroup(pid_t pid, char *path)
{
bCPUQuota = true;
}
-static int get_relative_value(const char *cgroup_name,
+/*static int get_relative_value(const char *cgroup_name,
const char *file_name, int percent)
{
unsigned int val;
}
return val * percent / 100;
-}
+}*/
-static int load_cpu_config(struct parse_result *result, void *user_data)
+/*static int load_cpu_config(struct parse_result *result, void *user_data)
{
pid_t pid = 0, value;
if (!result)
}
return RESOURCED_ERROR_NONE;
-}
+}*/
static int cpu_service_state(void *data)
{
pri = getpriority(PRIO_PROCESS, ps->pid);
if (pri == -1 || pri > CPU_DEFAULT_PRI)
setpriority(PRIO_PGRP, ps->pid, CPU_DEFAULT_PRI);
- if (check_predefined(ps->pid) != SET_DEFAULT)
- cpu_move_cgroup_foreach(ps->pid, ps->pai, CPUCG_HIGH_GROUP_PATH);
+/* if (check_predefined(ps->pid) != SET_DEFAULT)
+ cpu_move_cgroup_foreach(ps->pid, ps->pai, CPUCG_HIGH_GROUP_PATH);*/
return RESOURCED_ERROR_NONE;
}
static int cpu_prelaunch_state(void *data)
{
- struct proc_status *ps = (struct proc_status *)data;
+/* struct proc_status *ps = (struct proc_status *)data;
int i = 0;
assert(ps && ps->pai);
return RESOURCED_ERROR_NONE;
}
}
- }
+ }*/
return RESOURCED_ERROR_NONE;
}
static int cpu_exclude_state(void *data)
{
struct proc_exclude *pe = (struct proc_exclude *)data;
- if (check_predefined(pe->pid) == SET_DEFAULT)
- return RESOURCED_ERROR_NONE;
+/* if (check_predefined(pe->pid) == SET_DEFAULT)
+ return RESOURCED_ERROR_NONE;*/
if (pe->type == PROC_INCLUDE)
cpu_move_cgroup(pe->pid, CPUCG_MEDIUM_GROUP_PATH);
else
return RESOURCED_ERROR_NONE;
}
-static gboolean cpu_predefined_cb(gpointer data)
+/*static gboolean cpu_predefined_cb(gpointer data)
{
int i = 0;
ioprio_set(IOPRIO_WHO_PROCESS, def_list.control[i].pid, IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT);
}
}
- cpu_predefined_timer = NULL;
+// cpu_predefined_timer = NULL;
return false;
-}
+}*/
static int resourced_cpu_init(void *data)
{
ret_code = cgroup_make_full_subdir(CPUCG_PATH);
ret_value_msg_if(ret_code < 0, ret_code, "cpu cgroup init failed\n");
cpu_check_cpuquota();
- config_parse(CPU_CONF_FILE, load_cpu_config, NULL);
+/* config_parse(CPU_CONF_FILE, load_cpu_config, NULL);
if (def_list.num) {
cpu_predefined_timer = g_timeout_source_new_seconds(CPU_TIMER_INTERVAL);
g_source_set_callback(cpu_predefined_timer, cpu_predefined_cb, NULL, NULL);
g_source_attach(cpu_predefined_timer, NULL);
- }
+ }*/
register_notifier(RESOURCED_NOTIFIER_SERVICE_LAUNCH, cpu_service_state);
register_notifier(RESOURCED_NOTIFIER_APP_RESUME, cpu_foreground_state);
register_notifier(RESOURCED_NOTIFIER_APP_FOREGRD, cpu_foreground_state);
#include <bundle.h>
#include <eventsystem.h>
#include <malloc.h>
+#include <libsyscommon/libsystemd.h>
#include "trace.h"
#include "cgroup.h"
MEMORY_LEVEL_CRITICAL,
};
-static GPtrArray *vip_apps;
-
static const char *convert_cgroup_type_to_str(int type)
{
static const char *type_table[] =
return mem_state;
}
-static int vip_load_config(struct parse_result *result, void *user_data)
-{
- char *app_name;
-
- if (!result || !vip_apps)
- return RESOURCED_ERROR_INVALID_PARAMETER;
-
- if (strncmp(result->section, MEM_VIP_SECTION, sizeof(MEM_VIP_SECTION)))
- return RESOURCED_ERROR_NONE;
-
- if (!strcmp(result->name, MEM_VIP_PREDEFINE)) {
- app_name = g_strdup(result->value);
-
- /* check whether this app is already registered or not */
- for (int vip_index = 0; vip_index < vip_apps->len; vip_index++) {
- char *vip_name = g_ptr_array_index(vip_apps, vip_index);
- if (!strncmp(vip_name, app_name, strlen(app_name) + 1))
- return RESOURCED_ERROR_NONE;
- }
-
- g_ptr_array_add(vip_apps, (gpointer)app_name);
- }
-
- return RESOURCED_ERROR_NONE;
-}
-
static int load_bg_reclaim_config(struct parse_result *result, void *user_data)
{
if (!result)
if (!pai) {
pai = find_app_info(pid);
+ /* service instead of app */
if (!pai) {
cgroup_write_pid_fullpath(mi->name, pid);
return;
return RESOURCED_ERROR_NONE;
}
-static int allocate_vip_app_list(void)
-{
- vip_apps = g_ptr_array_new();
- if (!vip_apps) {
- _E("g_ptr_array_new : out of memory");
- return RESOURCED_ERROR_OUT_OF_MEMORY;
- }
-
- return RESOURCED_ERROR_NONE;
-}
-
static int set_vip_list(void)
{
pid_t pid = -1;
- DIR *dp;
- struct dirent *dentry;
- char proc_name[PROC_NAME_MAX];
- int vip_index;
- char *vip_name;
-
- dp = opendir("/proc");
- if (!dp) {
- _E("fail to open /proc");
- return RESOURCED_ERROR_FAIL;
- }
-
- while ((dentry = readdir(dp))) {
- if (!isdigit(dentry->d_name[0]))
- continue;
-
- pid = atoi(dentry->d_name);
- if (!pid)
- continue;
-
- if (proc_get_cmdline(pid, proc_name, sizeof proc_name) != RESOURCED_ERROR_NONE)
- continue;
-
- for (vip_index = 0; vip_index < vip_apps->len; vip_index++) {
- vip_name = g_ptr_array_index(vip_apps, vip_index);
- if (strncmp(vip_name, proc_name, strlen(proc_name) + 1))
- continue;
-
- if (pid > 0) {
- proc_set_oom_score_adj(pid, OOMADJ_SERVICE_MIN, NULL);
- break;
- }
+ GSList *iter;
+ GVariant *variant;
+ struct proc_conf_info *pci = NULL;
+
+ gslist_for_each_item(iter, get_service_conf_info_list()) {
+ pci = (struct proc_conf_info *)iter->data;
+ variant = systemd_get_service_property(pci->name, "ExecMainPID");
+ if (!g_variant_get_safe(variant, "u", &pid))
+ _E("Failed to get pid of a service (%s)", pci->name);
+
+ if (pid > 0) {
+ proc_set_oom_score_adj(pid, OOMADJ_SERVICE_MIN, NULL);
}
}
- closedir(dp);
return RESOURCED_ERROR_NONE;
}
-static void free_vip_app_list(void)
-{
- if (vip_apps) {
- g_ptr_array_foreach(vip_apps, (GFunc)g_free, NULL);
- g_ptr_array_free(vip_apps, true);
- vip_apps = NULL;
- }
+static int lowmem_booting_done_handler(void *data) {
+ int ret = set_vip_list();
+
+ remove_app_conf_info_list();
+ remove_service_conf_info_list();
+
+ return ret;
}
static void load_configs(const char *path)
if (config_parse(path, load_mem_log_config, NULL))
_E("(%s-mem-log) parse Fail", path);
-
- if (config_parse(path, vip_load_config, NULL))
- _E("(%s-vip) parse Fail", path);
-}
-
-static void load_per_vendor_configs(void)
-{
- int count;
- int idx;
- struct dirent **namelist;
-
- if ((count = scandir(CGROUP_VIP_LIST_DIR, &namelist, NULL, alphasort)) == -1) {
- _W("failed to opendir (%s)", CGROUP_VIP_LIST_DIR);
- return;
- }
-
- for (idx = 0; idx < count; idx++) {
- char path[PATH_MAX] = {0, };
-
- if (!strstr(namelist[idx]->d_name, CONF_FILE_SUFFIX))
- continue;
-
- snprintf(path, sizeof(path), "%s/%s", CGROUP_VIP_LIST_DIR, namelist[idx]->d_name);
- load_configs(path);
- free(namelist[idx]);
- }
-
- free(namelist);
}
static void print_mem_configs(void)
_I("the batch threshold of memory log is %d", memlog_remove_batch_thres);
_I("prefix of memps is %s", memlog_prefix[MEMLOG_MEMPS]);
_I("prefix of memlimit memps is %s", memlog_prefix[MEMLOG_MEMPS_MEMLIMIT]);
-
- /* print info of VIP_PROCESS section */
- if (!vip_apps)
- return;
-
- _I("vip app list is");
- for (int vip_index = 0; vip_index < vip_apps->len; vip_index++) {
- char *vip_name = g_ptr_array_index(vip_apps, vip_index);
- _I("\t%s", vip_name);
- }
}
/* To Do: should we need lowmem_fd_start, lowmem_fd_stop ?? */
setup_memcg_params();
- /* allocate vip list memory */
- if (allocate_vip_app_list() != RESOURCED_ERROR_NONE)
- _E("allocate_vip_app_list FAIL");
-
/* default configuration */
load_configs(MEM_CONF_FILE);
- /* parse /etc/resourced/limiter.conf.d/xxx configurations*/
- load_per_vendor_configs();
-
- /* vip_list is only needed at the set_vip_list */
- if (set_vip_list() != RESOURCED_ERROR_NONE)
- _E("set_vip_list FAIL");
/* this function should be called after parsing configurations */
memcg_write_params();
print_mem_configs();
- free_vip_app_list();
/* make a worker thread called low memory killer */
ret = lowmem_activate_worker();
lowmem_limit_init();
lowmem_system_init();
+ register_notifier(RESOURCED_NOTIFIER_BOOTING_DONE, lowmem_booting_done_handler);
register_notifier(RESOURCED_NOTIFIER_APP_PRELAUNCH, lowmem_prelaunch_handler);
register_notifier(RESOURCED_NOTIFIER_MEM_CONTROL, lowmem_control_handler);
register_notifier(RESOURCED_NOTIFIER_LCD_OFF, lowmem_bg_reclaim_handler);
lowmem_limit_exit();
lowmem_system_exit();
+ unregister_notifier(RESOURCED_NOTIFIER_BOOTING_DONE, lowmem_booting_done_handler);
unregister_notifier(RESOURCED_NOTIFIER_APP_PRELAUNCH, lowmem_prelaunch_handler);
unregister_notifier(RESOURCED_NOTIFIER_MEM_CONTROL, lowmem_control_handler);
unregister_notifier(RESOURCED_NOTIFIER_LCD_OFF, lowmem_bg_reclaim_handler);