- rename Qalloc and friends to QA_alloc

- add a QA_strdup
- add Cache_{Add,Remove,Get,Release}, for the locking version of the
  cache
- Convert libs/audio/* over to locking cache functions
This commit is contained in:
Adam Olsen 2001-08-30 11:37:50 +00:00
parent fa036c7c11
commit e149094bd2
5 changed files with 177 additions and 68 deletions

View File

@ -118,9 +118,15 @@ void *Hunk_TempAlloc (int size);
void Hunk_Check (void); void Hunk_Check (void);
struct cache_user_s;
typedef void * (*cache_allocator_t) (struct cache_user_s *c, int size, const char *name);
typedef void (*cache_loader_t) (struct cache_user_s *cache, cache_allocator_t allocator);
typedef struct cache_user_s typedef struct cache_user_s
{ {
void *data; void *data;
char *filename;
cache_loader_t loader;
} cache_user_t; } cache_user_t;
void Cache_Flush (void); void Cache_Flush (void);
@ -137,6 +143,11 @@ void *Cache_Alloc (cache_user_t *c, int size, const char *name);
void Cache_Report (void); void Cache_Report (void);
void Cache_Add (cache_user_t *c, const char *filename, cache_loader_t loader);
void Cache_Remove (cache_user_t *c);
void *Cache_Get (cache_user_t *c);
void Cache_Release (cache_user_t *c);
/* Modes, pick one */ /* Modes, pick one */
#define QA_NOFAIL 1 #define QA_NOFAIL 1
#define QA_LATEFAIL 2 #define QA_LATEFAIL 2
@ -147,12 +158,13 @@ void Cache_Report (void);
/* Flags, OR them with the mode */ /* Flags, OR them with the mode */
#define QA_ZEROED 4 #define QA_ZEROED 4
extern size_t (*Qalloc_callback) (size_t size); extern size_t (*QA_alloc_callback) (size_t size);
void *Qalloc (void *ptr, size_t size, unsigned modes); void *QA_alloc (void *ptr, size_t size, unsigned modes);
void *Qmalloc (size_t size); void *QA_malloc (size_t size);
void *Qcalloc (size_t nmemb, size_t size); void *QA_calloc (size_t nmemb, size_t size);
void *Qrealloc (void *ptr, size_t size); void *QA_realloc (void *ptr, size_t size);
void Qfree (void *ptr); void QA_free (void *ptr);
char *QA_strdup (const char *s);
#endif // __zone_h #endif // __zone_h

View File

