- 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);
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
{
void *data;
char *filename;
cache_loader_t loader;
} cache_user_t;
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_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 */
#define QA_NOFAIL 1
#define QA_LATEFAIL 2
@ -147,12 +158,13 @@ void Cache_Report (void);
/* Flags, OR them with the mode */
#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 *Qmalloc (size_t size);
void *Qcalloc (size_t nmemb, size_t size);
void *Qrealloc (void *ptr, size_t size);
void Qfree (void *ptr);
void *QA_alloc (void *ptr, size_t size, unsigned modes);
void *QA_malloc (size_t size);
void *QA_calloc (size_t nmemb, size_t size);
void *QA_realloc (void *ptr, size_t size);
void QA_free (void *ptr);
char *QA_strdup (const char *s);
#endif // __zone_h

View File

@ -59,9 +59,9 @@ void SND_StopAllSoundsC (void);
void SND_Update_ (void);
sfx_t *SND_PrecacheSound (const char *name);
sfxcache_t *SND_LoadSound (sfx_t *s);
void SND_ClearBuffer (void);
void SND_PaintChannels (int endtime);
void SND_CallbackLoad (struct cache_user_s *cache, cache_allocator_t allocator);
void SND_Init_Cvars ();
@ -331,6 +331,7 @@ SND_FindName (const char *name)
sfx = &known_sfx[i];
strcpy (sfx->name, name);
Cache_Add (&sfx->cache, name, SND_CallbackLoad);
num_sfx++;
@ -360,8 +361,10 @@ SND_PrecacheSound (const char *name)
sfx = SND_FindName (name);
// cache it in
if (precache->int_val)
SND_LoadSound (sfx);
if (precache->int_val) {
Cache_Get (&sfx->cache);
Cache_Release (&sfx->cache);
}
return sfx;
}
@ -417,7 +420,6 @@ SND_Spatialize (channel_t *ch)
int phase; // in samples
vec_t lscale, rscale, scale;
vec3_t source_vec;
sfx_t *snd;
// anything coming from the view entity will always be full volume
if (ch->entnum == *plugin_info_snd_render_data.viewentity) {
@ -428,7 +430,6 @@ SND_Spatialize (channel_t *ch)
}
// calculate stereo seperation and distance attenuation
snd = ch->sfx;
VectorSubtract (ch->origin, listener_origin, source_vec);
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
// new channel
sc = SND_LoadSound (sfx);
sc = Cache_Get (&sfx->cache);
if (!sc) {
target_chan->sfx = NULL;
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->pos = 0.0;
target_chan->end = paintedtime + sc->length;
Cache_Release (&sfx->cache);
// 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
@ -613,12 +615,13 @@ SND_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss = &channels[total_channels];
total_channels++;
sc = SND_LoadSound (sfx);
sc = Cache_Get (&sfx->cache);
if (!sc)
return;
if (sc->loopstart == -1) {
Con_Printf ("Sound %s not looped\n", sfx->name);
Cache_Release (&sfx->cache);
return;
}
@ -627,6 +630,7 @@ SND_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss->master_vol = vol;
ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist;
ss->end = paintedtime + sc->length;
Cache_Release (&sfx->cache);
SND_Spatialize (ss);
ss->oldphase = ss->phase;
@ -891,10 +895,20 @@ SND_SoundList (void)
sfx_t *sfx;
sfxcache_t *sc;
int size, total;
int load;
if (Cmd_Argc() >= 2 && !strcmp (Cmd_Argv (1), "known"))
load = 1;
else
load = 0;
total = 0;
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)
continue;
size = sc->length * sc->width * (sc->stereo + 1);
@ -904,6 +918,9 @@ SND_SoundList (void)
else
Con_Printf (" ");
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);
}

View File

