plugins: properties: further reduce stack pressure

Follow-up to 9f20c45.

tagtree.c's retrieve_entries has significant stack usage
(>1.5k) and is called from tagtree_entries_iterate.

Further Reduce stack usage of tagtree_entries_iterate,
going from 784 B to 72 B, by using static memory allocation
for the the tagcache_search struct in the Properties plugin.

Change-Id: I75a170bea1c5392c18a891844a0ff31fbd2114eb
This commit is contained in:
Christian Soffke 2026-05-29 20:40:25 +02:00
parent 8af98332ab
commit 3507f32d01
5 changed files with 23 additions and 18 deletions

View file

@ -701,6 +701,7 @@ static const struct plugin_api rockbox_api = {
count_mp3_frames, count_mp3_frames,
create_xing_header, create_xing_header,
#ifdef HAVE_TAGCACHE #ifdef HAVE_TAGCACHE
tagtree_entries_iterate,
tagcache_search, tagcache_search,
tagcache_search_set_uniqbuf, tagcache_search_set_uniqbuf,
tagcache_search_add_filter, tagcache_search_add_filter,
@ -714,9 +715,8 @@ static const struct plugin_api rockbox_api = {
tagcache_is_in_ram, tagcache_is_in_ram,
#if defined(HAVE_DIRCACHE) #if defined(HAVE_DIRCACHE)
tagcache_fill_tags, tagcache_fill_tags,
#endif #endif /* HAVE_DIRCACHE */
#endif #endif /* HAVE_TC_RAMCACHE */
tagtree_entries_iterate,
#endif /* HAVE_TAGCACHE */ #endif /* HAVE_TAGCACHE */
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART

View file

@ -180,7 +180,7 @@ int plugin_open(const char *plugin, const char *parameter);
* when this happens please take the opportunity to sort in * when this happens please take the opportunity to sort in
* any new functions "waiting" at the end of the list. * any new functions "waiting" at the end of the list.
*/ */
#define PLUGIN_API_VERSION 283 #define PLUGIN_API_VERSION 284
/* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */ /* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */
@ -824,6 +824,9 @@ struct plugin_api {
void (*progressfunc)(int), bool generate_toc, void (*progressfunc)(int), bool generate_toc,
unsigned char* tempbuf, size_t tempbuf_len); unsigned char* tempbuf, size_t tempbuf_len);
#ifdef HAVE_TAGCACHE #ifdef HAVE_TAGCACHE
bool (*tagtree_entries_iterate)(struct tagcache_search *tcs,
bool (*action_cb)(const char *file_name),
char *buf, size_t buf_sz);
bool (*tagcache_search)(struct tagcache_search *tcs, int tag); bool (*tagcache_search)(struct tagcache_search *tcs, int tag);
void (*tagcache_search_set_uniqbuf)(struct tagcache_search *tcs, void (*tagcache_search_set_uniqbuf)(struct tagcache_search *tcs,
void *buffer, long length); void *buffer, long length);
@ -840,10 +843,8 @@ struct plugin_api {
bool (*tagcache_is_in_ram)(void); bool (*tagcache_is_in_ram)(void);
#if defined(HAVE_DIRCACHE) #if defined(HAVE_DIRCACHE)
bool (*tagcache_fill_tags)(struct mp3entry *id3, const char *filename); bool (*tagcache_fill_tags)(struct mp3entry *id3, const char *filename);
#endif #endif /* HAVE_DIRCACHE */
#endif #endif /* HAVE_TC_RAMCACHE */
bool (*tagtree_entries_iterate)(bool (*action_cb)(const char *file_name),
char *buf, size_t buf_sz);
#endif /* HAVE_TAGCACHE */ #endif /* HAVE_TAGCACHE */
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART

View file

@ -34,6 +34,9 @@ enum props_types {
PROPS_DIR PROPS_DIR
}; };
#ifdef HAVE_TAGCACHE
static struct tagcache_search tcs;
#endif
static struct gui_synclist properties_lists; static struct gui_synclist properties_lists;
static struct mp3entry id3; static struct mp3entry id3;
static struct tm tm; static struct tm tm;
@ -307,8 +310,8 @@ static bool assemble_track_info(const char *filename, struct dir_stats *stats)
return false; return false;
#ifdef HAVE_TAGCACHE #ifdef HAVE_TAGCACHE
else if (props_type == PROPS_MUL_ID3 && else if (props_type == PROPS_MUL_ID3 &&
!rb->tagtree_entries_iterate(&mul_id3_add, str_filename, !rb->tagtree_entries_iterate(&tcs, &mul_id3_add, str_filename,
sizeof str_filename)) sizeof str_filename))
return false; return false;
#endif #endif

View file

@ -1795,7 +1795,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
{ /* Fallback to basename */ { /* Fallback to basename */
char *lastname = dptr->name; char *lastname = dptr->name;
dptr->name = core_get_data(c->cache.name_buffer_handle)+namebufused; dptr->name = core_get_data(c->cache.name_buffer_handle)+namebufused;
if ((c->cache.name_buffer_size - namebufused) > 0 && if ((c->cache.name_buffer_size - namebufused) > 0 &&
tagcache_retrieve(&tcs, tcs.idx_id, tag_virt_basename, dptr->name, tagcache_retrieve(&tcs, tcs.idx_id, tag_virt_basename, dptr->name,
c->cache.name_buffer_size - namebufused)) c->cache.name_buffer_size - namebufused))
{ {
@ -2654,10 +2654,10 @@ static bool tagtree_insert_selection(int position, bool queue,
* callback function parameter. Parameter will be NULL for * callback function parameter. Parameter will be NULL for
* entries whose filename couldn't be retrieved. * entries whose filename couldn't be retrieved.
*/ */
bool tagtree_entries_iterate(bool (*action_cb)(const char *file_name), bool tagtree_entries_iterate(struct tagcache_search *tcs,
bool (*action_cb)(const char *file_name),
char* buf, size_t buf_sz) char* buf, size_t buf_sz)
{ {
struct tagcache_search tcs;
int i, n; int i, n;
unsigned long last_tick; unsigned long last_tick;
int ret = true; int ret = true;
@ -2668,7 +2668,7 @@ bool tagtree_entries_iterate(bool (*action_cb)(const char *file_name),
cpu_boost(true); cpu_boost(true);
if (!goto_allsubentries(newtable)) if (!goto_allsubentries(newtable))
ret = false; ret = false;
else if (tagcache_search(&tcs, tag_filename)) else if (tagcache_search(tcs, tag_filename))
{ {
last_tick = current_tick + HZ/2; last_tick = current_tick + HZ/2;
splash_progress_set_delay(HZ / 2); /* wait 1/2 sec before progress */ splash_progress_set_delay(HZ / 2); /* wait 1/2 sec before progress */
@ -2684,8 +2684,8 @@ bool tagtree_entries_iterate(bool (*action_cb)(const char *file_name),
last_tick = current_tick; last_tick = current_tick;
} }
if (!action_cb(tagcache_retrieve(&tcs, tagtree_get_entry(tc, i)->extraseek, if (!action_cb(tagcache_retrieve(tcs, tagtree_get_entry(tc, i)->extraseek,
tcs.type, buf, buf_sz) ? buf : NULL)) tcs->type, buf, buf_sz) ? buf : NULL))
{ {
ret = false; ret = false;
break; break;
@ -2693,7 +2693,7 @@ bool tagtree_entries_iterate(bool (*action_cb)(const char *file_name),
yield(); yield();
} }
tagcache_search_finish(&tcs); tagcache_search_finish(tcs);
} }
else else
{ {

View file

@ -47,7 +47,8 @@ int tagtree_get_icon(struct tree_context* c);
int tagtree_get_filename(struct tree_context* c, char *buf, int buflen); int tagtree_get_filename(struct tree_context* c, char *buf, int buflen);
int tagtree_get_custom_action(struct tree_context* c); int tagtree_get_custom_action(struct tree_context* c);
bool tagtree_get_subentry_filename(char *buf, size_t bufsize); bool tagtree_get_subentry_filename(char *buf, size_t bufsize);
bool tagtree_entries_iterate(bool (*action_cb)(const char *file_name), bool tagtree_entries_iterate(struct tagcache_search *tcs,
bool (*action_cb)(const char *file_name),
char *buf, size_t buf_sz); char *buf, size_t buf_sz);
#endif #endif