DVX_GUI/core/dvxMem.h

48 lines
1.9 KiB
C

// dvxMem.h -- Per-app memory tracking for DVX
//
// REQUIRED: Every .c file compiled into a DXE (library, widget, shell,
// or app) MUST include this header AFTER all system includes. This
// ensures every malloc/free/calloc/realloc call goes through the
// tracking wrappers, maintaining pointer consistency.
//
// The implementation (dvxPlatformDos.c) does NOT include this header,
// so its dvxMalloc/dvxFree/dvxCalloc/dvxRealloc call the real libc
// functions with no recursion.
//
// How it works:
// 1. dvxMalloc prepends a 16-byte header (magic, appId, size) to
// each allocation and returns a pointer past the header.
// 2. dvxFree checks the magic value at ptr-16. If it matches, the
// header is valid and the allocation is tracked. If not, the
// pointer came from code outside DVX (libc internals, loader)
// and is passed through to the real free() unchanged.
// 3. The appId in the header comes from *dvxMemAppIdPtr, which the
// shell points at ctx->currentAppId.
//
// The magic check makes cross-boundary frees safe: if DXE code frees
// a pointer allocated by libc (e.g. from strdup, stb_ds internals),
// dvxFree detects the missing header and falls through to real free.
#ifndef DVX_MEM_H
#define DVX_MEM_H
#include <stdlib.h>
extern int32_t *dvxMemAppIdPtr;
void *dvxMalloc(size_t size);
void *dvxCalloc(size_t nmemb, size_t size);
void *dvxRealloc(void *ptr, size_t size);
void dvxFree(void *ptr);
void dvxMemSnapshotLoad(int32_t appId);
uint32_t dvxMemGetAppUsage(int32_t appId);
void dvxMemResetApp(int32_t appId);
// Redirect standard allocator calls to tracking wrappers.
// This MUST appear after <stdlib.h> so the real prototypes exist.
#define malloc(s) dvxMalloc(s)
#define calloc(n, s) dvxCalloc((n), (s))
#define realloc(p, s) dvxRealloc((p), (s))
#define free(p) dvxFree(p)
#endif // DVX_MEM_H