From 79ea1c7f6fd1fb296aaa195d9fd5ef3f5f257faa Mon Sep 17 00:00:00 2001 From: IonutParau Date: Tue, 19 May 2026 23:44:54 +0200 Subject: [PATCH] simplified the memory management --- src/main.c | 14 ++++++++++++-- src/neonucleus.c | 15 +++++++++++++++ src/neonucleus.h | 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 52862cf..3cf4281 100644 --- a/src/main.c +++ b/src/main.c @@ -500,6 +500,7 @@ typedef struct ne_memSand { char *buf; size_t used; size_t cap; + size_t active; } ne_memSand; void *ne_sandbox_alloc(void *state, void *memory, size_t oldSize, size_t newSize) { @@ -509,12 +510,16 @@ void *ne_sandbox_alloc(void *state, void *memory, size_t oldSize, size_t newSize newSize = ne_alignAlloc(newSize, NN_ALLOC_ALIGN); // never free - if(newSize == 0) return NULL; + if(newSize == 0) { + sand->active -= oldSize; + return NULL; + } if(memory == NULL) { if(sand->cap - sand->used < newSize) return NULL; // alloc new void *mem = sand->buf + sand->used; sand->used += newSize; + sand->active += newSize; return mem; } // realloc @@ -522,6 +527,7 @@ void *ne_sandbox_alloc(void *state, void *memory, size_t oldSize, size_t newSize if(sand->cap - sand->used < newSize) return NULL; void *mem = sand->buf + sand->used; sand->used += newSize; + sand->active += newSize; memcpy(mem, memory, oldSize); return mem; } @@ -570,6 +576,7 @@ int main(int argc, char **argv) { ne_memSand sand; sand.buf = NULL; + sand.active = 0; if(sandboxMem) { // 1 MiB pre-allocated to prevent erasing the free-list @@ -704,7 +711,7 @@ int main(int argc, char **argv) { ncl_mountKeyboard(scrstate, "mainKB"); // we assume server basically - nn_Computer *c = nn_createComputer(u, NULL, NULL, ramTotal, nn_defaultComponentLimits[tier-1] * 4, 256); + nn_Computer * volatile c = nn_createComputer(u, NULL, NULL, ramTotal, nn_defaultComponentLimits[tier-1] * 4, 256); nn_Environment cEnv = { .userdata = NULL, .handler = ne_env, @@ -995,5 +1002,8 @@ cleanup:; if(eepromPath != NULL) free(eepromCode); CloseWindow(); free(sand.buf); + if(sand.buf != NULL) { + printf("Leaked: %zu bytes\n", sand.active); + } return 0; } diff --git a/src/neonucleus.c b/src/neonucleus.c index 667678e..c4707c0 100644 --- a/src/neonucleus.c +++ b/src/neonucleus.c @@ -1074,6 +1074,7 @@ struct nn_Computer { nn_Universe *universe; nn_Environment env; nn_Lock *lock; + nn_refc_t refc; void *userdata; char *address; char *tmpaddress; @@ -1176,6 +1177,7 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char c->state = NN_BOOTUP; c->universe = universe; c->userdata = userdata; + c->refc = 1; c->lock = nn_createLock(ctx); if(c->lock == NULL) { @@ -1233,6 +1235,14 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char return c; } +void nn_retainComputer(nn_Computer *computer) { + nn_retainComputerN(computer, 1); +} + +void nn_retainComputerN(nn_Computer *computer, size_t n) { + nn_incRef(&computer->refc, n); +} + void nn_lockComputer(nn_Computer *computer) { nn_lock(&computer->universe->ctx, computer->lock); } @@ -1441,6 +1451,11 @@ void nn_beepComputerMorse(nn_Computer *computer, nn_MorseBeep beep) { } void nn_destroyComputer(nn_Computer *computer) { + nn_destroyComputerN(computer, 1); +} + +void nn_destroyComputerN(nn_Computer *computer, size_t n) { + if(!nn_decRef(&computer->refc, n)) return; nn_Context *ctx = &computer->universe->ctx; nn_stopComputer(computer); diff --git a/src/neonucleus.h b/src/neonucleus.h index fdbfc28..a435fed 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -456,8 +456,11 @@ typedef struct nn_Environment { // maxComponents and maxDevices determine how many components can be connected simultaneously to this computer, and how much device info can be // registered on this computer. nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char *address, size_t totalMemory, size_t maxComponents, size_t maxDevices); +void nn_retainComputer(nn_Computer *computer); +void nn_retainComputerN(nn_Computer *computer, size_t n); // Destroys the state, effectively shutting down the computer. void nn_destroyComputer(nn_Computer *computer); +void nn_destroyComputerN(nn_Computer *computer, size_t n); void nn_lockComputer(nn_Computer *computer); void nn_unlockComputer(nn_Computer *computer); // stops the computer if an architecture state is already present,