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:
Sam Lantinga
2024-07-22 07:18:00 -07:00
parent 70c1012e8c
commit ff1d351390
6 changed files with 34 additions and 88 deletions

View File

@@ -130,7 +130,6 @@ SDL3_0.0.0 {
SDL_FlushEvent;
SDL_FlushEvents;
SDL_FlushRenderer;
SDL_FreeTemporaryMemory;
SDL_GDKSuspendComplete;
SDL_GL_CreateContext;
SDL_GL_DestroyContext;

View File

@@ -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

View File

@@ -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)

View File

@@ -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();