evas/cserve2: Fix cserve2_usage tool
authorJean-Philippe Andre <jp.andre@samsung.com>
Tue, 20 Aug 2013 09:26:02 +0000 (18:26 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Oct 2013 06:47:14 +0000 (15:47 +0900)
Also, print shared arrays usage as it is sent as first message
upon connection to the server.

Add fonts to LRU and flush LRU as needed.
Seems to work okay. Could probably be finetuned a bit.

src/bin/evas/evas_cserve2.h
src/bin/evas/evas_cserve2_cache.c
src/bin/evas/evas_cserve2_debug.c
src/bin/evas/evas_cserve2_index.c
src/bin/evas/evas_cserve2_usage.c
src/lib/evas/cserve2/evas_cs2.h

index 88f4370..badd33c 100644 (file)
@@ -352,6 +352,7 @@ const char *cserve2_shared_array_name_get(Shared_Array *sa);
 void cserve2_shared_array_del(Shared_Array *sa);
 int cserve2_shared_array_size_get(Shared_Array *sa);
 int cserve2_shared_array_count_get(Shared_Array *sa);
+int cserve2_shared_array_map_size_get(Shared_Array *sa);
 int cserve2_shared_array_item_size_get(Shared_Array *sa);
 int cserve2_shared_array_generation_id_get(Shared_Array *sa);
 int cserve2_shared_array_size_set(Shared_Array *sa, int newcount);
index 7c7932e..86fb804 100644 (file)
@@ -1080,12 +1080,34 @@ _font_entry_key_hash(const Font_Entry *key, int key_length EINA_UNUSED)
    return hash;
 }
 
+static int
+_font_entry_memory_usage_get(Font_Entry *fe)
+{
+   int size;
+
+   if (!fe) return 0;
+   if (!fe->mempool && !fe->glyph_datas)
+     return 0;
+
+   size = cserve2_shared_mempool_size_get(fe->mempool);
+   size += cserve2_shared_array_map_size_get(fe->glyph_datas);
+   size += fe->nglyphs * sizeof(Glyph_Entry);
+
+   return size;
+}
+
 static void
 _font_entry_free(Font_Entry *fe)
 {
    Font_Data *fd;
+   int size;
 
    if (!fe) return;
+   size = _font_entry_memory_usage_get(fe);
+
+   DBG("Font memory usage down: %d -> %d / %d", font_mem_usage,
+       font_mem_usage - size, max_font_usage);
+   font_mem_usage -= size;
 
    fd = _font_data_find(fe->font_data_id);
    if (fd)
@@ -1098,6 +1120,7 @@ _font_entry_free(Font_Entry *fe)
 
    fash_gl_free(fe->glyph_entries);
    cserve2_shared_array_del(fe->glyph_datas);
+   cserve2_shared_mempool_del(fe->mempool);
    cserve2_font_ft_free(fe->ft);
    fe->src->refcount--;
    if (fe->src->refcount <= 0)
@@ -1141,79 +1164,49 @@ _font_source_free(Font_Source *fs)
    free(fs);
 }
 
-#if 0
 static void
-_font_shm_promote(Font_Cache *fc)
+_font_lru_update(Font_Entry *fe)
 {
    Eina_List *l;
-   l = eina_list_data_find_list(font_shm_lru, fc);
-   font_shm_lru = eina_list_demote_list(font_shm_lru, l);
-}
-
-static int
-_font_shm_size_get(Font_Cache *fc)
-{
-   int size;
-
-   size = sizeof(*fc) + cserve2_shm_size_get(fc->shm);
-
-   return size;
-}
-
-static void
-_font_shm_free(Font_Cache *fc)
-{
-   Glyph_Data *gd;
-   Font_Entry *fe = fc->fe;
-   unsigned int k;
-
-   fe->caches = eina_list_remove(fe->caches, fc);
-   if (fc == fe->last_cache)
-     fe->last_cache = NULL;
-
-   for (k = 0; k < fc->nglyphs; k++)
+   l = eina_list_data_find_list(font_shm_lru, fe);
+   if (l)
      {
-        int *gldata_id = cserve2_shared_array_item_data_get(fc->glyphs, k);
-        gd = _glyph_data_find(*gldata_id);
-        fash_gl_del(fe->glyphs, gd->index);
+        if (fe->unused)
+          font_shm_lru = eina_list_promote_list(font_shm_lru, l);
+        else
+          font_shm_lru = eina_list_demote_list(font_shm_lru, l);
      }
-
-   cserve2_shared_array_del(fc->glyphs);
-   cserve2_shm_unref(fc->shm);
-   free(fc);
-
-   if (!fe->caches)
-     eina_hash_del_by_key(font_entries, fe);
+   else
+     font_shm_lru = eina_list_append(font_shm_lru, fe);
 }
 
 static void
