87 lines
2.6 KiB
C
87 lines
2.6 KiB
C
|
// Copyright (c) 2025, Zak Fenton
|
||
|
// Zak Fenton's libc is licensed under the Mulan PSL v2. You can use this
|
||
|
// software according to the terms and conditions of the Mulan PSL v2.
|
||
|
// You may obtain a copy of Mulan PSL v2 at:
|
||
|
// http://license.coscl.org.cn/MulanPSL2
|
||
|
// THIS SOFTWARE IS PROVIDED ON AN “AS IS” BASIS, WITHOUT warranties of
|
||
|
// any kind, either express or implied, including but not limited to
|
||
|
// non-infringement, merchantability or fit for a particular purpose.
|
||
|
// See the Mulan PSL v2 for more details.
|
||
|
|
||
|
#include <memory.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <syscalls.h>
|
||
|
#include "elmalloc.h"
|
||
|
#include "internal.h"
|
||
|
|
||
|
elmm_t _libc_mm;
|
||
|
elmm_sbrk_data_t _libc_sbrkdata;
|
||
|
|
||
|
#define SIMGC_SYSMALLOC(x) elmm_malloc(&_libc_mm, x)
|
||
|
#define SIMGC_FREE(x) elmm_free(&_libc_mm, x)
|
||
|
#define SIMGC_IMPLEMENTATION
|
||
|
#include "simgc.h"
|
||
|
|
||
|
simgc_t _libc_gc;
|
||
|
simgc_thread_t* _libc_gcmainthread;
|
||
|
|
||
|
void _libc_malloc_init(void* stackptr) {
|
||
|
// Initialising the memory manager is currently a bit of work, but in
|
||
|
// theory should pay off as the memory manager code is easy to fine
|
||
|
// tune and adapt for more specialised allocators.
|
||
|
_libc_sbrkdata.func = (void*)(&sbrk); // Hooking it straight to the syscall should work, the userdata argument will be ignored
|
||
|
_libc_sbrkdata.max = 1024 * 1024 * 8;
|
||
|
_libc_sbrkdata.onlyChunk = NULL;
|
||
|
_libc_sbrkdata.udata = NULL;
|
||
|
_libc_mm.bigchunkMinimum = 1024 * 1024;
|
||
|
_libc_mm.bigchunkGranularity = 1024;
|
||
|
_libc_mm.initialised = false;
|
||
|
_libc_mm.lockFunction = NULL;
|
||
|
_libc_mm.bigchunkData = &_libc_sbrkdata;
|
||
|
_libc_mm.bigchunkFunction = &elmm_bigchunk_sbrk;
|
||
|
if (!elmm_init(&_libc_mm)) {
|
||
|
const char* err = "ERROR: Failed to initialise memory manager!\n";
|
||
|
write(2, err, strlen(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
if (!elmm_growheap(&_libc_mm, 1024*1024*4)) {
|
||
|
printf("Growheap failed.\n");
|
||
|
} else {
|
||
|
printf("Growheap success!\n");
|
||
|
}
|
||
|
simgc_init(&_libc_gc);
|
||
|
_libc_gcmainthread = simgc_begin_inner(&_libc_gc, stackptr);
|
||
|
}
|
||
|
|
||
|
void _libc_malloc_finish() {
|
||
|
simgc_end_inner(_libc_gcmainthread);
|
||
|
simgc_reclaim(&_libc_gc);
|
||
|
}
|
||
|
|
||
|
void* _libc_gcalloc(size_t sz) {
|
||
|
return simgc_alloc(&_libc_gc, sz);
|
||
|
}
|
||
|
|
||
|
void* malloc(size_t sz) {
|
||
|
return elmm_malloc(&_libc_mm, sz);
|
||
|
}
|
||
|
|
||
|
void free(void* mem) {
|
||
|
return elmm_free(&_libc_mm, mem);
|
||
|
}
|
||
|
|
||
|
void* calloc(size_t n, size_t sz) {
|
||
|
/* TODO: check for overflow of n * sz? Probably not a problem IRL (may
|
||
|
* have been more of a thing back in the 16-bit era but I guess math
|
||
|
* overflow is not an important issue on 64-bit or even 32-bit memory
|
||
|
* allocator calls)
|
||
|
*/
|
||
|
return elmm_calloc(&_libc_mm, n, sz);
|
||
|
}
|
||
|
|
||
|
void* realloc(void* mem, size_t sz) {
|
||
|
return elmm_realloc(&_libc_mm, mem, sz);
|
||
|
}
|
||
|
|