From 2c47b22bc498d1e5e649c7786aaf2f331572ed02 Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Mon, 23 Oct 2023 21:54:29 +0200 Subject: [PATCH] [libsixel] memcount --- src/dialogs/info.cpp | 3 ++ src/terminal/sixel.c | 30 ++++++++++++++- src/util/memcount.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++ src/util/memcount.h | 14 +++++++ 4 files changed, 136 insertions(+), 1 deletion(-) diff --git a/src/dialogs/info.cpp b/src/dialogs/info.cpp index 0e324f8f..fd4c8034 100644 --- a/src/dialogs/info.cpp +++ b/src/dialogs/info.cpp @@ -275,6 +275,9 @@ get_resource_info(struct terminal *term, void *data) #ifdef CONFIG_GZIP add_format_to_string(&info, "\nGzip: used times: %ld active: %ld, size: %ld", get_gzip_total_allocs(), get_gzip_active(), get_gzip_size()); #endif +#ifdef CONFIG_LIBSIXEL + add_format_to_string(&info, "\nSixel: used times: %ld active: %ld, size: %ld", get_sixel_total_allocs(), get_sixel_active(), get_sixel_size()); +#endif #endif #ifdef DEBUG_MEMLEAK diff --git a/src/terminal/sixel.c b/src/terminal/sixel.c index 9ba0329e..fa0825ce 100644 --- a/src/terminal/sixel.c +++ b/src/terminal/sixel.c @@ -41,6 +41,10 @@ #include "terminal/sixel.h" #include "terminal/terminal.h" +#ifdef CONFIG_DEBUG +#include "util/memcount.h" +#endif + /* encode settings object */ struct sixel_decoder { unsigned int ref; @@ -93,6 +97,20 @@ struct sixel_encoder { void *dither_cache; }; +#ifdef CONFIG_DEBUG +static sixel_allocator_t *el_sixel_allocator; + +static void +init_allocator(void) +{ + static int initialized = 0; + if (!initialized) { + sixel_allocator_new(&el_sixel_allocator, el_sixel_malloc, el_sixel_calloc, el_sixel_realloc, el_sixel_free); + initialized = 1; + } +} +#endif + /* palette type */ #define SIXEL_COLOR_OPTION_DEFAULT 0 /* use default settings */ #define SIXEL_COLOR_OPTION_MONOCHROME 1 /* use monochrome palette */ @@ -832,8 +850,12 @@ add_image_to_document(struct document *doc, struct string *pixels, int lineno) mem_free(im); return 0; } +#ifdef CONFIG_DEBUG + init_allocator(); + status = sixel_decoder_new(&decoder, el_sixel_allocator); +#else status = sixel_decoder_new(&decoder, NULL); - +#endif if (SIXEL_FAILED(status)) { goto end; } @@ -884,6 +906,7 @@ end: return ile; } + struct image * copy_frame(struct image *src, int box_width, int box_height, int cell_width, int cell_height, int dx, int dy) { @@ -909,7 +932,12 @@ copy_frame(struct image *src, int box_width, int box_height, int cell_width, int mem_free(dest); return NULL; } +#ifdef CONFIG_DEBUG + init_allocator(); + status = sixel_decoder_new(&decoder, el_sixel_allocator); +#else status = sixel_decoder_new(&decoder, NULL); +#endif if (SIXEL_FAILED(status)) { goto end; diff --git a/src/util/memcount.cpp b/src/util/memcount.cpp index 62bc2b06..5f4da32e 100644 --- a/src/util/memcount.cpp +++ b/src/util/memcount.cpp @@ -66,6 +66,7 @@ get_brotli_active(void) } #endif + #ifdef CONFIG_GZIP static std::map el_gzip_allocs; @@ -118,3 +119,92 @@ get_gzip_active(void) return el_gzip_allocs.size(); } #endif + +#ifdef CONFIG_LIBSIXEL + +static std::map el_sixel_allocs; +static uint64_t el_sixel_total_allocs; +static uint64_t el_sixel_size; + +/* call custom malloc() */ +void * +el_sixel_malloc( + size_t /* in */ size) /* allocation size */ +{ + void *res = malloc(size); + + if (res) { + el_sixel_allocs[res] = size; + el_sixel_total_allocs++; + el_sixel_size += size; + } + + return res; +} + + +/* call custom calloc() */ +void * +el_sixel_calloc( + size_t /* in */ nelm, /* allocation size */ + size_t /* in */ elsize) /* allocation size */ +{ + uint64_t alloc_size = nelm * elsize; + void *res = calloc(nelm, elsize); + + if (res) { + el_sixel_allocs[res] = alloc_size; + el_sixel_total_allocs++; + el_sixel_size += alloc_size; + } + + return res; +} + +/* call custom realloc() */ +void * +el_sixel_realloc( + void /* in */ *p, /* existing buffer to be re-allocated */ + size_t /* in */ n) /* re-allocation size */ +{ + el_sixel_free(p); + return el_sixel_malloc(n); +} + +/* call custom free() */ +void +el_sixel_free( + void /* in */ *p) /* existing buffer to be freed */ +{ + if (!p) { + return; + } + + auto el = el_sixel_allocs.find(p); + + if (el == el_sixel_allocs.end()) { + fprintf(stderr, "sixel %p not found\n", p); + return; + } + el_sixel_size -= el->second; + el_sixel_allocs.erase(el); +} + +uint64_t +get_sixel_total_allocs(void) +{ + return el_sixel_total_allocs; +} + +uint64_t +get_sixel_size(void) +{ + return el_sixel_size; +} + +uint64_t +get_sixel_active(void) +{ + return el_sixel_allocs.size(); +} +#endif diff --git a/src/util/memcount.h b/src/util/memcount.h index bae61de3..b460fba0 100644 --- a/src/util/memcount.h +++ b/src/util/memcount.h @@ -1,6 +1,10 @@ #ifndef EL__UTIL_MEMCOUNT_H #define EL__UTIL_MEMCOUNT_H +#ifdef CONFIG_LIBSIXEL +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -21,6 +25,16 @@ uint64_t get_gzip_size(void); uint64_t get_gzip_active(void); #endif +#ifdef CONFIG_LIBSIXEL +void *el_sixel_malloc(size_t size); +void *el_sixel_calloc(size_t nelm, size_t elsize); +void *el_sixel_realloc(void *p, size_t n); +void el_sixel_free(void *p); +uint64_t get_sixel_total_allocs(void); +uint64_t get_sixel_size(void); +uint64_t get_sixel_active(void); +#endif + #ifdef __cplusplus } #endif