Removed SDL_FreeTemporaryMemory()
This was just causing confusion and anxiety. SDL temporary memory will be automatically freed on the main thread when processing events and on other threads when it ages out after a second. The application can free it directly by calling SDL_ClaimTemporaryMemory() to get ownership of the pointer, if necessary.
This commit is contained in:
@@ -130,7 +130,6 @@ SDL3_0.0.0 {
|
||||
SDL_FlushEvent;
|
||||
SDL_FlushEvents;
|
||||
SDL_FlushRenderer;
|
||||
SDL_FreeTemporaryMemory;
|
||||
SDL_GDKSuspendComplete;
|
||||
SDL_GL_CreateContext;
|
||||
SDL_GL_DestroyContext;
|
||||
|
||||
@@ -155,7 +155,6 @@
|
||||
#define SDL_FlushEvent SDL_FlushEvent_REAL
|
||||
#define SDL_FlushEvents SDL_FlushEvents_REAL
|
||||
#define SDL_FlushRenderer SDL_FlushRenderer_REAL
|
||||
#define SDL_FreeTemporaryMemory SDL_FreeTemporaryMemory_REAL
|
||||
#define SDL_GDKSuspendComplete SDL_GDKSuspendComplete_REAL
|
||||
#define SDL_GL_CreateContext SDL_GL_CreateContext_REAL
|
||||
#define SDL_GL_DestroyContext SDL_GL_DestroyContext_REAL
|
||||
|
||||
@@ -175,7 +175,6 @@ SDL_DYNAPI_PROC(int,SDL_FlushAudioStream,(SDL_AudioStream *a),(a),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_FlushEvent,(Uint32 a),(a),)
|
||||
SDL_DYNAPI_PROC(void,SDL_FlushEvents,(Uint32 a, Uint32 b),(a,b),)
|
||||
SDL_DYNAPI_PROC(int,SDL_FlushRenderer,(SDL_Renderer *a),(a),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_FreeTemporaryMemory,(const void *a),(a),)
|
||||
SDL_DYNAPI_PROC(void,SDL_GDKSuspendComplete,(void),(),)
|
||||
SDL_DYNAPI_PROC(SDL_GLContext,SDL_GL_CreateContext,(SDL_Window *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GL_DestroyContext,(SDL_GLContext a),(a),return)
|
||||
|
||||
@@ -74,6 +74,7 @@ static Uint32 SDL_userevents = SDL_EVENT_USER;
|
||||
typedef struct SDL_TemporaryMemory
|
||||
{
|
||||
void *memory;
|
||||
Uint64 timestamp;
|
||||
struct SDL_TemporaryMemory *prev;
|
||||
struct SDL_TemporaryMemory *next;
|
||||
} SDL_TemporaryMemory;
|
||||
@@ -105,11 +106,13 @@ static struct
|
||||
SDL_EventEntry *free;
|
||||
} SDL_EventQ = { NULL, SDL_FALSE, { 0 }, 0, NULL, NULL, NULL };
|
||||
|
||||
static void SDL_FreeTemporaryMemory(void);
|
||||
|
||||
static void SDL_CleanupTemporaryMemory(void *data)
|
||||
{
|
||||
SDL_TemporaryMemoryState *state = (SDL_TemporaryMemoryState *)data;
|
||||
|
||||
SDL_FreeTemporaryMemory(NULL);
|
||||
SDL_FreeTemporaryMemory();
|
||||
SDL_free(state);
|
||||
}
|
||||
|
||||
@@ -260,6 +263,23 @@ static void SDL_TransferTemporaryMemoryFromEvent(SDL_EventEntry *event)
|
||||
event->memory = NULL;
|
||||
}
|
||||
|
||||
static void SDL_CollectTemporaryMemory(SDL_TemporaryMemoryState *state, Uint64 now)
|
||||
{
|
||||
// Temporary memory will age out and be collected after 1 second
|
||||
const int TEMPORARY_MEMORY_COLLECT_TIME_MS = 1000;
|
||||
|
||||
while (state->head) {
|
||||
SDL_TemporaryMemory *entry = state->head;
|
||||
|
||||
if ((now - entry->timestamp) < TEMPORARY_MEMORY_COLLECT_TIME_MS) {
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_UnlinkTemporaryMemoryEntry(state, entry);
|
||||
SDL_FreeTemporaryMemoryEntry(state, entry, SDL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void *SDL_FreeLater(void *memory)
|
||||
{
|
||||
SDL_TemporaryMemoryState *state;
|
||||
@@ -276,12 +296,16 @@ void *SDL_FreeLater(void *memory)
|
||||
return memory; // this is now a leak, but you probably have bigger problems if malloc failed.
|
||||
}
|
||||
|
||||
Uint64 now = SDL_GetTicks();
|
||||
SDL_CollectTemporaryMemory(state, now);
|
||||
|
||||
SDL_TemporaryMemory *entry = (SDL_TemporaryMemory *)SDL_malloc(sizeof(*entry));
|
||||
if (!entry) {
|
||||
return memory; // this is now a leak, but you probably have bigger problems if malloc failed. We could probably pool up and reuse entries, though.
|
||||
}
|
||||
|
||||
entry->memory = memory;
|
||||
entry->timestamp = now;
|
||||
|
||||
SDL_LinkTemporaryMemoryEntry(state, entry);
|
||||
|
||||
@@ -317,7 +341,7 @@ void *SDL_ClaimTemporaryMemory(const void *mem)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SDL_FreeTemporaryMemory(const void *mem)
|
||||
void SDL_FreeTemporaryMemory(void)
|
||||
{
|
||||
SDL_TemporaryMemoryState *state;
|
||||
|
||||
@@ -326,19 +350,11 @@ void SDL_FreeTemporaryMemory(const void *mem)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mem) {
|
||||
SDL_TemporaryMemory *entry = SDL_GetTemporaryMemoryEntry(state, mem);
|
||||
if (entry) {
|
||||
SDL_UnlinkTemporaryMemoryEntry(state, entry);
|
||||
SDL_FreeTemporaryMemoryEntry(state, entry, SDL_TRUE);
|
||||
}
|
||||
} else {
|
||||
while (state->head) {
|
||||
SDL_TemporaryMemory *entry = state->head;
|
||||
while (state->head) {
|
||||
SDL_TemporaryMemory *entry = state->head;
|
||||
|
||||
SDL_UnlinkTemporaryMemoryEntry(state, entry);
|
||||
SDL_FreeTemporaryMemoryEntry(state, entry, SDL_TRUE);
|
||||
}
|
||||
SDL_UnlinkTemporaryMemoryEntry(state, entry);
|
||||
SDL_FreeTemporaryMemoryEntry(state, entry, SDL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,7 +878,7 @@ void SDL_StopEventLoop(void)
|
||||
SDL_EventQ.free = NULL;
|
||||
SDL_AtomicSet(&SDL_sentinel_pending, 0);
|
||||
|
||||
SDL_FreeTemporaryMemory(NULL);
|
||||
SDL_FreeTemporaryMemory();
|
||||
|
||||
/* Clear disabled event state */
|
||||
for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
|
||||
@@ -1159,7 +1175,7 @@ static void SDL_PumpEventsInternal(SDL_bool push_sentinel)
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
||||
/* Free old event memory */
|
||||
SDL_FreeTemporaryMemory(NULL);
|
||||
SDL_FreeTemporaryMemory();
|
||||
|
||||
/* Release any keys held down from last frame */
|
||||
SDL_ReleaseAutoReleaseKeys();
|
||||
|
||||
Reference in New Issue
Block a user