-_font_shm_lru_flush(void)
+_font_lru_flush(void)
 {
    Eina_List *l, *l_next;
 
    l = font_shm_lru;
    l_next = eina_list_next(l);
 
+   DBG("Font memory usage [begin]: %d / %d", font_mem_usage, max_font_usage);
+
    while (l && font_mem_usage > max_font_usage)
      {
-        int size;
-        Font_Cache *fc;
+        Font_Entry *fe;
 
-        fc = eina_list_data_get(l);
-        if (fc->fe->unused && fc->inuse == 0)
+        fe = eina_list_data_get(l);
+        if (fe->unused)
           {
              font_shm_lru = eina_list_remove_list(font_shm_lru, l);
-             size = _font_shm_size_get(fc);
-             size += fc->nglyphs * sizeof(Glyph_Entry);
-             _font_shm_free(fc);
-             font_mem_usage -= size;
+             eina_hash_del_by_key(font_entries, fe);
           }
 
         l = l_next;
         l_next = eina_list_next(l);
      }
+
+   DBG("Font memory usage [end]: %d / %d", font_mem_usage, max_font_usage);
 }
-#endif
 
 void
 cserve2_cache_init(void)
@@ -1352,10 +1345,10 @@ _entry_reference_del(Entry *entry, Reference *ref)
      }
    else if (entry->type == CSERVE2_FONT_ENTRY)
      {
-        Font_Entry *fe = (Font_Entry *)entry;
+        Font_Entry *fe = (Font_Entry *) entry;
         fe->unused = EINA_TRUE;
-        if (!fe->mempool)
-          eina_hash_del_by_key(font_entries, fe);
+        _font_lru_update(fe);
+        _font_lru_flush();
      }
    else
      ERR("Wrong type of entry.");
@@ -1719,150 +1712,6 @@ _glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load)
    return (req->nanswer == req->nglyphs);
 }
 
