diff options
| author | John "Lameguy" Wilbert Villamor <lameguy64@gmail.com> | 2022-10-19 17:57:06 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-19 17:57:06 +0800 |
| commit | e08a3d9366f8ca14a76b3dd569dac1fb9f569748 (patch) | |
| tree | 33654513b0b184c27f8035dbc405640fcbeb44ab /libpsn00b/libc/malloc.c | |
| parent | c4a2533d21dfd05cde841ea48c67b05e0e6a853f (diff) | |
| parent | 9b2ffc6078a850b7d354855cca7622090b41f30c (diff) | |
| download | psn00bsdk-e08a3d9366f8ca14a76b3dd569dac1fb9f569748.tar.gz | |
Merge pull request #59 from spicyjpeg/psxmdec
IRQ handler fix, .STR playback example, multiple library builds (v0.21)
Diffstat (limited to 'libpsn00b/libc/malloc.c')
| -rw-r--r-- | libpsn00b/libc/malloc.c | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/libpsn00b/libc/malloc.c b/libpsn00b/libc/malloc.c index 9d538cd..e9fd6f4 100644 --- a/libpsn00b/libc/malloc.c +++ b/libpsn00b/libc/malloc.c @@ -9,6 +9,8 @@ * latter being built on top of the former. This makes it possible to override * only InitHeap() and sbrk() while still using the default allocator, or * override malloc()/realloc()/free() while using the default heap manager. + * Custom allocators should call TrackHeapUsage() to let the heap manager know + * how much memory is allocated at a given time. */ #include <stddef.h> @@ -25,11 +27,13 @@ typedef struct _BlockHeader { size_t size; } BlockHeader; -/* Data */ +/* Internal globals */ static void *_heap_start, *_heap_end, *_heap_limit; -static void *_alloc_start = 0; -static BlockHeader *_alloc_head = 0, *_alloc_tail = 0; +static size_t _heap_alloc, _heap_alloc_max; + +static void *_alloc_start; +static BlockHeader *_alloc_head, *_alloc_tail; /* Heap management API */ @@ -37,6 +41,13 @@ __attribute__((weak)) void InitHeap(void *addr, size_t size) { _heap_start = addr; _heap_end = addr; _heap_limit = (void *) ((uintptr_t) addr + size); + + _heap_alloc = 0; + _heap_alloc_max = 0; + + _alloc_start = addr; + _alloc_head = 0; + _alloc_tail = 0; } __attribute__((weak)) void *sbrk(ptrdiff_t incr) { @@ -50,6 +61,22 @@ __attribute__((weak)) void *sbrk(ptrdiff_t incr) { return old_end; } +__attribute__((weak)) void TrackHeapUsage(ptrdiff_t alloc_incr) { + _heap_alloc += alloc_incr; + + if (_heap_alloc > _heap_alloc_max) + _heap_alloc_max = _heap_alloc; +} + +__attribute__((weak)) void GetHeapUsage(HeapUsage *usage) { + usage->total = _heap_limit - _heap_start; + usage->heap = _heap_end - _heap_start; + usage->stack = _heap_limit - _heap_end; + + usage->alloc = _heap_alloc; + usage->alloc_max = _heap_alloc_max; +} + /* Memory allocator */ static BlockHeader *_find_fit(BlockHeader *head, size_t size) { @@ -69,13 +96,16 @@ static BlockHeader *_find_fit(BlockHeader *head, size_t size) { } __attribute__((weak)) void *malloc(size_t size) { + if (!size) + return 0; + size_t _size = _align(size + sizeof(BlockHeader), 8); // Nothing's initialized yet? Let's just initialize the bottom of our heap, // flag it as allocated. if (!_alloc_head) { - if (!_alloc_start) - _alloc_start = sbrk(0); + //if (!_alloc_start) + //_alloc_start = sbrk(0); BlockHeader *new = (BlockHeader *) sbrk(_size); if (!new) @@ -89,6 +119,8 @@ __attribute__((weak)) void *malloc(size_t size) { _alloc_head = new; _alloc_tail = new; + + TrackHeapUsage(size); return ptr; } @@ -106,6 +138,8 @@ __attribute__((weak)) void *malloc(size_t size) { _alloc_head->prev = new; _alloc_head = new; + + TrackHeapUsage(size); return ptr; } @@ -122,6 +156,8 @@ __attribute__((weak)) void *malloc(size_t size) { (new->next)->prev = new; prev->next = new; + + TrackHeapUsage(size); return ptr; } @@ -138,6 +174,8 @@ __attribute__((weak)) void *malloc(size_t size) { _alloc_tail->next = new; _alloc_tail = new; + + TrackHeapUsage(size); return ptr; } @@ -153,13 +191,14 @@ __attribute__((weak)) void *realloc(void *ptr, size_t size) { if (!ptr) return malloc(size); - size_t _size = _align(size + sizeof(BlockHeader), 8); - + size_t _size = _align(size + sizeof(BlockHeader), 8); BlockHeader *prev = (BlockHeader *) ((uintptr_t) ptr - sizeof(BlockHeader)); // New memory block shorter? if (prev->size >= _size) { + TrackHeapUsage(size - prev->size); prev->size = _size; + if (!prev->next) sbrk((ptr - sbrk(0)) + _size); @@ -172,12 +211,14 @@ __attribute__((weak)) void *realloc(void *ptr, size_t size) { if (!new) return 0; + TrackHeapUsage(size - prev->size); prev->size = _size; return ptr; } // Do we have free memory after it? if (((prev->next)->ptr - ptr) > _size) { + TrackHeapUsage(size - prev->size); prev->size = _size; return ptr; } @@ -209,11 +250,13 @@ __attribute__((weak)) void free(void *ptr) { sbrk(-size); } + TrackHeapUsage(-(_alloc_head->size)); return; } // Finding the proper block BlockHeader *cur = _alloc_head; + for (cur = _alloc_head; ptr != cur->ptr; cur = cur->next) { if (!cur->next) return; @@ -221,15 +264,16 @@ __attribute__((weak)) void free(void *ptr) { if (cur->next) { // In the middle, just unlink it - cur->next->prev = cur->prev; + (cur->next)->prev = cur->prev; } else { // At the end, shrink heap - _alloc_tail = cur->prev; - void *top = sbrk(0); size_t size = (top - (cur->prev)->ptr) - (cur->prev)->size; + _alloc_tail = cur->prev; + sbrk(-size); } + TrackHeapUsage(-(cur->size)); (cur->prev)->next = cur->next; } |
