diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/abort.c | 93 | ||||
-rw-r--r-- | core/alloc.c | 157 | ||||
-rw-r--r-- | core/callbacks.c | 27 | ||||
-rw-r--r-- | core/init.c | 37 | ||||
-rw-r--r-- | core/logging.c | 114 | ||||
-rw-r--r-- | core/mod.c | 90 | ||||
-rw-r--r-- | core/thread.c | 218 |
7 files changed, 0 insertions, 736 deletions
diff --git a/core/abort.c b/core/abort.c deleted file mode 100644 index 5ee42f6..0000000 --- a/core/abort.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/abort.h> -#include <rune/core/alloc.h> -#include <rune/core/init.h> -#include <rune/core/logging.h> -#include <rune/util/exits.h> -#include <stdlib.h> - -#define MAX_TRACE_ITEMS 30 - -#ifdef _WIN32 - -#include <windows.h> -#include <dbghelp.h> - -void _stack_trace(void) { - void* buffer[MAX_TRACE_ITEMS]; - HANDLE process = GetCurrentProcess(); - - SymInitialize(process, NULL, TRUE); - int num_links = CaptureStackBackTrace(0, MAX_TRACE_ITEMS, buffer, NULL); - SYMBOL_INFO *symbol = (SYMBOL_INFO*)rune_alloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char)); - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = 255; - - for (int i = 0; i < num_links; i++) { - SymFromAddr(process, (DWORD64)(buffer[i]), 0, symbol); - log_output(LOG_INFO, "#%d: %s", i, symbol->Name, symbol->Address); - } - - rune_free(symbol); - SymCleanup(process); -} - -#else - -#include <execinfo.h> - -void _stack_trace(void) { - void* buffer[MAX_TRACE_ITEMS]; - int num_links = backtrace(buffer, MAX_TRACE_ITEMS); - char** symbuf = backtrace_symbols(buffer, num_links); - - for (int i = 0; i < num_links; i++) - log_output(LOG_INFO, "#%d: %s", i, symbuf[i]); - - free(symbuf); -} - -#endif - -NORET void rune_abort(void) { - log_output(LOG_INFO, "Abort called, printing stack trace"); - _stack_trace(); - rune_exit(); - exit(REXIT_FAIL); -} - -#ifdef MSVC - -NORET void __security_error_handler(void) { - log_output(LOG_FATAL, "Stack smashing detected in engine code"); - rune_abort(); -} - -#else - -NORET void __stack_chk_fail(void) { - log_output(LOG_FATAL, "Stack smashing detected in engine code"); - rune_abort(); -} - -#endif diff --git a/core/alloc.c b/core/alloc.c deleted file mode 100644 index 0ed705c..0000000 --- a/core/alloc.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/alloc.h> -#include <rune/core/logging.h> -#include <stdlib.h> -#include <string.h> - -// TODO: implement block coalescing so we can reuse freed blocks - -#define DEADBLOCK ((void*)0xDEADBEEF) - -static mem_block_t first_block; - -static mem_block_t* _find_free_block(size_t sz) { - list_head_t *temp = &first_block.list; - mem_block_t *block; - while (temp != NULL) { - block = (mem_block_t*)((void*)temp - offsetof(mem_block_t, list)); - if (block->sz == sz && block->free == 1) - return block; - temp = temp->next; - } - return NULL; -} - -static mem_block_t* _find_block(void *ptr) { - list_head_t *temp = &first_block.list; - mem_block_t *block; - while (temp != NULL) { - block = (mem_block_t*)((void*)temp - offsetof(mem_block_t, list)); - if (block->ptr == ptr) - return block; - temp = temp->next; - } - return NULL; -} - -static mem_block_t* _alloc_block(size_t sz) { - if (first_block.ptr == NULL) { - first_block.ptr == DEADBLOCK; - first_block.sz = 0; - } - - mem_block_t *ret = _find_free_block(sz); - if (ret != NULL) { - ret->free = 0; - return ret->ptr; - } - - ret = malloc(sizeof(mem_block_t)); - if (ret == NULL) { - log_output(LOG_ERROR, "Cannot allocate block of size %d", sz); - return NULL; - } - - ret->ptr = malloc(sz); - ret->sz = sz; - ret->free = 0; - list_add(&ret->list, &first_block.list); - log_output(LOG_DEBUG, "Alloc'd block of size %d", sz); - return ret; -} - -static void _free_block(mem_block_t *block, int hard) { - if (hard == 1) { - list_del(&block->list); - log_output(LOG_DEBUG, "Freed block of size %d", block->sz); - free(block); - return; - } - block->free = 1; -} - -void* rune_alloc(size_t sz) { - if (sz == 0) - return NULL; - - mem_block_t *block = _find_free_block(sz); - if (block != NULL) { - block->free = 0; - return block->ptr; - } - - block = _alloc_block(sz); - return block->ptr; -} - -void* rune_calloc(size_t nmemb, size_t sz) { - if (sz == 0) - return NULL; - - mem_block_t *block = _find_free_block(sz); - if (block != NULL) { - block->free = 0; - return block->ptr; - } - - block = _alloc_block(sz); - memset(block->ptr, 0, sz); - return block->ptr; -} - -void* rune_realloc(void *ptr, size_t sz) { - if (ptr == NULL || sz == 0) - return rune_alloc(sz); - - mem_block_t *old = _find_block(ptr); - mem_block_t *new = _alloc_block(sz); - memcpy(new->ptr, old->ptr, old->sz); - old->free = 1; - return new->ptr; -} - -void rune_free(void *ptr) { - if (ptr == NULL) - return; - - mem_block_t *block = _find_block(ptr); - if (block->free == 1) - return; - block->free = 1; -} - -void rune_free_all(void) { - list_head_t *temp = &first_block.list; - mem_block_t *block; - while (temp != NULL) { - block = (mem_block_t*)((void*)temp - offsetof(mem_block_t, list)); - if (block->ptr == DEADBLOCK) { - temp = temp->next; - continue; - } - - temp = temp->next; - if (block->ptr != NULL) - _free_block(block, 1); - } -} diff --git a/core/callbacks.c b/core/callbacks.c deleted file mode 100644 index ea7f50e..0000000 --- a/core/callbacks.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/callbacks.h> -#include <rune/core/logging.h> - -void error_callback(int error, const char *desc) { - log_output(LOG_ERROR, "%d: %s\n", error, desc); -} diff --git a/core/init.c b/core/init.c deleted file mode 100644 index 5df4d04..0000000 --- a/core/init.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/init.h> -#include <rune/core/abort.h> -#include <rune/core/logging.h> -#include <rune/core/thread.h> - -int rune_init(int argc, char* argv[]) { - log_output(LOG_INFO, "Started Rune Engine version %s", RUNE_VER); - _parse_args(argc, argv); - rune_init_thread_api(); - return 0; -} - -void rune_exit(void) { - log_output(LOG_INFO, "Engine shutdown requested"); - rune_free_all(); -} diff --git a/core/logging.c b/core/logging.c deleted file mode 100644 index b7f77bd..0000000 --- a/core/logging.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/logging.h> -#include <rune/core/config.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> - -#define COLOR_NONE "" -#define COLOR_DEFAULT "\033[0m" -#define COLOR_RED "\033[31m" -#define COLOR_GREEN "\033[32m" -#define COLOR_YELLOW "\033[33m" -#define COLOR_BLUE "\033[34m" - -#define LSTR_FATAL "[FATAL]" -#define LSTR_ERROR "[ERROR]" -#define LSTR_WARN "[WARNING]" -#define LSTR_INFO "[INFO]" -#define LSTR_DEBUG "[DEBUG]" - -static int debug_enabled = 0; -static int color_enabled = 0; - -void log_output(int level, const char *fmt, ...) { - char out[4096]; - memset(out, 0, sizeof(out)); - - debug_enabled = rune_get_log_debug(); - color_enabled = rune_get_log_color(); - - va_list arg_ptr; - va_start(arg_ptr, fmt); - vsnprintf(out, 4096, fmt, arg_ptr); - va_end(arg_ptr); - - char *lvl_str; - char *color = COLOR_NONE; - switch (level) { - case LOG_FATAL: - if (color_enabled == 1) - color = COLOR_RED; - lvl_str = LSTR_FATAL; - break; - case LOG_ERROR: - if (color_enabled == 1) - color = COLOR_RED; - lvl_str = LSTR_ERROR; - break; - case LOG_WARN: - if (color_enabled == 1) - color = COLOR_YELLOW; - lvl_str = LSTR_WARN; - break; - case LOG_INFO: - lvl_str = LSTR_INFO; - break; - case LOG_DEBUG: - if (color_enabled == 1) - color = COLOR_GREEN; - if (debug_enabled == 0) - return; - lvl_str = LSTR_DEBUG; - break; - } - - if (color_enabled == 0) { - printf("%s %s\n", lvl_str, out); - } else { - printf("%s%s %s\n", color, lvl_str, out); - printf(COLOR_DEFAULT); - } -} - -//#ifdef _WIN32 -// -//#include <windows.h> -// -//void enable_log_color(void) { -// HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); -// SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING); -// color_enabled = 1; -//} -// -//#else -// -//void enable_log_color(void) { -// color_enabled = 1; -//} -// -//#endif -// -//void disable_log_color(void) { -// color_enabled = 0; -//} diff --git a/core/mod.c b/core/mod.c deleted file mode 100644 index 3d9e710..0000000 --- a/core/mod.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/mod.h> -#include <rune/core/logging.h> -#include <rune/core/alloc.h> -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include <dlfcn.h> - -list_head_t *mods = NULL; - -void _load_mod(const char *filename) { - char mod_path[4096]; - sprintf(mod_path, "mods/%s", filename); - void *handle = dlopen(mod_path, RTLD_LAZY); - if (handle == NULL) - log_output(LOG_ERROR, "Error loading mod %s: %s", filename, dlerror()); -} - -void rune_load_mods(void) { - DIR *dir = opendir("mods"); - if (dir == NULL) { - log_output(LOG_INFO, "No mods folder found, skipping mod loading"); - return; - } - - struct dirent *mods_de; - while ((mods_de = readdir(dir)) != NULL) { - if (strstr(mods_de->d_name, ".so")) - _load_mod(mods_de->d_name); - } -} - -void rune_init_mods(void) { - list_head_t *temp = mods; - struct mod *mod; - while (temp != NULL) { - mod = (struct mod*)((void*)temp - offsetof(struct mod, list)); - (*mod->init_func)(); - temp = temp->next; - } -} - -void rune_close_mods(void) { - if (mods == NULL) - return; - - list_head_t *temp = mods; - struct mod *mod; - while (temp != NULL) { - mod = (struct mod*)((void*)temp - offsetof(struct mod, list)); - (*mod->exit_func)(); - temp = temp->next; - rune_free(mod); - } -} - -void rune_register_mod(const char *name, mod_func init_func, mod_func exit_func, mod_func update_func) { - struct mod *new = rune_alloc(sizeof(struct mod)); - new->name = name; - new->init_func = init_func; - new->exit_func = exit_func; - new->update_func = update_func; - new->list.next = NULL; - new->list.prev = NULL; - if (mods == NULL) - mods = &new->list; - else - list_add(&new->list, mods); -} diff --git a/core/thread.c b/core/thread.c deleted file mode 100644 index 3c5db8c..0000000 --- a/core/thread.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/thread.h> -#include <rune/core/logging.h> -#include <rune/core/alloc.h> -#include <pthread.h> -#include <string.h> -#include <stdatomic.h> - -static list_head_t *threads = NULL; -static list_head_t *mutexes = NULL; -static int next_tid = 0; -static int next_mid = 0; - -struct start_args { - struct thread *thread; - void* (*thread_fn)(void*); - void *thread_args; -}; - -static struct thread* _find_thread_by_handle(void *handle) { - if (threads == NULL) - return NULL; - - list_head_t *temp = threads; - struct thread *ret; - while (temp != NULL) { - ret = (struct thread*)((void*)temp - offsetof(struct thread, list)); - if (pthread_equal(*(pthread_t*)ret->thread_handle, *(pthread_t*)handle) == 1) - return ret; - temp = temp->next; - } - return NULL; -} - -static struct thread* _find_thread_by_id(int ID) { - if (threads == NULL) - return NULL; - - list_head_t *temp = threads; - struct thread *ret; - while (temp != NULL) { - ret = (struct thread*)((void*)temp - offsetof(struct thread, list)); - if (ret->ID == ID) - return ret; - temp = temp->next; - } - return NULL; -} - -static struct mutex* _find_mutex_by_id(int ID) { - if (mutexes == NULL) - return NULL; - - list_head_t *temp = mutexes; - struct mutex *ret; - while (temp != NULL) { - ret = (struct mutex*)((void*)temp - offsetof(struct mutex, list)); - if (ret->ID == ID) - return ret; - temp = temp->next; - } - return NULL; -} - - -static void _cleanup_pthread(void *arg) { - struct thread *thread = (struct thread*)arg; - if (&thread->list != threads) - list_del(&thread->list); - rune_free(thread->thread_handle); - rune_free(thread); -} - -static void* _startup_pthread(void *arg) { - struct start_args *start_args = (struct start_args*)arg; - - void* (*thread_fn)(void *data) = start_args->thread_fn; - pthread_cleanup_push(_cleanup_pthread, start_args->thread); - if (thread_fn != NULL) - (*thread_fn)(start_args->thread_args); - pthread_cleanup_pop(1); - return NULL; -} - -void rune_init_thread_api(void) { - struct thread *start_thread = rune_alloc(sizeof(struct thread)); - start_thread->ID = next_tid++; - start_thread->detached = 0; - start_thread->thread_handle = rune_alloc(sizeof(pthread_t)); - *(pthread_t*)start_thread->thread_handle = pthread_self(); - pthread_cleanup_push(_cleanup_pthread, threads); - pthread_cleanup_pop(0); -} - -int rune_thread_init(void* (*thread_fn)(void *data), void *data, int detached) { - struct thread *thread = rune_alloc(sizeof(struct thread)); - thread->ID = next_tid++; - thread->detached = detached; - thread->thread_handle = rune_alloc(sizeof(pthread_t)); - if (threads == NULL) - threads = &thread->list; - else - list_add(&thread->list, threads); - - struct start_args *args = rune_alloc(sizeof(struct start_args)); - args->thread = thread; - args->thread_fn = thread_fn; - args->thread_args = data; - int retval = pthread_create(thread->thread_handle, NULL, _startup_pthread, args); - rune_free(args); - if (retval != 0) { - log_output(LOG_ERROR, "Thread creation failed: %s", strerror(retval)); - return -1; - } - log_output(LOG_DEBUG, "Initialized new thread with ID=%d", thread->ID); - if (detached == 1) { - log_output(LOG_DEBUG, "Thread %d has been detached, join no longer possible"); - pthread_detach(*(pthread_t*)thread->thread_handle); - } - return thread->ID; -} - -int rune_thread_cancel(int ID) { - log_output(LOG_DEBUG, "Received cancel request for thread %d", ID); - struct thread *thread = _find_thread_by_id(ID); - if (thread == NULL) { - log_output(LOG_ERROR, "Thread %d does not exist", ID); - return -1; - } - pthread_cancel(*((pthread_t*)thread->thread_handle)); - return 0; -} - -int rune_thread_join(int ID, void **retval) { - struct thread *thread = _find_thread_by_id(ID); - if (thread == NULL) - return 0; - - if (thread->detached == 1) { - log_output(LOG_ERROR, "Cannot join thread %d, detached", thread->ID); - return -1; - } - pthread_join(*((pthread_t*)thread->thread_handle), retval); - return 0; -} - -int rune_thread_self(void) { - pthread_t cur = pthread_self(); - struct thread *ret = _find_thread_by_handle((void*)&cur); - if (ret != NULL) - return ret->ID; - return -1; -} - -void rune_thread_exit(void *retval) { - pthread_t cur = pthread_self(); - struct thread *self = _find_thread_by_handle((void*)&cur); - log_output(LOG_DEBUG, "Thread %d called thread_exit", self->ID); - pthread_exit(retval); -} - -int rune_mutex_init(void) { - struct mutex *mutex = rune_alloc(sizeof(struct mutex)); - mutex->ID = next_mid++; - mutex->mutex_handle = rune_alloc(sizeof(pthread_mutex_t)); - pthread_mutex_init((pthread_mutex_t*)mutex->mutex_handle, NULL); - if (mutexes == NULL) - mutexes = &mutex->list; - else - list_add(&mutex->list, mutexes); - return mutex->ID; -} - -int rune_mutex_destroy(int ID) { - struct mutex *mutex = _find_mutex_by_id(ID); - rune_free(mutex->mutex_handle); - if (&mutex->list != mutexes) - list_del(&mutex->list); - rune_free(mutex); -} - -int rune_mutex_lock(int ID) { - struct mutex *mutex = _find_mutex_by_id(ID); - int retval = pthread_mutex_lock((pthread_mutex_t*)mutex->mutex_handle); - if (retval != 0) { - char *str = strerror(retval); - log_output(LOG_ERROR, "Cannot lock mutex %d: %s", mutex->ID, str); - } -} - -int rune_mutex_unlock(int ID) { - struct mutex *mutex = _find_mutex_by_id(ID); - int retval = pthread_mutex_unlock((pthread_mutex_t*)mutex->mutex_handle); - if (retval != 0) { - char *str = strerror(retval); - log_output(LOG_ERROR, "Cannot unlock mutex %d: %s", mutex->ID, str); - } -} |