2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <sys/types.h>
28 #include "ss_device_plugin.h"
32 #include "include/ss_data.h"
34 #define DELETE_SM "sh -c "PREFIX"/bin/delete.sm"
36 #define MEMNOTIFY_NORMAL 0x0000
37 #define MEMNOTIFY_LOW 0xfaac
38 #define MEMNOTIFY_CRITICAL 0xdead
39 #define MEMNOTIFY_REBOOT 0xb00f
41 #define _SYS_RES_CLEANUP "RES_CLEANUP"
43 #define MEM_THRESHOLD_LV1 60
44 #define MEM_THRESHOLD_LV2 40
47 struct lowmem_process_entry {
48 unsigned cur_mem_state;
49 unsigned new_mem_state;
50 int (*action) (void *);
53 static int lowmem_fd = -1;
54 static int cur_mem_state = MEMNOTIFY_NORMAL;
56 Ecore_Timer *oom_timer;
57 #define OOM_TIMER_INTERVAL 5
59 static int memory_low_act(void *ad);
60 static int memory_oom_act(void *ad);
61 static int memory_normal_act(void *ad);
63 static struct lowmem_process_entry lpe[] = {
64 {MEMNOTIFY_NORMAL, MEMNOTIFY_LOW, memory_low_act},
65 {MEMNOTIFY_NORMAL, MEMNOTIFY_CRITICAL, memory_oom_act},
66 {MEMNOTIFY_LOW, MEMNOTIFY_CRITICAL, memory_oom_act},
67 {MEMNOTIFY_CRITICAL, MEMNOTIFY_CRITICAL, memory_oom_act},
68 {MEMNOTIFY_LOW, MEMNOTIFY_NORMAL, memory_normal_act},
69 {MEMNOTIFY_CRITICAL, MEMNOTIFY_NORMAL, memory_normal_act},
73 unsigned int oom_delete_sm_time = 0;
75 static int remove_shm()
78 struct shmid_ds shmseg;
79 struct shm_info shm_info;
81 maxid = shmctl(0, SHM_INFO, (struct shmid_ds *)(void *)&shm_info);
83 PRT_TRACE_ERR("shared mem error\n");
87 for (id = 0; id <= maxid; id++) {
88 shmid = shmctl(id, SHM_STAT, &shmseg);
91 if (shmseg.shm_nattch == 0) {
92 PRT_TRACE("shared memory killer ==> %d killed\n",
94 shmctl(shmid, IPC_RMID, NULL);
100 static char *convert_to_str(unsigned int mem_state)
104 case MEMNOTIFY_NORMAL:
110 case MEMNOTIFY_CRITICAL:
111 tmp = "mem critical";
113 case MEMNOTIFY_REBOOT:
122 static void print_lowmem_state(unsigned int mem_state)
124 PRT_TRACE("[LOW MEM STATE] %s ==> %s", convert_to_str(cur_mem_state),
125 convert_to_str(mem_state));
128 static int memory_low_act(void *data)
130 char lowmem_noti_name[NAME_MAX];
132 PRT_TRACE("[LOW MEM STATE] memory low state");
135 heynoti_get_snoti_name(_SYS_RES_CLEANUP, lowmem_noti_name, NAME_MAX);
136 ss_noti_send(lowmem_noti_name);
137 vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY,
138 VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING);
140 ss_action_entry_call_internal(PREDEF_LOWMEM, 1, LOW_MEM_ACT);
145 static int memory_oom_act(void *data)
147 unsigned int cur_time;
148 char lowmem_noti_name[NAME_MAX];
150 PRT_TRACE("[LOW MEM STATE] memory oom state");
151 cur_time = time(NULL);
152 PRT_TRACE("cur=%d, old=%d, cur-old=%d", cur_time, oom_delete_sm_time,
153 cur_time - oom_delete_sm_time);
154 if (cur_time - oom_delete_sm_time > 15) {
156 oom_delete_sm_time = cur_time;
157 /* Also clean up unreturned memory of applications */
158 heynoti_get_snoti_name(_SYS_RES_CLEANUP, lowmem_noti_name,
160 ss_noti_send(lowmem_noti_name);
162 vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY,
163 VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING);
165 ss_action_entry_call_internal(PREDEF_LOWMEM, 1, OOM_MEM_ACT);
170 static int memory_normal_act(void *data)
172 PRT_TRACE("[LOW MEM STATE] memory normal state");
173 vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY,
174 VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL);
178 static int lowmem_process(unsigned int mem_state, void *ad)
181 for (i = 0; i < sizeof(lpe) / sizeof(struct lowmem_process_entry); i++) {
182 if ((cur_mem_state == lpe[i].cur_mem_state)
183 && (mem_state == lpe[i].new_mem_state)) {
185 if(oom_timer != NULL) {
186 ecore_timer_del(oom_timer);
190 if(mem_state == MEMNOTIFY_CRITICAL)
191 oom_timer = ecore_timer_add(OOM_TIMER_INTERVAL,lpe[i].action, ad);
198 static unsigned int lowmem_read(int fd)
200 unsigned int mem_state;
201 read(fd, &mem_state, sizeof(mem_state));
205 static int lowmem_cb(void *data, Ecore_Fd_Handler * fd_handler)
208 struct ss_main_data *ad = (struct ss_main_data *)data;
209 unsigned int mem_state;
211 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
213 ("ecore_main_fd_handler_active_get error , return\n");
217 fd = ecore_main_fd_handler_fd_get(fd_handler);
219 mem_state = lowmem_read(fd);
220 print_lowmem_state(mem_state);
221 lowmem_process(mem_state, ad);
222 cur_mem_state = mem_state;
227 static int set_threshold()
229 if (0 > plugin_intf->OEM_sys_set_memnotify_threshold_lv1(MEM_THRESHOLD_LV1)) {
230 PRT_TRACE_ERR("Set memnorify threshold lv1 failed");
234 if (0 > plugin_intf->OEM_sys_set_memnotify_threshold_lv2(MEM_THRESHOLD_LV2)) {
235 PRT_TRACE_ERR("Set memnorify threshold lv2 failed");
242 int ss_lowmem_init(struct ss_main_data *ad)
244 char lowmem_dev_node[PATH_MAX];
246 if (0 > plugin_intf->OEM_sys_get_memnotify_node(lowmem_dev_node)) {
247 PRT_TRACE_ERR("Low memory handler fd init failed");
251 lowmem_fd = open(lowmem_dev_node, O_RDONLY);
253 PRT_TRACE_ERR("ss_lowmem_init fd open failed");
258 ecore_main_fd_handler_add(lowmem_fd, ECORE_FD_READ, lowmem_cb, ad, NULL,
260 if (set_threshold() < 0) {
261 PRT_TRACE_ERR("Setting lowmem threshold is failed");