arena allocator
This commit is contained in:
parent
0c97ba45b1
commit
59fee5094b
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
1
.idea/.name
generated
1
.idea/.name
generated
@ -1 +0,0 @@
|
||||
flint
|
91
.idea/editor.xml
generated
91
.idea/editor.xml
generated
@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="BackendCodeEditorSettings">
|
||||
<option name="/Default/Housekeeping/GlobalSettingsUpgraded/IsUpgraded/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
|
||||
</component>
|
||||
</project>
|
2
.idea/libfputs.iml
generated
2
.idea/libfputs.iml
generated
@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
7
.idea/misc.xml
generated
7
.idea/misc.xml
generated
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakePythonSetting">
|
||||
<option name="pythonIntegrationState" value="YES" />
|
||||
</component>
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/libfputs.iml" filepath="$PROJECT_DIR$/.idea/libfputs.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -22,6 +22,7 @@ set(SOURCES
|
||||
src/crypto.c
|
||||
src/parsing.c
|
||||
src/network.c
|
||||
src/memory.c
|
||||
)
|
||||
|
||||
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin"))
|
||||
|
@ -57,3 +57,11 @@ Works the same as `bresenham()` but uses the `Point` struct instead of `int`
|
||||
```c
|
||||
Point *bresenham_p(Point p1, Point p2, size_t *sz);
|
||||
```
|
||||
|
||||
## is_power_of_two
|
||||
|
||||
Returns `1` if `i` is a power of two, otherwise returns `1`.
|
||||
|
||||
```c
|
||||
int is_power_of_two(int i);
|
||||
```
|
||||
|
99
docs/memory.md
Normal file
99
docs/memory.md
Normal file
@ -0,0 +1,99 @@
|
||||
# memory
|
||||
|
||||
Custom allocators and memory functions
|
||||
|
||||
# Arena Allocator
|
||||
|
||||
A simple arena-style allocator
|
||||
|
||||
## Structs
|
||||
|
||||
### ArenaAllocator
|
||||
|
||||
Represents an arena allocator. `ArenaAllocator` holds its own buffer, but managing its size is left to the user. Like
|
||||
most structs in `libflint`, it must be malloced first before being passed to `arena_init()`.
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
unsigned char* buf;
|
||||
size_t buf_sz;
|
||||
size_t offset_cur;
|
||||
size_t offset_prev;
|
||||
} ArenaAllocator;
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
### arena_init
|
||||
|
||||
Initializes the `ArenaAllocator`. The struct must first be created by the user using `malloc()`, see the example below.
|
||||
`buf_sz` is the size of the underlying buffer in bytes.
|
||||
|
||||
```c
|
||||
void arena_init(ArenaAllocator *allocator, size_t buf_sz);
|
||||
|
||||
/* Usage */
|
||||
ArenaAllocator *a = malloc(sizeof(ArenaAllocator));
|
||||
arena_init(a, 1024);
|
||||
```
|
||||
|
||||
### arena_free
|
||||
Frees `allocator` and its underlying buffer. Users should set `allocator` to `NULL` after calling `arena_free()`.
|
||||
```c
|
||||
void arena_free(ArenaAllocator *allocator);
|
||||
|
||||
/* Usage */
|
||||
arena_free(allocator);
|
||||
allocator = NULL;
|
||||
```
|
||||
|
||||
### arena_clear
|
||||
|
||||
Resets the offset markers of the arena to `0`, but does not wipe the underlying buffer. Technically, any assigned pointers
|
||||
will still work and
|
||||
|
||||
```c
|
||||
void arena_clear(ArenaAllocator *allocator);
|
||||
```
|
||||
|
||||
|
||||
### *arena_malloc
|
||||
|
||||
Request memory of `size` bytes in length from the arena. Returns `NULL` if the assignment failed.
|
||||
|
||||
```c
|
||||
void *arena_malloc(ArenaAllocator* allocator, size_t size);
|
||||
```
|
||||
|
||||
### arena_resize_buf
|
||||
|
||||
Reallocates the underlying buffer in the arena to `new_sz`. You can grow or shrink the arena using this function. Any
|
||||
pointers allocated out of the arena are invalid after using this function.
|
||||
|
||||
```c
|
||||
void arena_resize_buf(ArenaAllocator *allocator, size_t new_sz);
|
||||
```
|
||||
|
||||
### *arena_resize
|
||||
|
||||
Resize an allocated pointer from the arena. See the example below for a simple use case
|
||||
|
||||
```c
|
||||
void *arena_resize(ArenaAllocator *allocator, void *mem, size_t old_sz, size_t new_sz);
|
||||
|
||||
/* Usage */
|
||||
int *i = arena_malloc(a, sizeof(int));
|
||||
*i = 1;
|
||||
long *l = arena_resize(a, i1, sizeof(int), sizeof(long));
|
||||
assert(*l == 1);
|
||||
```
|
||||
|
||||
## Macros
|
||||
|
||||
### arena_sz
|
||||
|
||||
Convenience macro for getting the size of the arena's buffer
|
||||
|
||||
```c
|
||||
#define arena_sz(a) (a)->buf_sz
|
||||
```
|
@ -1,6 +1,8 @@
|
||||
#ifndef LIBFLINT_H_MATH
|
||||
#define LIBFLINT_H_MATH
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "lfutility.h"
|
||||
|
||||
int max_int(int a, int b);
|
||||
@ -11,6 +13,8 @@ int clamp_int(int i, int low, int high);
|
||||
|
||||
int binstr_to_int(const char *s);
|
||||
|
||||
int is_power_of_two(int i);
|
||||
|
||||
Point *bresenham(int x0, int y0, int x1, int y1, size_t *sz);
|
||||
|
||||
Point *bresenham_p(Point p1, Point p2, size_t *sz);
|
||||
|
20
include/lfmemory.h
Normal file
20
include/lfmemory.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef LIBFLINT_H_MEMORY
|
||||
#define LIBFLINT_H_MEMORY
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned char* buf;
|
||||
size_t buf_sz;
|
||||
size_t offset_cur;
|
||||
size_t offset_prev;
|
||||
} ArenaAllocator;
|
||||
|
||||
void arena_init(ArenaAllocator *allocator, size_t buf_sz);
|
||||
void arena_free(ArenaAllocator *allocator);
|
||||
void *arena_malloc(ArenaAllocator* allocator, size_t size);
|
||||
void arena_resize_buf(ArenaAllocator *allocator, size_t new_sz);
|
||||
void *arena_resize(ArenaAllocator *allocator, void *mem, size_t old_sz, size_t new_sz);
|
||||
void arena_clear(ArenaAllocator *allocator);
|
||||
|
||||
#endif // LIBFLINT_H_MEMORY
|
@ -77,3 +77,6 @@ Point *bresenham_p(Point p1, Point p2, size_t *sz) {
|
||||
return bresenham(p1.x, p1.y, p2.x, p2.y, sz);
|
||||
}
|
||||
|
||||
int is_power_of_two(int i) {
|
||||
return (i & (i - 1)) == 0;
|
||||
}
|
||||
|
109
src/memory.c
Normal file
109
src/memory.c
Normal file
@ -0,0 +1,109 @@
|
||||
#include <lfmath.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lfmemory.h"
|
||||
|
||||
#define arena_sz(a) (a)->buf_sz
|
||||
|
||||
void arena_init(ArenaAllocator *allocator, size_t buf_sz) {
|
||||
if (allocator == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
allocator->buf = malloc(sizeof(unsigned char) * buf_sz);
|
||||
allocator->buf_sz = buf_sz;
|
||||
allocator->offset_cur = 0;
|
||||
allocator->offset_prev = 0;
|
||||
}
|
||||
|
||||
void arena_free(ArenaAllocator *allocator) {
|
||||
free(allocator->buf);
|
||||
free(allocator);
|
||||
}
|
||||
|
||||
void arena_clear(ArenaAllocator *allocator) {
|
||||
allocator->offset_cur = 0;
|
||||
allocator->offset_prev = 0;
|
||||
}
|
||||
|
||||
static uintptr_t align_forward(uintptr_t ptr, size_t align) {
|
||||
uintptr_t p, a, m;
|
||||
if (!is_power_of_two(align)) {
|
||||
// TODO: Error
|
||||
}
|
||||
p = ptr;
|
||||
a = (uintptr_t)align;
|
||||
m = p & (a - 1);
|
||||
|
||||
if (m != 0) {
|
||||
p += a - m;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void *arena_malloc_align(ArenaAllocator *allocator, size_t size, size_t align) {
|
||||
uintptr_t cur_ptr = (uintptr_t)allocator->buf + (uintptr_t)allocator->offset_cur;
|
||||
|
||||
// Push forward to align, then change to relative offset
|
||||
uintptr_t offset = align_forward(cur_ptr, align);
|
||||
offset -= (uintptr_t)allocator->buf;
|
||||
|
||||
if (offset + size <= allocator->buf_sz) {
|
||||
void *ptr = &allocator->buf[offset];
|
||||
allocator->offset_prev = offset;
|
||||
allocator->offset_cur = offset + size;
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Arena is full
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *arena_resize_align(ArenaAllocator *allocator, void *mem, size_t old_sz, size_t new_sz, size_t align) {
|
||||
unsigned char *old_mem = (unsigned char *)mem;
|
||||
if (!is_power_of_two(align)) {
|
||||
// TODO: Error handling
|
||||
}
|
||||
|
||||
if (old_mem == NULL || old_sz == 0) {
|
||||
return arena_malloc_align(allocator, new_sz, align);
|
||||
}
|
||||
|
||||
if (allocator->buf <= mem && mem < allocator->buf + allocator->buf_sz) {
|
||||
if (allocator->buf + allocator->offset_prev == old_mem) {
|
||||
allocator->offset_cur = allocator->offset_prev + new_sz;
|
||||
if (new_sz > old_sz) {
|
||||
// Zero out memory
|
||||
memset(&allocator->buf[allocator->offset_cur], 0, new_sz - old_sz);
|
||||
}
|
||||
return old_mem;
|
||||
}
|
||||
|
||||
void *new_mem = arena_malloc_align(allocator, new_sz, align);
|
||||
size_t copy_size = old_sz < new_sz ? old_sz : new_sz;
|
||||
memmove(new_mem, old_mem, copy_size);
|
||||
return new_mem;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void arena_resize_buf(ArenaAllocator *allocator, size_t new_sz) {
|
||||
allocator->buf = realloc(allocator->buf, sizeof(unsigned char) * new_sz);
|
||||
}
|
||||
|
||||
#ifndef DEFAULT_ALIGNMENT
|
||||
#define DEFAULT_ALIGNMENT (2*sizeof(void*))
|
||||
#endif // DEFAULT_ALIGNMENT
|
||||
|
||||
void *arena_malloc(ArenaAllocator *allocator, size_t size) {
|
||||
return arena_malloc_align(allocator, size, DEFAULT_ALIGNMENT);
|
||||
}
|
||||
|
||||
void *arena_resize(ArenaAllocator *allocator, void *mem, size_t old_sz, size_t new_sz) {
|
||||
return arena_resize_align(allocator, mem, old_sz, new_sz, DEFAULT_ALIGNMENT);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "lfcrypto.h"
|
||||
#include "lfparsing.h"
|
||||
#include "lfinput.h"
|
||||
#include "lfmemory.h"
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
#include "lfmacos.h"
|
||||
@ -468,6 +469,30 @@ void test_macos() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_memory() {
|
||||
printf("\n--- MEMORY TEST ---\n");
|
||||
ArenaAllocator *a = malloc(sizeof(ArenaAllocator));
|
||||
arena_init(a, 1024);
|
||||
|
||||
int *i1 = arena_malloc(a, sizeof(int));
|
||||
int *i2 = arena_malloc(a, sizeof(int));
|
||||
|
||||
*i1 = 1;
|
||||
*i2 = 2;
|
||||
|
||||
assert(i1 < i2);
|
||||
assert(*i1 < *i2);
|
||||
|
||||
long *l = arena_resize(a, i1, sizeof(int), sizeof(long));
|
||||
assert(*l == 1);
|
||||
|
||||
unsigned char *c = arena_resize(a, i2, sizeof(int), sizeof(unsigned char));
|
||||
assert(*c == 2);
|
||||
|
||||
arena_free(a);
|
||||
printf("Passes all memory tests\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_ll();
|
||||
test_set();
|
||||
@ -479,6 +504,7 @@ int main() {
|
||||
test_crypto();
|
||||
test_parsing();
|
||||
test_network();
|
||||
test_memory();
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
test_macos();
|
||||
|
Loading…
x
Reference in New Issue
Block a user