-#if 0
-/* organize answer (cache1{gl1, gl2,}, cache2{gl3,gl4,gl5}, cache3{gl6})
- */
-static Eina_List *
-_glyphs_group_create(Glyphs_Request *req)
-{
-   Eina_List *groups = NULL;
-   unsigned int i;
-   Glyphs_Group *gg;
-
-   gg = calloc(1, sizeof(*gg));
-   groups = eina_list_append(groups, gg);
-
-   for (i = 0; i < req->nanswer; i++)
-     gg->glyphs = eina_list_append(gg->glyphs, req->answer[i]);
-
-   return groups;
-
-   /*
-   for (i = 0; i < req->nanswer; i++)
-     {
-        Eina_List *l;
-        Glyphs_Group *iter, *gg = NULL;
-        Font_Cache *fc = req->answer[i]->fc;
-
-        EINA_LIST_FOREACH(groups, l, iter)
-          {
-             if (iter->fc == fc)
-               {
-                  gg = iter;
-                  break;
-               }
-          }
-
-        if (!gg)
-          {
-             gg = calloc(1, sizeof(*gg));
-             gg->fc = fc;
-             groups = eina_list_append(groups, gg);
-          }
-        gg->glyphs = eina_list_append(gg->glyphs, req->answer[i]);
-     }
-
-   return groups;
-   */
-}
-
-static Msg_Font_Glyphs_Loaded *
-_glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
-{
-   Msg_Font_Glyphs_Loaded msg;
-   unsigned int size;
-   Eina_List *ll, *answers = NULL;
-   const char *shmname;
-   unsigned int shmsize;
-   char *resp, *buf;
-   Glyphs_Group *iter;
-
-   memset(&msg, 0, sizeof(msg));
-   msg.base.type = CSERVE2_FONT_GLYPHS_LOADED;
-
-   answers = _glyphs_group_create(req);
-   msg.ncaches = eina_list_count(answers);
-   size = sizeof(msg);
-
-   // calculate size of message
-   // ncaches * sizeof(cache) + nglyphs1 * sizeof(glyph) +
-   //   nglyphs2 * sizeof(glyph)...
-
-   EINA_LIST_FOREACH(answers, ll, iter)
-     {
-        shmname = cserve2_shm_name_get(iter->fc->shm);
-        shmsize = eina_stringshare_strlen(shmname) + 1;
-        // shm namelen + name
-        size += sizeof(int) + shmsize;
-
-        // nglyphs
-        size += sizeof(int);
-        // nglyphs * (index + offset + size + rows + width + pitch +
-        //            num_grays + pixel_mode)
-        size += eina_list_count(iter->glyphs) * 9 * sizeof(int);
-     }
-
-   resp = malloc(size);
-   memcpy(resp, &msg, sizeof(msg));
-   buf = resp + sizeof(msg);
-
-   EINA_LIST_FREE(answers, iter)
-     {
-        Glyph_Entry *gl;
-        unsigned int nglyphs;
-
-        shmname = cserve2_shm_name_get(iter->fc->shm);
-        shmsize = eina_stringshare_strlen(shmname) + 1;
-        memcpy(buf, &shmsize, sizeof(int));
-        buf += sizeof(int);
-        memcpy(buf, shmname, shmsize);
-        buf += shmsize;
-
-        nglyphs = eina_list_count(iter->glyphs);
-        memcpy(buf, &nglyphs, sizeof(int));
-        buf += sizeof(int);
-
-        iter->fc->inuse -= eina_list_count(iter->glyphs);
-
-        EINA_LIST_FREE(iter->glyphs, gl)
-          {
-             // TODO: Factorize memcpy
-             Glyph_Data *gldata;
-
-             gldata = _glyph_data_find(gl->gldata_id);
-             memcpy(buf, &gldata->index, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->shm_id, sizeof(string_t));
-             buf += sizeof(string_t);
-             memcpy(buf, &gldata->offset, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->size, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->rows, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->width, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->pitch, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->num_grays, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->pixel_mode, sizeof(int));
-             buf += sizeof(int);
-          }
-
-        /* We are removing SHMs from the beginning of the list, so this
-         * gives a higher priority to them */
-        _font_shm_promote(iter->fc);
-        eina_list_free(iter->glyphs);
-        free(iter);
-     }
-
-   *resp_size = size;
-
-   return (Msg_Font_Glyphs_Loaded *)resp;
-}
-#endif
-
 static Msg_Font_Glyphs_Loaded *
 _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
 {
@@ -2105,11 +1954,19 @@ _glyphs_load_request_response(Glyphs_Request *req,
    if (!msg->nglyphs)
      return _glyphs_loaded_msg_create(req, size);
 
+   DBG("Font memory usage [begin]: %d / %d", font_mem_usage, max_font_usage);
+
    if (!mempool)
-     mempool = cserve2_shared_mempool_new(0);
+     {
+        mempool = cserve2_shared_mempool_new(0);
+        font_mem_usage += cserve2_shared_mempool_size_get(mempool);
+     }
 
    if (!fe->glyph_datas)
-     fe->glyph_datas = cserve2_shared_array_new(1, sizeof(Glyph_Data), 0);
+     {
+        fe->glyph_datas = cserve2_shared_array_new(1, sizeof(Glyph_Data), 0);
+        font_mem_usage += cserve2_shared_array_map_size_get(fe->glyph_datas);
+     }
 
    shm_id = cserve2_shared_string_add(cserve2_shared_mempool_name_get(mempool));
    for (j = 0; j < msg->nglyphs; j++)
@@ -2119,9 +1976,11 @@ _glyphs_load_request_response(Glyphs_Request *req,
         gl = fash_gl_find(fe->glyph_entries, msg->glyphs[j].index);
         if (!gl)
           {
-             int glyph_id;
+             int glyph_id, orig_mapsize, new_mapsize;
              Glyph_Data *gldata;
 
+             orig_mapsize = cserve2_shared_array_map_size_get(fe->glyph_datas);
+
              glyph_id = cserve2_shared_array_item_new(fe->glyph_datas);
              gldata = cserve2_shared_array_item_data_get(fe->glyph_datas,
                                                          glyph_id);
@@ -2152,7 +2011,9 @@ _glyphs_load_request_response(Glyphs_Request *req,
              fe->nglyphs++;
              fash_gl_add(fe->glyph_entries, gldata->index, gl);
 
-             font_mem_usage += sizeof(*gl) + sizeof(*gldata);
+             new_mapsize = cserve2_shared_array_map_size_get(fe->glyph_datas);
+             font_mem_usage += new_mapsize - orig_mapsize;
+             font_mem_usage += sizeof(*gl);
           }
         req->answer[req->nanswer++] = gl;
      }
@@ -2169,6 +2030,9 @@ _glyphs_load_request_response(Glyphs_Request *req,
 
    fe->mempool = mempool;
 
+   DBG("Font memory usage [end]: %d / %d", font_mem_usage, max_font_usage);
+   _font_lru_flush();
+
    return _glyphs_loaded_msg_create(req, size);
 }
 
@@ -2185,42 +2049,39 @@ static Slave_Request_Funcs _glyphs_load_funcs = {
 };
 
 static Eina_Bool
-_font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
+_font_requested_size_cb(const Eina_Hash *hash EINA_UNUSED,
+                        Glyph_Data *gldata, Msg_Stats *msg)
 {
-   // FIXME TODO Must reimplement this
+   if (gldata->refcount)
+     msg->fonts.requested_size += gldata->size;
 
-#if 0
+   return EINA_TRUE;
+}
+
+
+static Eina_Bool
+_font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED,
+                     const void *key EINA_UNUSED, void *data, void *fdata)
+{
    Font_Entry *fe = data;
    Msg_Stats *msg = fdata;
-   Eina_List *iter;
-   Font_Cache *fc;
-   int nrefs = eina_list_count(fe->base.references);
+   unsigned int shmsize;
 
    msg->fonts.fonts_loaded++;
    if (fe->unused) msg->fonts.fonts_unused++;
 
    // accounting size
-   EINA_LIST_FOREACH(fe->caches, iter, fc)
-     {
-        unsigned int fc_usage, shmsize;
-        /* This is not real requested usage, but an approximation. We don't
-         * know how many times each glyph would be used by each client, but
-         * assume that a similar set of glyphs from a given font would be used
-         * by each client, thus counting them one time per client referencing
-         * them.
-         */
-        fc_usage = fc->usage * nrefs;
-        shmsize = cserve2_shm_size_get(fc->shm);
+   shmsize = cserve2_shared_mempool_size_get(fe->mempool);
+   msg->fonts.real_size += shmsize;
+   if (fe->unused) msg->fonts.unused_size += shmsize;
 
-        msg->fonts.requested_size += fc_usage;
-        msg->fonts.real_size += shmsize;
-        if (fe->unused) msg->fonts.unused_size += shmsize;
-     }
+   cserve2_shared_array_foreach(fe->glyph_datas,
+                                EINA_EACH_CB(_font_requested_size_cb), msg);
 
 #ifdef DEBUG_LOAD_TIME
    // accounting fonts load time
    msg->fonts.fonts_load_time += fe->base.load_time;
-   if (fe->caches)
+   if (fe->mempool)
      {
         msg->fonts.fonts_used_load_time += fe->base.load_time;
         msg->fonts.fonts_used_saved_time += fe->base.saved_time;
@@ -2234,8 +2095,6 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
    msg->fonts.glyphs_slave_time += fe->gl_slave_time;
 #endif
 
-#endif
-
    return EINA_TRUE;
 }
 
@@ -2319,52 +2178,53 @@ struct _debug_info
 };
 
 static Eina_Bool
-_font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
+_font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED,
+                          const void *key EINA_UNUSED, void *data, void *fdata)
 {
    struct _debug_info *di = fdata;
-   unsigned int size = di->size;
    Font_Entry *fe = data;
    const char *str;
 
    // filelen
-   size += sizeof(int);
+   di->size+= sizeof(int);
 
    // file
    if (fe->src->file)
      {
         str = cserve2_shared_string_get(fe->src->file);
-        size += strlen(str) + 1;
+        di->size+= strlen(str) + 1;
      }
 
    // namelen
-   size += sizeof(int);
+   di->size+= sizeof(int);
 
    // name
    if (fe->src->name)
      {
         str = cserve2_shared_string_get(fe->src->file);
-        size += strlen(str) + 1;
+        di->size+= strlen(str) + 1;
      }
 
-   // rend_flags, size, dpi
-   size += 3 * sizeof(int);
+   // rend_flags, size, dpi, unused
+   di->size+= 4 * sizeof(int);
 
-   // unused
-   size += sizeof(int);
+   // glyph_data_shm and glyph_mempool_shm (short strings)
+   di->size+= 2 * 64;
 
-   // ncaches
-   size += sizeof(int);
+   // nglyphs
+   di->size+= sizeof(int);
 
-   size += cserve2_shared_mempool_size_get(fe->mempool);
+   // glyphs
+   di->size+= fe->nglyphs * sizeof(Glyph_Data);
 
-   di->size = size;
    di->nfonts++;
 
    return EINA_TRUE;
 }
 
 static Eina_Bool
-_font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
+_font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED,
+                     const void *key EINA_UNUSED, void *data, void *fdata)
 {
    char **pos = fdata;
    char *buf = *pos;
@@ -2451,124 +2311,6 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
    return EINA_TRUE;
 }
 
