diff options
author | Nicholas <nbnoll@eml.cc> | 2021-11-20 10:53:19 -0800 |
---|---|---|
committer | Nicholas <nbnoll@eml.cc> | 2021-11-20 10:53:19 -0800 |
commit | a9bfe650038afea8b751175cac16f6027345e45f (patch) | |
tree | 9a7f9feb76a64bb3efe573036d80b7bdbf8a59a5 /include/base/mem.h | |
parent | 1c8d4e69205fd875f6bec3fa3bd929c2e7f52f62 (diff) |
Chore: reorganize libutf and libfmt into base
I found the split to be arbitrary. Better to include the functionality
in the standard library. I also split the headers to allow for more
granular inclusion (but the library is still monolithic). The only
ugliness is the circular dependency introduced with libutf's generated
functions. We put explicit prereqs with the necessary object files
instead.
Diffstat (limited to 'include/base/mem.h')
-rw-r--r-- | include/base/mem.h | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/include/base/mem.h b/include/base/mem.h new file mode 100644 index 0000000..3f1b6e1 --- /dev/null +++ b/include/base/mem.h @@ -0,0 +1,63 @@ +#pragma once + +// ---------------------------------------------------------------------------- +// dynamic array + +typedef struct BufHdr +{ + vlong len; + vlong cap; + byte buf[]; +} BufHdr; + +#define bufhdr(b) ((BufHdr*)((uint8*)(b)-offsetof(BufHdr, buf))) +#define buflen(b) ((b) ? (bufhdr(b)->len) : 0) +#define bufcap(b) ((b) ? (bufhdr(b)->cap) : 0) +#define bufend(b) ((b) + buflen(b)) +#define bufsize(b) ((b) ? (buflen(b) * sizeof((b)[0])) : 0) + +#define buffree(b) ((b) ? (free(bufhdr(b)), (b) = nil) : 0) +#define buffit(b, n) ((n) <= bufcap(b) ? 0 : ((b) = ·bufgrow((b), (n), sizeof(*(b))))) + +#define bufpush(b, ...) (buffit((b), 1 + buflen(b)), (b)[bufhdr(b)->len++] = (__VA_ARGS__)) +#define bufaddn(b, n) (buffit(b, buflen(b)+n), bufhdr(b)->len += n, b+bufhdr(b)->len-n) + +#define bufpop(b) ((b)[--bufhdr(b)->len]) +#define bufdel(b, i) bufdeln((b), (i), 1) +#define bufdeln(b, i, n) (memmove((b)+(i), (b)+(i)+(n), sizeof(*(b))*(bufhdr(b)->len-(n)-(i)), bufhdr(b)->len -= (n)) +#define bufdelswap(b, i) ((b)[i] = bufend(b)[-1], bufhdr(b)->len-=1) + +void* ·bufgrow(void*, vlong, vlong); + +// ----------------------------------------------------------------------------- +// memory allocation + +/* allocator interface */ +typedef struct mem·Allocator { + void *(*alloc)(void *heap, uint n, ulong size); + void (*free)(void *heap, void *ptr); +} mem·Allocator; + +extern mem·Allocator sys·Memory; + +typedef struct mem·Reallocator { + void *(*alloc)(void *iface, uint n, ulong size); + void *(*realloc)(void *iface, void *ptr, uint n, ulong size); + void (*free)(void *iface, void *ptr); +} mem·Reallocator; + +extern mem·Reallocator sys·FullMemory; + +/* simple memory arena */ +typedef struct mem·Arena mem·Arena; + +mem·Arena *mem·makearena(mem·Allocator from, void*); +void *mem·arenaalloc(mem·Arena *A, uint n, ulong size); +void mem·freearena(mem·Arena *A); + +extern mem·Allocator mem·ArenaAllocator; + +/* generalized memxxx functions */ +void memset64(void *dst, uint64 val, uintptr size); + + |