evas/cserve2: Reduce repacking and resizing of SHM
authorJean-Philippe Andre <jp.andre@samsung.com>
Thu, 10 Oct 2013 08:15:21 +0000 (17:15 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Oct 2013 06:47:16 +0000 (15:47 +0900)
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.

src/bin/evas/evas_cserve2.h
src/bin/evas/evas_cserve2_cache.c
src/bin/evas/evas_cserve2_fonts.c
src/bin/evas/evas_cserve2_index.c
src/bin/evas/evas_cserve2_shm.c

index a90dc07..219bb0d 100644 (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);
 
index dc2939b..15ce2c3 100644 (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));
      }
 }
 
index b9da989..51b87fe 100644 (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) \
@@ -406,24 +406,6 @@ end:
 }
 
 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)
 {
    const char *c;
@@ -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
index ce5b93a..0a3a629 100644 (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)
index 2045cdd..d95afc7 100644 (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");