-   // FIXME TODO Must reimplement this
-#if 0
-
-   char **pos = fdata;
-   char *buf = *pos;
-   Font_Entry *fe = data;
-   Font_Cache *fc;
-   Eina_List *iter;
-   unsigned int len;
-   unsigned int unused;
-   unsigned int ncaches;
-   const char *str;
-
-   // filelen + file
-   len = 0;
-   if (fe->src->file)
-     {
-        str = cserve2_shared_string_get(fe->src->file);
-        len = strlen(str) + 1;
-     }
-   memcpy(buf, &len, sizeof(int));
-   buf += sizeof(int);
-   if (len) memcpy(buf, cserve2_shared_string_get(fe->src->file), len);
-   buf += len;
-
-   // namelen + name
-   len = 0;
-   if (fe->src->name)
-     {
-        str = cserve2_shared_string_get(fe->src->name);
-        len = strlen(str) + 1;
-     }
-   memcpy(buf, &len, sizeof(int));
-   buf += sizeof(int);
-   if (len) memcpy(buf, cserve2_shared_string_get(fe->src->name), len);
-   buf += len;
-
-   // rend_flags, size, dpi
-   memcpy(buf, &fe->rend_flags, sizeof(int));
-   buf += sizeof(int);
-   memcpy(buf, &fe->size, sizeof(int));
-   buf += sizeof(int);
-   memcpy(buf, &fe->dpi, sizeof(int));
-   buf += sizeof(int);
-
-   // unused
-   unused = fe->unused;
-   memcpy(buf, &unused, sizeof(int));
-   buf += sizeof(int);
-
-   // ncaches
-   ncaches = eina_list_count(fe->caches);
-   memcpy(buf, &ncaches, sizeof(int));
-   buf += sizeof(int);
-
-   EINA_LIST_FOREACH(fe->caches, iter, fc)
-     {
-        Glyph_Data *gldata;
-        const char *shmname;
-        unsigned int shmsize;
-        unsigned int k;
-
-        // shmnamelen + shmname
-        shmname = cserve2_shm_name_get(fc->shm);
-        len = strlen(shmname) + 1;
-        memcpy(buf, &len, sizeof(int));
-        buf += sizeof(int);
-        memcpy(buf, shmname, len);
-        buf += len;
-
-        // TODO: Simplify memcpy operations (can be factorized into 1)
-
-        // size, usage, nglyphs
-        shmsize = cserve2_shm_size_get(fc->shm);
-        memcpy(buf, &shmsize, sizeof(int));
-        buf += sizeof(int);
-        memcpy(buf, &fc->usage, sizeof(int));
-        buf += sizeof(int);
-        memcpy(buf, &fc->nglyphs, sizeof(int));
-        buf += sizeof(int);
-
-        for (k = 0; k < fc->nglyphs; k++)
-          {
-             int *gldata_id = cserve2_shared_array_item_data_get(
-                      fc->glyphs, fc->nglyphs);
-             gldata = _glyph_data_find(*gldata_id);
-
-             // index, shm_id, offset, size
-             memcpy(buf, &gldata->index, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->shm_id, sizeof(string_t));
-             buf += sizeof(string_t);
-             memcpy(buf, &gldata->offset, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->size, sizeof(int));
-             buf += sizeof(int);
-
-             // rows, width, pitch
-             memcpy(buf, &gldata->rows, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->width, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->pitch, sizeof(int));
-             buf += sizeof(int);
-
-             // num_grays, pixel_mode
-             memcpy(buf, &gldata->num_grays, sizeof(int));
-             buf += sizeof(int);
-             memcpy(buf, &gldata->pixel_mode, sizeof(int));
-             buf += sizeof(int);
-          }
-     }
-
-   *pos = buf;
-   return EINA_TRUE;
-#endif
-}
-
 static void *
 _cserve2_cache_font_debug(unsigned int rid, unsigned int *size)
 {
@@ -2582,27 +2324,24 @@ _cserve2_cache_font_debug(unsigned int rid, unsigned int *size)
 
    msg.base.type = CSERVE2_FONT_DEBUG;
    msg.base.rid = rid;
+   eina_strlcpy(msg.fonts_index_path,
+                cserve2_shared_array_name_get(_font_data_array),
+                sizeof(msg.fonts_index_path));
 
-   // First calculate how much size is needed for this message:
-
-   // nfonts
-   di.size += sizeof(unsigned int);
-
-   // size needed for each font entry
+   // First calculate how much size is needed for this message
    eina_hash_foreach(font_entries, _font_entry_debug_size_cb, &di);
 
    // Now really create the message
    buf = malloc(di.size);
    pos = buf;
 
+   // nfonts
+   msg.nfonts = di.nfonts;
+
    // msg base
    memcpy(buf, &msg, sizeof(msg));
    pos += sizeof(msg);
 
-   // nfonts
-   memcpy(pos, &di.nfonts, sizeof(unsigned int));
-   pos += sizeof(unsigned int);
-
    eina_hash_foreach(font_entries, _font_entry_debug_cb, &pos);
 
    *size = di.size;
@@ -3072,6 +2811,7 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name,
 
         _entry_load_reused(&fe->base);
         fe->unused = EINA_FALSE;
+        _font_lru_update(fe);
 
         if (fe->base.request)
           cserve2_request_waiter_add(fe->base.request, rid, client);
@@ -3090,6 +2830,7 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name,
    ref = _entry_reference_add((Entry *)fe, client, 0);
    client->fonts.referencing = eina_list_append(client->fonts.referencing, ref);
    fe->unused = EINA_FALSE;
+   _font_lru_update(fe);
 
    fs = _cserve2_font_source_find(fullname);
    if (!fs)
@@ -3204,12 +2945,6 @@ cserve2_cache_font_glyphs_used(Client *client, const char *source,
                                unsigned int nglyphs,
                                unsigned int rid EINA_UNUSED)
 {
-   // FIXME TODO: Must reimplement this
-   return 0;
-
-#if 0
-   Glyphs_Group *gg;
-   Eina_List *groups;
    Glyphs_Request *req;
 
    DBG("Received report of used glyphs from client %d", client->id);
@@ -3221,22 +2956,12 @@ cserve2_cache_font_glyphs_used(Client *client, const char *source,
         return 0;
      }
 
-   _glyphs_request_check(req, EINA_FALSE);
-   groups = _glyphs_group_create(req);
-
-   // Promote SHMs which are still cached and in use
-   // TODO: We can use later the information from request_prepare to preload
-   // glyphs which are not cached anymore, but are in use on the client.
-   EINA_LIST_FREE(groups, gg)
-     {
-        //_font_shm_promote(gg->fc);
-        eina_list_free(gg->glyphs);
-        free(gg);
-     }
+   // TODO: We could finetune based on which glyphs exactly are used.
+   req->fe->unused = EINA_FALSE;
+   _font_lru_update(req->fe);
 
    _glyphs_request_free(req);
    return 0;
-#endif
 }
 
 void
index e68e113..10b9d5c 100644 (file)
@@ -177,8 +177,6 @@ _debug_msg_send(void)
 }
 
 typedef struct _Font_Entry Font_Entry;