@ -59,9 +59,9 @@ void SND_StopAllSoundsC (void);
void SND_Update_ (void); void SND_Update_ (void);
sfx_t *SND_PrecacheSound (const char *name); sfx_t *SND_PrecacheSound (const char *name);
sfxcache_t *SND_LoadSound (sfx_t *s);
void SND_ClearBuffer (void); void SND_ClearBuffer (void);
void SND_PaintChannels (int endtime); void SND_PaintChannels (int endtime);
void SND_CallbackLoad (struct cache_user_s *cache, cache_allocator_t allocator);
void SND_Init_Cvars (); void SND_Init_Cvars ();
@ -331,6 +331,7 @@ SND_FindName (const char *name)
sfx = &known_sfx[i]; sfx = &known_sfx[i];
strcpy (sfx->name, name); strcpy (sfx->name, name);
Cache_Add (&sfx->cache, name, SND_CallbackLoad);
num_sfx++; num_sfx++;
@ -360,8 +361,10 @@ SND_PrecacheSound (const char *name)
sfx = SND_FindName (name); sfx = SND_FindName (name);
// cache it in // cache it in
if (precache->int_val) if (precache->int_val) {
SND_LoadSound (sfx); Cache_Get (&sfx->cache);
Cache_Release (&sfx->cache);
}
return sfx; return sfx;
} }
@ -417,7 +420,6 @@ SND_Spatialize (channel_t *ch)
int phase; // in samples int phase; // in samples
vec_t lscale, rscale, scale; vec_t lscale, rscale, scale;
vec3_t source_vec; vec3_t source_vec;
sfx_t *snd;
// anything coming from the view entity will always be full volume // anything coming from the view entity will always be full volume
if (ch->entnum == *plugin_info_snd_render_data.viewentity) { if (ch->entnum == *plugin_info_snd_render_data.viewentity) {
@ -428,7 +430,6 @@ SND_Spatialize (channel_t *ch)
} }
// calculate stereo seperation and distance attenuation // calculate stereo seperation and distance attenuation
snd = ch->sfx;
VectorSubtract (ch->origin, listener_origin, source_vec); VectorSubtract (ch->origin, listener_origin, source_vec);
dist = VectorNormalize (source_vec) * ch->dist_mult; dist = VectorNormalize (source_vec) * ch->dist_mult;
@ -499,7 +500,7 @@ SND_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin,
return; // not audible at all return; // not audible at all
// new channel // new channel
sc = SND_LoadSound (sfx); sc = Cache_Get (&sfx->cache);
if (!sc) { if (!sc) {
target_chan->sfx = NULL; target_chan->sfx = NULL;
return; // couldn't load the sound's data return; // couldn't load the sound's data
@ -508,6 +509,7 @@ SND_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin,
target_chan->sfx = sfx; target_chan->sfx = sfx;
target_chan->pos = 0.0; target_chan->pos = 0.0;
target_chan->end = paintedtime + sc->length; target_chan->end = paintedtime + sc->length;
Cache_Release (&sfx->cache);
// if an identical sound has also been started this frame, offset the pos // if an identical sound has also been started this frame, offset the pos
// a bit to keep it from just making the first one louder // a bit to keep it from just making the first one louder
@ -613,12 +615,13 @@ SND_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss = &channels[total_channels]; ss = &channels[total_channels];
total_channels++; total_channels++;
sc = SND_LoadSound (sfx); sc = Cache_Get (&sfx->cache);
if (!sc) if (!sc)
return; return;
if (sc->loopstart == -1) { if (sc->loopstart == -1) {
Con_Printf ("Sound %s not looped\n", sfx->name); Con_Printf ("Sound %s not looped\n", sfx->name);
Cache_Release (&sfx->cache);
return; return;
} }
@ -627,6 +630,7 @@ SND_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss->master_vol = vol; ss->master_vol = vol;
ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist; ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist;
ss->end = paintedtime + sc->length; ss->end = paintedtime + sc->length;
Cache_Release (&sfx->cache);
SND_Spatialize (ss); SND_Spatialize (ss);
ss->oldphase = ss->phase; ss->oldphase = ss->phase;
@ -891,10 +895,20 @@ SND_SoundList (void)
sfx_t *sfx; sfx_t *sfx;
sfxcache_t *sc; sfxcache_t *sc;
int size, total; int size, total;
int load;
if (Cmd_Argc() >= 2 && !strcmp (Cmd_Argv (1), "known"))
load = 1;
else
load = 0;
total = 0; total = 0;
for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) { for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) {
sc = Cache_Check (&sfx->cache); if (load)
sc = Cache_Get (&sfx->cache);
else
sc = Cache_Check (&sfx->cache);
if (!sc) if (!sc)
continue; continue;
size = sc->length * sc->width * (sc->stereo + 1); size = sc->length * sc->width * (sc->stereo + 1);
@ -904,6 +918,9 @@ SND_SoundList (void)
else else
Con_Printf (" "); Con_Printf (" ");
Con_Printf ("(%2db) %6i : %s\n", sc->width * 8, size, sfx->name); Con_Printf ("(%2db) %6i : %s\n", sc->width * 8, size, sfx->name);
if (load)
Cache_Release (&sfx->cache);
} }
Con_Printf ("Total resident: %i\n", total); Con_Printf ("Total resident: %i\n", total);
} }

View File

