X-Git-Url: https://git.distorted.org.uk/~mdw/jog/blobdiff_plain/b41f38f059a9e191c97c03259649b27393475f2f..af666e6f949ddb4f2cdfc4d3564fbe82e8b8d81b:/au.c diff --git a/au.c b/au.c index 80382b8..5c90186 100644 --- a/au.c +++ b/au.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: au.c,v 1.1 2002/02/02 19:16:28 mdw Exp $ + * $Id: au.c,v 1.2 2002/02/02 22:43:50 mdw Exp $ * * High-level audio subsystem * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: au.c,v $ + * Revision 1.2 2002/02/02 22:43:50 mdw + * Provide a decent interface for finding out about the audio cache and + * configuring its capacity. + * * Revision 1.1 2002/02/02 19:16:28 mdw * New audio subsystem. * @@ -68,7 +72,7 @@ static unsigned au_flags = 0; static sym_table au_tab; /* Sample cache, by name */ static const char *au_dir = AUDIODIR; /* Directory containing samples */ static struct { au_data *next, *prev; } au_spare; /* Lists for sample data */ -static size_t au_sz, au_max; /* Size of cached samples */ +static au_cacheinfo cache; /* Cache usage information */ #define AU_SPARE ((au_data*)&au_spare) #define f_init 1u @@ -106,18 +110,21 @@ static const char *filename(const char *tag) static void prune(void) { T( trace(T_AU, "au: pruning cache (%lu/%lu)", - (unsigned long)au_sz, (unsigned long)au_max); ) - while (au_sz > au_max && AU_SPARE->next != AU_SPARE) { + (unsigned long)cache.sz_total, (unsigned long)cache.sz_max); ) + while (cache.sz_total > cache.sz_max && AU_SPARE->next != AU_SPARE) { au_data *a = AU_SPARE->next; au_sample *s = a->s; assert(!a->ref); AU_SPARE->next = a->next; a->next->prev = AU_SPARE; s->a = 0; - au_sz -= a->sz; + cache.sz_spare -= a->sz; + cache.sz_total -= a->sz; + cache.n_spare--; + cache.n_total--; ausys_free(a); T( trace(T_AU, "au: ... discarded `%s' (%lu/%lu)", SYM_NAME(s), - (unsigned long)au_sz, (unsigned long)au_max); ) + (unsigned long)cache.sz_total, (unsigned long)cache.sz_max); ) } } @@ -149,7 +156,7 @@ void au_init(const char *dir, size_t max) sym_create(&au_tab); AU_SPARE->next = AU_SPARE->prev = AU_SPARE; - au_max = max; + cache.sz_max = max; /* --- Initialize the system-specific subsystem --- */ @@ -178,6 +185,42 @@ void au_shutdown(void) T( trace(T_AU, "au: shutdown ok"); ) } +/* --- @au_getcacheinfo@ --- * + * + * Arguments: @au_cacheinfo *c@ = where to put the information + * + * Returns: --- + * + * Use: Extracts audio cache information. + */ + +void au_getcacheinfo(au_cacheinfo *c) +{ + ausys_lock(); + *c = cache; + ausys_unlock(); + assert(c->sz_spare + c->sz_queue == c->sz_total); + assert(c->n_spare + c->n_queue == c->n_total); +} + +/* --- @au_setcachelimit@ --- * + * + * Arguments: @size_t max@ = new cache limit + * + * Returns: --- + * + * Use: Reconfigures the maximum cache size. This probably isn't + * very useful, but it was easy... + */ + +void au_setcachelimit(size_t max) +{ + ausys_lock(); + cache.sz_max = max; + prune(); + ausys_unlock(); +} + /* --- @au_find@ --- * * * Arguments: @const char *tag@ = sample tag string @@ -251,6 +294,11 @@ au_data *au_fetch(au_sample *s) a->prev->next = a->next; a->next->prev = a->prev; a->next = a->prev = 0; + cache.sz_spare -= a->sz; + cache.sz_queue += a->sz; + cache.n_spare--; + cache.n_queue++; + cache.hits++; } a->ref++; T( trace(T_AU, "au: reusing sample `%s'", SYM_NAME(s)); ) @@ -302,7 +350,6 @@ au_data *au_fetch(au_sample *s) if ((a = ausys_decode(s, d.buf, d.len)) == 0) goto fail_0; - au_sz += a->sz; a->ref = 1; a->next = a->prev = 0; a->s = s; @@ -311,6 +358,11 @@ au_data *au_fetch(au_sample *s) /* --- Done --- */ ausys_lock(); + cache.sz_queue += a->sz; + cache.sz_total += a->sz; + cache.n_queue++; + cache.n_total++; + cache.misses++; prune(); ausys_unlock(); goto done; @@ -385,6 +437,10 @@ void au_free_unlocked(au_data *a) a->prev = AU_SPARE->prev; AU_SPARE->prev->next = a; AU_SPARE->prev = a; + cache.sz_queue -= a->sz; + cache.sz_spare += a->sz; + cache.n_queue--; + cache.n_spare++; T( trace(T_AU, "au: drop last ref to `%s'", SYM_NAME(a->s)); ) prune(); }