-typedef struct _Cache_Entry Cache_Entry;
-typedef struct _Glyph_Entry Glyph_Entry;
 
 struct _Font_Entry
 {
@@ -188,27 +186,9 @@ struct _Font_Entry
    unsigned int size;
    unsigned int dpi;
    unsigned int unused;
-   Eina_List *caches;
-};
-
-struct _Cache_Entry
-{
-   const char *shmname;
-   unsigned int size;
-   unsigned int usage;
-   Eina_List *glyphs;
-};
-
-struct _Glyph_Entry
-{
-   unsigned int index;
-   unsigned int offset;
-   unsigned int size;
-   unsigned int rows;
-   unsigned int width;
-   unsigned int pitch;
-   unsigned int num_grays;
-   unsigned int pixel_mode;
+   char glyph_data_shm[64];
+   char glyph_mempool_shm[64];
+   Eina_List *glyphs; // Glyph_Data
 };
 
 #define READIT(_dst, _src) \
@@ -217,6 +197,7 @@ struct _Glyph_Entry
       _src += sizeof(_dst); \
    } while(0)
 
+#if 0
 static Glyph_Entry *
 _parse_glyph_entry(char **msg)
 {
@@ -267,6 +248,7 @@ _parse_cache_entry(char **msg)
 
    return ce;
 }
