From 1e4ee656a0c44cbf915e124aa59c50fdde9f0973 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 20 Aug 2013 18:26:02 +0900 Subject: [PATCH] evas/cserve2: Fix cserve2_usage tool 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 | 1 + src/bin/evas/evas_cserve2_cache.c | 495 +++++++----------------------- src/bin/evas/evas_cserve2_debug.c | 136 ++++---- src/bin/evas/evas_cserve2_index.c | 10 +- src/bin/evas/evas_cserve2_usage.c | 85 +++-- src/lib/evas/cserve2/evas_cs2.h | 19 +- 6 files changed, 255 insertions(+), 491 deletions(-) diff --git a/src/bin/evas/evas_cserve2.h b/src/bin/evas/evas_cserve2.h index 88f4370346..badd33c8d6 100644 --- a/src/bin/evas/evas_cserve2.h +++ b/src/bin/evas/evas_cserve2.h @@ -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); diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c index 7c7932ef8a..86fb80464c 100644 --- a/src/bin/evas/evas_cserve2_cache.c +++ b/src/bin/evas/evas_cserve2_cache.c @@ -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; @@ -2232,8 +2093,6 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU msg->fonts.glyphs_saved_time += fe->gl_saved_time; msg->fonts.glyphs_request_time += fe->gl_request_time; 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 diff --git a/src/bin/evas/evas_cserve2_debug.c b/src/bin/evas/evas_cserve2_debug.c index e68e1138fc..10b9d5c92f 100644 --- a/src/bin/evas/evas_cserve2_debug.c +++ b/src/bin/evas/evas_cserve2_debug.c @@ -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) diff --git a/src/bin/evas/evas_cserve2_index.c b/src/bin/evas/evas_cserve2_index.c index 7c3f176d89..ec63660493 100644 --- a/src/bin/evas/evas_cserve2_index.c +++ b/src/bin/evas/evas_cserve2_index.c @@ -292,6 +292,13 @@ cserve2_shared_array_count_get(Shared_Array *sa) return sa->header->emptyidx; } +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) { @@ -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 * diff --git a/src/bin/evas/evas_cserve2_usage.c b/src/bin/evas/evas_cserve2_usage.c index bcf0cdd7d0..3ab78a8383 100644 --- a/src/bin/evas/evas_cserve2_usage.c +++ b/src/bin/evas/evas_cserve2_usage.c @@ -176,48 +176,81 @@ _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"); } diff --git a/src/lib/evas/cserve2/evas_cs2.h b/src/lib/evas/cserve2/evas_cs2.h index b233be6c2e..32e70a7863 100644 --- a/src/lib/evas/cserve2/evas_cs2.h +++ b/src/lib/evas/cserve2/evas_cs2.h @@ -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; }; /**