Compare commits
3 Commits
main
...
a983df1ac6
| Author | SHA1 | Date | |
|---|---|---|---|
| a983df1ac6 | |||
| 490d450a82 | |||
| 61da9ad161 |
@@ -24,15 +24,15 @@ Autoarr_declare(u64)
|
|||||||
Autoarr_declare(Unitype)
|
Autoarr_declare(Unitype)
|
||||||
|
|
||||||
#define Autoarr_foreach(ar, elem, codeblock...) { \
|
#define Autoarr_foreach(ar, elem, codeblock...) { \
|
||||||
if(ar->blocks_count>0) { \
|
if(ar->chunks_count>0) { \
|
||||||
typeof(**ar->values) elem; \
|
typeof(**ar->chunks) elem; \
|
||||||
for(u16 blockI=0;blockI<ar->blocks_count-1;blockI++) \
|
for(u16 chunkI=0;chunkI<ar->chunks_count-1;chunkI++) \
|
||||||
for(u32 elemI=0;elemI<ar->max_block_length;elemI++){ \
|
for(u32 elemI=0;elemI<ar->max_chunk_length;elemI++){ \
|
||||||
elem=ar->values[blockI][elemI]; \
|
elem=ar->chunks[chunkI][elemI]; \
|
||||||
{ codeblock; } \
|
{ codeblock; } \
|
||||||
} \
|
} \
|
||||||
for(u16 elemI=0;elemI<ar->block_length;elemI++){ \
|
for(u16 elemI=0;elemI<ar->chunk_length;elemI++){ \
|
||||||
elem=ar->values[ar->blocks_count-1][elemI]; \
|
elem=ar->chunks[ar->chunks_count-1][elemI]; \
|
||||||
{ codeblock; } \
|
{ codeblock; } \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ extern "C" {
|
|||||||
#include "Autoarr.h"
|
#include "Autoarr.h"
|
||||||
#include "../Hashtable/KeyValuePair.h"
|
#include "../Hashtable/KeyValuePair.h"
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_KVPair_create(u16 max_blocks_count, u16 max_block_length, Autoarr_KVPair** output){
|
EXPORT void CALL kerep_Autoarr_KVPair_create(u16 max_chunks_count, u16 max_chunk_length, Autoarr_KVPair** output){
|
||||||
*output=Autoarr_create(KVPair, max_blocks_count, max_block_length);
|
*output=Autoarr_create(KVPair, max_chunks_count, max_chunk_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){
|
EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ extern "C" {
|
|||||||
|
|
||||||
#include "Autoarr.h"
|
#include "Autoarr.h"
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_blocks_count, u16 max_block_length, Autoarr_Unitype** output){
|
EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_chunks_count, u16 max_chunk_length, Autoarr_Unitype** output){
|
||||||
*output=Autoarr_create(Unitype, max_blocks_count, max_block_length);
|
*output=Autoarr_create(Unitype, max_chunks_count, max_chunk_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){
|
EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){
|
||||||
|
|||||||
@@ -23,22 +23,22 @@ typedef struct __Autoarr_##type##_functions_list_t { \
|
|||||||
extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \
|
extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \
|
||||||
\
|
\
|
||||||
STRUCT(Autoarr_##type, \
|
STRUCT(Autoarr_##type, \
|
||||||
u16 blocks_count; \
|
u16 chunks_count; \
|
||||||
u16 max_blocks_count; \
|
u16 max_chunks_count; \
|
||||||
u16 block_length; \
|
u16 chunk_length; \
|
||||||
u16 max_block_length; \
|
u16 max_chunk_length; \
|
||||||
type** values; \
|
type** chunks; \
|
||||||
__Autoarr_##type##_functions_list_t* functions; \
|
__Autoarr_##type##_functions_list_t* functions; \
|
||||||
) \
|
) \
|
||||||
\
|
\
|
||||||
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length); \
|
Autoarr_##type* __Autoarr_##type##_create(u16 max_chunks_count, u16 max_chunk_length); \
|
||||||
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr); \
|
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr); \
|
||||||
void ____Autoarr_##type##_freeWithMembers(void* ar);
|
void ____Autoarr_##type##_freeWithMembers(void* ar);
|
||||||
|
|
||||||
#define Autoarr(type) Autoarr_##type
|
#define Autoarr(type) Autoarr_##type
|
||||||
|
|
||||||
#define Autoarr_create(type, max_blocks_count, max_block_length) \
|
#define Autoarr_create(type, max_chunks_count, max_chunk_length) \
|
||||||
__Autoarr_##type##_create(max_blocks_count, max_block_length)
|
__Autoarr_##type##_create(max_chunks_count, max_chunk_length)
|
||||||
#define Autoarr_add(autoarr, element) \
|
#define Autoarr_add(autoarr, element) \
|
||||||
autoarr->functions->add(autoarr, element)
|
autoarr->functions->add(autoarr, element)
|
||||||
#define Autoarr_get(autoarr, index) \
|
#define Autoarr_get(autoarr, index) \
|
||||||
@@ -55,18 +55,18 @@ void ____Autoarr_##type##_freeWithMembers(void* ar);
|
|||||||
autoarr->functions->toArray(autoarr)
|
autoarr->functions->toArray(autoarr)
|
||||||
|
|
||||||
#define Autoarr_length(autoarr) \
|
#define Autoarr_length(autoarr) \
|
||||||
(u32)(!autoarr->blocks_count ? 0 : \
|
(u32)(!autoarr->chunks_count ? 0 : \
|
||||||
autoarr->max_block_length*(autoarr->blocks_count-1)+autoarr->block_length)
|
autoarr->max_chunk_length*(autoarr->chunks_count-1)+autoarr->chunk_length)
|
||||||
#define Autoarr_max_length(autoarr) \
|
#define Autoarr_max_length(autoarr) \
|
||||||
(u32)(autoarr->max_block_length*autoarr->max_blocks_count)
|
(u32)(autoarr->max_chunk_length*autoarr->max_chunks_count)
|
||||||
|
|
||||||
#define Autoarr_pop(AR){ \
|
#define Autoarr_pop(AR){ \
|
||||||
if(AR->block_length==1){ \
|
if(AR->chunk_length==1){ \
|
||||||
AR->blocks_count--; \
|
AR->chunks_count--; \
|
||||||
AR->block_length=AR->max_block_length; \
|
AR->chunk_length=AR->max_chunk_length; \
|
||||||
free(AR->values[AR->blocks_count]); \
|
free(AR->chunks[AR->chunks_count]); \
|
||||||
} \
|
} \
|
||||||
else AR->block_length--; \
|
else AR->chunk_length--; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
@@ -11,40 +11,40 @@ extern "C" {
|
|||||||
kt_define(Autoarr_##type, ____Autoarr_##type##_freeWithMembers, NULL); \
|
kt_define(Autoarr_##type, ____Autoarr_##type##_freeWithMembers, NULL); \
|
||||||
\
|
\
|
||||||
void __Autoarr_##type##_add(Autoarr_##type* ar, type element){ \
|
void __Autoarr_##type##_add(Autoarr_##type* ar, type element){ \
|
||||||
if(!ar->values){ \
|
if(!ar->chunks){ \
|
||||||
ar->values=malloc(ar->max_blocks_count*sizeof(type*)); \
|
ar->chunks=malloc(ar->max_chunks_count*sizeof(type*)); \
|
||||||
goto create_block; \
|
goto create_chunk; \
|
||||||
} \
|
} \
|
||||||
if(ar->block_length==ar->max_block_length){ \
|
if(ar->chunk_length==ar->max_chunk_length){ \
|
||||||
if (ar->blocks_count>=ar->max_blocks_count) throw(ERR_MAXLENGTH); \
|
if (ar->chunks_count>=ar->max_chunks_count) throw(ERR_MAXLENGTH); \
|
||||||
ar->block_length=0; \
|
ar->chunk_length=0; \
|
||||||
create_block: \
|
create_chunk: \
|
||||||
ar->values[ar->blocks_count]=malloc(ar->max_block_length*sizeof(type)); \
|
ar->chunks[ar->chunks_count]=malloc(ar->max_chunk_length*sizeof(type)); \
|
||||||
ar->blocks_count++; \
|
ar->chunks_count++; \
|
||||||
} \
|
} \
|
||||||
ar->values[ar->blocks_count-1][ar->block_length]=element; \
|
ar->chunks[ar->chunks_count-1][ar->chunk_length]=element; \
|
||||||
ar->block_length++; \
|
ar->chunk_length++; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
type __Autoarr_##type##_get(Autoarr_##type* ar, u32 index){ \
|
type __Autoarr_##type##_get(Autoarr_##type* ar, u32 index){ \
|
||||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||||
return ar->values[index/ar->max_block_length][index%ar->max_block_length]; \
|
return ar->chunks[index/ar->max_chunk_length][index%ar->max_chunk_length]; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
type* __Autoarr_##type##_getPtr(Autoarr_##type* ar, u32 index){ \
|
type* __Autoarr_##type##_getPtr(Autoarr_##type* ar, u32 index){ \
|
||||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||||
return ar->values[index/ar->max_block_length]+(index%ar->max_block_length); \
|
return ar->chunks[index/ar->max_chunk_length]+(index%ar->max_chunk_length); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
void __Autoarr_##type##_set(Autoarr_##type* ar, u32 index, type element){ \
|
void __Autoarr_##type##_set(Autoarr_##type* ar, u32 index, type element){ \
|
||||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||||
ar->values[index/ar->max_block_length][index%ar->max_block_length]=element; \
|
ar->chunks[index/ar->max_chunk_length][index%ar->max_chunk_length]=element; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
void __Autoarr_##type##_freeWithoutMembers(Autoarr_##type* ar, bool freePtr){ \
|
void __Autoarr_##type##_freeWithoutMembers(Autoarr_##type* ar, bool freePtr){ \
|
||||||
for(u16 i=0; i<ar->blocks_count;i++) \
|
for(u16 i=0; i<ar->chunks_count;i++) \
|
||||||
free(ar->values[i]); \
|
free(ar->chunks[i]); \
|
||||||
free(ar->values); \
|
free(ar->chunks); \
|
||||||
if(freePtr) free(ar); \
|
if(freePtr) free(ar); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -82,14 +82,14 @@ __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list={ \
|
|||||||
&__Autoarr_##type##_toArray \
|
&__Autoarr_##type##_toArray \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length){ \
|
Autoarr_##type* __Autoarr_##type##_create(u16 max_chunks_count, u16 max_chunk_length){ \
|
||||||
Autoarr_##type* ar=malloc(sizeof(Autoarr_##type)); \
|
Autoarr_##type* ar=malloc(sizeof(Autoarr_##type)); \
|
||||||
*ar=(Autoarr_##type){ \
|
*ar=(Autoarr_##type){ \
|
||||||
.max_blocks_count=max_blocks_count, \
|
.max_chunks_count=max_chunks_count, \
|
||||||
.blocks_count=0, \
|
.chunks_count=0, \
|
||||||
.max_block_length=max_block_length, \
|
.max_chunk_length=max_chunk_length, \
|
||||||
.block_length=0, \
|
.chunk_length=0, \
|
||||||
.values=NULL, \
|
.chunks=NULL, \
|
||||||
.functions=&__Autoarr_##type##_functions_list \
|
.functions=&__Autoarr_##type##_functions_list \
|
||||||
}; \
|
}; \
|
||||||
return ar; \
|
return ar; \
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ char* __path_concat(u32 n, ...){
|
|||||||
// copying content of all strings to rezult
|
// copying content of all strings to rezult
|
||||||
u16 k=0;
|
u16 k=0;
|
||||||
for(; k<n-1; k++){
|
for(; k<n-1; k++){
|
||||||
memcopy(parts[k], totality, lengths[k]);
|
memcpy(totality, parts[k], lengths[k]);
|
||||||
totality+=lengths[k];
|
totality+=lengths[k];
|
||||||
*totality=path_sep;
|
*totality=path_sep;
|
||||||
totality++;
|
totality++;
|
||||||
}
|
}
|
||||||
memcopy(parts[k], totality, lengths[k]);
|
memcpy(totality, parts[k], lengths[k]);
|
||||||
|
|
||||||
free(parts);
|
free(parts);
|
||||||
free(lengths);
|
free(lengths);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ void complete_buf(StringBuilder* b){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void try_complete_buf(StringBuilder* b){
|
void try_complete_buf(StringBuilder* b){
|
||||||
if(b->curr_buf->blocks_count==BL_C)
|
if(b->curr_buf->chunks_count==BL_C)
|
||||||
complete_buf(b);
|
complete_buf(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ string StringBuilder_build(StringBuilder* b){
|
|||||||
|
|
||||||
|
|
||||||
void StringBuilder_rmchar(StringBuilder* b){
|
void StringBuilder_rmchar(StringBuilder* b){
|
||||||
if(b->curr_buf->block_length!=0)
|
if(b->curr_buf->chunk_length!=0)
|
||||||
Autoarr_pop(b->curr_buf)
|
Autoarr_pop(b->curr_buf)
|
||||||
else {
|
else {
|
||||||
if(!b->compl_bufs) throw(ERR_NULLPTR);
|
if(!b->compl_bufs) throw(ERR_NULLPTR);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ extern "C" {
|
|||||||
#include "type_system/type_system.h"
|
#include "type_system/type_system.h"
|
||||||
#include "../kprint/kprintf.h"
|
#include "../kprint/kprintf.h"
|
||||||
#include "endian.h"
|
#include "endian.h"
|
||||||
|
#include "memory/memory.h"
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ u32 cptr_length(const char* str){
|
|||||||
char* cptr_copy(const char* src){
|
char* cptr_copy(const char* src){
|
||||||
u32 len=cptr_length(src)+1;
|
u32 len=cptr_length(src)+1;
|
||||||
char* dst=malloc(len);
|
char* dst=malloc(len);
|
||||||
while(len--!=0)
|
memcpy(dst, src, len);
|
||||||
dst[len]=src[len];
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,13 +130,6 @@ i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 see
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memcopy(void* from, void* to, u32 size){
|
|
||||||
if(from==NULL || to==NULL)
|
|
||||||
throw(ERR_NULLPTR);
|
|
||||||
for(u32 i=0; i<size; i++)
|
|
||||||
((char*)to)[i]=((char*)from)[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
char* __cptr_concat(u32 n, ...){
|
char* __cptr_concat(u32 n, ...){
|
||||||
char** strs=(char**)malloc(n*sizeof(char*));
|
char** strs=(char**)malloc(n*sizeof(char*));
|
||||||
u32* lengths=malloc(n*sizeof(u32));
|
u32* lengths=malloc(n*sizeof(u32));
|
||||||
@@ -162,7 +154,7 @@ char* __cptr_concat(u32 n, ...){
|
|||||||
|
|
||||||
// copying content of all strings to rezult
|
// copying content of all strings to rezult
|
||||||
for(u16 k=0; k<n; k++){
|
for(u16 k=0; k<n; k++){
|
||||||
memcopy(strs[k], totality, lengths[k]);
|
memcpy(totality, strs[k], lengths[k]);
|
||||||
totality+=lengths[k];
|
totality+=lengths[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,8 +66,6 @@ static inline bool cptr_contains(const char* src, const char* fragment){
|
|||||||
return cptr_seek(src, fragment, 0, -1) +1;
|
return cptr_seek(src, fragment, 0, -1) +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memcopy(void* from, void* to, u32 size);
|
|
||||||
|
|
||||||
char* __cptr_concat(u32 n, ...);
|
char* __cptr_concat(u32 n, ...);
|
||||||
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)
|
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)
|
||||||
|
|
||||||
|
|||||||
18
src/base/memory/CstdAllocator.c
Normal file
18
src/base/memory/CstdAllocator.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include "allocators_internal.h"
|
||||||
|
|
||||||
|
void* CstdAllocator_alloc(allocator_t* self, size_t size){
|
||||||
|
assert(size>0);
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CstdAllocator_free(allocator_t* self, void* ptr){
|
||||||
|
assert(ptr!=NULL);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CstdAllocator_construct(CstdAllocator* self){
|
||||||
|
self->base.alloc_f=CstdAllocator_alloc;
|
||||||
|
self->base.free_f=CstdAllocator_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
kt_define(CstdAllocator, NULL, NULL);
|
||||||
84
src/base/memory/LinearAllocator.c
Normal file
84
src/base/memory/LinearAllocator.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include "allocators_internal.h"
|
||||||
|
|
||||||
|
#define chunks_per_allocation 16
|
||||||
|
#define default_chunk_size add_padding(1024)
|
||||||
|
#define chunk_alloc(SZ, OCCUPIED) (MemoryChunk){ .data=malloc(SZ), .size=SZ, .occupied_size=OCCUPIED }
|
||||||
|
#define curr_chunk (self->chunks+self->curr_chunk_i)
|
||||||
|
|
||||||
|
__attribute__ ((noinline)) void* ___alloc_realloc_chunk(LinearAllocator* self, size_t size){
|
||||||
|
free(curr_chunk->data);
|
||||||
|
*curr_chunk=chunk_alloc(size, size);
|
||||||
|
return curr_chunk->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((noinline)) void* __alloc_new_chunk(LinearAllocator* self, size_t size){
|
||||||
|
self->curr_chunk_i++;
|
||||||
|
// next chunk has been already allocated
|
||||||
|
if(self->curr_chunk_i < self->chunks_count)
|
||||||
|
return curr_chunk->data;
|
||||||
|
|
||||||
|
// self->chunks array is full
|
||||||
|
if(self->chunks_count == self->max_chunks_count){
|
||||||
|
self->max_chunks_count += chunks_per_allocation;
|
||||||
|
self->chunks = realloc(self->chunks, sizeof(MemoryChunk) * self->max_chunks_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// new chunk allocation
|
||||||
|
self->chunks_count++;
|
||||||
|
size_t new_chunk_size=default_chunk_size > size ? size : default_chunk_size;
|
||||||
|
*curr_chunk=chunk_alloc(new_chunk_size, new_chunk_size);
|
||||||
|
return curr_chunk->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* LinearAllocator_alloc(allocator_t* _self, size_t size){
|
||||||
|
// assert(_self!=NULL);
|
||||||
|
// assert(size>0);
|
||||||
|
LinearAllocator* self = (LinearAllocator*)_self;
|
||||||
|
size=add_padding(size);
|
||||||
|
|
||||||
|
// aligned size can fit into the current chunk
|
||||||
|
if(curr_chunk->occupied_size + size <= curr_chunk->size){
|
||||||
|
void* data_ptr=curr_chunk->data + curr_chunk->occupied_size;
|
||||||
|
curr_chunk->occupied_size += size;
|
||||||
|
return data_ptr;
|
||||||
|
}
|
||||||
|
// reallocation of current chunk because it is clean
|
||||||
|
if(curr_chunk->occupied_size == 0){
|
||||||
|
// It is very unefficient operation.
|
||||||
|
// If it happens not only in the first chunk, code have to be refactored
|
||||||
|
assert(self->curr_chunk_i==0);
|
||||||
|
return ___alloc_realloc_chunk(self, size);
|
||||||
|
}
|
||||||
|
// creation of a new chunk
|
||||||
|
else {
|
||||||
|
return __alloc_new_chunk(self, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearAllocator_free(allocator_t* _self, void* ptr){
|
||||||
|
// LinearAllocator can't free pointers
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearAllocator_destruct(LinearAllocator* self){
|
||||||
|
// assert(_self!=NULL);
|
||||||
|
for(u16 chunk_i=0; chunk_i < self->chunks_count; chunk_i++){
|
||||||
|
free(self->chunks[chunk_i].data);
|
||||||
|
}
|
||||||
|
free(self->chunks);
|
||||||
|
self->chunks=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearAllocator_construct(LinearAllocator* self, size_t starting_size){
|
||||||
|
assert(self!=NULL);
|
||||||
|
assert(starting_size>0);
|
||||||
|
self->base.alloc_f=LinearAllocator_alloc;
|
||||||
|
self->base.free_f=LinearAllocator_free;
|
||||||
|
|
||||||
|
self->curr_chunk_i=0;
|
||||||
|
self->chunks_count=1;
|
||||||
|
self->max_chunks_count=chunks_per_allocation;
|
||||||
|
self->chunks=malloc(sizeof(*self->chunks) * chunks_per_allocation);
|
||||||
|
self->chunks[0]=chunk_alloc(starting_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
kt_define(LinearAllocator, (freeMembers_t)LinearAllocator_destruct, NULL)
|
||||||
58
src/base/memory/StackingAllocator.c
Normal file
58
src/base/memory/StackingAllocator.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "allocators_internal.h"
|
||||||
|
|
||||||
|
#define chunk_alloc(SZ) (MemoryChunk){ .data=malloc(SZ), .size=SZ, .occupied_size=0 }
|
||||||
|
#define linear self->base
|
||||||
|
#define curr_chunk (linear.chunks+linear.curr_chunk_i)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t data_size;
|
||||||
|
} AllocationHeader;
|
||||||
|
|
||||||
|
void* StackingAllocator_alloc(allocator_t* _self, size_t size){
|
||||||
|
assert(_self!=NULL);
|
||||||
|
assert(size>0);
|
||||||
|
StackingAllocator* self = (StackingAllocator*)_self;
|
||||||
|
size=add_padding(size);
|
||||||
|
|
||||||
|
// allocates memory with header struct before data
|
||||||
|
AllocationHeader* header_ptr=LinearAllocator_alloc(_self, sizeof(AllocationHeader) + size);
|
||||||
|
void* data_ptr = (void*)header_ptr + sizeof(AllocationHeader);
|
||||||
|
header_ptr->data_size = size;
|
||||||
|
|
||||||
|
self->allocations_count++;
|
||||||
|
return data_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StackingAllocator_free(allocator_t* _self, void* data_ptr){
|
||||||
|
assert(_self!=NULL);
|
||||||
|
assert(data_ptr!=NULL);
|
||||||
|
StackingAllocator* self = (StackingAllocator*)_self;
|
||||||
|
AllocationHeader* header_ptr = data_ptr - sizeof(AllocationHeader);
|
||||||
|
|
||||||
|
// chunk is empty
|
||||||
|
if(curr_chunk->occupied_size==0){
|
||||||
|
// isn't the first chunk
|
||||||
|
assert(linear.curr_chunk_i>0);
|
||||||
|
linear.curr_chunk_i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t allocation_size=header_ptr->data_size+sizeof(*header_ptr);
|
||||||
|
// data must fit in chunk
|
||||||
|
assert(allocation_size <= curr_chunk->occupied_size);
|
||||||
|
curr_chunk->occupied_size -= allocation_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StackingAllocator_destruct(StackingAllocator* self){
|
||||||
|
LinearAllocator_destruct(&self->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StackingAllocator_construct(StackingAllocator* self, size_t starting_size){
|
||||||
|
assert(self!=NULL);
|
||||||
|
assert(starting_size>0);
|
||||||
|
LinearAllocator_construct(&linear, starting_size);
|
||||||
|
linear.base.alloc_f=StackingAllocator_alloc;
|
||||||
|
linear.base.free_f=StackingAllocator_free;
|
||||||
|
self->allocations_count=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kt_define(StackingAllocator, (freeMembers_t)StackingAllocator_destruct, NULL)
|
||||||
9
src/base/memory/allocators.c
Normal file
9
src/base/memory/allocators.c
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
void* allocator_transfer(allocator_t* src, allocator_t* dest, void* data, size_t data_size)
|
||||||
|
{
|
||||||
|
void* transfered=allocator_alloc(dest, data_size);
|
||||||
|
memcpy(transfered, data, data_size);
|
||||||
|
allocator_free(src, data);
|
||||||
|
return transfered;
|
||||||
|
}
|
||||||
91
src/base/memory/allocators.h
Normal file
91
src/base/memory/allocators.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../std.h"
|
||||||
|
#include "../type_system/ktDescriptor.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// MemoryAllocator interface //
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct MemoryAllocator allocator_t;
|
||||||
|
|
||||||
|
typedef void* (*alloc_t)(allocator_t*, size_t size);
|
||||||
|
typedef void (*free_t)(allocator_t*, void* ptr);
|
||||||
|
|
||||||
|
typedef struct MemoryAllocator {
|
||||||
|
alloc_t alloc_f;
|
||||||
|
free_t free_f;
|
||||||
|
} allocator_t;
|
||||||
|
|
||||||
|
#define allocator_alloc(ALLOCATOR, SIZE) \
|
||||||
|
((allocator_t*)ALLOCATOR)->alloc_f(ALLOCATOR, SIZE)
|
||||||
|
#define allocator_free(ALLOCATOR, PTR) \
|
||||||
|
((allocator_t*)ALLOCATOR)->free_f(ALLOCATOR, PTR)
|
||||||
|
#define allocator_destruct(ALLOCATOR) \
|
||||||
|
((allocator_t*)ALLOCATOR)->destruct_f(ALLOCATOR)
|
||||||
|
|
||||||
|
void* allocator_transfer(allocator_t* src, allocator_t* dest, void* data, size_t data_size);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// CstdAllocator //
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// Just wrapper for malloc() and free() //
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
STRUCT(CstdAllocator,
|
||||||
|
allocator_t base;
|
||||||
|
);
|
||||||
|
|
||||||
|
void CstdAllocator_construct(CstdAllocator* self);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// LinearAllocator //
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// Can't free allocated memory. //
|
||||||
|
// Allocates new memory chunk when the //
|
||||||
|
// current is full. //
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct MemoryChunk {
|
||||||
|
void* data;
|
||||||
|
size_t size;
|
||||||
|
size_t occupied_size; /* free memory position in the current chunk. */
|
||||||
|
} MemoryChunk;
|
||||||
|
|
||||||
|
STRUCT(LinearAllocator,
|
||||||
|
allocator_t base;
|
||||||
|
MemoryChunk* chunks; /* MemoryChunk[max_chunks_count] */
|
||||||
|
u16 chunks_count; /* allocated chunks */
|
||||||
|
u16 max_chunks_count; /* chunks that can be allocated without reallocating .chunks */
|
||||||
|
u16 curr_chunk_i; /* index of current chunk in .chunks, can be < .chunks_count */
|
||||||
|
);
|
||||||
|
|
||||||
|
void LinearAllocator_construct(LinearAllocator* self, size_t starting_size);
|
||||||
|
void LinearAllocator_destruct(LinearAllocator* self);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// StackingAllocator //
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// The same as Linear, but can free //
|
||||||
|
// allocations in reverse order //
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
STRUCT(StackingAllocator,
|
||||||
|
LinearAllocator base;
|
||||||
|
u32 allocations_count;
|
||||||
|
);
|
||||||
|
|
||||||
|
void StackingAllocator_construct(StackingAllocator* self, size_t starting_size);
|
||||||
|
void StackingAllocator_destruct(StackingAllocator* self);
|
||||||
|
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
4
src/base/memory/allocators_internal.h
Normal file
4
src/base/memory/allocators_internal.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
void* LinearAllocator_alloc(allocator_t* _self, size_t size);
|
||||||
6
src/base/memory/memory.h
Normal file
6
src/base/memory/memory.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "allocators.h"
|
||||||
|
|
||||||
|
// addresses must be aligned to this value
|
||||||
|
#define memory_align sizeof(void*)
|
||||||
|
// adds padding if memory_align if N isn't a multiple of memory_aligh
|
||||||
|
#define add_padding(N) (N + (N%memory_align != 0)*(memory_align - N%memory_align))
|
||||||
@@ -38,6 +38,10 @@ typedef u8 bool;
|
|||||||
#define false 0
|
#define false 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef memcpy
|
||||||
|
extern void* memcpy(void *dest, const void * src, size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define dbg(N) kprintf("\e[95m%d\n",N)
|
#define dbg(N) kprintf("\e[95m%d\n",N)
|
||||||
|
|
||||||
#define nameof(V) #V
|
#define nameof(V) #V
|
||||||
|
|||||||
@@ -199,12 +199,12 @@ static const char* _kp_colorNames[16]={
|
|||||||
"white"
|
"white"
|
||||||
};
|
};
|
||||||
|
|
||||||
char* kp_bgColor_toString(kp_fmt c){
|
char* kp_bgColor_toString(kp_bgColor c){
|
||||||
u32 color_index=(c&0x00f00000)>>20;
|
u32 color_index=(c&0x00f00000)>>20;
|
||||||
if(color_index>15) throw(ERR_WRONGINDEX);
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
return _kp_colorNames[color_index];
|
return _kp_colorNames[color_index];
|
||||||
}
|
}
|
||||||
char* kp_fgColor_toString(kp_fmt c){
|
char* kp_fgColor_toString(kp_fgColor c){
|
||||||
u32 color_index=(c&0x00f00000)>>24;
|
u32 color_index=(c&0x00f00000)>>24;
|
||||||
if(color_index>15) throw(ERR_WRONGINDEX);
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
return _kp_colorNames[color_index];
|
return _kp_colorNames[color_index];
|
||||||
|
|||||||
47
tests/test_allocators.c
Normal file
47
tests/test_allocators.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "tests.h"
|
||||||
|
|
||||||
|
void _test_allocator(allocator_t* al){
|
||||||
|
void* ptr=allocator_alloc(al, 1);
|
||||||
|
allocator_free(al, ptr);
|
||||||
|
ptr=allocator_alloc(al, 5);
|
||||||
|
allocator_free(al, ptr);
|
||||||
|
ptr=allocator_alloc(al, 41);
|
||||||
|
allocator_free(al, ptr);
|
||||||
|
ptr=allocator_alloc(al, 19);
|
||||||
|
void* ptr1=allocator_alloc(al, 1);
|
||||||
|
void* ptr2=allocator_alloc(al, 5);
|
||||||
|
// allocator_free(al, ptr); // temp case
|
||||||
|
allocator_free(al, ptr2);
|
||||||
|
allocator_free(al, ptr1);
|
||||||
|
allocator_free(al, ptr);
|
||||||
|
ptr=allocator_alloc(al, 500);
|
||||||
|
ptr1=allocator_alloc(al, 1025);
|
||||||
|
allocator_free(al, ptr1);
|
||||||
|
allocator_free(al, ptr);/*
|
||||||
|
ptr=allocator_alloc(al, 5000);
|
||||||
|
ptr1=allocator_alloc(al, 5000000);
|
||||||
|
allocator_free(al, ptr1);
|
||||||
|
allocator_free(al, ptr);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_allocators(){
|
||||||
|
kprintf("\e[96m----------[test_allocators]-----------\n");
|
||||||
|
optime("test CstdAllocator", 10000,
|
||||||
|
CstdAllocator al;
|
||||||
|
CstdAllocator_construct(&al);
|
||||||
|
_test_allocator((allocator_t*)&al);
|
||||||
|
);
|
||||||
|
optime("test LinearAllocator", 10000,
|
||||||
|
LinearAllocator al;
|
||||||
|
LinearAllocator_construct(&al, 4096);
|
||||||
|
_test_allocator((allocator_t*)&al);
|
||||||
|
LinearAllocator_destruct(&al);
|
||||||
|
);
|
||||||
|
optime("test StackingAllocator", 10000,
|
||||||
|
StackingAllocator al;
|
||||||
|
StackingAllocator_construct(&al, 4096);
|
||||||
|
_test_allocator((allocator_t*)&al);
|
||||||
|
StackingAllocator_destruct(&al);
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
#include "../src/Autoarr/Autoarr.h"
|
#include "../src/Autoarr/Autoarr.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
i64 _autoarrVsVector(u16 blockCount, u16 blockLength){
|
i64 _autoarrVsVector(u16 chunkCount, u16 chunkLength){
|
||||||
u32 count=blockLength*blockCount;
|
u32 count=chunkLength*chunkCount;
|
||||||
kprintf("\e[94mblock count: %u block length: %u count: " IFWIN("%llu", "%lu") "\n", blockCount, blockLength, (u64)count);
|
kprintf("\e[94mchunk count: %u chunk length: %u count: " IFWIN("%llu", "%lu") "\n", chunkCount, chunkLength, (u64)count);
|
||||||
Autoarr_i64* ar=Autoarr_create(i64, blockCount, blockLength);
|
Autoarr_i64* ar=Autoarr_create(i64, chunkCount, chunkLength);
|
||||||
std::vector<i64> vec=std::vector<i64>();
|
std::vector<i64> vec=std::vector<i64>();
|
||||||
optime("Autoarr_add", count,
|
optime("Autoarr_add", count,
|
||||||
Autoarr_add(ar, op_i));
|
Autoarr_add(ar, op_i));
|
||||||
|
|||||||
@@ -4,17 +4,17 @@
|
|||||||
static void printautoarr(Autoarr(u16)* ar){
|
static void printautoarr(Autoarr(u16)* ar){
|
||||||
kprintf("\e[94mAutoarr(u16): "
|
kprintf("\e[94mAutoarr(u16): "
|
||||||
IFWIN("%llu", "%lu")
|
IFWIN("%llu", "%lu")
|
||||||
"\n max_blocks_count: %u\n"
|
"\n max_chunks_count: %u\n"
|
||||||
" blocks_count: %u\n"
|
" chunks_count: %u\n"
|
||||||
" max_block_length: %u\n"
|
" max_chunk_length: %u\n"
|
||||||
" block_length: %u\n"
|
" chunk_length: %u\n"
|
||||||
" max_length: %u\n"
|
" max_length: %u\n"
|
||||||
" length: %u\n",
|
" length: %u\n",
|
||||||
sizeof(Autoarr(u16)),
|
sizeof(Autoarr(u16)),
|
||||||
ar->max_blocks_count,
|
ar->max_chunks_count,
|
||||||
ar->blocks_count,
|
ar->chunks_count,
|
||||||
ar->max_block_length,
|
ar->max_chunk_length,
|
||||||
ar->block_length,
|
ar->chunk_length,
|
||||||
Autoarr_max_length(ar),
|
Autoarr_max_length(ar),
|
||||||
Autoarr_length(ar));
|
Autoarr_length(ar));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void test_allocators();
|
||||||
void test_cptr();
|
void test_cptr();
|
||||||
void test_string();
|
void test_string();
|
||||||
void test_safethrow();
|
void test_safethrow();
|
||||||
@@ -20,22 +21,23 @@ void test_kprint_colors();
|
|||||||
void test_kprint();
|
void test_kprint();
|
||||||
void test_type_system();
|
void test_type_system();
|
||||||
|
|
||||||
inline void test_all(){
|
static inline void test_all(){
|
||||||
kprintf("\e[97mkerep tests are starting!\n");
|
kprintf("\e[97mkerep tests are starting!\n");
|
||||||
optime(__func__, 1,
|
optime(__func__, 1,
|
||||||
test_cptr();
|
test_allocators();
|
||||||
test_type_system();
|
/*test_cptr();
|
||||||
test_string();
|
test_string();
|
||||||
test_safethrow();
|
test_safethrow();
|
||||||
test_searchtree();
|
test_searchtree();
|
||||||
test_autoarr();
|
test_autoarr();
|
||||||
|
test_hash_functions();
|
||||||
|
test_hashtable();
|
||||||
|
test_dtsod();
|
||||||
test_autoarrVsVector();
|
test_autoarrVsVector();
|
||||||
test_rng_algorithms();
|
test_rng_algorithms();
|
||||||
test_kprint_colors();
|
test_kprint_colors();
|
||||||
test_kprint();
|
test_kprint();
|
||||||
test_hash_functions();
|
test_type_system();*/
|
||||||
test_hashtable();
|
|
||||||
test_dtsod();
|
|
||||||
kprintf("\e[96m--------------------------------------\e[0m\n");
|
kprintf("\e[96m--------------------------------------\e[0m\n");
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user