New allocators, testing framework, overall improvements
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
#include "malunal/allocators/linear.h"
|
||||
|
||||
typedef struct {
|
||||
allocator_t allocator;
|
||||
malunal_size_t size;
|
||||
malunal_size_t used;
|
||||
malunal_uint8_t* buffer;
|
||||
} impl_t;
|
||||
|
||||
typedef impl_t* impl_mptr_t;
|
||||
typedef const impl_t* impl_iptr_t;
|
||||
_Static_assert(
|
||||
sizeof(linear_allocator_t) == sizeof(impl_t),
|
||||
"Linear allocator must be the size of its implementation"
|
||||
);
|
||||
|
||||
static const
|
||||
allocator_vtable_t linear_allocator_vtable = {
|
||||
.acquire = (allocator_acquire_pfn_t)&linear_allocator_acquire,
|
||||
.dispose = (allocator_dispose_pfn_t)&linear_allocator_dispose
|
||||
};
|
||||
|
||||
error_t
|
||||
linear_allocator_size(
|
||||
linear_allocator_iptr_t allocator,
|
||||
malunal_uint32_t* out
|
||||
) {
|
||||
if (allocator == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_NULL_ALLOCATOR
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)allocator;
|
||||
*out = self->size;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
linear_allocator_used(
|
||||
linear_allocator_iptr_t allocator,
|
||||
malunal_uint32_t* out
|
||||
) {
|
||||
if (allocator == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_NULL_ALLOCATOR
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)allocator;
|
||||
*out = self->used;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
linear_allocator_init(
|
||||
malunal_size_t size,
|
||||
malunal_mptr_t buffer,
|
||||
linear_allocator_mptr_t allocator
|
||||
) {
|
||||
if (allocator == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_NULL_ALLOCATOR
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)allocator;
|
||||
self->allocator.vtable = &linear_allocator_vtable;
|
||||
self->buffer = buffer;
|
||||
self->size = size;
|
||||
self->used = 0;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
linear_allocator_acquire(
|
||||
linear_allocator_mptr_t allocator,
|
||||
malunal_size_t size,
|
||||
malunal_mptr_t* out
|
||||
) {
|
||||
if (allocator == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_NULL_ALLOCATOR
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)allocator;
|
||||
if (self->used + size > self->size)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_OUT_OF_MEMORY
|
||||
};
|
||||
|
||||
*out = self->buffer + self->used;
|
||||
self->used += size;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
linear_allocator_dispose(
|
||||
linear_allocator_mptr_t allocator,
|
||||
malunal_mptr_t address,
|
||||
malunal_size_t size
|
||||
) {
|
||||
if (allocator == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_NULL_ALLOCATOR
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)allocator;
|
||||
|
||||
malunal_uint8_t* addr = address;
|
||||
malunal_uint8_t* beg = self->buffer;
|
||||
malunal_uint8_t* end = self->buffer + self->size;
|
||||
if (addr < beg || addr > end)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_NOT_MY_ADDRESS
|
||||
};
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
linear_allocator_reset(
|
||||
linear_allocator_mptr_t allocator
|
||||
) {
|
||||
if (allocator == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_ALLOCATOR_T,
|
||||
.code = ALLOCATOR_ERROR_NULL_ALLOCATOR
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)allocator;
|
||||
|
||||
self->used = 0;
|
||||
return NO_ERROR;
|
||||
}
|
||||
Reference in New Issue
Block a user