diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2025-02-09 08:20:38 +0100 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2025-02-09 08:20:38 +0100 |
commit | a8d7b8b5d90b0251f5e37e98d079c1d88498f697 (patch) | |
tree | df412b6fdb1e34df71125db76fee1ae8cc35e49d | |
parent | b7b092a08dd3a61abcd7f9daabfc21fd3a392fa9 (diff) | |
download | reduced_system_layer-a8d7b8b5d90b0251f5e37e98d079c1d88498f697.zip |
Cleanup
-rwxr-xr-x | reduced_system_layer.c | 94 | ||||
-rwxr-xr-x | stackless_coroutine.c | 98 |
2 files changed, 127 insertions, 65 deletions
diff --git a/reduced_system_layer.c b/reduced_system_layer.c index 847edae..b1bb8ce 100755 --- a/reduced_system_layer.c +++ b/reduced_system_layer.c @@ -775,25 +775,16 @@ void run_main_window_event_loop(void) { // // ================================================================ -enum { - OCCUPIED_SIZE_ = (STATIC_MEMORY_BUFFER_SIZE + 64 * MEMORY_CHUNK_SIZE - 1) / (64 * MEMORY_CHUNK_SIZE), -}; - -typedef struct { - i64 next_chunk; - u64 occupied[OCCUPIED_SIZE_]; -} Memory_Buffer_Header_; - static u8 memory_buffer_[STATIC_MEMORY_BUFFER_SIZE] = {0}; -static i64 num_memory_slots_(void) { - return *(i64 *) &g_platform.memory_buffer[g_platform.memory_buffer_size - 8]; -} - static i64 align_(i64 x, i64 alignment) { return ((x + (alignment - 1)) / alignment) * alignment; } +static i64 memory_buffer_occupied_len_(i64 buffer_size) { + return (buffer_size + 64 * MEMORY_CHUNK_SIZE - 1) / (64 * MEMORY_CHUNK_SIZE); +} + void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *previous_data) { if (g_platform.memory_buffer_size < 0) { LOG_ERROR("Invalid memory buffer size."); @@ -810,32 +801,62 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p g_platform.memory_buffer = memory_buffer_; } - if (g_platform.memory_buffer_size <= (i64) sizeof(Memory_Buffer_Header_)) { + i64 occupied_len = memory_buffer_occupied_len_(g_platform.memory_buffer_size); + u64 *occupied = (u64 *) g_platform.memory_buffer; + + if (g_platform.memory_buffer_size <= occupied_len * 64) { LOG_ERROR("Memory buffer too small."); return NULL; } - Memory_Buffer_Header_ *h = (Memory_Buffer_Header_ *) g_platform.memory_buffer; - u8 * data = g_platform.memory_buffer + sizeof(Memory_Buffer_Header_); + if (alignment <= 0) { + LOG_ERROR("Invalid alignment: %lld", alignment); + return NULL; + } + + if (size < 0) { + LOG_ERROR("Invalid size: %lld", size); + return NULL; + } + + if (previous_size < 0) { + LOG_ERROR("Invalid previous size: %lld", previous_size); + return NULL; + } + + if (previous_size > 0 && previous_data == NULL) { + LOG_ERROR("Invalid previous data."); + return NULL; + } - i64 prev_num_chunks = (align_(previous_size, alignment) + MEMORY_CHUNK_SIZE - 1) / MEMORY_CHUNK_SIZE; - i64 prev_chunk = ((u8 *) previous_data - data) / MEMORY_CHUNK_SIZE; + u8 *data = g_platform.memory_buffer + occupied_len * 64; - i64 num_chunks = (align_(size, alignment) + MEMORY_CHUNK_SIZE - 1) / MEMORY_CHUNK_SIZE; - i64 chunk = 0; + i64 prev_num_chunks = 0; + i64 prev_chunk = 0; + + if (previous_size > 0) { + prev_num_chunks = (align_(previous_size, alignment) + MEMORY_CHUNK_SIZE - 1) / MEMORY_CHUNK_SIZE; + prev_chunk = ((u8 *) previous_data - data) / MEMORY_CHUNK_SIZE; + } - // Find free space - for (i64 i = h->next_chunk; i < OCCUPIED_SIZE_ * 64; ++i) { - b8 occupied = 0; + i64 num_chunks = (align_(size, alignment) + MEMORY_CHUNK_SIZE - 1) / MEMORY_CHUNK_SIZE; + i64 chunk = (g_platform.memory_buffer_size + MEMORY_CHUNK_SIZE - 1) / MEMORY_CHUNK_SIZE; + + // Search free space + i64 i0 = 0; + while (i0 < occupied_len && occupied[i0] == ~0ull) + ++i0; + for (i64 i = i0; i < occupied_len * 64; ++i) { + b8 is_occupied = 0; for (i64 j = i; j < i + num_chunks; ++j) { if (j >= prev_chunk && j < prev_chunk + prev_num_chunks) continue; - if ((h->occupied[j / 64] & (1ull << (j % 64))) == 0) continue; - occupied = 1; + if ((occupied[j / 64] & (1ull << (j % 64))) == 0) continue; + is_occupied = 1; break; } - if (occupied) { + if (is_occupied) { chunk = i; break; } @@ -846,14 +867,14 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p i64 len = size < previous_size ? size : previous_size; // Check if out of memory - if (data + size > g_platform.memory_buffer + g_platform.memory_buffer_size) { + if (dst + size > g_platform.memory_buffer + g_platform.memory_buffer_size) { LOG_ERROR("Out of memory."); return NULL; } // Claim required space for (i64 j = chunk; j < chunk + num_chunks; ++j) - h->occupied[j / 64] |= 1ull << (j % 64); + occupied[j / 64] |= 1ull << (j % 64); // Copy data if (dst > src) @@ -866,7 +887,7 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p // Free previous space for (i64 j = prev_chunk; j < prev_chunk + prev_num_chunks; ++j) { if (j >= chunk && j < chunk + num_chunks) continue; - h->occupied[j / 64] &= ~(1ull << (j % 64)); + occupied[j / 64] &= ~(1ull << (j % 64)); } if (num_chunks == 0) @@ -875,6 +896,21 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p return dst; } +void memory_buffer_wrap(i64 *num, void **data, i64 element_size, i64 new_num) { + void *new_data = memory_buffer_allocate( + new_num * element_size, + element_size, + *num * element_size, + *data + ); + + if (new_data == NULL && new_num > 0) + return; + + *num = new_num; + *data = new_data; +} + // ================================================================ // // BLAKE2B diff --git a/stackless_coroutine.c b/stackless_coroutine.c index cbd02f9..27a1123 100755 --- a/stackless_coroutine.c +++ b/stackless_coroutine.c @@ -123,7 +123,7 @@ static void stackless_coroutine_dispatch(void *promise) { # pragma GCC diagnostic pop #endif -#define CORO_PROMISE_STRUCT_(Ret_Type_, coro_, ...) \ +#define CORO_PROMISE_STRUCT_(coro_, Ret_Type_, ...) \ struct Coro_Promise_##coro_ { \ CORO_PROMISE_DATA_; \ Ret_Type_ return_value; \ @@ -147,30 +147,30 @@ static void stackless_coroutine_dispatch(void *promise) { self->_index = -1; \ } -#define CORO_DECL(Ret_Type_, coro_, ...) \ - CORO_PROMISE_STRUCT_(Ret_Type_, coro_, __VA_ARGS__); \ +#define CORO_DECL(coro_, Ret_Type_, ...) \ + CORO_PROMISE_STRUCT_(coro_, Ret_Type_, __VA_ARGS__); \ CORO_PROC_DECL_(coro_) -#define CORO_DECL_STATIC(Ret_Type_, coro_, ...) \ - CORO_PROMISE_STRUCT_(Ret_Type_, coro_, __VA_ARGS__); \ +#define CORO_DECL_STATIC(coro_, Ret_Type_, ...) \ + CORO_PROMISE_STRUCT_(coro_, Ret_Type_, __VA_ARGS__); \ static CORO_PROC_DECL_(coro_) -#define CORO(Ret_Type_, coro_, ...) \ - CORO_PROMISE_STRUCT_(Ret_Type_, coro_, __VA_ARGS__); \ +#define CORO(coro_, Ret_Type_, ...) \ + CORO_PROMISE_STRUCT_(coro_, Ret_Type_, __VA_ARGS__); \ CORO_IMPL(coro_) #define CORO_DECL_VOID(coro_, ...) \ - CORO_DECL(Coro_Void_, coro_, __VA_ARGS__) + CORO_DECL(coro_, Coro_Void_, __VA_ARGS__) #define CORO_VOID(coro_, ...) \ - CORO(Coro_Void_, coro_, __VA_ARGS__) + CORO(coro_, Coro_Void_, __VA_ARGS__) -#define CORO_STATIC(Ret_Type_, coro_, ...) \ - CORO_PROMISE_STRUCT_(Ret_Type_, coro_, __VA_ARGS__); \ +#define CORO_STATIC(coro_, Ret_Type_, ...) \ + CORO_PROMISE_STRUCT_(coro_, Ret_Type_, __VA_ARGS__); \ static CORO_IMPL(coro_) #define CORO_STATIC_VOID(coro_, ...) \ - CORO_STATIC(Coro_Void_, coro_, __VA_ARGS__) + CORO_STATIC(coro_, Coro_Void_, __VA_ARGS__) #define coro_resume(promise_) \ stackless_coroutine_dispatch(&(promise_)) @@ -285,11 +285,16 @@ static void stackless_coroutine_dispatch(void *promise) { #define TEST_FILE stackless_coroutine #include "test.c" -CORO_DECL(int, test_foo, ); +CORO_DECL( + test_foo, + int, +); -CORO_IMPL(test_foo) { - async_return(42); -} CORO_END +CORO_IMPL(test_foo) +{ + async_return (42); +} +CORO_END TEST("coroutine init") { Promise_Of(test_foo) promise; @@ -311,12 +316,17 @@ TEST("coroutine execute and return") { REQUIRE(coro_finished(promise)); } -CORO_DECL_STATIC(int, test_bar, ); +CORO_DECL_STATIC( + test_bar, + int, +); -CORO_IMPL(test_bar) { +CORO_IMPL(test_bar) +{ yield_void; - async_return(42); -} CORO_END + async_return (42); +} +CORO_END TEST("coroutine execute two steps") { Promise_Of(test_bar) promise; @@ -327,17 +337,22 @@ TEST("coroutine execute two steps") { REQUIRE(promise.return_value == 42); } -CORO_STATIC(int, test_gen, int i; int min; int max;) { +CORO_STATIC( + test_gen, + int, + int i; int min; int max; +) { for (self->i = self->min; self->i < self->max; self->i++) - yield(self->i); - async_return(self->max); -} CORO_END + yield (self->i); + async_return (self->max); +} +CORO_END TEST("coroutine generator") { - int i; Promise_Of(test_gen) promise; CORO_INIT(promise, test_gen, .min = 10, .max = 15); - for (i = 0; i <= 5; i++) REQUIRE(coro_next(promise) == 10 + i); + for (i32 i = 0; i <= 5; i++) + REQUIRE(coro_next(promise) == 10 + i); } TEST("coroutine status finished") { @@ -350,11 +365,13 @@ TEST("coroutine status finished") { REQUIRE(coro_finished(promise)); } -CORO_STATIC_VOID(test_task, ) { +CORO_STATIC_VOID(test_task, ) +{ yield_void; yield_void; async_return_void; -} CORO_END +} +CORO_END TEST("coroutine task") { Promise_Of(test_task) promise; @@ -367,12 +384,16 @@ TEST("coroutine task") { REQUIRE(coro_finished(promise)); } -CORO_STATIC_VOID(test_nest_task, Promise_Of(test_task) promise;) { +CORO_STATIC_VOID( + test_nest_task, + Promise_Of(test_task) promise; +) { CORO_INIT(self->promise, test_task, ); - await(self->promise); - await(self->promise); - await(self->promise); -} CORO_END + await (self->promise); + await (self->promise); + await (self->promise); +} +CORO_END TEST("coroutine nested task") { Promise_Of(test_nest_task) promise; @@ -385,10 +406,15 @@ TEST("coroutine nested task") { REQUIRE(coro_finished(promise)); } -CORO_STATIC(int, test_nest_generator, Promise_Of(test_gen) promise;) { +CORO_STATIC( + test_nest_generator, + int, + Promise_Of(test_gen) promise; +) { CORO_INIT(self->promise, test_gen, .min = 1, .max = 3); - yield_await(self->promise); -} CORO_END + yield_await (self->promise); +} +CORO_END TEST("coroutine nested generator") { Promise_Of(test_nest_generator) promise; |