Use clang-format

This commit is contained in:
2025-12-21 22:53:25 +01:00
parent 8794a61073
commit b2d8294b12
36 changed files with 925 additions and 842 deletions

View File

@@ -1,79 +1,75 @@
/* liballoc breaks when optimized too aggressively, for eg. clang's -Oz */
#pragma clang optimize off
#include <limine/requests.h>
#include <mm/liballoc.h>
#include <mm/pmm.h>
#include <mm/types.h>
#include <sync/spin_lock.h>
#include <limine/requests.h>
/* Porting */
spin_lock_t _liballoc_lock = SPIN_LOCK_INIT;
int liballoc_lock(void) {
spin_lock(&_liballoc_lock);
int liballoc_lock (void) {
spin_lock (&_liballoc_lock);
return 0;
}
int liballoc_unlock(void) {
spin_unlock(&_liballoc_lock);
int liballoc_unlock (void) {
spin_unlock (&_liballoc_lock);
return 0;
}
void *liballoc_alloc(int pages) {
physaddr_t p_addr = pmm_alloc(pages);
void* liballoc_alloc (int pages) {
physaddr_t p_addr = pmm_alloc (pages);
if (p_addr == PMM_ALLOC_ERR)
return NULL;
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
uintptr_t addr = (uintptr_t)(p_addr + hhdm->offset);
return (void *)addr;
return (void*)addr;
}
int liballoc_free(void *ptr, int pages) {
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
int liballoc_free (void* ptr, int pages) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
physaddr_t p_addr = (uintptr_t)ptr - hhdm->offset;
pmm_free(p_addr, pages);
pmm_free (p_addr, pages);
return 0;
}
/** Durand's Ridiculously Amazing Super Duper Memory functions. */
//#define DEBUG
//#define DEBUG
#define LIBALLOC_MAGIC 0xc001c0de
#define MAXCOMPLETE 5
#define MAXEXP 32
#define MINEXP 8
#define LIBALLOC_MAGIC 0xc001c0de
#define MAXCOMPLETE 5
#define MAXEXP 32
#define MINEXP 8
#define MODE_BEST 0
#define MODE_INSTANT 1
#define MODE_BEST 0
#define MODE_INSTANT 1
#define MODE MODE_BEST
#define MODE MODE_BEST
#ifdef DEBUG
#include <stdio.h>
#endif
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
#ifdef DEBUG
unsigned int l_allocated = 0; //< The real amount of memory allocated.
unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed).
unsigned int l_allocated = 0; //< The real amount of memory allocated.
unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed).
#endif
static int l_initialized = 0; //< Flag to indicate initialization.
static int l_pageSize = 4096; //< Individual page size
static int l_pageCount = 16; //< Minimum number of pages to allocate.
static int l_initialized = 0; //< Flag to indicate initialization.
static int l_pageSize = 4096; //< Individual page size
static int l_pageCount = 16; //< Minimum number of pages to allocate.
// *********** HELPER FUNCTIONS *******************************
@@ -81,495 +77,456 @@ static int l_pageCount = 16; //< Minimum number of pages to allocate.
*
* Returns n where 2^n <= size < 2^(n+1)
*/
static inline int getexp( unsigned int size )
{
if ( size < (1<<MINEXP) )
{
#ifdef DEBUG
printf("getexp returns -1 for %i less than MINEXP\n", size );
#endif
return -1; // Smaller than the quantum.
}
int shift = MINEXP;
static inline int getexp (unsigned int size) {
if (size < (1 << MINEXP)) {
#ifdef DEBUG
printf ("getexp returns -1 for %i less than MINEXP\n", size);
#endif
return -1; // Smaller than the quantum.
}
while ( shift < MAXEXP )
{
if ( (1<<shift) > size ) break;
shift += 1;
}
int shift = MINEXP;
#ifdef DEBUG
printf("getexp returns %i (%i bytes) for %i size\n", shift - 1, (1<<(shift -1)), size );
#endif
while (shift < MAXEXP) {
if ((1 << shift) > size)
break;
shift += 1;
}
return shift - 1;
#ifdef DEBUG
printf ("getexp returns %i (%i bytes) for %i size\n", shift - 1,
(1 << (shift - 1)), size);
#endif
return shift - 1;
}
static void* liballoc_memset (void* s, int c, size_t n) {
size_t i;
for (i = 0; i < n; i++)
((char*)s)[i] = c;
static void* liballoc_memset(void* s, int c, size_t n)
{
size_t i;
for ( i = 0; i < n ; i++)
((char*)s)[i] = c;
return s;
return s;
}
static void* liballoc_memcpy(void* s1, const void* s2, size_t n)
{
char *cdest;
char *csrc;
unsigned int *ldest = (unsigned int*)s1;
unsigned int *lsrc = (unsigned int*)s2;
static void* liballoc_memcpy (void* s1, const void* s2, size_t n) {
char* cdest;
char* csrc;
unsigned int* ldest = (unsigned int*)s1;
unsigned int* lsrc = (unsigned int*)s2;
while ( n >= sizeof(unsigned int) )
{
*ldest++ = *lsrc++;
n -= sizeof(unsigned int);
while (n >= sizeof (unsigned int)) {
*ldest++ = *lsrc++;
n -= sizeof (unsigned int);
}
cdest = (char*)ldest;
csrc = (char*)lsrc;
while ( n > 0 )
{
*cdest++ = *csrc++;
n -= 1;
csrc = (char*)lsrc;
while (n > 0) {
*cdest++ = *csrc++;
n -= 1;
}
return s1;
}
#ifdef DEBUG
static void dump_array()
{
int i = 0;
struct boundary_tag *tag = NULL;
static void dump_array () {
int i = 0;
struct boundary_tag* tag = NULL;
printf("------ Free pages array ---------\n");
printf("System memory allocated: %i\n", l_allocated );
printf("Memory in used (malloc'ed): %i\n", l_inuse );
printf ("------ Free pages array ---------\n");
printf ("System memory allocated: %i\n", l_allocated);
printf ("Memory in used (malloc'ed): %i\n", l_inuse);
for ( i = 0; i < MAXEXP; i++ )
{
printf("%.2i(%i): ",i, l_completePages[i] );
tag = l_freePages[ i ];
while ( tag != NULL )
{
if ( tag->split_left != NULL ) printf("*");
printf("%i", tag->real_size );
if ( tag->split_right != NULL ) printf("*");
printf(" ");
tag = tag->next;
}
printf("\n");
}
for (i = 0; i < MAXEXP; i++) {
printf ("%.2i(%i): ", i, l_completePages[i]);
printf("'*' denotes a split to the left/right of a tag\n");
fflush( stdout );
tag = l_freePages[i];
while (tag != NULL) {
if (tag->split_left != NULL)
printf ("*");
printf ("%i", tag->real_size);
if (tag->split_right != NULL)
printf ("*");
printf (" ");
tag = tag->next;
}
printf ("\n");
}
printf ("'*' denotes a split to the left/right of a tag\n");
fflush (stdout);
}
#endif
static inline void insert_tag (struct boundary_tag* tag, int index) {
int realIndex;
if (index < 0) {
realIndex = getexp (tag->real_size - sizeof (struct boundary_tag));
if (realIndex < MINEXP)
realIndex = MINEXP;
} else
realIndex = index;
static inline void insert_tag( struct boundary_tag *tag, int index )
{
int realIndex;
if ( index < 0 )
{
realIndex = getexp( tag->real_size - sizeof(struct boundary_tag) );
if ( realIndex < MINEXP ) realIndex = MINEXP;
}
else
realIndex = index;
tag->index = realIndex;
if ( l_freePages[ realIndex ] != NULL )
{
l_freePages[ realIndex ]->prev = tag;
tag->next = l_freePages[ realIndex ];
}
tag->index = realIndex;
l_freePages[ realIndex ] = tag;
if (l_freePages[realIndex] != NULL) {
l_freePages[realIndex]->prev = tag;
tag->next = l_freePages[realIndex];
}
l_freePages[realIndex] = tag;
}
static inline void remove_tag( struct boundary_tag *tag )
{
if ( l_freePages[ tag->index ] == tag ) l_freePages[ tag->index ] = tag->next;
static inline void remove_tag (struct boundary_tag* tag) {
if (l_freePages[tag->index] == tag)
l_freePages[tag->index] = tag->next;
if ( tag->prev != NULL ) tag->prev->next = tag->next;
if ( tag->next != NULL ) tag->next->prev = tag->prev;
if (tag->prev != NULL)
tag->prev->next = tag->next;
if (tag->next != NULL)
tag->next->prev = tag->prev;
tag->next = NULL;
tag->prev = NULL;
tag->index = -1;
tag->next = NULL;
tag->prev = NULL;
tag->index = -1;
}
static inline struct boundary_tag* melt_left (struct boundary_tag* tag) {
struct boundary_tag* left = tag->split_left;
static inline struct boundary_tag* melt_left( struct boundary_tag *tag )
{
struct boundary_tag *left = tag->split_left;
left->real_size += tag->real_size;
left->split_right = tag->split_right;
if ( tag->split_right != NULL ) tag->split_right->split_left = left;
left->real_size += tag->real_size;
left->split_right = tag->split_right;
return left;
if (tag->split_right != NULL)
tag->split_right->split_left = left;
return left;
}
static inline struct boundary_tag* absorb_right (struct boundary_tag* tag) {
struct boundary_tag* right = tag->split_right;
static inline struct boundary_tag* absorb_right( struct boundary_tag *tag )
{
struct boundary_tag *right = tag->split_right;
remove_tag (right); // Remove right from free pages.
remove_tag( right ); // Remove right from free pages.
tag->real_size += right->real_size;
tag->real_size += right->real_size;
tag->split_right = right->split_right;
if (right->split_right != NULL)
right->split_right->split_left = tag;
tag->split_right = right->split_right;
if ( right->split_right != NULL )
right->split_right->split_left = tag;
return tag;
return tag;
}
static inline struct boundary_tag* split_tag( struct boundary_tag* tag )
{
unsigned int remainder = tag->real_size - sizeof(struct boundary_tag) - tag->size;
struct boundary_tag *new_tag =
(struct boundary_tag*)((uintptr_t)tag + sizeof(struct boundary_tag) + tag->size);
new_tag->magic = LIBALLOC_MAGIC;
new_tag->real_size = remainder;
static inline struct boundary_tag* split_tag (struct boundary_tag* tag) {
unsigned int remainder =
tag->real_size - sizeof (struct boundary_tag) - tag->size;
new_tag->next = NULL;
new_tag->prev = NULL;
new_tag->split_left = tag;
new_tag->split_right = tag->split_right;
if (new_tag->split_right != NULL) new_tag->split_right->split_left = new_tag;
tag->split_right = new_tag;
tag->real_size -= new_tag->real_size;
insert_tag( new_tag, -1 );
return new_tag;
struct boundary_tag* new_tag = (struct boundary_tag*)((uintptr_t)tag +
sizeof (struct boundary_tag) + tag->size);
new_tag->magic = LIBALLOC_MAGIC;
new_tag->real_size = remainder;
new_tag->next = NULL;
new_tag->prev = NULL;
new_tag->split_left = tag;
new_tag->split_right = tag->split_right;
if (new_tag->split_right != NULL)
new_tag->split_right->split_left = new_tag;
tag->split_right = new_tag;
tag->real_size -= new_tag->real_size;
insert_tag (new_tag, -1);
return new_tag;
}
// ***************************************************************
static struct boundary_tag* allocate_new_tag (unsigned int size) {
unsigned int pages;
unsigned int usage;
struct boundary_tag* tag;
// This is how much space is required.
usage = size + sizeof (struct boundary_tag);
// Perfect amount of space
pages = usage / l_pageSize;
if ((usage % l_pageSize) != 0)
pages += 1;
static struct boundary_tag* allocate_new_tag( unsigned int size )
{
unsigned int pages;
unsigned int usage;
struct boundary_tag *tag;
// Make sure it's >= the minimum size.
if (pages < (unsigned int)l_pageCount)
pages = l_pageCount;
// This is how much space is required.
usage = size + sizeof(struct boundary_tag);
tag = (struct boundary_tag*)liballoc_alloc (pages);
// Perfect amount of space
pages = usage / l_pageSize;
if ( (usage % l_pageSize) != 0 ) pages += 1;
if (tag == NULL)
return NULL; // uh oh, we ran out of memory.
// Make sure it's >= the minimum size.
if ( pages < (unsigned int)l_pageCount ) pages = l_pageCount;
tag->magic = LIBALLOC_MAGIC;
tag->size = size;
tag->real_size = pages * l_pageSize;
tag->index = -1;
tag = (struct boundary_tag*)liballoc_alloc( pages );
tag->next = NULL;
tag->prev = NULL;
tag->split_left = NULL;
tag->split_right = NULL;
if ( tag == NULL ) return NULL; // uh oh, we ran out of memory.
tag->magic = LIBALLOC_MAGIC;
tag->size = size;
tag->real_size = pages * l_pageSize;
tag->index = -1;
#ifdef DEBUG
printf ("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag,
pages, pages * l_pageSize, size);
tag->next = NULL;
tag->prev = NULL;
tag->split_left = NULL;
tag->split_right = NULL;
l_allocated += pages * l_pageSize;
printf ("Total memory usage = %i KB\n", (int)((l_allocated / (1024))));
#endif
#ifdef DEBUG
printf("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag, pages, pages * l_pageSize, size );
l_allocated += pages * l_pageSize;
printf("Total memory usage = %i KB\n", (int)((l_allocated / (1024))) );
#endif
return tag;
return tag;
}
void* malloc (size_t size) {
int index;
void* ptr;
struct boundary_tag* tag = NULL;
liballoc_lock ();
void *malloc(size_t size)
{
int index;
void *ptr;
struct boundary_tag *tag = NULL;
if (l_initialized == 0) {
#ifdef DEBUG
printf ("%s\n", "liballoc initializing.");
#endif
for (index = 0; index < MAXEXP; index++) {
l_freePages[index] = NULL;
l_completePages[index] = 0;
}
l_initialized = 1;
}
liballoc_lock();
index = getexp (size) + MODE;
if (index < MINEXP)
index = MINEXP;
if ( l_initialized == 0 )
{
#ifdef DEBUG
printf("%s\n","liballoc initializing.");
#endif
for ( index = 0; index < MAXEXP; index++ )
{
l_freePages[index] = NULL;
l_completePages[index] = 0;
}
l_initialized = 1;
}
// Find one big enough.
tag = l_freePages[index]; // Start at the front of the list.
while (tag != NULL) {
// If there's enough space in this tag.
if ((tag->real_size - sizeof (struct boundary_tag)) >=
(size + sizeof (struct boundary_tag))) {
#ifdef DEBUG
printf ("Tag search found %i >= %i\n",
(tag->real_size - sizeof (struct boundary_tag)),
(size + sizeof (struct boundary_tag)));
#endif
break;
}
index = getexp( size ) + MODE;
if ( index < MINEXP ) index = MINEXP;
tag = tag->next;
}
// Find one big enough.
tag = l_freePages[ index ]; // Start at the front of the list.
while ( tag != NULL )
{
// If there's enough space in this tag.
if ( (tag->real_size - sizeof(struct boundary_tag))
>= (size + sizeof(struct boundary_tag) ) )
{
#ifdef DEBUG
printf("Tag search found %i >= %i\n",(tag->real_size - sizeof(struct boundary_tag)), (size + sizeof(struct boundary_tag) ) );
#endif
break;
}
// No page found. Make one.
if (tag == NULL) {
if ((tag = allocate_new_tag (size)) == NULL) {
liballoc_unlock ();
return NULL;
}
tag = tag->next;
}
index = getexp (tag->real_size - sizeof (struct boundary_tag));
} else {
remove_tag (tag);
// No page found. Make one.
if ( tag == NULL )
{
if ( (tag = allocate_new_tag( size )) == NULL )
{
liballoc_unlock();
return NULL;
}
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
}
else
{
remove_tag( tag );
if ((tag->split_left == NULL) && (tag->split_right == NULL))
l_completePages[index] -= 1;
}
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
l_completePages[ index ] -= 1;
}
// We have a free page. Remove it from the free pages list.
tag->size = size;
// We have a free page. Remove it from the free pages list.
// Removed... see if we can re-use the excess space.
tag->size = size;
#ifdef DEBUG
printf("Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n", tag->real_size - sizeof(struct boundary_tag), size, tag->real_size - size - sizeof(struct boundary_tag), index, 1<<index );
#endif
unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder
// Removed... see if we can re-use the excess space.
if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ )
{
int childIndex = getexp( remainder );
if ( childIndex >= 0 )
{
#ifdef DEBUG
printf("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex, (1<<childIndex) );
#endif
#ifdef DEBUG
printf (
"Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n",
tag->real_size - sizeof (struct boundary_tag), size,
tag->real_size - size - sizeof (struct boundary_tag), index, 1 << index);
#endif
struct boundary_tag *new_tag = split_tag( tag );
unsigned int remainder = tag->real_size - size -
sizeof (struct boundary_tag) * 2; // Support a new tag + remainder
(void)new_tag;
if (((int)(remainder) >
0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/) {
int childIndex = getexp (remainder);
#ifdef DEBUG
printf("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n", tag->real_size, new_tag->real_size, new_tag->index );
#endif
}
}
if (childIndex >= 0) {
#ifdef DEBUG
printf ("Seems to be splittable: %i >= 2^%i .. %i\n", remainder,
childIndex, (1 << childIndex));
#endif
ptr = (void*)((uintptr_t)tag + sizeof( struct boundary_tag ) );
struct boundary_tag* new_tag = split_tag (tag);
(void)new_tag;
#ifdef DEBUG
l_inuse += size;
printf("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
dump_array();
#endif
#ifdef DEBUG
printf ("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n",
tag->real_size, new_tag->real_size, new_tag->index);
#endif
}
}
ptr = (void*)((uintptr_t)tag + sizeof (struct boundary_tag));
liballoc_unlock();
return ptr;
#ifdef DEBUG
l_inuse += size;
printf ("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024,
(int)l_allocated / 1024);
dump_array ();
#endif
liballoc_unlock ();
return ptr;
}
void free (void* ptr) {
int index;
struct boundary_tag* tag;
if (ptr == NULL)
return;
liballoc_lock ();
tag = (struct boundary_tag*)((uintptr_t)ptr - sizeof (struct boundary_tag));
void free(void *ptr)
{
int index;
struct boundary_tag *tag;
if (tag->magic != LIBALLOC_MAGIC) {
liballoc_unlock (); // release the lock
return;
}
if ( ptr == NULL ) return;
#ifdef DEBUG
l_inuse -= tag->size;
printf (
"free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024);
#endif
liballoc_lock();
// MELT LEFT...
while ((tag->split_left != NULL) && (tag->split_left->index >= 0)) {
#ifdef DEBUG
printf (
"Melting tag left into available memory. Left was %i, becomes %i (%i)\n",
tag->split_left->real_size, tag->split_left->real_size + tag->real_size,
tag->split_left->real_size);
#endif
tag = melt_left (tag);
remove_tag (tag);
}
tag = (struct boundary_tag*)((uintptr_t)ptr - sizeof( struct boundary_tag ));
if ( tag->magic != LIBALLOC_MAGIC )
{
liballoc_unlock(); // release the lock
return;
}
// MELT RIGHT...
while ((tag->split_right != NULL) && (tag->split_right->index >= 0)) {
#ifdef DEBUG
printf (
"Melting tag right into available memory. This was was %i, becomes %i (%i)\n",
tag->real_size, tag->split_right->real_size + tag->real_size,
tag->split_right->real_size);
#endif
tag = absorb_right (tag);
}
// Where is it going back to?
index = getexp (tag->real_size - sizeof (struct boundary_tag));
if (index < MINEXP)
index = MINEXP;
// A whole, empty block?
if ((tag->split_left == NULL) && (tag->split_right == NULL)) {
if (l_completePages[index] == MAXCOMPLETE) {
// Too many standing by to keep. Free this one.
unsigned int pages = tag->real_size / l_pageSize;
#ifdef DEBUG
l_inuse -= tag->size;
printf("free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
#endif
if ((tag->real_size % l_pageSize) != 0)
pages += 1;
if (pages < (unsigned int)l_pageCount)
pages = l_pageCount;
// MELT LEFT...
while ( (tag->split_left != NULL) && (tag->split_left->index >= 0) )
{
#ifdef DEBUG
printf("Melting tag left into available memory. Left was %i, becomes %i (%i)\n", tag->split_left->real_size, tag->split_left->real_size + tag->real_size, tag->split_left->real_size );
#endif
tag = melt_left( tag );
remove_tag( tag );
}
liballoc_free (tag, pages);
// MELT RIGHT...
while ( (tag->split_right != NULL) && (tag->split_right->index >= 0) )
{
#ifdef DEBUG
printf("Melting tag right into available memory. This was was %i, becomes %i (%i)\n", tag->real_size, tag->split_right->real_size + tag->real_size, tag->split_right->real_size );
#endif
tag = absorb_right( tag );
}
#ifdef DEBUG
l_allocated -= pages * l_pageSize;
printf ("Resource freeing %x of %i pages\n", tag, pages);
dump_array ();
#endif
// Where is it going back to?
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
if ( index < MINEXP ) index = MINEXP;
// A whole, empty block?
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
{
liballoc_unlock ();
return;
}
if ( l_completePages[ index ] == MAXCOMPLETE )
{
// Too many standing by to keep. Free this one.
unsigned int pages = tag->real_size / l_pageSize;
l_completePages[index] += 1; // Increase the count of complete pages.
}
if ( (tag->real_size % l_pageSize) != 0 ) pages += 1;
if ( pages < (unsigned int)l_pageCount ) pages = l_pageCount;
// ..........
liballoc_free( tag, pages );
insert_tag (tag, index);
#ifdef DEBUG
l_allocated -= pages * l_pageSize;
printf("Resource freeing %x of %i pages\n", tag, pages );
dump_array();
#endif
#ifdef DEBUG
printf (
"Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n",
tag->real_size, tag->size, index);
dump_array ();
#endif
liballoc_unlock();
return;
}
l_completePages[ index ] += 1; // Increase the count of complete pages.
}
// ..........
insert_tag( tag, index );
#ifdef DEBUG
printf("Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n", tag->real_size, tag->size, index );
dump_array();
#endif
liballoc_unlock();
liballoc_unlock ();
}
void* calloc (size_t nobj, size_t size) {
int real_size;
void* p;
real_size = nobj * size;
p = malloc (real_size);
void* calloc(size_t nobj, size_t size)
{
int real_size;
void *p;
liballoc_memset (p, 0, real_size);
real_size = nobj * size;
p = malloc( real_size );
liballoc_memset( p, 0, real_size );
return p;
return p;
}
void* realloc (void* p, size_t size) {
void* ptr;
struct boundary_tag* tag;
int real_size;
if (size == 0) {
free (p);
return NULL;
}
if (p == NULL)
return malloc (size);
void* realloc(void *p, size_t size)
{
void *ptr;
struct boundary_tag *tag;
int real_size;
if ( size == 0 )
{
free( p );
return NULL;
}
if ( p == NULL ) return malloc( size );
if (&liballoc_lock != NULL)
liballoc_lock (); // lockit
tag = (struct boundary_tag*)((uintptr_t)p - sizeof (struct boundary_tag));
real_size = tag->size;
if (&liballoc_unlock != NULL)
liballoc_unlock ();
if ( &liballoc_lock != NULL ) liballoc_lock(); // lockit
tag = (struct boundary_tag*)((uintptr_t)p - sizeof( struct boundary_tag ));
real_size = tag->size;
if ( &liballoc_unlock != NULL ) liballoc_unlock();
if ((size_t)real_size > size)
real_size = size;
if ( (size_t)real_size > size ) real_size = size;
ptr = malloc (size);
liballoc_memcpy (ptr, p, real_size);
free (p);
ptr = malloc( size );
liballoc_memcpy( ptr, p, real_size );
free( p );
return ptr;
return ptr;
}

View File

@@ -9,12 +9,11 @@
#ifndef _HAVE_SIZE_T
#define _HAVE_SIZE_T
typedef unsigned int size_t;
typedef unsigned int size_t;
#endif
#ifndef NULL
#define NULL 0
#ifndef NULL
#define NULL 0
#endif
#endif
@@ -23,29 +22,24 @@ typedef unsigned int size_t;
extern "C" {
#endif
/** This is a boundary tag which is prepended to the
* page or section of a page which we have allocated. It is
* used to identify valid memory blocks that the
* application is trying to free.
*/
struct boundary_tag
{
unsigned int magic; //< It's a kind of ...
unsigned int size; //< Requested size.
unsigned int real_size; //< Actual size.
int index; //< Location in the page table.
struct boundary_tag {
unsigned int magic; //< It's a kind of ...
unsigned int size; //< Requested size.
unsigned int real_size; //< Actual size.
int index; //< Location in the page table.
struct boundary_tag *split_left; //< Linked-list info for broken pages.
struct boundary_tag *split_right; //< The same.
struct boundary_tag *next; //< Linked list info.
struct boundary_tag *prev; //< Linked list info.
struct boundary_tag* split_left; //< Linked-list info for broken pages.
struct boundary_tag* split_right; //< The same.
struct boundary_tag* next; //< Linked list info.
struct boundary_tag* prev; //< Linked list info.
};
/** This function is supposed to lock the memory data structures. It
* could be as simple as disabling interrupts or acquiring a spinlock.
* It's up to you to decide.
@@ -53,7 +47,7 @@ struct boundary_tag
* \return 0 if the lock was acquired successfully. Anything else is
* failure.
*/
extern int liballoc_lock();
extern int liballoc_lock ();
/** This function unlocks what was previously locked by the liballoc_lock
* function. If it disabled interrupts, it enables interrupts. If it
@@ -61,7 +55,7 @@ extern int liballoc_lock();
*
* \return 0 if the lock was successfully released.
*/
extern int liballoc_unlock();
extern int liballoc_unlock ();
/** This is the hook into the local system which allocates pages. It
* accepts an integer parameter which is the number of pages
@@ -70,7 +64,7 @@ extern int liballoc_unlock();
* \return NULL if the pages were not allocated.
* \return A pointer to the allocated memory.
*/
extern void* liballoc_alloc(int);
extern void* liballoc_alloc (int);
/** This frees previously allocated memory. The void* parameter passed
* to the function is the exact same value returned from a previous
@@ -80,20 +74,15 @@ extern void* liballoc_alloc(int);
*
* \return 0 if the memory was successfully freed.
*/
extern int liballoc_free(void*,int);
void *malloc(size_t); //< The standard function.
void *realloc(void *, size_t); //< The standard function.
void *calloc(size_t, size_t); //< The standard function.
void free(void *); //< The standard function.
extern int liballoc_free (void*, int);
void* malloc (size_t); //< The standard function.
void* realloc (void*, size_t); //< The standard function.
void* calloc (size_t, size_t); //< The standard function.
void free (void*); //< The standard function.
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,52 +1,51 @@
#include <libk/std.h>
#include <libk/bm.h>
#include <libk/string.h>
#include <libk/align.h>
#include <sys/mm.h>
#include <sys/debug.h>
#include <sync/spin_lock.h>
#include <mm/types.h>
#include <mm/pmm.h>
#include <libk/bm.h>
#include <libk/std.h>
#include <libk/string.h>
#include <limine/limine.h>
#include <limine/requests.h>
#include <mm/pmm.h>
#include <mm/types.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
#include <sys/mm.h>
static struct pmm pmm;
void pmm_init(void) {
memset(&pmm, 0, sizeof(pmm));
void pmm_init (void) {
memset (&pmm, 0, sizeof (pmm));
struct limine_memmap_response *memmap = limine_memmap_request.response;
struct limine_hhdm_response *hhdm = limine_hhdm_request.response;
struct limine_memmap_response* memmap = limine_memmap_request.response;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
size_t region = 0;
for (size_t i = 0; i < memmap->entry_count; i++) {
struct limine_memmap_entry *entry = memmap->entries[i];
static const char *entry_strings[] = {
"usable", "reserved", "acpi reclaimable", "acpi nvs",
"bad memory", "bootloader reclaimable", "executable and modules",
"framebuffer", "acpi tables"
};
struct limine_memmap_entry* entry = memmap->entries[i];
static const char* entry_strings[] = {"usable", "reserved",
"acpi reclaimable", "acpi nvs", "bad memory", "bootloader reclaimable",
"executable and modules", "framebuffer", "acpi tables"};
DEBUG("memmap entry: %-25s %p (%zu bytes)\n", entry_strings[entry->type], entry->base, entry->length);
DEBUG ("memmap entry: %-25s %p (%zu bytes)\n", entry_strings[entry->type],
entry->base, entry->length);
if (entry->type == LIMINE_MEMMAP_USABLE && region < PMM_REGIONS_MAX) {
struct pmm_region *pmm_region = &pmm.regions[region];
struct pmm_region* pmm_region = &pmm.regions[region];
/*
* We need to calculate sizes for the pmm region and the bitmap. The bitmap MUSTN'T include it's
* own region within the bit range.
* */
size_t size = align_down(entry->length, PAGE_SIZE);
physaddr_t start = align_up(entry->base, PAGE_SIZE);
size_t size = align_down (entry->length, PAGE_SIZE);
physaddr_t start = align_up (entry->base, PAGE_SIZE);
size_t max_pages = (size * 8) / (PAGE_SIZE * 8 + 1);
size_t bm_nbits = max_pages;
size_t bm_size = align_up(bm_nbits, 8) / 8;
size_t bm_size = align_up (bm_nbits, 8) / 8;
physaddr_t bm_base = start;
physaddr_t data_base = align_up(bm_base + bm_size, PAGE_SIZE);
physaddr_t data_base = align_up (bm_base + bm_size, PAGE_SIZE);
if (bm_base + bm_size >= start + size)
continue;
@@ -57,22 +56,22 @@ void pmm_init(void) {
if (final_pages < max_pages) {
bm_nbits = final_pages;
bm_size = align_up(bm_nbits, 8) / 8;
data_base = align_up(bm_base + bm_size, PAGE_SIZE);
bm_size = align_up (bm_nbits, 8) / 8;
data_base = align_up (bm_base + bm_size, PAGE_SIZE);
}
size_t managed_size = final_pages * PAGE_SIZE;
uint8_t *bm_base1 = (uint8_t *)(bm_base + hhdm->offset);
uint8_t* bm_base1 = (uint8_t*)(bm_base + hhdm->offset);
/* Init the pm region. */
pmm_region->lock = SPIN_LOCK_INIT;
pmm_region->membase = data_base;
pmm_region->size = managed_size;
bm_init(&pmm_region->bm, bm_base1, bm_nbits);
bm_clear_region(&pmm_region->bm, 0, bm_nbits);
bm_init (&pmm_region->bm, bm_base1, bm_nbits);
bm_clear_region (&pmm_region->bm, 0, bm_nbits);
pmm_region->flags |= PMM_REGION_ACTIVE; /* mark as active */
region++;
}
}
@@ -82,9 +81,10 @@ void pmm_init(void) {
* Find free space for a block range. For every bit of the bitmap, we test nblks bits forward.
* bm_test_region helps us out, because it automatically does range checks. See comments there.
*/
static size_t pmm_find_free_space(struct pmm_region *pmm_region, size_t nblks) {
static size_t pmm_find_free_space (
struct pmm_region* pmm_region, size_t nblks) {
for (size_t bit = 0; bit < pmm_region->bm.nbits; bit++) {
if (bm_test_region(&pmm_region->bm, bit, nblks)) {
if (bm_test_region (&pmm_region->bm, bit, nblks)) {
continue;
}
@@ -94,56 +94,57 @@ static size_t pmm_find_free_space(struct pmm_region *pmm_region, size_t nblks) {
return (size_t)-1;
}
physaddr_t pmm_alloc(size_t nblks) {
physaddr_t pmm_alloc (size_t nblks) {
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
struct pmm_region *pmm_region = &pmm.regions[region];
struct pmm_region* pmm_region = &pmm.regions[region];
/* Inactive region, so don't bother with it. */
if (!(pmm_region->flags & PMM_REGION_ACTIVE))
continue;
spin_lock(&pmm_region->lock);
spin_lock (&pmm_region->lock);
/* Find starting bit of the free bit range */
size_t bit = pmm_find_free_space(pmm_region, nblks);
size_t bit = pmm_find_free_space (pmm_region, nblks);
/* Found a free range? */
if (bit != (size_t)-1) {
/* Mark it */
bm_set_region(&pmm_region->bm, bit, nblks);
spin_unlock(&pmm_region->lock);
bm_set_region (&pmm_region->bm, bit, nblks);
spin_unlock (&pmm_region->lock);
return pmm_region->membase + bit * PAGE_SIZE;
}
spin_unlock(&pmm_region->lock);
spin_unlock (&pmm_region->lock);
}
return PMM_ALLOC_ERR;
}
void pmm_free(physaddr_t p_addr, size_t nblks) {
void pmm_free (physaddr_t p_addr, size_t nblks) {
/* Round down to nearest page boundary */
physaddr_t aligned_p_addr = align_down(p_addr, PAGE_SIZE);
physaddr_t aligned_p_addr = align_down (p_addr, PAGE_SIZE);
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
struct pmm_region *pmm_region = &pmm.regions[region];
struct pmm_region* pmm_region = &pmm.regions[region];
/* Inactive region, so don't bother with it. */
if (!(pmm_region->flags & PMM_REGION_ACTIVE))
continue;
/* If aligned_p_addr is within the range if this region, it belongs to it. */
if (aligned_p_addr >= pmm_region->membase && aligned_p_addr < pmm_region->size) {
if (aligned_p_addr >= pmm_region->membase &&
aligned_p_addr < pmm_region->size) {
physaddr_t addr = aligned_p_addr - pmm_region->membase;
size_t bit = div_align_up(addr, PAGE_SIZE);
size_t bit = div_align_up (addr, PAGE_SIZE);
spin_lock(&pmm_region->lock);
bm_clear_region(&pmm_region->bm, bit, nblks);
spin_lock (&pmm_region->lock);
spin_unlock(&pmm_region->lock);
bm_clear_region (&pmm_region->bm, bit, nblks);
spin_unlock (&pmm_region->lock);
break;
}

View File

@@ -1,16 +1,16 @@
#ifndef _KERNEL_MM_PMM_H
#define _KERNEL_MM_PMM_H
#include <libk/std.h>
#include <libk/bm.h>
#include <sync/spin_lock.h>
#include <libk/std.h>
#include <mm/types.h>
#include <sync/spin_lock.h>
#define PMM_ALLOC_ERR ((physaddr_t)-1)
#define PMM_ALLOC_ERR ((physaddr_t) - 1)
#define PMM_REGIONS_MAX 32
#define PMM_REGION_ACTIVE (1 << 0)
#define PMM_REGION_ACTIVE (1 << 0)
struct pmm_region {
spin_lock_t lock;
@@ -24,8 +24,8 @@ struct pmm {
struct pmm_region regions[PMM_REGIONS_MAX];
};
void pmm_init(void);
physaddr_t pmm_alloc(size_t nblks);
void pmm_free(physaddr_t p_addr, size_t nblks);
void pmm_init (void);
physaddr_t pmm_alloc (size_t nblks);
void pmm_free (physaddr_t p_addr, size_t nblks);
#endif // _KERNEL_MM_PMM_H