Add calloc, realloc, memmove. Sync klibc and libc

This commit is contained in:
Mathieu Maret 2024-03-30 20:56:46 +01:00 committed by Mathieu Maret
parent 946c47a988
commit bd25bb8478
4 changed files with 75 additions and 13 deletions

View File

@ -102,6 +102,7 @@ screenshot: ## Take a screenshot of the qemu window
clean: clean:
$(RM) kernel $(asmobj) $(gasmobj) $(cobj) $(deps) $(cinc) fd.iso kernel.debug kernel.map $(docobj) $(RM) kernel $(asmobj) $(gasmobj) $(cobj) $(deps) $(cinc) fd.iso kernel.debug kernel.map $(docobj)
$(RM) -r isodir $(RM) -r isodir
$(MAKE) -C userspace clean
.PHONY: .PHONY:
userspace screenshot userspace screenshot

View File

@ -37,8 +37,8 @@ int vprintf(const char *format, va_list ap) __attribute__ ((__format__ (printf,
int printf(const char *format, ...) __attribute__ ((__format__ (printf, 1, 2))); int printf(const char *format, ...) __attribute__ ((__format__ (printf, 1, 2)));
// Could be used after malloc is available // Could be used after malloc is available
int asprintf(char **strp, const char *fmt, ...); int asprintf(char **strp, const char *fmt, ...) __attribute__ ((__format__ (printf, 2, 3)));
int vasprintf(char **strp, const char *fmt, va_list ap); int vasprintf(char **strp, const char *fmt, va_list ap) __attribute__ ((__format__ (printf, 2, 0)));
/* /*
* Dummy printk for disabled debugging statements to use whilst maintaining * Dummy printk for disabled debugging statements to use whilst maintaining

View File

@ -80,6 +80,16 @@ void *memcpy(void *dst0, const void *src0, size_t len0)
#endif #endif
} }
void *memmove(void *dst, const void *src, size_t n)
{
char *dstChar = dst;
const char *srcChar = src;
for (size_t i = 0; i < n; i++) {
*(dstChar++) = *(srcChar++);
}
return dst;
}
void *memset(void *src, int c, size_t n) void *memset(void *src, int c, size_t n)
{ {
for (char *ptr = (char *)src; n > 0; n--, ptr++) { for (char *ptr = (char *)src; n > 0; n--, ptr++) {
@ -602,20 +612,25 @@ struct heapBlock {
static struct heapBlock *heapBlkList = NULL; static struct heapBlock *heapBlkList = NULL;
struct heapBlock *findFreeBlock(size_t size){ static struct heapBlock *findFreeBlock(size_t size)
struct heapBlock *cur = NULL; {
struct heapBlock *cur = NULL;
struct heapBlock *found = NULL; struct heapBlock *found = NULL;
int idx; int idx;
list_foreach(heapBlkList, cur, idx){
if(cur->size >= size && cur->free){ list_foreach(heapBlkList, cur, idx)
{
if (cur->size >= size && cur->free) {
found = cur; found = cur;
break; break;
} }
} }
return found; return found;
} }
struct heapBlock *allocNewBlock(size_t size) { static struct heapBlock *allocNewBlock(size_t size)
{
struct heapBlock *blk = sbrk(size + sizeof(struct heapBlock)); struct heapBlock *blk = sbrk(size + sizeof(struct heapBlock));
struct heapBlock *head = sbrk(0); struct heapBlock *head = sbrk(0);
size_t blkSize = (intptr_t)head - (intptr_t)blk - sizeof(struct heapBlock); size_t blkSize = (intptr_t)head - (intptr_t)blk - sizeof(struct heapBlock);
@ -625,10 +640,11 @@ struct heapBlock *allocNewBlock(size_t size) {
blk->size = blkSize; blk->size = blkSize;
blk->free = 1; blk->free = 1;
list_add_tail(heapBlkList, blk); list_add_tail(heapBlkList, blk);
return blk; return blk;
} }
struct heapBlock *splitBlock(struct heapBlock *blk, size_t neededSize) static struct heapBlock *splitBlock(struct heapBlock *blk, size_t neededSize)
{ {
if (blk->size < neededSize + sizeof(struct heapBlock) + 1) { if (blk->size < neededSize + sizeof(struct heapBlock) + 1) {
return NULL; return NULL;
@ -637,6 +653,7 @@ struct heapBlock *splitBlock(struct heapBlock *blk, size_t neededSize)
newBlk->free = 1; newBlk->free = 1;
newBlk->size = blk->size - sizeof(struct heapBlock) - neededSize; newBlk->size = blk->size - sizeof(struct heapBlock) - neededSize;
blk->size = neededSize; blk->size = neededSize;
return newBlk; return newBlk;
} }
@ -655,16 +672,18 @@ void *malloc(size_t size)
list_add_head(heapBlkList, remainBlock); list_add_head(heapBlkList, remainBlock);
} }
blk->free = 0; blk->free = 0;
return blk + 1; // return the area after the blk description return blk + 1; // return the area after the blk description
} }
struct heapBlock *getHeapBlock(void *ptr) { static struct heapBlock *getHeapBlock(void *ptr)
{
return (struct heapBlock *)ptr - 1; return (struct heapBlock *)ptr - 1;
} }
void free(void *ptr)
void free(void *ptr){ {
if(!ptr) if (!ptr)
return; return;
struct heapBlock *blk = getHeapBlock(ptr); struct heapBlock *blk = getHeapBlock(ptr);
@ -673,3 +692,36 @@ void free(void *ptr){
blk->free = 1; blk->free = 1;
} }
void *calloc(size_t nmemb, size_t size)
{
size_t allocSize = nmemb * size;
void *ptr = malloc(allocSize);
if (ptr != NULL)
memset(ptr, 0, allocSize);
return ptr;
}
void *realloc(void *ptr, size_t size)
{
if (!ptr) {
return malloc(size);
}
struct heapBlock *blk = getHeapBlock(ptr);
if (blk->size >= size) {
return ptr;
}
void *new_ptr;
new_ptr = malloc(size);
if (!new_ptr) {
return NULL;
}
memmove(new_ptr, ptr, blk->size);
free(ptr);
return new_ptr;
}

View File

@ -14,8 +14,15 @@
#define isprint(c) ((' ' <= (c)) && ((c) <= '~')) #define isprint(c) ((' ' <= (c)) && ((c) <= '~'))
#define EOF (-1) #define EOF (-1)
/** compares the first @param n bytes (each interpreted as
* unsigned char) of the memory areas @param s1 and @param s2.
*/
__attribute__ ((access (read_only, 1, 3), access (read_only, 2, 3))) int memcmp(const void *s1, const void *s2, size_t n); __attribute__ ((access (read_only, 1, 3), access (read_only, 2, 3))) int memcmp(const void *s1, const void *s2, size_t n);
/**
* copies n bytes from memory area src to memory area dest. The memory areas may overlap
*/
__attribute__ ((access (write_only, 1, 3), access (read_only, 2, 3))) void *memmove(void *dest, const void *src, size_t n);
__attribute__ ((access (write_only, 1, 3), access (read_only, 2, 3))) void *memcpy(void *dest, const void *src, size_t n); __attribute__ ((access (write_only, 1, 3), access (read_only, 2, 3))) void *memcpy(void *dest, const void *src, size_t n);
__attribute__ ((access (write_only, 1, 3))) void *memset(void *s, int c, size_t n); __attribute__ ((access (write_only, 1, 3))) void *memset(void *s, int c, size_t n);
char *itoa(long long int value, char *str, int base); char *itoa(long long int value, char *str, int base);
@ -51,4 +58,6 @@ int readline(char *buf, int size);
int brk(void *addr); int brk(void *addr);
void *sbrk(intptr_t increment); void *sbrk(intptr_t increment);
void *malloc(size_t size); void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr); void free(void *ptr);