From 2e7ec3979aec71f11c45b737b77d58978cbee7e2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 21 May 2016 03:27:51 -0700 Subject: Avoid using realloc in a number of places --- Alc/effects/chorus.c | 8 ++++---- Alc/effects/echo.c | 8 ++++---- Alc/effects/flanger.c | 8 ++++---- Alc/effects/reverb.c | 12 +++++++----- Alc/helpers.c | 5 ++++- Alc/vector.h | 4 +++- OpenAL32/Include/alBuffer.h | 1 + OpenAL32/alBuffer.c | 35 +++++++++++++++++++++++------------ OpenAL32/alSource.c | 4 +++- 9 files changed, 53 insertions(+), 32 deletions(-) diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index e1cbba2d..7877ff6f 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -57,7 +57,7 @@ typedef struct ALchorusState { static ALvoid ALchorusState_Destruct(ALchorusState *state) { - free(state->SampleBuffer[0]); + al_free(state->SampleBuffer[0]); state->SampleBuffer[0] = NULL; state->SampleBuffer[1] = NULL; ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); @@ -73,10 +73,10 @@ static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Dev if(maxlen != state->BufferLength) { - void *temp; - - temp = realloc(state->SampleBuffer[0], maxlen * sizeof(ALfloat) * 2); + void *temp = al_calloc(16, maxlen * sizeof(ALfloat) * 2); if(!temp) return AL_FALSE; + + al_free(state->SampleBuffer[0]); state->SampleBuffer[0] = temp; state->SampleBuffer[1] = state->SampleBuffer[0] + maxlen; diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index 0632a44d..163b6ecb 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -52,7 +52,7 @@ typedef struct ALechoState { static ALvoid ALechoState_Destruct(ALechoState *state) { - free(state->SampleBuffer); + al_free(state->SampleBuffer); state->SampleBuffer = NULL; ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } @@ -69,10 +69,10 @@ static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device) if(maxlen != state->BufferLength) { - void *temp; - - temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfloat)); + void *temp = al_calloc(16, maxlen * sizeof(ALfloat)); if(!temp) return AL_FALSE; + + al_free(state->SampleBuffer); state->SampleBuffer = temp; state->BufferLength = maxlen; } diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c index 7b55977e..f18b2b0f 100644 --- a/Alc/effects/flanger.c +++ b/Alc/effects/flanger.c @@ -57,7 +57,7 @@ typedef struct ALflangerState { static ALvoid ALflangerState_Destruct(ALflangerState *state) { - free(state->SampleBuffer[0]); + al_free(state->SampleBuffer[0]); state->SampleBuffer[0] = NULL; state->SampleBuffer[1] = NULL; ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); @@ -73,10 +73,10 @@ static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *D if(maxlen != state->BufferLength) { - void *temp; - - temp = realloc(state->SampleBuffer[0], maxlen * sizeof(ALfloat) * 2); + void *temp = al_calloc(16, maxlen * sizeof(ALfloat) * 2); if(!temp) return AL_FALSE; + + al_free(state->SampleBuffer[0]); state->SampleBuffer[0] = temp; state->SampleBuffer[1] = state->SampleBuffer[0] + maxlen; diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index 3f22b787..f8680d24 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -170,7 +170,7 @@ typedef struct ALreverbState { static ALvoid ALreverbState_Destruct(ALreverbState *State) { - free(State->SampleBuffer); + al_free(State->SampleBuffer); State->SampleBuffer = NULL; ALeffectState_Destruct(STATIC_CAST(ALeffectState,State)); } @@ -295,7 +295,6 @@ static ALboolean AllocLines(ALuint frequency, ALreverbState *State) { ALuint totalSamples, index; ALfloat length; - ALfloat *newBuffer = NULL; // All delay line lengths are calculated to accomodate the full range of // lengths given their respective paramters. @@ -352,10 +351,13 @@ static ALboolean AllocLines(ALuint frequency, ALreverbState *State) if(totalSamples != State->TotalSamples) { + ALfloat *newBuffer; + TRACE("New reverb buffer length: %u samples (%f sec)\n", totalSamples, totalSamples/(float)frequency); - newBuffer = realloc(State->SampleBuffer, sizeof(ALfloat) * totalSamples); - if(newBuffer == NULL) - return AL_FALSE; + newBuffer = al_calloc(16, sizeof(ALfloat) * totalSamples); + if(!newBuffer) return AL_FALSE; + + al_free(State->SampleBuffer); State->SampleBuffer = newBuffer; State->TotalSamples = totalSamples; } diff --git a/Alc/helpers.c b/Alc/helpers.c index 950a67bf..38a34939 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -759,9 +759,12 @@ ALboolean vector_reserve(char *ptr, size_t base_size, size_t obj_size, size_t ob /* Need to be explicit with the caller type's base size, because it * could have extra padding before the start of the array (that is, * sizeof(*vector_) may not equal base_size). */ - temp = realloc(*vecptr, base_size + obj_size*obj_count); + temp = al_calloc(16, base_size + obj_size*obj_count); if(temp == NULL) return AL_FALSE; + memcpy(((ALubyte*)temp)+base_size, ((ALubyte*)*vecptr)+base_size, + obj_size*old_size); + al_free(*vecptr); *vecptr = temp; (*vecptr)->Capacity = obj_count; (*vecptr)->Size = old_size; diff --git a/Alc/vector.h b/Alc/vector.h index cb64b5a9..5a0219c0 100644 --- a/Alc/vector.h +++ b/Alc/vector.h @@ -5,6 +5,8 @@ #include +#include "almalloc.h" + /* "Base" vector type, designed to alias with the actual vector types. */ typedef struct vector__s { size_t Capacity; @@ -27,7 +29,7 @@ typedef const _##N* const_##N; #define VECTOR_INIT(_x) do { (_x) = NULL; } while(0) #define VECTOR_INIT_STATIC() NULL -#define VECTOR_DEINIT(_x) do { free((_x)); (_x) = NULL; } while(0) +#define VECTOR_DEINIT(_x) do { al_free((_x)); (_x) = NULL; } while(0) /* Helper to increase a vector's reserve. Do not call directly. */ ALboolean vector_reserve(char *ptr, size_t base_size, size_t obj_size, size_t obj_count, ALboolean exact); diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index 4807dd16..351c81bc 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -80,6 +80,7 @@ typedef struct ALbuffer { enum FmtChannels FmtChannels; enum FmtType FmtType; + ALuint BytesAlloc; enum UserFmtChannels OriginalChannels; enum UserFmtType OriginalType; diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 8e2c5cf2..193ab44f 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -985,7 +985,6 @@ ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum FmtChannels DstChannels; enum FmtType DstType; ALuint64 newsize; - ALvoid *temp; if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE || (long)SrcChannels != (long)DstChannels) @@ -1007,13 +1006,25 @@ ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, return AL_INVALID_OPERATION; } - temp = realloc(ALBuf->data, (size_t)newsize); - if(!temp && newsize) + /* Round up to the next 16-byte multiple. This could reallocate only when + * increasing or the new size is less than half the current, but then the + * buffer's AL_SIZE would not be very reliable for accounting buffer memory + * usage, and reporting the real size could cause problems for apps that + * use AL_SIZE to try to get the buffer's play length. + */ + newsize = (newsize+15) & ~0xf; + if(newsize != ALBuf->BytesAlloc) { - WriteUnlock(&ALBuf->lock); - return AL_OUT_OF_MEMORY; + void *temp = al_calloc(16, (size_t)newsize); + if(!temp && newsize) + { + WriteUnlock(&ALBuf->lock); + return AL_OUT_OF_MEMORY; + } + al_free(ALBuf->data); + ALBuf->data = temp; + ALBuf->BytesAlloc = (ALuint)newsize; } - ALBuf->data = temp; if(data != NULL) ConvertData(ALBuf->data, (enum UserFmtType)DstType, data, SrcType, NewChannels, frames, align); @@ -1349,7 +1360,7 @@ ALbuffer *NewBuffer(ALCcontext *context) ALbuffer *buffer; ALenum err; - buffer = calloc(1, sizeof(ALbuffer)); + buffer = al_calloc(16, sizeof(ALbuffer)); if(!buffer) SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); RWLockInit(&buffer->lock); @@ -1361,7 +1372,7 @@ ALbuffer *NewBuffer(ALCcontext *context) { FreeThunkEntry(buffer->id); memset(buffer, 0, sizeof(ALbuffer)); - free(buffer); + al_free(buffer); SET_ERROR_AND_RETURN_VALUE(context, err, NULL); } @@ -1374,10 +1385,10 @@ void DeleteBuffer(ALCdevice *device, ALbuffer *buffer) RemoveBuffer(device, buffer->id); FreeThunkEntry(buffer->id); - free(buffer->data); + al_free(buffer->data); memset(buffer, 0, sizeof(*buffer)); - free(buffer); + al_free(buffer); } @@ -1394,10 +1405,10 @@ ALvoid ReleaseALBuffers(ALCdevice *device) ALbuffer *temp = device->BufferMap.array[i].value; device->BufferMap.array[i].value = NULL; - free(temp->data); + al_free(temp->data); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALbuffer)); - free(temp); + al_free(temp); } } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a0e40c1d..22774fa4 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2268,14 +2268,16 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) newcount = context->MaxVoices << 1; if(newcount > 0) - temp = realloc(context->Voices, newcount * sizeof(context->Voices[0])); + temp = al_malloc(16, newcount * sizeof(context->Voices[0])); if(!temp) { UnlockContext(context); SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } + memcpy(temp, context->Voices, context->MaxVoices * sizeof(temp[0])); memset(&temp[context->MaxVoices], 0, (newcount-context->MaxVoices) * sizeof(temp[0])); + al_free(context->Voices); context->Voices = temp; context->MaxVoices = newcount; } -- cgit v1.2.3