4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * @file lock-detector.c
32 #include <sys/types.h>
36 #include "core/list.h"
48 #define LIMIT_COUNT 128
50 static dd_list *lock_info_list;
52 static long get_time(void)
55 gettimeofday(&now, NULL);
56 return (long)(now.tv_sec * 1000 + now.tv_usec / 1000);
59 static void shrink_lock_info_list(void)
62 struct lock_info *info;
65 count = DD_LIST_LENGTH(lock_info_list);
66 if (count <= LIMIT_COUNT)
68 _D("list is shrink : count %d", count);
70 DD_LIST_REVERSE_FOREACH_SAFE(lock_info_list, l, l_prev, info) {
71 if (info->locktime == 0) {
72 DD_LIST_REMOVE_LIST(lock_info_list, l);
78 if (count <= (LIMIT_COUNT / 2))
83 int set_lock_time(const char *pname, int state)
85 struct lock_info *info;
92 if (state < S_NORMAL || state > S_SLEEP)
95 val = g_str_hash(pname);
97 DD_LIST_FOREACH(lock_info_list, l, info)
98 if (info->hash == val &&
99 !strncmp(info->name, pname, strlen(pname)+1) &&
100 info->state == state) {
102 if (info->locktime == 0)
103 info->locktime = get_time();
104 info->unlocktime = 0;
105 DD_LIST_REMOVE(lock_info_list, info);
106 DD_LIST_PREPEND(lock_info_list, info);
110 info = malloc(sizeof(struct lock_info));
112 _E("Malloc is failed for lock_info!");
117 info->name = strndup(pname, strlen(pname));
120 info->locktime = get_time();
121 info->unlocktime = 0;
124 DD_LIST_APPEND(lock_info_list, info);
129 int set_unlock_time(const char *pname, int state)
133 struct lock_info *info;
140 if (state < S_NORMAL || state > S_SLEEP)
143 val = g_str_hash(pname);
145 DD_LIST_FOREACH(lock_info_list, l, info)
146 if (info->hash == val &&
147 !strncmp(info->name, pname, strlen(pname)+1) &&
148 info->state == state) {
149 DD_LIST_REMOVE(lock_info_list, info);
150 DD_LIST_PREPEND(lock_info_list, info);
158 if (info->locktime == 0)
162 info->unlocktime = get_time();
163 diff = info->unlocktime - info->locktime;
168 if (DD_LIST_LENGTH(lock_info_list) > LIMIT_COUNT)
169 shrink_lock_info_list();
174 void free_lock_info_list(void)
177 struct lock_info *info;
182 DD_LIST_FOREACH_SAFE(lock_info_list, l, l_next, info) {
183 DD_LIST_REMOVE(lock_info_list, info);
188 lock_info_list = NULL;
191 void print_lock_info_list(int fd)
193 struct lock_info *info;
201 snprintf(buf, sizeof(buf),
202 "current time : %ld ms\n", get_time());
203 ret = write(fd, buf, strlen(buf));
205 _E("write() failed (%d)", errno);
207 snprintf(buf, sizeof(buf),
208 "[%10s %6s] %6s %10s %10s %10s %s\n", "hash", "state",
209 "count", "locktime", "unlocktime", "time", "process name");
210 ret = write(fd, buf, strlen(buf));
212 _E("write() failed (%d)", errno);
214 DD_LIST_FOREACH(lock_info_list, l, info) {
216 if (info->locktime != 0 && info->unlocktime == 0)
217 time = get_time() - info->locktime;
218 snprintf(buf, sizeof(buf),
219 "[%10lu %6d] %6d %10ld %10ld %10ld %s\n",
227 ret = write(fd, buf, strlen(buf));
229 _E("write() failed (%d)", errno);