threading context in place because we are a multi-threading system dammit!

This commit is contained in:
Tijani Lawal 2024-08-08 06:40:00 -05:00
parent d8d99933e6
commit a1ffe981a6
7 changed files with 166 additions and 13 deletions

View File

@ -38,8 +38,34 @@ typedef double f64;
#define Million(n) ((n) * 1000000) #define Million(n) ((n) * 1000000)
#define Billion(n) ((n) * 1000000000) #define Billion(n) ((n) * 1000000000)
// C++ linking shenanigans
#if LANG_CPP
#define C_LINK_BEGIN extern "C" {
#define C_LINK_END }
#define C_LINK extern "C"
#else
#define C_LINK_BEGIN
#define C_LINK_END
#define C_LINK
#endif
// Threads stuff
#if COMPILER_MSVC
#define thread_static __declspec(thread)
#else
#error "Thread local storage supported this platform."
#endif
// Misc helpers
// NOTE(tijani): Divides total size of array by size of one element in the array gives
// the number of elements in the array.
#define ArrayCount(array_to_count) (sizeof(array_to_count) / sizeof((array_to_count)[0]))
// Memory operations // Memory operations
#define MemoryZero(dest, count) memset((dest), 0, (count)) #define MemoryZero(dest, count) memset((dest), 0, (count))
#define MemoryZeroStruct(count) MemoryZero((count), sizeof(*(count)))
#define MemoryCopy(dest, src, src_size) memmove((dest), (src), (src_size))
// Max, Min, Clamps // Max, Min, Clamps
#define Max(A, B) (((A) > (B)) ? (A) : (B)) #define Max(A, B) (((A) > (B)) ? (A) : (B))

View File

@ -2,5 +2,6 @@
#include "base_arena.c" #include "base_arena.c"
#include "base_strings.c" #include "base_strings.c"
#include "base_markup.c"
#include "base_threading_context.c"
// clang-format on // clang-format on

View File

@ -8,7 +8,8 @@
#include "base_arena.h" #include "base_arena.h"
#include "base_strings.h" #include "base_strings.h"
#include "base_markup.h"
#include "base_thread_context.h"
// clang-format on // clang-format on
#endif // BASE_INC_H #endif // BASE_INC_H

14
src/base/base_markup.c Normal file
View File

@ -0,0 +1,14 @@
internal void set_thread_name(String8 str) {
// ??(tijani): Profiling
os_set_thread_name(str);
}
internal void set_thread_namef(char *fmt, ...) {
Temp scratch = temp_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
set_thread_name(string);
va_end(args);
scratch_end(scratch);
}

10
src/base/base_markup.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef BASE_MARKUP_H
#define BASE_MARKUP_H
internal void set_thread_name(String8 string);
internal void set_thread_namef(char *fmt, ...);
#define ThreadName(str) (set_thread_name(str))
#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__))
#endif // BASE_MARKUP_H

View File

@ -0,0 +1,71 @@
// Thread related functions
C_LINK thread_static THCTX *thctx_thread_local;
internal void thctx_init_and_equip(THCTX *thctx) {
MemoryZeroStruct(thctx);
Arena **arena_ptr = thctx->arenas;
for (u64 i = 0; i < ArrayCount(thctx->arenas); i += 1, arena_ptr += 1) {
*arena_ptr = arena_alloc();
}
thctx_thread_local = thctx;
}
internal void thctx_release(void) {
for (u64 i = 0; i < ArrayCount(thctx_thread_local->arenas); i += 1) {
arena_release(thctx_thread_local->arenas[i]);
}
}
internal THCTX *thctx_get_equipped(void){return (thctx_thread_local)}
// NOTE(tijani): This is used by a thread get temporary memory
// for use (scratch space). It makes sure their are no conflics
// in the memory block it's selecting before assigning it to the
// thread that needs it.
internal Arena *thctx_get_scratch(Arena **conflicts, u64 count) {
THCTX *thctx = thctx_get_equipped();
Arena *memory = 0;
Arena **arena_ptr = thctx->arenas;
for (u64 i = 0; i < ArrayCount(thctx->arenas); i += 1, arena_ptr += 1) {
Arena **conflicts_ptr = conflicts;
b32 has_conflict = 0;
for (u64 j = 0; j < count; j += 1, conflicts_ptr += 1) {
if (*arena_ptr == *conflicts_ptr) {
has_conflicts = 1;
break;
}
}
if (!has_conflicts) {
memory = *arena_ptr;
break;
}
}
return (memory);
}
internal void thctx_set_thread_name(String8 name) {
THCTX *thctx = thctx_get_equipped();
u64 size = ClampTop(name.size, sizeof(thctx->thread_name));
MemoryCopy(thctx->thread_name, name.str, size);
thctx->thread_name_size = size;
}
internal String8 thctx_get_thread_name(void) {
THCTX *thctx = thctx_get_equipped();
String8 name = str8(thctx->thread_name, thctx->thread_name_size);
return (name);
}
internal void thctx_write_srcloc(char *file_name, u64 line_number) {
THCTX *thctx = thctx_get_equipped();
thctx->file_name = file_name;
thctx->line_number = line_number;
}
internal void thctx_read_srcloc(char **file_name, u64 *line_number) {
THCTX *thctx = thctx_get_equipped();
*file_name = thctx->file_name;
*line_number = thctx->line_number;
}

View File

@ -0,0 +1,30 @@
#ifndef BASE_THREAD_CONTEXT_H
#define BASE_THREAD_CONTEXT_H
typedef struct THCTX THCTX;
struct THCTX {
Arena *arenas[2];
u8 thread_name[32];
u64 thread_name_size;
char *file_name;
u64 line_number;
};
// Thread related functions
internal void thctx_init_and_equip(THCTX *thctx);
internal void thctx_release(void);
internal THCTX *thctx_get_equipped(void);
internal Arena *thctx_get_scratch(Arena **conflicts, u64 count);
internal void thctx_set_thread_name(String8 name);
internal String8 thctx_get_thread_name(void);
// NOTE(tijani): Debugging errors within a thread context.
internal void thctx_write_srcloc(char *file_name, u64 line_number);
internal void thctx_read_srcloc(char **file_name, u64 *line_number);
#define thctx_write_this_srcloc() thctx_write_srcloc(__FILE__, __LINE__);
#define scratch_begin(conflicts, count) temp_begin(thctx_get_scratch((conflicts), (count)))
#define scratch_end(scratch) temp_end(scratch)
#endif // BASE_THREAD_CONTEXT_H