mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Debugger: Add cache statistics command
Add `info cache` command that reports cache usage and cumulative hit rates for glyph, CG, and archive data.
This commit is contained in:
@@ -148,3 +148,7 @@ int ald_get_maxno(DRIFILETYPE type) {
|
||||
return 0;
|
||||
return dri[type]->maxno;
|
||||
}
|
||||
|
||||
CacheStats ald_get_cache_stats(void) {
|
||||
return cache_get_stats(dri_cache);
|
||||
}
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
#define __ALD_MANAGER__
|
||||
|
||||
#include "portab.h"
|
||||
#include "cache.h"
|
||||
#include "dri.h"
|
||||
|
||||
#define DRIFILETYPEMAX 7
|
||||
@@ -44,6 +45,6 @@ bool ald_exists(DRIFILETYPE type, int no);
|
||||
dridata *ald_getdata(DRIFILETYPE type, int no);
|
||||
void ald_freedata(dridata *data);
|
||||
int ald_get_maxno(DRIFILETYPE type);
|
||||
CacheStats ald_get_cache_stats(void);
|
||||
|
||||
#endif /* !__ALD_MANAGER__ */
|
||||
|
||||
|
||||
+18
-1
@@ -41,6 +41,8 @@ struct Cache {
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
size_t count;
|
||||
size_t hits;
|
||||
size_t misses;
|
||||
};
|
||||
|
||||
static bool is_pinned(const Cache *cache, const CacheEntry *entry) {
|
||||
@@ -112,8 +114,11 @@ void *cache_get(Cache *cache, const void *key) {
|
||||
if (!cache || !key)
|
||||
return NULL;
|
||||
CacheEntry *entry = find_entry(cache, key, cache->ops.hash(key));
|
||||
if (!entry)
|
||||
if (!entry) {
|
||||
cache->misses++;
|
||||
return NULL;
|
||||
}
|
||||
cache->hits++;
|
||||
lru_remove(cache, entry);
|
||||
lru_prepend(cache, entry);
|
||||
return entry->data;
|
||||
@@ -176,3 +181,15 @@ size_t cache_clear(Cache *cache) {
|
||||
}
|
||||
return cache->count;
|
||||
}
|
||||
|
||||
CacheStats cache_get_stats(const Cache *cache) {
|
||||
if (!cache)
|
||||
return (CacheStats){0};
|
||||
return (CacheStats){
|
||||
.count = cache->count,
|
||||
.size = cache->size,
|
||||
.capacity = cache->capacity,
|
||||
.hits = cache->hits,
|
||||
.misses = cache->misses,
|
||||
};
|
||||
}
|
||||
|
||||
+11
@@ -40,6 +40,14 @@ typedef enum {
|
||||
CACHE_INSERT_NOMEM,
|
||||
} CacheInsertResult;
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
size_t hits;
|
||||
size_t misses;
|
||||
} CacheStats;
|
||||
|
||||
Cache *cache_new(size_t capacity, const CacheOps *ops);
|
||||
void cache_destroy(Cache *cache);
|
||||
|
||||
@@ -55,4 +63,7 @@ bool cache_remove(Cache *cache, const void *key);
|
||||
/* Removes all unpinned entries and returns the number of entries left. */
|
||||
size_t cache_clear(Cache *cache);
|
||||
|
||||
/* Returns zero-filled statistics when cache is NULL. */
|
||||
CacheStats cache_get_stats(const Cache *cache);
|
||||
|
||||
#endif /* XSYSTEM35_CACHE_H */
|
||||
|
||||
@@ -64,14 +64,27 @@ void cache_test(void) {
|
||||
Cache *cache = cache_new(2, &ops);
|
||||
ASSERT_TRUE(cache);
|
||||
destroyed = 0;
|
||||
CacheStats stats = cache_get_stats(cache);
|
||||
ASSERT_EQUAL(stats.count, 0);
|
||||
ASSERT_EQUAL(stats.size, 0);
|
||||
ASSERT_EQUAL(stats.capacity, 2);
|
||||
ASSERT_EQUAL(stats.hits, 0);
|
||||
ASSERT_EQUAL(stats.misses, 0);
|
||||
|
||||
// A lookup makes k1 most-recently used, so inserting k3 evicts k2.
|
||||
int k1 = 1, k2 = 2, k3 = 3, k4 = 4, k5 = 5;
|
||||
ASSERT_EQUAL(cache_insert(cache, &k1, new_value(1), 1), CACHE_INSERT_OK);
|
||||
ASSERT_EQUAL(cache_insert(cache, &k2, new_value(2), 1), CACHE_INSERT_OK);
|
||||
stats = cache_get_stats(cache);
|
||||
ASSERT_EQUAL(stats.count, 2);
|
||||
ASSERT_EQUAL(stats.size, 2);
|
||||
ASSERT_EQUAL(stats.capacity, 2);
|
||||
ASSERT_EQUAL(((TestValue *)cache_get(cache, &k1))->value, 1);
|
||||
ASSERT_EQUAL(cache_insert(cache, &k3, new_value(3), 1), CACHE_INSERT_OK);
|
||||
ASSERT_NULL(cache_get(cache, &k2));
|
||||
stats = cache_get_stats(cache);
|
||||
ASSERT_EQUAL(stats.hits, 1);
|
||||
ASSERT_EQUAL(stats.misses, 1);
|
||||
|
||||
// Pinned entries survive both capacity eviction and cache_clear().
|
||||
((TestValue *)cache_get(cache, &k1))->pinned = true;
|
||||
@@ -94,4 +107,11 @@ void cache_test(void) {
|
||||
ASSERT_EQUAL(cache_clear(cache), 0);
|
||||
ASSERT_EQUAL(destroyed, 4);
|
||||
cache_destroy(cache);
|
||||
|
||||
stats = cache_get_stats(NULL);
|
||||
ASSERT_EQUAL(stats.count, 0);
|
||||
ASSERT_EQUAL(stats.size, 0);
|
||||
ASSERT_EQUAL(stats.capacity, 0);
|
||||
ASSERT_EQUAL(stats.hits, 0);
|
||||
ASSERT_EQUAL(stats.misses, 0);
|
||||
}
|
||||
|
||||
@@ -354,6 +354,10 @@ void cg_reset(void) {
|
||||
memset(&loc_where0, 0, sizeof(loc_where0));
|
||||
}
|
||||
|
||||
CacheStats cg_get_cache_stats(void) {
|
||||
return cache_get_stats(cg_cache);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set cg display location
|
||||
* x : display location x
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define __CG__
|
||||
|
||||
#include <SDL_rect.h>
|
||||
#include "cache.h"
|
||||
#include "portab.h"
|
||||
|
||||
struct SDL_Surface;
|
||||
@@ -88,6 +89,7 @@ extern void cgdata_free(cgdata *cg);
|
||||
extern struct SDL_Surface *cg_load_as_sdlsurface(int no);
|
||||
struct SDL_Surface *cg_load_as_sdlsurface_from_data(uint8_t *data, size_t size, bool mosaic, bool as_alpha);
|
||||
extern void load_censor_list(const char *path);
|
||||
extern CacheStats cg_get_cache_stats(void);
|
||||
|
||||
extern int cg_vspPB;
|
||||
extern int cg_fflg;
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "debugger.h"
|
||||
#include "debugger_private.h"
|
||||
#include "debug_symbol.h"
|
||||
#include "ald_manager.h"
|
||||
#include "cg.h"
|
||||
#include "font.h"
|
||||
#include "nact.h"
|
||||
#include "variable.h"
|
||||
#ifdef HAVE_SIGACTION
|
||||
@@ -207,6 +210,34 @@ static const char * const help_help = NULL;
|
||||
|
||||
static CommandResult cmd_help(void);
|
||||
|
||||
static const char desc_info[] = "Print information about the program.";
|
||||
static const char help_info[] =
|
||||
"Syntax: info cache\n"
|
||||
"\n"
|
||||
"Displays usage and lookup statistics for each cache.";
|
||||
|
||||
static void print_cache_stats(const char *name, CacheStats stats) {
|
||||
size_t lookups = stats.hits + stats.misses;
|
||||
double hit_rate = lookups ? 100.0 * stats.hits / lookups : 0.0;
|
||||
printf("%-8s %8zu %12zu %12zu %8zu %8zu %8.1f%%\n",
|
||||
name, stats.count, stats.size, stats.capacity,
|
||||
stats.hits, stats.misses, hit_rate);
|
||||
}
|
||||
|
||||
static CommandResult cmd_info(void) {
|
||||
char *arg = strtok(NULL, whitespaces);
|
||||
if (!arg || strcmp(arg, "cache") || strtok(NULL, whitespaces)) {
|
||||
puts(help_info);
|
||||
return CONTINUE_REPL;
|
||||
}
|
||||
|
||||
puts("Cache Entries Size Capacity Hits Misses Hit rate");
|
||||
print_cache_stats("Glyph", font_get_cache_stats());
|
||||
print_cache_stats("CG", cg_get_cache_stats());
|
||||
print_cache_stats("Archive", ald_get_cache_stats());
|
||||
return CONTINUE_REPL;
|
||||
}
|
||||
|
||||
static const char desc_list[] = "List specified function or line.";
|
||||
static const char help_list[] =
|
||||
"Syntax: list\n"
|
||||
@@ -361,6 +392,7 @@ const Command dbg_cui_commands[] = {
|
||||
{"continue", "c", desc_continue, help_continue, cmd_continue},
|
||||
{"delete", "d", desc_delete, help_delete, cmd_delete},
|
||||
{"help", "h", desc_help, help_help, cmd_help},
|
||||
{"info", "i", desc_info, help_info, cmd_info},
|
||||
{"list", "l", desc_list, help_list, cmd_list},
|
||||
{"step", "s", desc_step, help_step, cmd_step},
|
||||
{"finish", NULL, desc_finish, help_finish, cmd_finish},
|
||||
|
||||
@@ -416,6 +416,10 @@ bool font_get_antialias(void) {
|
||||
return this.antialiase_on;
|
||||
}
|
||||
|
||||
CacheStats font_get_cache_stats(void) {
|
||||
return cache_get_stats(glyph_cache);
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_ASYNC_JS(bool, load_mincho_font, (void), {
|
||||
return await xsystem35.load_mincho_font();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define __FONT_H__
|
||||
|
||||
#include <SDL_surface.h>
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include "portab.h"
|
||||
|
||||
@@ -55,6 +56,7 @@ extern void font_measure_text(FontSpec spec, const char *str_utf8, int len, bool
|
||||
// Rows by which a rendered surface extends above the character cell. Subtract
|
||||
// it from a Y coordinate that denotes the cell top before blitting.
|
||||
extern int font_cell_overhang(FontSpec spec);
|
||||
extern CacheStats font_get_cache_stats(void);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
extern bool load_mincho_font(void);
|
||||
|
||||
Reference in New Issue
Block a user