summaryrefslogtreecommitdiff
path: root/reduced_system_layer.c
diff options
context:
space:
mode:
Diffstat (limited to 'reduced_system_layer.c')
-rwxr-xr-xreduced_system_layer.c94
1 files changed, 65 insertions, 29 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