evas/cserve2: Reduce repacking and resizing of SHM

These operations have tons of side effects and it's a lot
easier to just avoid doing them. Now, repacking will always
need to happen as applications will add/delete strings and
items, but the less frequent, the better :)

Also, align most arrays & mempools to 32K instead of the
default page size (4K). This will also reduce resizes.
This commit is contained in:
Jean-Philippe Andre 2013-10-10 17:15:21 +09:00
parent c8e6f9e5f9
commit cd702b3785
5 changed files with 26 additions and 35 deletions

View File

@ -307,7 +307,7 @@ size_t cserve2_shm_map_size_get(const Shm_Handle *shm);
size_t cserve2_shm_size_get(const Shm_Handle *shm);
void *cserve2_shm_map(Shm_Handle *shm);
void cserve2_shm_unmap(Shm_Handle *shm);
size_t cserve2_shm_size_normalize(size_t size);
size_t cserve2_shm_size_normalize(size_t size, size_t align);
void cserve2_command_run(Client *client, Message_Type type);

View File

@ -171,6 +171,7 @@ static int max_font_usage = 10 * 4 * 1024; /* in kbytes */
static int font_mem_usage = 0;
#define MAX_PREEMPTIVE_LOAD_SIZE (320*320*4)
#define ARRAY_REPACK_TRIGGER_PERCENT 25 // repack when array conains 25% holes
#ifdef DEBUG_LOAD_TIME
static int
@ -354,7 +355,7 @@ _repack()
count = cserve2_shared_array_size_get(_file_data_array);
if ((count > 0) && (_freed_file_entry_count > 100 ||
((_freed_file_entry_count * 100) / count >= 10)))
((_freed_file_entry_count * 100) / count >= ARRAY_REPACK_TRIGGER_PERCENT)))
{
DBG("Repacking file data array: %s",
cserve2_shared_array_name_get(_file_data_array));
@ -379,7 +380,7 @@ skip_files:
count = cserve2_shared_array_size_get(_image_data_array);
if ((count > 0) && (_freed_image_entry_count > 100 ||
((_freed_image_entry_count * 100) / count >= 10)))
((_freed_image_entry_count * 100) / count >= ARRAY_REPACK_TRIGGER_PERCENT)))
{
DBG("Repacking image data array: %s",
cserve2_shared_array_name_get(_image_data_array));
@ -405,7 +406,7 @@ skip_images:
count = cserve2_shared_array_size_get(_font_data_array);
if ((count > 0) && (_freed_font_entry_count > 100 ||
((_freed_font_entry_count * 100) / count >= 10)))
((_freed_font_entry_count * 100) / count >= ARRAY_REPACK_TRIGGER_PERCENT)))
{
DBG("Repacking font data array: %s",
cserve2_shared_array_name_get(_font_data_array));
@ -1145,7 +1146,6 @@ _file_data_free(File_Data *fd)
cserve2_shared_string_del(fd->key);
cserve2_shared_string_del(fd->path);
cserve2_shared_string_del(fd->loader_data);
memset((char *) fd + sizeof(fd->id), 0, sizeof(*fd) - sizeof(fd->id));
}
}

View File

