|
|
|
@ -166,8 +166,8 @@ static struct memblk *blk_slice(struct list_head *heap, struct memblk *bottom, s
|
|
|
|
|
|
|
|
|
|
long sys_malloc(size_t size)
|
|
|
|
|
{
|
|
|
|
|
void *ptr = kmalloc(size);
|
|
|
|
|
return (long)ptr;
|
|
|
|
|
void *ptr = kmalloc(size, MEM_USER);
|
|
|
|
|
return *(long *)&ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sys_free(void *ptr)
|
|
|
|
@ -202,11 +202,29 @@ void kmalloc_init(void *heap, size_t size)
|
|
|
|
|
atomic_heap_free = blk_get_size(atomic_block);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *kmalloc(size_t size)
|
|
|
|
|
static void *atomic_kmalloc(size_t);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* this is still the old algorithm and all flags except atomic are ignored,
|
|
|
|
|
* so that at least the code still compiles to do some testing
|
|
|
|
|
*/
|
|
|
|
|
void *kmalloc(size_t size, enum memflags flags)
|
|
|
|
|
{
|
|
|
|
|
# ifdef DEBUG
|
|
|
|
|
if ((flags & MEM_KERNEL) && (flags & MEM_USER))
|
|
|
|
|
__breakpoint;
|
|
|
|
|
if ((flags & (MEM_USER | MEM_KERNEL)) == 0)
|
|
|
|
|
__breakpoint;
|
|
|
|
|
if ((flags & MEM_USER) && (flags & MEM_ATOMIC))
|
|
|
|
|
__breakpoint;
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
if (size == 0)
|
|
|
|
|
return NULL; /* as per POSIX */
|
|
|
|
|
|
|
|
|
|
if (flags & MEM_ATOMIC)
|
|
|
|
|
return atomic_kmalloc(size);
|
|
|
|
|
|
|
|
|
|
if (size > generic_heap_free)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
@ -241,11 +259,8 @@ void *kmalloc(size_t size)
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *atomic_kmalloc(size_t size)
|
|
|
|
|
static void *atomic_kmalloc(size_t size)
|
|
|
|
|
{
|
|
|
|
|
if (size == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (size > atomic_heap_free)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
@ -296,7 +311,7 @@ void kfree(void *ptr)
|
|
|
|
|
if (!blk_is_alloc(blk))
|
|
|
|
|
__breakpoint;
|
|
|
|
|
|
|
|
|
|
word_t context = atomic_enter();
|
|
|
|
|
atomic_enter();
|
|
|
|
|
atomic_heap_free += blk_get_size(blk);
|
|
|
|
|
blk_clear_alloc(blk);
|
|
|
|
|
blk = blk_try_merge(&atomic_heap, blk);
|
|
|
|
@ -305,7 +320,7 @@ void kfree(void *ptr)
|
|
|
|
|
memset(&blk->data[MIN_SIZE], 0xaa, blk_get_size(blk) - MIN_SIZE);
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
atomic_restore(context);
|
|
|
|
|
atomic_leave();
|
|
|
|
|
} else {
|
|
|
|
|
__breakpoint;
|
|
|
|
|
}
|
|
|
|
@ -348,8 +363,8 @@ static struct memblk *blk_try_merge(struct list_head *heap, struct memblk *blk)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct memblk *blk_merge(struct list_head *heap,
|
|
|
|
|
struct memblk *bottom,
|
|
|
|
|
struct memblk *top)
|
|
|
|
|
struct memblk *bottom,
|
|
|
|
|
struct memblk *top)
|
|
|
|
|
{
|
|
|
|
|
size_t bottom_size = blk_get_size(bottom);
|
|
|
|
|
size_t top_size = blk_get_size(top);
|
|
|
|
@ -368,8 +383,7 @@ static struct memblk *blk_merge(struct list_head *heap,
|
|
|
|
|
return bottom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct memblk *blk_slice(struct list_head *heap, struct memblk *blk,
|
|
|
|
|
size_t slice_size)
|
|
|
|
|
static struct memblk *blk_slice(struct list_head *heap, struct memblk *blk, size_t slice_size)
|
|
|
|
|
{
|
|
|
|
|
list_delete(&blk->list);
|
|
|
|
|
|
|
|
|
@ -413,7 +427,7 @@ static struct memblk *blk_slice(struct list_head *heap, struct memblk *blk,
|
|
|
|
|
return blk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t round_alloc_size_up(size_t size)
|
|
|
|
|
static inline size_t round_alloc_size_up(size_t size)
|
|
|
|
|
{
|
|
|
|
|
size_t rounded = (size / MIN_SIZE) * MIN_SIZE;
|
|
|
|
|
if (rounded < size)
|
|
|
|
@ -437,7 +451,7 @@ static void blk_set_size(struct memblk *blk, size_t size)
|
|
|
|
|
blk->endsz[words] |= size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void blk_set_alloc(struct memblk *blk)
|
|
|
|
|
static inline void blk_set_alloc(struct memblk *blk)
|
|
|
|
|
{
|
|
|
|
|
size_t words = blk->size / sizeof(blk->size);
|
|
|
|
|
|
|
|
|
@ -445,7 +459,7 @@ static void blk_set_alloc(struct memblk *blk)
|
|
|
|
|
blk->endsz[words] |= ALLOC_FLAG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void blk_clear_alloc(struct memblk *blk)
|
|
|
|
|
static inline void blk_clear_alloc(struct memblk *blk)
|
|
|
|
|
{
|
|
|
|
|
size_t words = blk->size / sizeof(blk->size);
|
|
|
|
|
|
|
|
|
@ -473,38 +487,32 @@ static inline int blk_is_border_start(struct memblk *blk)
|
|
|
|
|
return blk->size & BORDER_FLAG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void blk_set_border_end(struct memblk *blk)
|
|
|
|
|
static inline void blk_set_border_end(struct memblk *blk)
|
|
|
|
|
{
|
|
|
|
|
size_t words = blk->size / sizeof(blk->size);
|
|
|
|
|
blk->endsz[words] |= BORDER_FLAG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void blk_clear_border_end(struct memblk *blk)
|
|
|
|
|
static inline void blk_clear_border_end(struct memblk *blk)
|
|
|
|
|
{
|
|
|
|
|
size_t words = blk->size / sizeof(blk->size);
|
|
|
|
|
blk->endsz[words] &= ~BORDER_FLAG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int blk_is_border_end(struct memblk *blk)
|
|
|
|
|
static inline int blk_is_border_end(struct memblk *blk)
|
|
|
|
|
{
|
|
|
|
|
size_t words = blk->size / sizeof(blk->size);
|
|
|
|
|
return blk->endsz[words] & BORDER_FLAG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct memblk *blk_prev(struct memblk *blk)
|
|
|
|
|
static inline struct memblk *blk_prev(struct memblk *blk)
|
|
|
|
|
{
|
|
|
|
|
if (blk_is_border_start(blk))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* gcc does not like accessing index -1 of zero-length arrays */
|
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
|
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wzero-length-bounds"
|
|
|
|
|
return (void *)blk - (blk->prevsz[-1] & SIZE_MSK) - OVERHEAD;
|
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct memblk *blk_next(struct memblk *blk)
|
|
|
|
|
static inline struct memblk *blk_next(struct memblk *blk)
|
|
|
|
|
{
|
|
|
|
|
if (blk_is_border_end(blk))
|
|
|
|
|
return NULL;
|
|
|
|
|