diff --git a/headers/private/kernel/heap.h b/headers/private/kernel/heap.h index 0f60cf4d14..329fc650e1 100644 --- a/headers/private/kernel/heap.h +++ b/headers/private/kernel/heap.h @@ -26,6 +26,10 @@ void *memalign(size_t alignment, size_t size); void deferred_free(void* block); +void* malloc_referenced(size_t size); +void* malloc_referenced_acquire(void* data); +void malloc_referenced_release(void* data); + status_t heap_init(addr_t heapBase, size_t heapSize); status_t heap_init_post_sem(); status_t heap_init_post_thread(); diff --git a/src/system/kernel/heap.cpp b/src/system/kernel/heap.cpp index f90e24aefe..4201d7ad6b 100644 --- a/src/system/kernel/heap.cpp +++ b/src/system/kernel/heap.cpp @@ -1273,3 +1273,40 @@ deferred_free(void* block) InterruptsSpinLocker _(sDeferredFreeListLock); sDeferredFreeList.Add(entry); } + + +void* +malloc_referenced(size_t size) +{ + int32* referencedData = (int32*)malloc(size + 4); + if (referencedData == NULL) + return NULL; + + *referencedData = 1; + + return referencedData + 1; +} + + +void* +malloc_referenced_acquire(void* data) +{ + if (data != NULL) { + int32* referencedData = (int32*)data - 1; + atomic_add(referencedData, 1); + } + + return data; +} + + +void +malloc_referenced_release(void* data) +{ + if (data == NULL) + return; + + int32* referencedData = (int32*)data - 1; + if (atomic_add(referencedData, -1) < 1) + free(referencedData); +}