diff --git a/src/bin/evas/evas_cserve2.h b/src/bin/evas/evas_cserve2.h index b6bdff3e63..361d08a768 100644 --- a/src/bin/evas/evas_cserve2.h +++ b/src/bin/evas/evas_cserve2.h @@ -322,7 +322,9 @@ void cserve2_shared_index_shutdown(void); typedef struct _Shared_Array Shared_Array; typedef struct _Shared_Mempool Shared_Mempool; -typedef Eina_Bool (* Shared_Array_Repack_Skip_Cb) (Shared_Array *, const void *); +typedef Eina_Bool (* Shared_Array_Repack_Skip_Cb) (Shared_Array *sa, + const void *elem, + void *user_data); // Shared arrays (arrays of fixed size object) Shared_Array *cserve2_shared_array_new(int tag, int elemsize, int initcount); @@ -337,7 +339,7 @@ int cserve2_shared_array_item_new(Shared_Array *sa); void *cserve2_shared_array_item_data_get(Shared_Array *sa, int elemid); Shared_Array *cserve2_shared_array_repack(Shared_Array *sa, Shared_Array_Repack_Skip_Cb skip, - Eina_Compare_Cb cmp); + Eina_Compare_Cb cmp, void *user_data); int cserve2_shared_array_item_find(Shared_Array *sa, void *data, Eina_Compare_Cb cmp); void *cserve2_shared_array_item_data_find(Shared_Array *sa, void *data, diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c index d3926e2a10..8624c08995 100644 --- a/src/bin/evas/evas_cserve2_cache.c +++ b/src/bin/evas/evas_cserve2_cache.c @@ -175,6 +175,8 @@ struct _File_Watch { }; static unsigned int _entry_id = 0; +static unsigned int _freed_entry_count = 0; + static Shared_Array *_file_data_array = NULL; static Eina_Hash *file_ids = NULL; // maps path + key --> file_id @@ -242,7 +244,7 @@ _entry_load_reused(Entry *e) static int -_shm_object_id_find_cb(const void *data1, const void *data2) +_shm_object_id_cmp_cb(const void *data1, const void *data2) { const Shm_Object *obj; unsigned int key; @@ -266,12 +268,14 @@ _file_data_find(unsigned int file_id) File_Data *fd; fd = cserve2_shared_array_item_data_find(_file_data_array, &file_id, - _shm_object_id_find_cb); + _shm_object_id_cmp_cb); if (fd && !fd->refcount) { ERR("Can not access object %u with refcount 0", file_id); return NULL; } + else if (!fd) + ERR("Could not find file %u", file_id); return fd; } @@ -287,6 +291,45 @@ _file_entry_find(unsigned int entry_id) return (File_Entry *) e; } +static Eina_Bool +_repack_skip_cb(Shared_Array *sa EINA_UNUSED, const void *elem, + void *user_data EINA_UNUSED) +{ + const File_Data *fd = elem; + return (!fd->refcount); +} + +static void +_repack() +{ + Shared_Array *sa; + int count; + + count = cserve2_shared_array_size_get(_file_data_array); + if (count <= 0) return; + + // Repack when we have 10% fragmentation over the whole shm buffer + if (_freed_entry_count > 100 || + ((_freed_entry_count * 100) / count >= 10)) + { + DBG("Repacking file data array: %s", + cserve2_shared_array_name_get(_file_data_array)); + + sa = cserve2_shared_array_repack(_file_data_array, + _repack_skip_cb, + _shm_object_id_cmp_cb, NULL); + if (!sa) + { + ERR("Failed to repack array. Keeping previous references!"); + return; + } + + cserve2_shared_array_del(_file_data_array); + _freed_entry_count = 0; + _file_data_array = sa; + } +} + static Msg_Opened * _image_opened_msg_create(File_Data *fd, int *size) @@ -845,8 +888,11 @@ _hash_file_entry_free(void *data) fd = _file_data_find(ASENTRY(fentry)->id); _file_id_free(fd); - _file_entry_free(fentry); _file_data_free(fd); + _file_entry_free(fentry); + + _freed_entry_count++; + _repack(); } static void @@ -1097,12 +1143,8 @@ _entry_reference_del(Entry *entry, Reference *ref) if (fd) { - if (fd->invalid) - { - _file_entry_free(fentry); - _file_data_free(fd); - } - else if (!fentry->images) + // FIXME: Check difference with master (2 cases vs. only one) + if (fd->invalid || !fentry->images) eina_hash_del_by_key(file_entries, &entry->id); } else @@ -1306,10 +1348,7 @@ _file_changed_cb(const char *path EINA_UNUSED, Eina_Bool deleted EINA_UNUSED, vo ASENTRY(fentry)->request = NULL; } if (!fentry->images && !ASENTRY(fentry)->references) - { - _file_entry_free(fentry); - _file_data_free(fd); - } + _hash_file_entry_free(fentry); } eina_hash_del_by_key(file_watch, fw->path); diff --git a/src/bin/evas/evas_cserve2_index.c b/src/bin/evas/evas_cserve2_index.c index b79c2f8e73..fd95aa510d 100644 --- a/src/bin/evas/evas_cserve2_index.c +++ b/src/bin/evas/evas_cserve2_index.c @@ -406,7 +406,8 @@ cserve2_shared_array_foreach(Shared_Array *sa, Eina_Each_Cb cb, void *data) Shared_Array * cserve2_shared_array_repack(Shared_Array *sa, Shared_Array_Repack_Skip_Cb skip, - Eina_Compare_Cb cmp) + Eina_Compare_Cb cmp, + void *user_data) { Eina_List *l = NULL; Shared_Array *sa2; @@ -422,7 +423,7 @@ cserve2_shared_array_repack(Shared_Array *sa, for (k = 0; k < sa->header->emptyidx; k++) { const char *data = srcdata + k * elemsize; - if (skip(sa, data)) continue; + if (skip(sa, data, user_data)) continue; l = eina_list_sorted_insert(l, cmp, data); newcount++; } @@ -443,6 +444,7 @@ cserve2_shared_array_repack(Shared_Array *sa, const char *data = eina_list_data_get(l); l = eina_list_remove_list(l, l); memcpy(dstdata, data, elemsize); + dstdata += elemsize; } // Finalize & return