@ -46,25 +46,21 @@
int cache_full_cycle;
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
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 srcsample;
float stepscale;
int i;
int sample, samplefrac, fracstep;
sfxcache_t *sc;
short *is, *os;
unsigned char *ib, *ob;
sc = Cache_Check (&sfx->cache);
if (!sc)
return;
is = (short *) data;
os = (short *) sc->data;
ib = data;
@ -161,24 +157,19 @@ SND_ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte * data)
//=============================================================================
sfxcache_t *
SND_LoadSound (sfx_t *s)
SND_LoadSound (cache_user_t *cache, const char *name, cache_allocator_t allocator)
{
char namebuffer[256];
byte *data;
wavinfo_t info;
int len;
float stepscale;
char namebuffer[256];
byte *data;
wavinfo_t info;
int len;
float stepscale;
sfxcache_t *sc;
byte stackbuf[1 * 1024]; // avoid dirtying the cache heap
// see if still in memory
sc = Cache_Check (&s->cache);
if (sc)
return sc;
byte stackbuf[1 * 1024]; // avoid dirtying the cache heap
// load it in
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));
@ -187,9 +178,9 @@ SND_LoadSound (sfx_t *s)
return NULL;
}
info = SND_GetWavinfo (s->name, data, com_filesize);
info = SND_GetWavinfo (name, data, com_filesize);
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;
}
@ -202,7 +193,7 @@ SND_LoadSound (sfx_t *s)
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)
return NULL;
@ -213,11 +204,18 @@ SND_LoadSound (sfx_t *s)
sc->width = info.width;
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;
}
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 */
byte *data_p;
@ -300,7 +298,7 @@ SND_DumpChunks (void)
}
wavinfo_t
SND_GetWavinfo (char *name, byte * wav, int wavlength)
SND_GetWavinfo (const char *name, byte * wav, int wavlength)
{
wavinfo_t info;
int i;

View File

@ -57,8 +57,6 @@ int *snd_p, snd_linear_count, snd_vol;
short *snd_out;
void SND_WriteLinearBlastStereo16 (void);
sfxcache_t *SND_LoadSound (sfx_t *s);
#ifndef USE_INTEL_ASM
void
@ -239,7 +237,7 @@ SND_PaintChannels (int endtime)
continue;
if (!ch->leftvol && !ch->rightvol)
continue;
sc = SND_LoadSound (ch->sfx);
sc = Cache_Get (&ch->sfx->cache);
if (!sc)
continue;
@ -265,12 +263,15 @@ SND_PaintChannels (int endtime)
ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos;
} else { // channel just stopped
Cache_Release (&ch->sfx->cache);
ch->sfx = NULL;
break;
}
}
}
if (ch->sfx)
Cache_Release (&ch->sfx->cache);
}
// 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);
void Cache_RealFree (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;
int cache_writelock;
@ -884,13 +885,20 @@ Cache_RealCheck (cache_user_t *c)
return c->data;
}
void *
void *
Cache_Alloc (cache_user_t *c, int size, const char *name)
{
cache_system_t *cs;
void *mem;
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)
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");
}
mem = Cache_RealCheck (c);
CACHE_WRITE_UNLOCK;
return mem;
return Cache_RealCheck (c);
}
void
@ -956,25 +962,100 @@ Cache_Profile (void)
CACHE_WRITE_UNLOCK;
}
/*
Qalloc and friends
*/
void
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 *
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;
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) {
do {
if (ptr) {
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
mem = realloc (ptr, size);
} else {
@ -984,49 +1065,49 @@ Qalloc (void *ptr, size_t size, unsigned modes)
mem = malloc (size);
}
} 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)
Sys_Error ("Qalloc: could not allocate %d bytes!\n", size);
Sys_Error ("QA_alloc: could not allocate %d bytes!\n", size);
return mem;
} else {
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);
return 0;
}
}
void *
Qmalloc (size_t size)
QA_malloc (size_t size)
{
return Qalloc (0, size, QA_NOFAIL);
return QA_alloc (0, size, QA_NOFAIL);
}
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 *
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
Qfree (void *ptr)
QA_free (void *ptr)
{
Qalloc (ptr, 0, QA_NOFAIL);
QA_alloc (ptr, 0, QA_NOFAIL);
}
char *
Qstrdup (const char *s)
QA_strdup (const char *s)
{
char *mem;
mem = Qmalloc (strlen (s) + 1);
mem = QA_malloc (strlen (s) + 1);
strcpy (mem, s);
return mem;
}