+#endif
 
 static Font_Entry *
 _parse_font_entry(char **msg)
@@ -291,12 +273,18 @@ _parse_font_entry(char **msg)
    READIT(fe->dpi, buf);
    READIT(fe->unused, buf);
 
+   eina_strlcpy(fe->glyph_data_shm, buf, 64);
+   buf += 64;
+   eina_strlcpy(fe->glyph_mempool_shm, buf, 64);
+   buf += 64;
+
    READIT(n, buf);
    while (n--)
      {
-        Cache_Entry *ce;
-        ce = _parse_cache_entry(&buf);
-        fe->caches = eina_list_append(fe->caches, ce);
+        Glyph_Data *gd = calloc(1, sizeof(Glyph_Data));
+        memcpy(gd, buf, sizeof(Glyph_Data));
+        buf += sizeof(Glyph_Data);
+        fe->glyphs = eina_list_append(fe->glyphs, gd);
      }
 
    *msg = buf;
@@ -307,7 +295,7 @@ _parse_font_entry(char **msg)
 static Eina_List *
 _debug_msg_read(void)
 {
-   Msg_Base *msg = NULL;
+   Msg_Font_Debug *msg = NULL;
    char *buf;
    int size;
    unsigned int nfonts;
@@ -317,16 +305,16 @@ _debug_msg_read(void)
    while (!msg)
      msg = _server_read(&size);
 
-   if (msg->type != CSERVE2_FONT_DEBUG)
+   if (msg->base.type != CSERVE2_FONT_DEBUG)
      {
-        ERR("Invalid message received from server."
+        ERR("Invalid message received from server. "
             "Something went badly wrong.");
         return NULL;
      }
 
    buf = (char *)msg + sizeof(*msg);
 
-   READIT(nfonts, buf);
+   nfonts = msg->nfonts;
    while (nfonts--)
      {
         Font_Entry *fe;
@@ -334,34 +322,18 @@ _debug_msg_read(void)
         fonts = eina_list_append(fonts, fe);
      }
 
+   printf("Font index table: %s\n", msg->fonts_index_path);
+   printf("Contains %u fonts\n\n", msg->nfonts);
    return fonts;
 }
 
 static void
-_glyph_entry_free(Glyph_Entry *ge)
-{
-   free(ge);
-}
-
-static void
-_cache_entry_free(Cache_Entry *ce)
-{
-   Glyph_Entry *ge;
-
-   EINA_LIST_FREE(ce->glyphs, ge)
-     _glyph_entry_free(ge);
-
-   eina_stringshare_del(ce->shmname);
-   free(ce);
-}
-
-static void
 _font_entry_free(Font_Entry *fe)
 {
-   Cache_Entry *ce;
+   Glyph_Data *gd;
 
-   EINA_LIST_FREE(fe->caches, ce)
-     _cache_entry_free(ce);
+   EINA_LIST_FREE(fe->glyphs, gd)
+     free(gd);
 
    eina_stringshare_del(fe->name);
    eina_stringshare_del(fe->file);
@@ -369,7 +341,7 @@ _font_entry_free(Font_Entry *fe)
 }
 
 static void
-_glyph_entry_print(Glyph_Entry *ge)
+_glyph_data_print(Glyph_Data *gd)
 {
    const char *pxmode[] = {
         "FT_PIXEL_MODE_NONE",
@@ -380,29 +352,18 @@ _glyph_entry_print(Glyph_Entry *ge)
         "FT_PIXEL_MODE_LCD",
         "FT_PIXEL_MODE_LCD_V"
    };
-   printf("\t\tGLYPH %u offset: %u size: %u %ux%u pitch: %u grays: %u "
-          "pixel mode: %s\n",
-          ge->index, ge->offset, ge->size, ge->width, ge->rows, ge->pitch,
-          ge->num_grays, pxmode[ge->pixel_mode]);
-}
-
-static void
-_cache_entry_print(Cache_Entry *ce)
-{
-   Eina_List *l;
-   Glyph_Entry *ge;
-
-   printf("\tSHM %s used %u/%u\n", ce->shmname, ce->usage, ce->size);
-
-   EINA_LIST_FOREACH(ce->glyphs, l, ge)
-     _glyph_entry_print(ge);
+   printf("  GLYPH id: %-4u refcount %-2u: index: %-6u offset: %-6u size: %-3u "
+          "%2ux%-3u pitch: %-2u grays: %-3u pixel mode: %s\n",
+          gd->id, gd->refcount, gd->index, gd->offset, gd->size,
+          gd->width, gd->rows, gd->pitch,
+          gd->num_grays, pxmode[gd->pixel_mode]);
 }
 
 static void
 _font_entry_print(Font_Entry *fe)
 {
    Eina_List *l;
-   Cache_Entry *ce;
+   Glyph_Data *gd;
 
    printf("FONT %s:%s size: %u dpi: %u %s%s%s %s\n",
           fe->file, fe->name, fe->size, fe->dpi,
@@ -410,18 +371,46 @@ _font_entry_print(Font_Entry *fe)
           fe->rend_flags & 1 ? "SLANT " : "",
           fe->rend_flags & 2 ? "WEIGHT" : "",
           fe->unused ? "(unused)" : "");
+   printf("  Index:       %s\n"
+          "  Mempool:     %s\n"
+          "  Glyph count: %u\n",
+          fe->glyph_data_shm, fe->glyph_mempool_shm,
+          eina_list_count(fe->glyphs));
 
-   EINA_LIST_FOREACH(fe->caches, l, ce)
-     _cache_entry_print(ce);
+   EINA_LIST_FOREACH(fe->glyphs, l, gd)
+     _glyph_data_print(gd);
 
    putchar('\n');
 }
 
+static void
+_shared_index_print(Msg_Index_List *msg, size_t size)
+{
+   if (size < sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST)
+     {
+        ERR("Invalid message received from server. "
+            "Something went wrong.");
+        return;
+     }
+
+   printf("Printing shared indexes status.\n");
+   printf("===============================\n\n");
+   printf("Generation ID:        %-4d\n", msg->generation_id);
+   printf("Strings entries path: %s\n", msg->strings_entries_path);
+   printf("Strings index path:   %s\n", msg->strings_index_path);
+   printf("Files index path:     %s\n", msg->files_index_path);
+   printf("Images index path:    %s\n", msg->images_index_path);
+   printf("Fonts index path:     %s\n", msg->fonts_index_path);
+   printf("\n\n\n");
+}
+
 int
 main(void)
 {
    Eina_List *fonts;
    Font_Entry *fe;
+   Msg_Index_List *msg = NULL;
+   int size;
 
    eina_init();
    _evas_cserve2_debug_log_dom = eina_log_domain_register
@@ -431,6 +420,11 @@ main(void)
         ERR("Could not connect to server.");
         return -1;
      }
+
+   while (!msg)
+     msg = _server_read(&size);
+   _shared_index_print(msg, size);
+
    _debug_msg_send();
    fonts = _debug_msg_read();
    EINA_LIST_FREE(fonts, fe)
index 7c3f176..ec63660 100644 (file)
@@ -293,6 +293,13 @@ cserve2_shared_array_count_get(Shared_Array *sa)
 }
 
 int