@ -46,25 +46,21 @@
int cache_full_cycle; int cache_full_cycle;
byte *SND_Alloc (int size); byte *SND_Alloc (int size);
wavinfo_t SND_GetWavinfo (char *name, byte * wav, int wavlength); wavinfo_t SND_GetWavinfo (const char *name, byte * wav, int wavlength);
sfxcache_t *SND_LoadSound (cache_user_t *cache, const char *name, cache_allocator_t allocator);
void void
SND_ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte * data) SND_ResampleSfx (sfxcache_t *sc, int inrate, int inwidth, byte * data)
{ {
int outcount; int outcount;
int srcsample; int srcsample;
float stepscale; float stepscale;
int i; int i;
int sample, samplefrac, fracstep; int sample, samplefrac, fracstep;
sfxcache_t *sc;
short *is, *os; short *is, *os;
unsigned char *ib, *ob; unsigned char *ib, *ob;
sc = Cache_Check (&sfx->cache);
if (!sc)
return;
is = (short *) data; is = (short *) data;
os = (short *) sc->data; os = (short *) sc->data;
ib = data; ib = data;
@ -161,24 +157,19 @@ SND_ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte * data)
//============================================================================= //=============================================================================
sfxcache_t * sfxcache_t *
SND_LoadSound (sfx_t *s) SND_LoadSound (cache_user_t *cache, const char *name, cache_allocator_t allocator)
{ {
char namebuffer[256]; char namebuffer[256];
byte *data; byte *data;
wavinfo_t info; wavinfo_t info;
int len; int len;
float stepscale; float stepscale;
sfxcache_t *sc; sfxcache_t *sc;
byte stackbuf[1 * 1024]; // avoid dirtying the cache heap byte stackbuf[1 * 1024]; // avoid dirtying the cache heap
// see if still in memory
sc = Cache_Check (&s->cache);
if (sc)
return sc;
// load it in // load it in
strcpy (namebuffer, "sound/"); strcpy (namebuffer, "sound/");
strncat (namebuffer, s->name, sizeof (namebuffer) - strlen (namebuffer)); strncat (namebuffer, name, sizeof (namebuffer) - strlen (namebuffer));
data = COM_LoadStackFile (namebuffer, stackbuf, sizeof (stackbuf)); data = COM_LoadStackFile (namebuffer, stackbuf, sizeof (stackbuf));
@ -187,9 +178,9 @@ SND_LoadSound (sfx_t *s)
return NULL; return NULL;
} }
info = SND_GetWavinfo (s->name, data, com_filesize); info = SND_GetWavinfo (name, data, com_filesize);
if (info.channels != 1) { if (info.channels != 1) {
Con_Printf ("%s is a stereo sample\n", s->name); Con_Printf ("%s is a stereo sample\n", name);
return NULL; return NULL;
} }
@ -202,7 +193,7 @@ SND_LoadSound (sfx_t *s)
len = len * 2 * info.channels; len = len * 2 * info.channels;
} }
sc = Cache_Alloc (&s->cache, len + sizeof (sfxcache_t), s->name); sc = allocator (cache, len + sizeof (sfxcache_t), name);
if (!sc) if (!sc)
return NULL; return NULL;
@ -213,11 +204,18 @@ SND_LoadSound (sfx_t *s)
sc->width = info.width; sc->width = info.width;
sc->stereo = info.channels; sc->stereo = info.channels;
SND_ResampleSfx (s, sc->speed, sc->width, data + info.dataofs); SND_ResampleSfx (sc, sc->speed, sc->width, data + info.dataofs);
return sc; return sc;
} }
void
SND_CallbackLoad (struct cache_user_s *cache, cache_allocator_t allocator)
{
if (!SND_LoadSound (cache, cache->filename, allocator))
Sys_Error ("SND_CallbackLoad: load failed!\n");
}
/* WAV loading */ /* WAV loading */
byte *data_p; byte *data_p;
@ -300,7 +298,7 @@ SND_DumpChunks (void)
} }
wavinfo_t wavinfo_t
SND_GetWavinfo (char *name, byte * wav, int wavlength) SND_GetWavinfo (const char *name, byte * wav, int wavlength)
{ {
wavinfo_t info; wavinfo_t info;
int i; int i;

View File

@ -57,8 +57,6 @@ int *snd_p, snd_linear_count, snd_vol;
short *snd_out; short *snd_out;
void SND_WriteLinearBlastStereo16 (void); void SND_WriteLinearBlastStereo16 (void);
sfxcache_t *SND_LoadSound (sfx_t *s);
#ifndef USE_INTEL_ASM #ifndef USE_INTEL_ASM
void void
@ -239,7 +237,7 @@ SND_PaintChannels (int endtime)
continue; continue;
if (!ch->leftvol && !ch->rightvol) if (!ch->leftvol && !ch->rightvol)
continue; continue;
sc = SND_LoadSound (ch->sfx); sc = Cache_Get (&ch->sfx->cache);
if (!sc) if (!sc)
continue; continue;
@ -265,12 +263,15 @@ SND_PaintChannels (int endtime)
ch->pos = sc->loopstart; ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos; ch->end = ltime + sc->length - ch->pos;
} else { // channel just stopped } else { // channel just stopped
Cache_Release (&ch->sfx->cache);
ch->sfx = NULL; ch->sfx = NULL;
break; break;
} }
} }
} }
if (ch->sfx)
Cache_Release (&ch->sfx->cache);
} }
// transfer out according to DMA format // transfer out according to DMA format