@ -26,7 +26,7 @@
#define _EVAS_FONT_SLANT_TAN 0.221694663
#define CHECK_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
#define MIN_GLYPHS 50
#define MIN_GLYPHS 100 // 26*2 + a nice margin :)
#define MAX_CACHE_SIZE 1 * 1024 * 1024 // 1MB
#define EVAS_FONT_ROUND_26_6_TO_INT(x) \
@ -405,24 +405,6 @@ end:
if (depth) *depth = 0;
}
static unsigned int
_font_slave_int_shm_prev_calculate(unsigned int size, unsigned int nglyphs)
{
unsigned int average;
unsigned int newsize;
if (!nglyphs) return cserve2_shm_size_normalize(1);
average = size / nglyphs;
newsize = MIN_GLYPHS * average;
newsize = cserve2_shm_size_normalize(newsize);
if (newsize > MAX_CACHE_SIZE)
return MAX_CACHE_SIZE;
return newsize;
}
static unsigned int
_font_slave_int_shm_calculate(Font_Info *fi, unsigned int hint)
{
@ -441,7 +423,7 @@ _font_slave_int_shm_calculate(Font_Info *fi, unsigned int hint)
average = size / i; // average glyph size
size = MIN_GLYPHS * average;
size = cserve2_shm_size_normalize(size);
size = cserve2_shm_size_normalize(size, 0);
if (size > MAX_CACHE_SIZE)
return MAX_CACHE_SIZE; // Assumes no glyph will be bigger than this

View File

@ -64,6 +64,9 @@ struct _Block
// fragmentation (after del). 16 is convenient for debugging with hd :)
#define DATA_BLOCKSIZE 8
// Recommended minimum size for arrays and mempools
#define ARRAY_MINSIZE (32 * 1024)
static inline int
_data_blocksize_roundup(int len)
{
@ -160,7 +163,7 @@ _shared_data_shm_new(const char *infix, int size)
ds = calloc(1, sizeof(Data_Shm));
if (!ds) return NULL;
mapping_size = cserve2_shm_size_normalize((size_t) size);
mapping_size = cserve2_shm_size_normalize((size_t) size, 0);
ds->shm = cserve2_shm_request(infix, mapping_size);
if (!ds->shm)
@ -200,7 +203,7 @@ _shared_data_shm_resize(Data_Shm *ds, size_t newsize)
if (newsize <= 0)
return -1;
mapping_size = cserve2_shm_size_normalize(newsize);
mapping_size = cserve2_shm_size_normalize(newsize, ARRAY_MINSIZE);
cserve2_shm_unmap(ds->shm);
ds->data = NULL;
@ -242,7 +245,8 @@ cserve2_shared_array_new(int tag, int generation_id, int elemsize, int initcount
if (!initcount) initcount = 1;
mapping_size = cserve2_shm_size_normalize(elemsize * initcount
+ sizeof(Shared_Array_Header));
+ sizeof(Shared_Array_Header),
ARRAY_MINSIZE);
ds = _shared_data_shm_new("array", mapping_size);
if (!ds)
{
@ -330,7 +334,8 @@ cserve2_shared_array_size_set(Shared_Array *sa, int newcount)
if (!sa) return -1;
mapping_size = cserve2_shm_size_normalize(sa->header->elemsize * newcount
+ sizeof(Shared_Array_Header));
+ sizeof(Shared_Array_Header),
ARRAY_MINSIZE);
if (_shared_data_shm_resize(sa->ds, mapping_size) < 0)
{
sa->header = NULL;
@ -638,7 +643,7 @@ cserve2_shared_mempool_new(int indextag, int generation_id, int initsize)
if (!sm) return NULL;
if (!initsize) initsize = 1;
mapping_size = cserve2_shm_size_normalize((size_t) initsize);
mapping_size = cserve2_shm_size_normalize((size_t) initsize, ARRAY_MINSIZE);
sm->ds = _shared_data_shm_new("mempool", mapping_size);
if (!sm->ds)

View File

@ -35,7 +35,7 @@ struct _Shm_Handle
static int id = 0;
size_t
cserve2_shm_size_normalize(size_t size)
cserve2_shm_size_normalize(size_t size, size_t align)
{
long pagesize;
size_t normalized;
@ -47,7 +47,11 @@ cserve2_shm_size_normalize(size_t size)
pagesize = 4096;
}
normalized = ((size + pagesize - 1) / pagesize) * pagesize;
if (align)
align = ((align + pagesize - 1) / pagesize) * pagesize;
else
align = pagesize;
normalized = ((size + align - 1) / align) * align;
return normalized;
}
@ -89,7 +93,7 @@ cserve2_shm_request(const char *infix, size_t size)
}
} while (fd == -1);
map_size = cserve2_shm_size_normalize(size);
map_size = cserve2_shm_size_normalize(size, 0);
if (ftruncate(fd, map_size) == -1)
{
@ -135,7 +139,7 @@ cserve2_shm_segment_request(Shm_Handle *shm, size_t size)
return NULL;
}
map_size = cserve2_shm_size_normalize(size);
map_size = cserve2_shm_size_normalize(size, 0);
map_size += map->length;
if (ftruncate(fd, map_size) == -1)
@ -186,7 +190,7 @@ cserve2_shm_resize(Shm_Handle *shm, size_t newsize)
return NULL;
}
map_size = cserve2_shm_size_normalize(newsize);
map_size = cserve2_shm_size_normalize(newsize, 0);
if (ftruncate(fd, map_size))
{
ERR("Could not set the size of the shm: %m");