4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
12 * This library is free software; you can redistribute it and/or modify it under
13 * the terms of the GNU Lesser General Public License as published by the
14 * Free Software Foundation; either version 2.1 of the License, or (at your option)
17 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
20 * License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this library; if not, write to the Free Software Foundation, Inc., 51
24 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <assert.h> // for assert
32 #include <stdlib.h> // for malloc, free
33 #include <string.h> // for strlen, strcpy
34 #include <pthread.h> // for pthread_mutex_t
38 #include "dacollection.h"
40 // hash table variable
41 __hashInfo _hashinfo =
43 NULL, // khash_t(symbol)* symHash
44 PTHREAD_MUTEX_INITIALIZER, // pthread_mutex_t symHashMutex
45 NULL, // khash_t(allocmap)* memHash
46 PTHREAD_MUTEX_INITIALIZER, // pthread_mutex_t memHashMutex
47 NULL, // khash_t(uiobject)* uiobjHash
48 PTHREAD_MUTEX_INITIALIZER, // pthread_mutex_t uiobjHashMutex
49 NULL, // khash_t(object)* objHash
50 PTHREAD_MUTEX_INITIALIZER, // pthread_mutex_t objHashMutex
51 NULL, // khash_t(detector)* dttHash
52 PTHREAD_MUTEX_INITIALIZER // pthread_mutex_t dttHashMutex
55 // glist typedef and variable
61 struct _element* next;
62 struct _element* prev;
65 typedef struct _element element_t;
67 element_t* gsymbol_list = NULL;
68 pthread_mutex_t glist_mutex = PTHREAD_MUTEX_INITIALIZER;
70 // *********************************************************************************************
71 // hash table related implemenation
72 // *********************************************************************************************
74 int initialize_hash_table()
77 SYMBOLHASH = kh_init(symbol);
81 MEMORYHASH = kh_init(allocmap);
85 UIOBJECTHASH = kh_init(uiobject);
89 OBJECTHASH = kh_init(object);
93 DETECTORHASH = kh_init(detector);
99 int finalize_hash_table()
107 for(k = kh_begin(SYMBOLHASH); k != kh_end(SYMBOLHASH); k++)
109 if (kh_exist(SYMBOLHASH, k))
111 val = kh_value(SYMBOLHASH, k);
115 kh_destroy(symbol, SYMBOLHASH);
123 kh_destroy(allocmap, MEMORYHASH);
134 for(k = kh_begin(UIOBJECTHASH); k != kh_end(UIOBJECTHASH); k++)
136 if (kh_exist(UIOBJECTHASH, k))
138 val = kh_value(UIOBJECTHASH, k);
139 if (likely(val->type != 0)) free(val->type);
140 if (likely(val->name != 0)) free(val->name);
144 kh_destroy(uiobject, UIOBJECTHASH);
152 kh_destroy(object, OBJECTHASH);
160 kh_destroy(detector, DETECTORHASH);
168 /***********************************************************
169 * symbol hash related functions
170 ***********************************************************/
171 // return 0 if there is no entry in hash
172 // return 1 if there is entry in hash
173 // return negative value if error occurred
174 int find_symbol_hash(void* ptr, char** psymbol)
179 if (unlikely(SYMBOLHASH == 0))
180 return ERR_NOTINITIALIZED;
182 if (unlikely(ptr == NULL))
183 return ERR_WRONGPARAMETER;
185 if (unlikely(psymbol == NULL))
186 return ERR_WRONGPARAMETER;
191 k = kh_get(symbol, SYMBOLHASH, (uint32_t)ptr);
192 if (k == kh_end(SYMBOLHASH)) // there is no entry for key
198 *psymbol = kh_value(SYMBOLHASH, k);
206 // return 0 if succeed
207 // return 1 if there is already exist in hash
208 // return negative value if other error occurred
209 int add_symbol_hash(void* ptr, const char* str, int strlen)
212 int rethash, ret = 0;
214 if (unlikely(SYMBOLHASH == 0))
215 return ERR_NOTINITIALIZED;
217 if (unlikely(ptr == NULL))
218 return ERR_WRONGPARAMETER;
220 if (unlikely(str == NULL))
221 return ERR_WRONGPARAMETER;
226 k = kh_put(symbol, SYMBOLHASH, (uint32_t)ptr, &rethash);
227 if (likely(rethash != 0)) // succeed to add in hash table
229 char* tlast = (char*)real_malloc(strlen);
230 if (likely(tlast != NULL))
232 memcpy(tlast, str, strlen);
233 kh_value(SYMBOLHASH, k) = tlast;
237 kh_del(symbol, SYMBOLHASH, k);
238 ret = ERR_OUTOFMEMORY;
243 // TODO : error handling
251 /***********************************************************
252 * memory hash related functions
253 ***********************************************************/
254 // return 0 if succeed
255 // return 1 if key is already exist in hash table
256 // return negative value if other error occurred
257 int add_memory_hash(void* ptr, size_t size, unsigned short type, unsigned short caller)
260 int rethash, ret = 0;
264 if (unlikely(MEMORYHASH == 0))
265 return ERR_NOTINITIALIZED;
267 if (unlikely(ptr == NULL))
268 return ERR_WRONGPARAMETER;
272 k = kh_put(allocmap, MEMORYHASH, (uint32_t)ptr, &rethash);
273 if (likely(rethash != 0)) // succeed to add in hash table
275 kh_value(MEMORYHASH, k) = MAKE_MEMINFO(caller, type, size);
276 update_heap_memory_size(true, size);
280 // key is already exist in hash
281 // update memory info
282 meminfo = kh_value(MEMORYHASH, k);
283 memsize = GET_MEMSIZE(meminfo);
286 kh_value(MEMORYHASH, k) = MAKE_MEMINFO(caller, type, size);
295 // return 0 if succeed
296 // return 1 if key is not in hash table
297 // return negative if other error occurred
298 int del_memory_hash(void* ptr, unsigned short type, unsigned short* caller)
305 if (unlikely(MEMORYHASH == 0))
306 return ERR_NOTINITIALIZED;
308 if (unlikely(ptr == NULL))
309 return ERR_WRONGPARAMETER;
313 k = kh_get(allocmap, MEMORYHASH, (uint32_t)ptr);
314 if (likely(k != kh_end(MEMORYHASH)))
315 { // there is entry in hash table
316 meminfo = kh_value(MEMORYHASH, k);
317 if (unlikely(type != GET_MEMTYPE(meminfo)))
323 size = GET_MEMSIZE(meminfo);
325 *caller = GET_MEMCALLER(meminfo);
326 update_heap_memory_size(false, size);
327 kh_del(allocmap, MEMORYHASH, k);
332 ret = 1; // there is not entry in hash table
340 /***********************************************************
341 * uiobject hash related functions
342 ***********************************************************/
343 // return 0 if there is no entry in hash
344 // return 1 if there is entry in hash
345 // return negative value if error occurred
346 int find_uiobject_hash(void* ptr, char** type, char** classname)
351 if (unlikely(UIOBJECTHASH == 0))
352 return ERR_NOTINITIALIZED;
354 if (unlikely(ptr == NULL))
355 return ERR_WRONGPARAMETER;
357 if (unlikely(type == NULL))
358 return ERR_WRONGPARAMETER;
360 if (unlikely(classname == NULL))
361 return ERR_WRONGPARAMETER;
366 k = kh_get(uiobject, UIOBJECTHASH, (uint32_t)ptr);
367 if (unlikely(k == kh_end(UIOBJECTHASH))) // there is no entry for key
373 *classname = kh_value(UIOBJECTHASH, k)->name;
374 *type = kh_value(UIOBJECTHASH, k)->type;
382 // return 0 if succeed
383 // return 1 if there is no entry in hash
384 // return negative value if other error occurred
385 int add_uiobject_hash_class(void* ptr, const char* classname)
389 int rethash, ret = 0;
391 if (unlikely(UIOBJECTHASH == 0))
392 return ERR_NOTINITIALIZED;
394 if (unlikely(ptr == NULL))
395 return ERR_WRONGPARAMETER;
397 if (unlikely(classname == NULL))
398 return ERR_WRONGPARAMETER;
402 str_len = strlen(classname) + 1;
405 k = kh_put(uiobject, UIOBJECTHASH, (uint32_t)ptr, &rethash);
406 if (likely(rethash == 0)) // entry is already in hash table
408 if (likely(kh_value(UIOBJECTHASH, k) != NULL))
410 if (kh_value(UIOBJECTHASH, k)->name == NULL)
412 char* tlast = (char*)real_malloc(str_len);
413 if (likely(tlast != NULL))
415 memcpy(tlast, classname, str_len);
416 kh_value(UIOBJECTHASH, k)->name = tlast;
420 kh_value(UIOBJECTHASH, k)->name = NULL;
421 ret = ERR_OUTOFMEMORY; // out of memory
425 ret = ERR_ALREADYEXIST;
428 ret = ERR_NOTEXIST; // there is entry but there is no value
431 ret = 1; // there is no entry
438 // return 0 if succeed
439 // return 1 if there is already exist in hash
440 // return negative value if other error occurred
441 int add_uiobject_hash_type(void* ptr, const char* type)
445 int rethash, ret = 0;
447 if (unlikely(UIOBJECTHASH == 0))
448 return ERR_NOTINITIALIZED;
450 if (unlikely(ptr == NULL))
451 return ERR_WRONGPARAMETER;
453 if (unlikely(type == NULL))
454 return ERR_WRONGPARAMETER;
458 str_len = strlen(type) + 1;
461 k = kh_put(uiobject, UIOBJECTHASH, (uint32_t)ptr, &rethash);
462 if (likely(rethash != 0)) // succeed to add in hash table
465 _uiobjectinfo* newentry;
467 newentry = (_uiobjectinfo*)calloc(1, sizeof(_uiobjectinfo));
468 if (likely(newentry != NULL))
470 kh_value(UIOBJECTHASH, k) = newentry;
472 tlast = (char*)real_malloc(str_len);
473 if (likely(tlast != NULL))
475 memcpy(tlast, type, str_len);
476 kh_value(UIOBJECTHASH, k)->type = tlast;
480 kh_value(UIOBJECTHASH, k)->type = NULL;
481 ret = ERR_OUTOFMEMORY;
486 kh_del(uiobject, UIOBJECTHASH, k);
487 ret = ERR_OUTOFMEMORY;
498 // return 0 if succeed
499 // return 1 if key is not in hash table
500 // return negative value if other error occurred
501 int del_uiobject_hash(void* ptr)
507 if (unlikely(UIOBJECTHASH == 0))
508 return ERR_NOTINITIALIZED;
510 if (unlikely(ptr == NULL))
511 return ERR_WRONGPARAMETER;
515 k = kh_get(uiobject, UIOBJECTHASH, (uint32_t)ptr);
516 if (likely(k != kh_end(UIOBJECTHASH))) // there is entry in hash table
518 val = kh_value(UIOBJECTHASH, k);
519 kh_del(uiobject, UIOBJECTHASH, k);
520 if (likely(val->type != NULL)) free(val->type);
521 if (likely(val->name != NULL)) free(val->name);
534 /***********************************************************
535 * object hash related functions
536 ***********************************************************/
537 // return 0 if there is no entry in hash
538 // return 1 if there is entry in hash
539 // return negative value if error occurred
540 int find_object_hash(void* ptr, unsigned short *caller)
545 if (unlikely(OBJECTHASH == 0))
546 return ERR_NOTINITIALIZED;
548 if (unlikely(ptr == NULL))
549 return ERR_WRONGPARAMETER;
551 if (unlikely(caller == NULL))
552 return ERR_WRONGPARAMETER;
557 k = kh_get(object, OBJECTHASH, (uint32_t)ptr);
558 if (unlikely(k == kh_end(OBJECTHASH))) // there is no entry for key
564 *caller = kh_value(OBJECTHASH, k);
572 // return 0 if succeed
573 // return 1 if there is no entry in hash
574 // return negative value if other error occurred
575 int add_object_hash(void* ptr, unsigned short caller)
578 int rethash, ret = 0;
580 if (unlikely(OBJECTHASH == 0))
581 return ERR_NOTINITIALIZED;
583 if (unlikely(ptr == NULL))
584 return ERR_WRONGPARAMETER;
589 k = kh_put(object, OBJECTHASH, (uint32_t)ptr, &rethash);
590 if (likely(rethash != 0)) // entry is already in hash table
592 kh_value(OBJECTHASH, k) = caller;
596 // TODO : error handling
605 // return 0 if succeed
606 // return 1 if key is not in hash table
607 // return negative value if other error occurred
608 int del_object_hash(void* ptr, unsigned short *caller)
613 if (unlikely(OBJECTHASH == 0))
614 return ERR_NOTINITIALIZED;
616 if (unlikely(ptr == NULL))
617 return ERR_WRONGPARAMETER;
619 if (unlikely(caller == NULL))
620 return ERR_WRONGPARAMETER;
625 k = kh_get(object, OBJECTHASH, (uint32_t)ptr);
626 if (likely(k != kh_end(OBJECTHASH))) // there is entry in hash table
628 *caller = kh_value(OBJECTHASH, k);
629 kh_del(object, OBJECTHASH, k);
641 /***********************************************************
642 * detector hash related functions
643 ***********************************************************/
644 // return 0 if succeed
645 // return 1 if there is already exist in hash
646 // return negative value if other error occurred
647 int add_detector_hash(void* ptr, void* listener)
650 int rethash, ret = 0;
652 if (unlikely(DETECTORHASH == 0))
653 return ERR_NOTINITIALIZED;
655 if (unlikely(ptr == NULL))
656 return ERR_WRONGPARAMETER;
658 if (unlikely(listener == NULL))
659 return ERR_WRONGPARAMETER;
664 k = kh_put(detector, DETECTORHASH, (uint32_t)ptr, &rethash);
665 if (likely(rethash != 0)) // succeed to add in hash table
667 kh_value(DETECTORHASH, k) = listener;
671 // TODO : error handling
679 // return 0 if succeed
680 // return 1 if key is not in hash table
681 // return negative value if other error occurred
682 int del_detector_hash(void* ptr)
687 if (unlikely(DETECTORHASH == 0))
688 return ERR_NOTINITIALIZED;
690 if (unlikely(ptr == NULL))
691 return ERR_WRONGPARAMETER;
695 k = kh_get(detector, DETECTORHASH, (uint32_t)ptr);
696 if (likely(k != kh_end(DETECTORHASH))) // there is entry in hash table
698 kh_del(detector, DETECTORHASH, k);
711 // *********************************************************************************************
712 // glist implemenation
713 // *********************************************************************************************
715 // all function to call this function have to use mutex_lock
716 static element_t* find_element(char* key)
721 if (unlikely(key == NULL))
724 keylen = strlen(key);
726 // pthread_mutex_lock(&glist_mutex); // this is commented because of static function
730 if (keylen == res->keylen && (strcmp(key, res->keystr) == 0))
734 // pthread_mutex_unlock(&glist_mutex); // this is commented because of static function
739 int add_to_glist(char* key, void* data)
744 if (unlikely(key == NULL || data == NULL))
747 pthread_mutex_lock(&glist_mutex);
748 elm = find_element(key);
751 elm = (element_t*)real_malloc(sizeof(element_t));
752 if (likely(elm != NULL))
754 elm->keylen = strlen(key);
755 elm->keystr = (char*)real_malloc(elm->keylen + 1);
756 if (likely(elm->keystr != NULL))
758 memcpy(elm->keystr, key, elm->keylen + 1);
760 elm->next = gsymbol_list;
763 gsymbol_list->prev = elm;
773 pthread_mutex_unlock(&glist_mutex);
778 int remove_from_glist(char* key)
783 pthread_mutex_lock(&glist_mutex);
784 elm = find_element(key);
788 elm->prev->next = elm->next;
790 elm->next->prev = elm->prev;
791 if (gsymbol_list == elm)
792 gsymbol_list = gsymbol_list->next;
794 pthread_mutex_unlock(&glist_mutex);
807 int remove_all_glist()
811 pthread_mutex_lock(&glist_mutex);
812 while(gsymbol_list != NULL)
815 gsymbol_list = elm->next;
820 pthread_mutex_unlock(&glist_mutex);
825 void* find_glist(char* key)
829 pthread_mutex_lock(&glist_mutex);
830 elm = find_element(key);
831 pthread_mutex_unlock(&glist_mutex);