View File

@ -541,6 +541,7 @@ typedef struct cache_system_s {
cache_system_t *Cache_TryAlloc (int size, qboolean nobottom); cache_system_t *Cache_TryAlloc (int size, qboolean nobottom);
void Cache_RealFree (cache_user_t *c); void Cache_RealFree (cache_user_t *c);
void *Cache_RealCheck (cache_user_t *c); void *Cache_RealCheck (cache_user_t *c);
void *Cache_RealAlloc (cache_user_t *c, int size, const char *name);
cache_system_t cache_head; cache_system_t cache_head;
int cache_writelock; int cache_writelock;
@ -884,13 +885,20 @@ Cache_RealCheck (cache_user_t *c)
return c->data; return c->data;
} }
void * void *
Cache_Alloc (cache_user_t *c, int size, const char *name) Cache_Alloc (cache_user_t *c, int size, const char *name)
{ {
cache_system_t *cs;
void *mem; void *mem;
CACHE_WRITE_LOCK; CACHE_WRITE_LOCK;
mem = Cache_RealAlloc (c, size, name);
CACHE_WRITE_UNLOCK;
return mem;
}
void *
Cache_RealAlloc (cache_user_t *c, int size, const char *name)
{
cache_system_t *cs;
if (c->data) if (c->data)
Sys_Error ("Cache_Alloc: already allocated"); Sys_Error ("Cache_Alloc: already allocated");
@ -914,9 +922,7 @@ Cache_Alloc (cache_user_t *c, int size, const char *name)
Sys_Error ("Cache_Alloc: out of memory"); Sys_Error ("Cache_Alloc: out of memory");
} }
mem = Cache_RealCheck (c); return Cache_RealCheck (c);
CACHE_WRITE_UNLOCK;
return mem;
} }
void void
@ -956,25 +962,100 @@ Cache_Profile (void)
CACHE_WRITE_UNLOCK; CACHE_WRITE_UNLOCK;
} }
/* void
Qalloc and friends Cache_Add (cache_user_t *c, const char *filename, cache_loader_t loader)
*/ {
CACHE_WRITE_LOCK;
size_t (*Qalloc_callback) (size_t size); if (c->data || c->filename || c->loader)
Sys_Error ("Cache_Add: cache item already exists!\n");
c->filename = strdup (filename);
if (!c->filename)
Sys_Error ("Cache_Add: strdup failed!\n");
c->loader = loader;
// c->loader (c, Cache_RealAlloc); // for debugging
CACHE_WRITE_UNLOCK;
}
void
Cache_Remove (cache_user_t *c)
{
CACHE_WRITE_LOCK;
if (!c->filename || !c->loader)
Sys_Error ("Cache_Remove: already removed!\n");
if (Cache_RealCheck (c))
Cache_RealFree (c);
free (c->filename);
c->filename = 0;
c->loader = 0;
CACHE_WRITE_UNLOCK;
}
void * void *
Qalloc (void *ptr, size_t size, unsigned modes) Cache_Get (cache_user_t *c)
{
void *mem;
CACHE_WRITE_LOCK;
mem = Cache_RealCheck (c);
if (!mem) {
c->loader (c, Cache_RealAlloc);
mem = Cache_RealCheck (c);
}
if (!mem)
Sys_Error ("Cache_Get: couldn't get cache!\n");
(((cache_system_t *)c->data) - 1)->readlock++;
CACHE_WRITE_UNLOCK;
return mem;
}
void
Cache_Release (cache_user_t *c)
{
int *readlock;
CACHE_WRITE_LOCK;
readlock = &(((cache_system_t *)c->data) - 1)->readlock;
if (!*readlock)
Sys_Error ("Cache_Release: already released!\n");
(*readlock)--;
// if (!*readlock)
// Cache_RealFree (c); // for debugging
CACHE_WRITE_UNLOCK;
}
/*
QA_alloc and friends
*/
size_t (*QA_alloc_callback) (size_t size);
void *
QA_alloc (void *ptr, size_t size, unsigned modes)
{ {
void *mem; void *mem;
if (modes & ~(_QA_MODEMASK | QA_ZEROED)) if (modes & ~(_QA_MODEMASK | QA_ZEROED))
Sys_Error ("Qalloc: bad modes field: %u\n", modes); Sys_Error ("QA_alloc: bad modes field: %u\n", modes);
if (size) { if (size) {
do { do {
if (ptr) { if (ptr) {
if (modes & QA_ZEROED) if (modes & QA_ZEROED)
Sys_Error ("Qalloc: Zeroing reallocated memory not yet supported\n"); Sys_Error ("QA_alloc: Zeroing reallocated memory not yet supported\n");
else else
mem = realloc (ptr, size); mem = realloc (ptr, size);
} else { } else {
@ -984,49 +1065,49 @@ Qalloc (void *ptr, size_t size, unsigned modes)
mem = malloc (size); mem = malloc (size);
} }
} while ((modes & _QA_MODEMASK) != QA_EARLYFAIL && !mem } while ((modes & _QA_MODEMASK) != QA_EARLYFAIL && !mem
&& Qalloc_callback && Qalloc_callback (size)); && QA_alloc_callback && QA_alloc_callback (size));
if (!mem && (modes & _QA_MODEMASK) == QA_NOFAIL) if (!mem && (modes & _QA_MODEMASK) == QA_NOFAIL)
Sys_Error ("Qalloc: could not allocate %d bytes!\n", size); Sys_Error ("QA_alloc: could not allocate %d bytes!\n", size);
return mem; return mem;
} else { } else {
if (!ptr) if (!ptr)
Sys_Error ("Qalloc: can't free a NULL pointers!\n"); Sys_Error ("QA_alloc: can't free a NULL pointers!\n");
free (ptr); free (ptr);
return 0; return 0;
} }
} }
void * void *
Qmalloc (size_t size) QA_malloc (size_t size)
{ {
return Qalloc (0, size, QA_NOFAIL); return QA_alloc (0, size, QA_NOFAIL);
} }
void * void *
Qcalloc (size_t nmemb, size_t size) QA_calloc (size_t nmemb, size_t size)
{ {
return Qalloc (0, nmemb * size, QA_NOFAIL | QA_ZEROED); return QA_alloc (0, nmemb * size, QA_NOFAIL | QA_ZEROED);
} }
void * void *
Qrealloc (void *ptr, size_t size) QA_realloc (void *ptr, size_t size)
{ {
return Qalloc (ptr, size, QA_NOFAIL); return QA_alloc (ptr, size, QA_NOFAIL);
} }
void void
Qfree (void *ptr) QA_free (void *ptr)
{ {
Qalloc (ptr, 0, QA_NOFAIL); QA_alloc (ptr, 0, QA_NOFAIL);
} }
char * char *
Qstrdup (const char *s) QA_strdup (const char *s)
{ {
char *mem; char *mem;
mem = Qmalloc (strlen (s) + 1); mem = QA_malloc (strlen (s) + 1);
strcpy (mem, s); strcpy (mem, s);
return mem; return mem;
} }