+cserve2_shared_array_map_size_get(Shared_Array *sa)
+{
+   if (!sa || !sa->ds) return 0;
+   return cserve2_shm_map_size_get(sa->ds->shm);
+}
+
+int
 cserve2_shared_array_item_size_get(Shared_Array *sa)
 {
    if (!sa) return -1;
@@ -841,7 +848,8 @@ size_t
 cserve2_shared_mempool_size_get(Shared_Mempool *sm)
 {
    if (!sm) return 0;
-   return cserve2_shm_map_size_get(sm->ds->shm);
+   return cserve2_shm_map_size_get(sm->ds->shm)
+         + cserve2_shared_array_map_size_get(sm->index->sa);
 }
 
 const char *
index bcf0cdd..3ab78a8 100644 (file)
@@ -177,47 +177,80 @@ _usage_msg_send(void)
 }
 
 static void
+_shared_index_print(Msg_Base *data, size_t size)
+{
+   Msg_Index_List *msg = (Msg_Index_List *) data;
+
+   if (size < sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST)
+     {
+        ERR("Invalid message received from server. "
+            "Something went wrong.");
+        return;
+     }
+
+   printf("Printing shared indexes status.\n");
+   printf("===============================\n\n");
+   printf("Generation ID:        %-4d\n", msg->generation_id);
+   printf("Strings entries path: %s\n", msg->strings_entries_path);
+   printf("Strings index path:   %s\n", msg->strings_index_path);
+   printf("Files index path:     %s\n", msg->files_index_path);
+   printf("Images index path:    %s\n", msg->images_index_path);
+   printf("Fonts index path:     %s\n", msg->fonts_index_path);
+   printf("\n\n\n");
+}
+
+static void
 _usage_msg_read(void)
 {
-   Msg_Stats *msg = NULL;
+   Msg_Stats *stats = NULL;
    int size;
 
    printf("Requesting server statistics.\n\n");
-   while (!msg)
-     msg = _server_read(&size);
 
-   if (msg->base.type != CSERVE2_STATS)
+   while (!stats)
      {
-        ERR("Invalid message received from server."
-            "Something went badly wrong.");
-        return;
+        Msg_Base *msg = _server_read(&size);
+        if (!msg) continue;
+        switch (msg->type)
+          {
+           case CSERVE2_INDEX_LIST:
+             _shared_index_print(msg, size);
+             break;
+           case CSERVE2_STATS:
+             stats = (Msg_Stats *) msg;
+             break;
+           default:
+             ERR("Invalid message received from server. "
+                 "Something went badly wrong.");
+             return;
+          }
      }
 
    printf("Printing server usage.\n");
    printf("======================\n\n");
    printf("\nImage Usage Statistics:\n");
    printf("----------------------\n\n");
-   printf("Image headers usage: %d bytes\n", msg->images.files_size);
-   printf("Image data requested: %d kbytes\n", msg->images.requested_size / 1024);
-   printf("Image data usage: %d kbytes\n", msg->images.images_size / 1024);
-   printf("Image data unused: %d kbytes\n", msg->images.unused_size / 1024);
-   printf("Image headers load time: %dus\n", msg->images.files_load_time);
-   printf("Image headers saved time: %dus\n", msg->images.files_saved_time);
-   printf("Image data load time: %dus\n", msg->images.images_load_time);
-   printf("Image data saved time: %dus\n", msg->images.images_saved_time);
+   printf("Image headers usage: %d bytes\n", stats->images.files_size);
+   printf("Image data requested: %d kbytes\n", stats->images.requested_size / 1024);
+   printf("Image data usage: %d kbytes\n", stats->images.images_size / 1024);
+   printf("Image data unused: %d kbytes\n", stats->images.unused_size / 1024);
+   printf("Image headers load time: %dus\n", stats->images.files_load_time);
+   printf("Image headers saved time: %dus\n", stats->images.files_saved_time);
+   printf("Image data load time: %dus\n", stats->images.images_load_time);
+   printf("Image data saved time: %dus\n", stats->images.images_saved_time);
    printf("\nFont Usage Statistics:\n");
    printf("----------------------\n\n");
-   printf("Requested usage: %d bytes\n", msg->fonts.requested_size);
-   printf("Real usage: %d bytes\n", msg->fonts.real_size);
-   printf("Unused size: %d bytes\n", msg->fonts.unused_size);
-   printf("Fonts load time: %dus\n", msg->fonts.fonts_load_time);
-   printf("Fonts used load time: %dus\n", msg->fonts.fonts_used_load_time);
-   printf("Fonts used saved time: %dus\n", msg->fonts.fonts_used_saved_time);
-   printf("Glyphs load time: %dus\n", msg->fonts.glyphs_load_time);
-   printf("Glyphs render time: %dus\n", msg->fonts.glyphs_render_time);
-   printf("Glyphs saved time: %dus\n", msg->fonts.glyphs_saved_time);
-   printf("Glyphs request time: %dus\n", msg->fonts.glyphs_request_time);
-   printf("Glyphs slave time: %dus\n", msg->fonts.glyphs_slave_time);
+   printf("Requested usage: %d bytes\n", stats->fonts.requested_size);
+   printf("Real usage: %d bytes\n", stats->fonts.real_size);
+   printf("Unused size: %d bytes\n", stats->fonts.unused_size);
+   printf("Fonts load time: %dus\n", stats->fonts.fonts_load_time);
+   printf("Fonts used load time: %dus\n", stats->fonts.fonts_used_load_time);
+   printf("Fonts used saved time: %dus\n", stats->fonts.fonts_used_saved_time);
+   printf("Glyphs load time: %dus\n", stats->fonts.glyphs_load_time);
+   printf("Glyphs render time: %dus\n", stats->fonts.glyphs_render_time);
+   printf("Glyphs saved time: %dus\n", stats->fonts.glyphs_saved_time);
+   printf("Glyphs request time: %dus\n", stats->fonts.glyphs_request_time);
+   printf("Glyphs slave time: %dus\n", stats->fonts.glyphs_slave_time);
 
    printf("\n");
 }
