forked from enlightenment/efl
evas/cserve2: Repack File_Data shared array
This commit is contained in:
parent
acae35b4d1
commit
d0e647fee3
|
@ -322,7 +322,9 @@ void cserve2_shared_index_shutdown(void);
|
||||||
|
|
||||||
typedef struct _Shared_Array Shared_Array;
|
typedef struct _Shared_Array Shared_Array;
|
||||||
typedef struct _Shared_Mempool Shared_Mempool;
|
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 arrays (arrays of fixed size object)
|
||||||
Shared_Array *cserve2_shared_array_new(int tag, int elemsize, int initcount);
|
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);
|
void *cserve2_shared_array_item_data_get(Shared_Array *sa, int elemid);
|
||||||
Shared_Array *cserve2_shared_array_repack(Shared_Array *sa,
|
Shared_Array *cserve2_shared_array_repack(Shared_Array *sa,
|
||||||
Shared_Array_Repack_Skip_Cb skip,
|
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,
|
int cserve2_shared_array_item_find(Shared_Array *sa, void *data,
|
||||||
Eina_Compare_Cb cmp);
|
Eina_Compare_Cb cmp);
|
||||||
void *cserve2_shared_array_item_data_find(Shared_Array *sa, void *data,
|
void *cserve2_shared_array_item_data_find(Shared_Array *sa, void *data,
|
||||||
|
|
|
@ -175,6 +175,8 @@ struct _File_Watch {
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int _entry_id = 0;
|
static unsigned int _entry_id = 0;
|
||||||
|
static unsigned int _freed_entry_count = 0;
|
||||||
|
|
||||||
static Shared_Array *_file_data_array = NULL;
|
static Shared_Array *_file_data_array = NULL;
|
||||||
|
|
||||||
static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
|
static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
|
||||||
|
@ -242,7 +244,7 @@ _entry_load_reused(Entry *e)
|
||||||
|
|
||||||
|
|
||||||
static int
|
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;
|
const Shm_Object *obj;
|
||||||
unsigned int key;
|
unsigned int key;
|
||||||
|
@ -266,12 +268,14 @@ _file_data_find(unsigned int file_id)
|
||||||
File_Data *fd;
|
File_Data *fd;
|
||||||
|
|
||||||
fd = cserve2_shared_array_item_data_find(_file_data_array, &file_id,
|
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)
|
if (fd && !fd->refcount)
|
||||||
{
|
{
|
||||||
ERR("Can not access object %u with refcount 0", file_id);
|
ERR("Can not access object %u with refcount 0", file_id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
else if (!fd)
|
||||||
|
ERR("Could not find file %u", file_id);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +291,45 @@ _file_entry_find(unsigned int entry_id)
|
||||||
return (File_Entry *) e;
|
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 *
|
static Msg_Opened *
|
||||||
_image_opened_msg_create(File_Data *fd, int *size)
|
_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);
|
fd = _file_data_find(ASENTRY(fentry)->id);
|
||||||
_file_id_free(fd);
|
_file_id_free(fd);
|
||||||
_file_entry_free(fentry);
|
|
||||||
_file_data_free(fd);
|
_file_data_free(fd);
|
||||||
|
_file_entry_free(fentry);
|
||||||
|
|
||||||
|
_freed_entry_count++;
|
||||||
|
_repack();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1097,12 +1143,8 @@ _entry_reference_del(Entry *entry, Reference *ref)
|
||||||
|
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
if (fd->invalid)
|
// FIXME: Check difference with master (2 cases vs. only one)
|
||||||
{
|
if (fd->invalid || !fentry->images)
|
||||||
_file_entry_free(fentry);
|
|
||||||
_file_data_free(fd);
|
|
||||||
}
|
|
||||||
else if (!fentry->images)
|
|
||||||
eina_hash_del_by_key(file_entries, &entry->id);
|
eina_hash_del_by_key(file_entries, &entry->id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1306,10 +1348,7 @@ _file_changed_cb(const char *path EINA_UNUSED, Eina_Bool deleted EINA_UNUSED, vo
|
||||||
ASENTRY(fentry)->request = NULL;
|
ASENTRY(fentry)->request = NULL;
|
||||||
}
|
}
|
||||||
if (!fentry->images && !ASENTRY(fentry)->references)
|
if (!fentry->images && !ASENTRY(fentry)->references)
|
||||||
{
|
_hash_file_entry_free(fentry);
|
||||||
_file_entry_free(fentry);
|
|
||||||
_file_data_free(fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eina_hash_del_by_key(file_watch, fw->path);
|
eina_hash_del_by_key(file_watch, fw->path);
|
||||||
|
|
|
@ -406,7 +406,8 @@ cserve2_shared_array_foreach(Shared_Array *sa, Eina_Each_Cb cb, void *data)
|
||||||
Shared_Array *
|
Shared_Array *
|
||||||
cserve2_shared_array_repack(Shared_Array *sa,
|
cserve2_shared_array_repack(Shared_Array *sa,
|
||||||
Shared_Array_Repack_Skip_Cb skip,
|
Shared_Array_Repack_Skip_Cb skip,
|
||||||
Eina_Compare_Cb cmp)
|
Eina_Compare_Cb cmp,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
Eina_List *l = NULL;
|
Eina_List *l = NULL;
|
||||||
Shared_Array *sa2;
|
Shared_Array *sa2;
|
||||||
|
@ -422,7 +423,7 @@ cserve2_shared_array_repack(Shared_Array *sa,
|
||||||
for (k = 0; k < sa->header->emptyidx; k++)
|
for (k = 0; k < sa->header->emptyidx; k++)
|
||||||
{
|
{
|
||||||
const char *data = srcdata + k * elemsize;
|
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);
|
l = eina_list_sorted_insert(l, cmp, data);
|
||||||
newcount++;
|
newcount++;
|
||||||
}
|
}
|
||||||
|
@ -443,6 +444,7 @@ cserve2_shared_array_repack(Shared_Array *sa,
|
||||||
const char *data = eina_list_data_get(l);
|
const char *data = eina_list_data_get(l);
|
||||||
l = eina_list_remove_list(l, l);
|
l = eina_list_remove_list(l, l);
|
||||||
memcpy(dstdata, data, elemsize);
|
memcpy(dstdata, data, elemsize);
|
||||||
|
dstdata += elemsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize & return
|
// Finalize & return
|
||||||
|
|
Loading…
Reference in New Issue