summaryrefslogtreecommitdiff
path: root/reduced_system_layer.c
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-02-11 11:06:28 +0100
committerMitya Selivanov <automainint@guattari.tech>2025-02-11 11:06:28 +0100
commit2d71f1099f0eb3ef6e17316a520d3d710dec1ac0 (patch)
tree32d2db34046c1496f20650e1d3857aa5d3f9c2d7 /reduced_system_layer.c
parented275e1296defb6cc5450cf5996cf97c1fa32dfa (diff)
downloadreduced_system_layer-2d71f1099f0eb3ef6e17316a520d3d710dec1ac0.zip
Memory buffer fixes
Diffstat (limited to 'reduced_system_layer.c')
-rwxr-xr-xreduced_system_layer.c218
1 files changed, 71 insertions, 147 deletions
diff --git a/reduced_system_layer.c b/reduced_system_layer.c
index ad5e990..3d6a08d 100755
--- a/reduced_system_layer.c
+++ b/reduced_system_layer.c
@@ -111,6 +111,9 @@
#/ - macOS support
#/ - Mobile devices support
#/
+#/ Bugs
+#/ - Buffer overflow after resizing the window.
+#/
#/ Done
#/
#/ - Examples
@@ -249,7 +252,7 @@ i32 main(i32 argc, c8 **argv);
#endif
#ifndef STATIC_MEMORY_BUFFER_SIZE
-#define STATIC_MEMORY_BUFFER_SIZE (10 * 1024 * 1024)
+#define STATIC_MEMORY_BUFFER_SIZE (20 * 1024 * 1024)
#endif
#ifndef MEMORY_CHUNK_SIZE
@@ -288,11 +291,11 @@ i32 main(i32 argc, c8 **argv);
#endif
#ifndef NUM_FRAMES_AVERAGED
-#define NUM_FRAMES_AVERAGED 400
+#define NUM_FRAMES_AVERAGED 600
#endif
#ifndef AVERAGE_FRAME_BIAS
-#define AVERAGE_FRAME_BIAS (0.02)
+#define AVERAGE_FRAME_BIAS (0.03)
#endif
#ifndef MAX_NUM_KEYS
@@ -616,8 +619,8 @@ typedef struct {
i64 num_sound_samples_elapsed;
i64 num_pixels;
- i64 sketch_len;
i64 input_len;
+ i64 input_capacity;
i64 num_drop_files;
i64 clipboard_text_len;
i64 clipboard_image_width;
@@ -626,11 +629,7 @@ typedef struct {
i64 num_clipboard_sound_samples;
i64 clipboard_sound_len;
- i64 pixels_capacity;
- i64 input_capacity;
-
vec4_f32 *pixels;
- f32 *sketch;
Input_Key *input;
Drop_File *drop_files;
c8 *clipboard_text;
@@ -713,12 +712,10 @@ extern Platform g_platform;
Platform g_platform = {0};
-static i64 _sound_clock_time = 0;
-static i64 _sound_clock_carry = 0;
-static i64 _sound_position = 0;
-static i64 _frame_index = 0;
-static i64 _drop_files_buffer_len = 0;
-static u8 *_drop_files_buffer = NULL;
+static i64 _sound_clock_time = 0;
+static i64 _sound_clock_carry = 0;
+static i64 _sound_position = 0;
+static i64 _frame_index = 0;
static f32 _sound_ring [MAX_NUM_PRIMARY_SOUND_FRAMES] = {0};
static i64 _frame_duration [NUM_FRAMES_AVERAGED] = {0};
@@ -792,10 +789,13 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p
g_platform.memory_buffer = memory_buffer_;
}
- i64 occupied_len = memory_buffer_occupied_len_(g_platform.memory_buffer_size);
- u64 *occupied = (u64 *) g_platform.memory_buffer;
+ i64 occupied_len = memory_buffer_occupied_len_(g_platform.memory_buffer_size);
+ i64 occupied_len_bytes = occupied_len * 8;
+ i64 occupied_len_bits = occupied_len * 64;
+
+ u64 *occupied = (u64 *) g_platform.memory_buffer;
- if (g_platform.memory_buffer_size <= occupied_len * 64) {
+ if (g_platform.memory_buffer_size <= occupied_len_bytes) {
LOG_ERROR("Memory buffer too small.");
return NULL;
}
@@ -820,7 +820,7 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p
return NULL;
}
- u8 *data = g_platform.memory_buffer + occupied_len * 64;
+ u8 *data = g_platform.memory_buffer + occupied_len_bytes;
i64 prev_num_chunks = 0;
i64 prev_chunk = 0;
@@ -835,31 +835,26 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p
// Search free space
i64 i0 = 0;
- while (i0 < occupied_len && occupied[i0] == ~0ull)
- ++i0;
- for (i64 i = i0; i < occupied_len * 64; ++i) {
+ while (i0 < occupied_len_bits && occupied[i0 / 64] == ~0ull)
+ i0 += 64;
+ for (i64 i = i0; i < occupied_len_bits; ++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 ((occupied[j / 64] & (1ull << (j % 64))) == 0) continue;
+ if ((occupied[j / 64] & (1ull << (j % 64))) == 0) continue;
is_occupied = 1;
break;
}
-
- if (is_occupied) {
+ if (!is_occupied) {
chunk = i;
break;
}
}
- u8 *src = data + prev_chunk * MEMORY_CHUNK_SIZE;
- u8 *dst = data + chunk * MEMORY_CHUNK_SIZE;
- i64 len = size < previous_size ? size : previous_size;
-
// Check if out of memory
+ u8 *dst = data + chunk * MEMORY_CHUNK_SIZE;
if (dst + size > g_platform.memory_buffer + g_platform.memory_buffer_size) {
- LOG_ERROR("Out of memory.");
+ LOG_ERROR("Out of memory: %lld bytes", size - previous_size);
return NULL;
}
@@ -868,6 +863,8 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p
occupied[j / 64] |= 1ull << (j % 64);
// Copy data
+ u8 *src = data + prev_chunk * MEMORY_CHUNK_SIZE;
+ i64 len = size < previous_size ? size : previous_size;
if (dst > src)
for (i64 k = len - 1; k >= 0; --k)
dst[k] = src[k];
@@ -901,6 +898,7 @@ void resize_dynamic_array_exact(i64 *num, void **data, i64 element_size, i64 new
);
if (new_data == NULL && new_num > 0)
+ // Out of memory.
return;
*num = new_num;
@@ -916,7 +914,8 @@ void resize_dynamic_array_capacity(i64 *num, i64 *capacity, void **data, i64 ele
if (new_num > *capacity)
resize_dynamic_array_exact(capacity, data, element_size, new_num);
- *num = new_num;
+ if (new_num <= *capacity)
+ *num = new_num;
}
// ================================================================
@@ -982,19 +981,6 @@ static b8 native_little_endian_(void) {
return ((u8 *) &(u32) { 1 })[0] == 1;
}
-static u32 load32_(void *src) {
- if (native_little_endian_())
- return *( u32 * )( src );
- else {
- u8 *p = ( u8 * )src;
- u32 w = *p++;
- w |= ( u32 )( *p++ ) << 8;
- w |= ( u32 )( *p++ ) << 16;
- w |= ( u32 )( *p++ ) << 24;
- return w;
- }
-}
-
static u64 load64_(void *src) {
if (native_little_endian_())
return *( u64 * )( src );
@@ -1040,39 +1026,6 @@ static void store64_(void *dst, u64 w) {
}
}
-static u64 load48_(void *src) {
- u8 *p = ( u8 * )src;
- u64 w = *p++;
- w |= ( u64 )( *p++ ) << 8;
- w |= ( u64 )( *p++ ) << 16;
- w |= ( u64 )( *p++ ) << 24;
- w |= ( u64 )( *p++ ) << 32;
- w |= ( u64 )( *p++ ) << 40;
- return w;
-}
-
-static void store48_(void *dst, u64 w) {
- u8 *p = ( u8 * )dst;
- *p++ = ( u8 )w; w >>= 8;
- *p++ = ( u8 )w; w >>= 8;
- *p++ = ( u8 )w; w >>= 8;
- *p++ = ( u8 )w; w >>= 8;
- *p++ = ( u8 )w; w >>= 8;
- *p++ = ( u8 )w;
-}
-
-static u32 rotl32_(u32 w, u32 c) {
- return ( w << c ) | ( w >> ( 32 - c ) );
-}
-
-static u64 rotl64_(u64 w, u32 c) {
- return ( w << c ) | ( w >> ( 64 - c ) );
-}
-
-static u32 rotr32_(u32 w, u32 c) {
- return ( w >> c ) | ( w << ( 32 - c ) );
-}
-
static u64 rotr64_(u64 w, u32 c) {
return ( w >> c ) | ( w << ( 64 - c ) );
}
@@ -1087,11 +1040,6 @@ static i32 blake2b_set_lastnode_(Blake2b_State *S) {
return 0;
}
-static i32 blake2b_clear_lastnode_(Blake2b_State *S) {
- S->f[1] = 0ull;
- return 0;
-}
-
static i32 blake2b_set_lastblock_(Blake2b_State *S) {
if( S->last_node ) blake2b_set_lastnode_( S );
@@ -1099,64 +1047,12 @@ static i32 blake2b_set_lastblock_(Blake2b_State *S) {
return 0;
}
-static i32 blake2b_clear_lastblock_(Blake2b_State *S) {
- if( S->last_node ) blake2b_clear_lastnode_( S );
-
- S->f[0] = 0ull;
- return 0;
-}
-
static i32 blake2b_increment_counter_(Blake2b_State *S, u64 inc) {
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
return 0;
}
-static i32 blake2b_param_set_digest_length_(Blake2b_Param *P, u8 digest_length) {
- P->digest_length = digest_length;
- return 0;
-}
-
-static i32 blake2b_param_set_fanout_(Blake2b_Param *P, u8 fanout) {
- P->fanout = fanout;
- return 0;
-}
-
-static i32 blake2b_param_set_max_depth_(Blake2b_Param *P, u8 depth) {
- P->depth = depth;
- return 0;
-}
-
-static i32 blake2b_param_set_leaf_length_(Blake2b_Param *P, u32 leaf_length) {
- store32_( &P->leaf_length, leaf_length );
- return 0;
-}
-
-static i32 blake2b_param_set_node_offset_(Blake2b_Param *P, u64 node_offset) {
- store64_( &P->node_offset, node_offset );
- return 0;
-}
-
-static i32 blake2b_param_set_node_depth_(Blake2b_Param *P, u8 node_depth) {
- P->node_depth = node_depth;
- return 0;
-}
-
-static i32 blake2b_param_set_inner_length_(Blake2b_Param *P, u8 inner_length) {
- P->inner_length = inner_length;
- return 0;
-}
-
-static i32 blake2b_param_set_salt_(Blake2b_Param *P, u8 salt[BLAKE2B_SALTBYTES]) {
- mem_cpy_( P->salt, salt, BLAKE2B_SALTBYTES );
- return 0;
-}
-
-static i32 blake2b_param_set_personal_(Blake2b_Param *P, u8 personal[BLAKE2B_PERSONALBYTES]) {
- mem_cpy_( P->personal, personal, BLAKE2B_PERSONALBYTES );
- return 0;
-}
-
static i32 blake2b_init0_(Blake2b_State *S) {
i32 i;
mem_set_( S, 0, sizeof( Blake2b_State ) );
@@ -1511,11 +1407,6 @@ static void drop_files_clean_(void) {
}
resize_dynamic_array_exact(&g_platform.num_drop_files, (void **) &g_platform.drop_files, sizeof *g_platform.drop_files, 0);
- resize_dynamic_array_exact(&_drop_files_buffer_len, (void **) &_drop_files_buffer, 1, 0);
-}
-
-static i64 align_size_(i64 x) {
- return (x + 7) & ~7ll;
}
static void drop_files_set_num_(i64 num) {
@@ -1693,6 +1584,8 @@ static void network_cleanup_(void) {
close(_sockets[i].socket);
_sockets[i].ready = 0;
}
+
+ resize_dynamic_array_exact(&_num_sockets, (void **) &_sockets, sizeof *_sockets, 0);
}
static b8 network_open_(u16 slot, IP_Address address, u16 *local_port) {
@@ -2674,6 +2567,19 @@ static i32 x11_error_handler_(Display *display, XErrorEvent *event) {
return 0;
}
+void update_main_window_frame_(void) {
+ i64 num_pixels = g_platform.frame_width * g_platform.frame_height;
+
+ if (g_platform.num_pixels < num_pixels)
+ resize_dynamic_array_exact(&g_platform.num_pixels, (void **) &g_platform.pixels, sizeof *g_platform.pixels, num_pixels);
+ if (_pixels_scaled_len < num_pixels)
+ resize_dynamic_array_exact(&_pixels_scaled_len, (void **) &_pixels_scaled, sizeof *_pixels_scaled, num_pixels);
+ if (_pixels_internal_len < num_pixels)
+ resize_dynamic_array_exact(&_pixels_internal_len, (void **) &_pixels_internal, sizeof *_pixels_internal, num_pixels);
+
+ _image.data = (c8 *) _pixels_internal;
+}
+
void init_main_window(void) {
for (i64 i = 0; i < NUM_FRAMES_AVERAGED; ++i)
_frame_duration[i] = (MIN_FRAME_DURATION + MAX_FRAME_DURATION) / 2;
@@ -2851,9 +2757,7 @@ void init_main_window(void) {
.width = g_platform.frame_width,
.height = g_platform.frame_height,
.depth = depth,
- .xoffset = 0,
.format = ZPixmap,
- .data = (c8 *) _pixels_internal,
.byte_order = LSBFirst,
.bitmap_unit = 32,
.bitmap_bit_order = LSBFirst,
@@ -2865,6 +2769,8 @@ void init_main_window(void) {
.blue_mask = 0x0000ff,
};
+ update_main_window_frame_();
+
XInitImage(&_image);
_wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", False);
@@ -2915,6 +2821,15 @@ void shutdown_all_systems(void) {
_window = 0;
_display = NULL;
+ drop_files_clean_();
+ g_platform.input_len = 0;
+
+ resize_dynamic_array_exact(&_pixels_scaled_len, (void **) &_pixels_scaled, sizeof *_pixels_scaled, 0);
+ resize_dynamic_array_exact(&_pixels_internal_len, (void **) &_pixels_internal, sizeof *_pixels_internal, 0);
+ resize_dynamic_array_exact(&g_platform.num_pixels, (void **) &g_platform.pixels, sizeof *g_platform.pixels, 0);
+ resize_dynamic_array_exact(&g_platform.input_capacity, (void **) &g_platform.input, sizeof *g_platform.input, 0);
+ resize_dynamic_array_exact(&g_platform.clipboard_text_len, (void **) &g_platform.clipboard_text, 1, 0);
+
network_cleanup_();
sound_cleanup_();
}
@@ -3466,11 +3381,7 @@ void render_main_window_frame(void) {
_mapped = 1;
}
- i64 num_pixels = g_platform.frame_width * g_platform.frame_height;
- if (_pixels_scaled_len < num_pixels)
- resize_dynamic_array_exact(&_pixels_scaled_len, (void **) &_pixels_scaled, sizeof *_pixels_scaled, num_pixels);
- if (_pixels_internal_len < num_pixels)
- resize_dynamic_array_exact(&_pixels_internal_len, (void **) &_pixels_internal, sizeof *_pixels_internal, num_pixels);
+ update_main_window_frame_();
if (g_platform.frame_width == _image.width && g_platform.frame_height == _image.height) {
i64 size = g_platform.frame_width * g_platform.frame_height;
@@ -3815,18 +3726,31 @@ i32 wait_main_window_events(void) {
void render_main_window_frame(void) {
if (_frame_width == g_platform.frame_width && _frame_height == g_platform.frame_height) {
i64 size = g_platform.frame_width * g_platform.frame_height;
+ if (size > g_platform.num_pixels)
+ size = g_platform.num_pixels;
+ if (size > _pixels_internal_len)
+ size = _pixels_internal_len;
+
for (i64 i = 0; i < size; ++i)
_pixels_internal[i] = 0xff000000u | rgb_u32_from_f32_((vec3_f32) { g_platform.pixels[i].z, g_platform.pixels[i].y, g_platform.pixels[i].x });
} else {
i64 size = g_platform.frame_width * g_platform.frame_height;
+ if (size > g_platform.num_pixels)
+ size = g_platform.num_pixels;
+ if (size > _pixels_scaled_len)
+ size = _pixels_scaled_len;
+
for (i64 i = 0; i < size; ++i)
_pixels_scaled[i] = rgb_u32_from_f32_((vec3_f32) { g_platform.pixels[i].z, g_platform.pixels[i].y, g_platform.pixels[i].x });
for (i64 j = 0; j < _frame_height; ++j) {
i64 j0 = (j * g_platform.frame_height) / _frame_height;
+ if ((j0 + 1) * _frame_width > _pixels_internal_len) break;
for (i64 i = 0; i < _frame_width; ++i) {
i64 i0 = (i * g_platform.frame_width) / _frame_width;
- _pixels_internal[j * _frame_width + i] = 0xff000000u | _pixels_scaled[j0 * g_platform.frame_width + i0];
+ i64 n0 = j0 * g_platform.frame_width + i0;
+ if (n0 > _pixels_scaled_len) break;
+ _pixels_internal[j * _frame_width + i] = 0xff000000u | _pixels_scaled[n0];
}
}
}