index b233be6..32e70a7 100644 (file)
@@ -231,6 +231,7 @@ struct _Msg_Stats {
  *
  * Content of the message follows:
  *
+ * * char fonts_index_path[64]
  * * number of font entries;
  * * each font entry:
  *   - unsigned int filelen
@@ -241,15 +242,15 @@ struct _Msg_Stats {
  *   - unsigned int size;
  *   - unsigned int dpi;
  *   - unsigned int unused;
- *   - ncaches:
- *   - each cache:
- *     * usigned int shmnamelen;
- *     * const char shmname;
- *     * unsigned int size;
- *     * unsigned int usage;
- *     * unsigned int nglyphs;
- *     * each glyph:
+ *   - const char glyph_data_shm[64];
+ *   - const char glyph_mempool_shm[64];
+ *   - unsigned int nglyphs;
+ *   - each glyph: Glyph_Data struct
+ *       - unsigned int id;
+ *       - unsigned int refcount;
  *       - unsigned int index;
+ *       - unsigned int shm_id; // shared string id
+ *       - unsigned int buffer_id;
  *       - unsigned int offset;
  *       - unsigned int size;
  *       - unsigned int rows;
@@ -260,6 +261,8 @@ struct _Msg_Stats {
  */
 struct _Msg_Font_Debug {
     Msg_Base base;
+    char fonts_index_path[64];
+    int nfonts;
 };
 
 /**