mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
- 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:
parent
fa036c7c11
commit
e149094bd2
5 changed files with 177 additions and 68 deletions
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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,7 +157,7 @@ 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;
|
||||
|
@ -171,14 +167,9 @@ SND_LoadSound (sfx_t *s)
|
|||
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;
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -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
|
||||
|
|
131
libs/util/zone.c
131
libs/util/zone.c
|
@ -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;
|
||||
|
||||
|
@ -887,10 +888,17 @@ Cache_RealCheck (cache_user_t *c)
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue