// 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 #include 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); // The dvxMalloc/dvxFree functions are passthrough wrappers. // Header-based per-allocation tracking was attempted but is unsafe // in the DXE3 environment (loader-compiled code like stb_ds uses // libc malloc while DXE code would use the wrapped version). // Per-app memory is tracked via DPMI snapshots instead. #endif // DVX_MEM_H