From bb912b081ed339e4a5419bd3d2ffd7465f2f72d3 Mon Sep 17 00:00:00 2001 From: nodist Date: Mon, 27 Jul 2026 17:17:56 -0400 Subject: bottom up redesign --- docs/application/buffer.md | 25 --- docs/application/error.md | 27 --- docs/application/group.md | 13 -- docs/application/identifier.md | 17 -- docs/application/index.md | 72 ------- docs/application/interface.md | 56 ------ docs/application/io.md | 39 ---- docs/application/map.md | 20 -- docs/application/memory.md | 39 ---- docs/application/mutex.md | 24 --- docs/application/namespace.md | 169 ----------------- docs/application/native.md | 11 -- docs/application/queue.md | 18 -- docs/application/shared.md | 38 ---- docs/application/testing.md | 52 ------ docs/application/thread.md | 415 ----------------------------------------- docs/application/type.md | 101 ---------- docs/application/union.md | 12 -- 18 files changed, 1148 deletions(-) delete mode 100644 docs/application/buffer.md delete mode 100644 docs/application/error.md delete mode 100644 docs/application/group.md delete mode 100644 docs/application/identifier.md delete mode 100644 docs/application/index.md delete mode 100644 docs/application/interface.md delete mode 100644 docs/application/io.md delete mode 100644 docs/application/map.md delete mode 100644 docs/application/memory.md delete mode 100644 docs/application/mutex.md delete mode 100644 docs/application/namespace.md delete mode 100644 docs/application/native.md delete mode 100644 docs/application/queue.md delete mode 100644 docs/application/shared.md delete mode 100644 docs/application/testing.md delete mode 100644 docs/application/thread.md delete mode 100644 docs/application/type.md delete mode 100644 docs/application/union.md (limited to 'docs/application') diff --git a/docs/application/buffer.md b/docs/application/buffer.md deleted file mode 100644 index 40c58e4..0000000 --- a/docs/application/buffer.md +++ /dev/null @@ -1,25 +0,0 @@ -# Buffer - ---- - -## Object Definitions - -```c -typedef struct _kpl_buffer { - KPL_DYNAMIC_OBJ_HEADER(); - int32_t byte_length; - kpl_interface *interface; - int16_t io_register_index; - uint8_t bytes[]; -} kpl_buffer; - -typedef struct { - // TODO RING BUFFERS BY POWERS OF TWO -} kpl_buffer_registered_pool; -``` - -## Io uring buffer sparse register - -### Set `io_register_index` to -1 if not used - -## Unicode Methods diff --git a/docs/application/error.md b/docs/application/error.md deleted file mode 100644 index 2e1e703..0000000 --- a/docs/application/error.md +++ /dev/null @@ -1,27 +0,0 @@ -# Error - ---- - -## Object Definitions - -```c -typedef union : uin16_t { - ERROR_C = 1 << 0, - ERROR_TOKEN = 1 << 1, - ERROR_TYPE = 1 << 2 -} kpl_error_flags; - -typedef struct _kpl_error { - uint16_t line, flags; - uin32_t class_options; - struct _kpl_error *stack; - union { - struct { - char *file, char *function; - } c; - kpl_token token; - kpl_type *type; - } source; - kpl_class class; -} kpl_error; -``` diff --git a/docs/application/group.md b/docs/application/group.md deleted file mode 100644 index 7ed6382..0000000 --- a/docs/application/group.md +++ /dev/null @@ -1,13 +0,0 @@ -# Group - ---- - -## Object Definitions - -```c -typedef struct _kpl_group { - KPL_DYNAMIC_OBJ_HEADER(); - int32_t item_length; - kpl_class items[]; -} kpl_group; -``` diff --git a/docs/application/identifier.md b/docs/application/identifier.md deleted file mode 100644 index ed4f3e7..0000000 --- a/docs/application/identifier.md +++ /dev/null @@ -1,17 +0,0 @@ -# Identifier - ---- - -Store vars, types and symbols as compressed strings - -## Object Definitions - -```c -#define KPL_IDENTIFIER_PARTS 5 - -// TODO 50 charaters of [A-Za-z0-9_] in 40 bytes - -typedef struct { - uint64_t parts[KPL_IDENTIFIER_PARTS]; -} kpl_identifier; -``` diff --git a/docs/application/index.md b/docs/application/index.md deleted file mode 100644 index 804e952..0000000 --- a/docs/application/index.md +++ /dev/null @@ -1,72 +0,0 @@ -# Runtime - ---- - -## Requirements - -* Linux X64 with io_uring (6+) -* GNU Make -* GCC with -std=gnu99 -fhardened (14+) - -## Sections - -* ##### [Interface](./interface.md) -* ##### [Thread](./thread.md) -* ##### [Mutex](./mutex.md) -* ##### [Memory](./memory.md) -* ##### [Io](./io.md) -* ##### [Shared](./shared.md) -* ##### [Identifier](./identifier.md) -* ##### [Type](./type.md) -* ##### [Group](./group.md) -* ##### [Buffer](./buffer.md) -* ##### [Map](./map.md) -* ##### [Queue](./queue.md) -* ##### [Union](./union.md) -* ##### [Native](./native.md) -* ##### [Namespace](./namespace.md) -* ##### [Error](./error.md) -* ##### [Testing](./testing.md) - -# Invocation - -## Startup - -1. Configuration - * `thread_count` - defaults to number of available processors -2. Initialize allocators -3. Initialize tasks -4. Initialize types - * Built In Alias -5. Initialize IO - * Size of registered sparse buffers -6. Initialize Jit -7. Initialize Op Matching -8. Initialize Ir Matching - -## Main - -### Module - -### String/REPL - -## Life cycle - -1. ##### [Register](../lifecycle/register.md) -2. ##### [Parse](../lifecycle/parse.md) -3. ##### [Scope](../lifecycle/scope.md) -4. ##### [Import](../lifecycle/import.md) -5. ##### [Check](../lifecycle/check.md) -6. ##### [Eval](../lifecycle/eval.md) -7. ##### [Ir](../lifecycle/ir.md) -8. ##### [Jit](../lifecycle/jit.md) -9. ##### [Exec](../lifecycle/exec.md) -10. ##### [Notify](../lifecycle/notify.md) - -## Shutdown - -1. Clean up Jit -2. Clean up IO -3. Clean up types -4. Clean up tasks -5. Clean up allocators diff --git a/docs/application/interface.md b/docs/application/interface.md deleted file mode 100644 index de9eebe..0000000 --- a/docs/application/interface.md +++ /dev/null @@ -1,56 +0,0 @@ -# Interface - ---- - -General definitions used throughout the code - -## Object Definitions - -```c -typedef union { - bool b; - uint8_t u8; - uint16_t u16; - uint32_t u32; - uint64_t u64; - int8_t i8; - int16_t i16; - int32_t i32; - int64_t i64; - float f32; - double f64; - void *ptr; -} kpl_any; - -typedef void kpl_interface_free(kpl_any a); - -typedef struct { - // TODO -} kpl_interface; - -typedef struct { - kpl_any *any; - kpl_interface *interface; -} kpl_class; - -typedef enum : uint8_t { - KPL_STATUS_ERROR, - KPL_STATUS_NULL, - KPL_STATUS_VALUE -} kpl_result_status; - -typedef struct { - any value; - kpl_result_status status; -} kpl_result; - -kpl_result kpl_result_error(error *er); - -kpl_result kpl_result_null(void); - -kpl_result kpl_result_value(any value); -``` - -## `kpl_interface` - -See [Operators](../language/operators.md) diff --git a/docs/application/io.md b/docs/application/io.md deleted file mode 100644 index a292718..0000000 --- a/docs/application/io.md +++ /dev/null @@ -1,39 +0,0 @@ -# Io (io_uring) - ---- - -# Design - -## Io Ring - -## Fixed Buffers - -## Fixed Files - -## Buffer Rings - -# Io Tasks - -Tasks for each IO operation are stored in the `user_data` field - -## Ring Submission `struct io_uring_sqe` - -## Ring Completion `struct io_uring_cqe` - -# Usage - -## File - -### Open - -### Statx - -### Read - -### Write - -## Directory - -## Timers - -## Network diff --git a/docs/application/map.md b/docs/application/map.md deleted file mode 100644 index 18fa7a8..0000000 --- a/docs/application/map.md +++ /dev/null @@ -1,20 +0,0 @@ -# Map - ---- - -## Object Definitions - -```c -typedef struct _kpl_map_bucket { - struct _kpl_map_bucket *prev, *next; - kpl_any key, value; -} kpl_map_bucket; - -typedef struct _kpl_map { - KPL_DYNAMIC_OBJ_HEADER(); - int32_t available_buckets; - kpl_interface *key_interface, *value_interface; - kpl_map_bucket *head, *tail; - kpl_map_bucket *buckets[]; -} kpl_map; -``` diff --git a/docs/application/memory.md b/docs/application/memory.md deleted file mode 100644 index e180b24..0000000 --- a/docs/application/memory.md +++ /dev/null @@ -1,39 +0,0 @@ -# Memory - ---- - -An allocator per Object definition with ring buffer pooling based - -# Single Allocation - -Once created never freed until shutdown - -# Pooling Allocations - -## Ring Buffer - -## Fixed Sized Objects - -## Dynamic Sized Objects - -Dynamically sized objects must be aligned to a power of two - -Requires a ring buffer for each power of two - -## Object Definitions - -```c -#define KPL_DYANMIC_OBJ_MIN_BITS 7 - -#define KPL_DYNAMIC_OBJ_MAX_BITS 30 - -#define KPL_DYNAMIC_OBJ_MIN_SIZE (1 << KPL_DYANMIC_OBJ_MIN_BITS) - -#define KPL_DYNAMIC_OBJ_MAX_SIZE (1 << KPL_DYNAMIC_OBJ_MAX_BITS) - -#define KPL_DYNAMIC_OBJ_HEADER() int32_t obj_size; - -typedef struct { - KPL_DYNAMIC_OBJ_HEADER(); -} kpl_dynamic_obj; -``` diff --git a/docs/application/mutex.md b/docs/application/mutex.md deleted file mode 100644 index e1b15c7..0000000 --- a/docs/application/mutex.md +++ /dev/null @@ -1,24 +0,0 @@ -# Mutex - ---- - -## Object Definitions - -```c -typedef struct { - kpl_task_queue queue; - _Atomic int32_t lock; -} kpl_mutex; -``` - -## Usage - -1. Before adding to the `queue` do `value = lock++` -2. Add to the queue -3. If `value` is `0` the thread does an async schedule of the mutex task, otherwise the thread moves on - -### Mutex Task - -1. Get task from `queue` and run task - * Use spinlock with `pasue`, the `lock` will be set before the task is added to the `queue` -2. After task completion, do `value = --lock`, stop if `value` is `0`, otherwise repeat diff --git a/docs/application/namespace.md b/docs/application/namespace.md deleted file mode 100644 index d276fd0..0000000 --- a/docs/application/namespace.md +++ /dev/null @@ -1,169 +0,0 @@ -# Namespace - ---- - -## Object Definitions - -```c -#define KPL_TREE_HEADER(STRUCT) uint32_t tree_weight, module_id; STRUCT *tree_left, *tree_right; kpl_buffer *name - -typedef struct _kpl_namespace_tree_obj { - KPL_TREE_HEADER(struct _kpl_namespace_tree_obj); -} kpl_namespace_tree_obj; - -typedef struct _kpl_namespace_native { - KPL_TREE_HEADER(struct _kpl_namespace_native); - kpl_type *export_var_tree; -} kpl_namespace_native; - -static kpl_namespace_native *namespace_native_tree; - -typedef struct _kpl_namespace_module { - KPL_TREE_HEADER(struct _kpl_namespace_module); - kpl_buffer *body; - kpl_type *ast, *export_var_tree; - kpl_mutex export_mutex; -} kpl_namespace_module; - -static kpl_namespace_module *namespace_module_tree; - -kpl_mutex namespace_module_tree_mutex; - -static kpl_namespace_module namespace_string; - -static kpl_namespace_module *module_array[KPL_MODULE_SIZE]; // module_id refers to index -``` - -Each `NAMESPACE_IDENTIFIER` maps to `kpl_namespace_native*` or `kpl_namespace_module*` depending on flags - -## Lookup and Storage - -The native and namespace objects are stored as a tree - -The exports are stored under a tree for both the native and namespace objects - -# Registering - -## Native - -TODO C code for exposing native code - -## Module/String/REPL - -### Main - -Begin life cycle and [Register](../lifecycle/register.md) - -### Scan ``import` - -Add a [Register](../lifecycle/register.md) task to `namespace_module_mutex` - -# Updating - -## Native - -### Native code should not be updated at runtime, doing so is undefined behavior - -## Module - -### ``export` - -Add exports directly to the namespaces `export_var_tree`, thread safe - -## String/REPL - -### Cannot export for String/REPL - -# Using - -## Native - -### ``use` - -Since the native modules are loaded statically the `native_module_tree` becomes read only at runtime, access is thread safe - -## Module/String/REPL - -### Import ``import` - -1. Add find namespace task to the `namespace_module_mutex`, the namespace not existing is an error -2. Add a get export task to the namespaces `export_mutex` -3. The `export_mutex` will not start processing it's queue until the namespace notifies that it's and unlocks its `export_mutex` -4. The importer will get a copy of the read only `export_var_tree` - -# AVL Tree Storage and Lookup - -## AVL Tree Example - -```c -typedef struct _avl { - int val, count; - struct _avl *left, *right; -} avl; - - -int get_count(const avl *node) { - return node ? node->count : 0; -} - -int get_balance(const avl *node) { - if (!node) - return 0; - return get_count(node->left) - get_count(node->right); -} - -void right_rotate(avl **right) { - avl *left = (*right)->left, *left_right = left->right; - left->right = *right; - (*right)->left = left_right; - (*right)->count = MAX(get_count((*right)->left), get_count((*right)->right)) + 1; - left->count = MAX(get_count(left->left), get_count(left->right)) + 1; - *right = left; -} - -void left_rotate(avl **left) { - avl *right = (*left)->right, *right_left = right->left; - right->left = *left; - (*left)->right = right_left; - (*left)->count = MAX(get_count((*left)->left), get_count((*left)->right)) + 1; - right->count = MAX(get_count(right->left), get_count(right->right)) + 1; - *left = right; -} - -void insert(avl **parent, avl *node) { - if (!*parent) { - *parent = node; - return; - } - if (node->val < (*parent)->val) - insert(&(*parent)->left, node); - else - insert(&(*parent)->right, node); - (*parent)->count = MAX(get_count((*parent)->left), get_count((*parent)->right)) + 1; - int balance = get_balance(*parent); - if (balance > 1 && get_balance((*parent)->left) >= 0) - right_rotate(parent); - if (balance > 1 && get_balance((*parent)->left) > 0) { - left_rotate(&(*parent)->left); - right_rotate(parent); - } - if (balance < -1 && get_balance((*parent)->right) <= 0) - left_rotate(parent); - if (balance < -1 && get_balance((*parent)->right) > 0) { - right_rotate(&(*parent)->right); - left_rotate(parent); - } -} - -struct TreeNode* sortedListToBST(struct ListNode* head) { - avl *root = NULL; - while (head) { - avl *node = calloc(1, sizeof(avl)); - node->val = head->val; - node->count = 1; - head = head->next; - insert(&root, node); - } - return (struct TreeNode*) root; -} -``` diff --git a/docs/application/native.md b/docs/application/native.md deleted file mode 100644 index c5108aa..0000000 --- a/docs/application/native.md +++ /dev/null @@ -1,11 +0,0 @@ -# Native - ---- - -## Object Definitions - -```c -typedef struct _kpl_native { - kpl_class class; -} kpl_native; -``` diff --git a/docs/application/queue.md b/docs/application/queue.md deleted file mode 100644 index a770ac7..0000000 --- a/docs/application/queue.md +++ /dev/null @@ -1,18 +0,0 @@ -# Queue - ---- - -## Object Definitions - -```c -typedef struct _kpl_queue_item { - struct _kpl_queue_item *prev, *next; - kpl_any any; -} kpl_queue_item; - -typedef struct _kpl_queue { - int32_t item_length; - kpl_interface *interface; - kpl_pool_any *head, *tail; -} kpl_queue; -``` diff --git a/docs/application/shared.md b/docs/application/shared.md deleted file mode 100644 index 0528645..0000000 --- a/docs/application/shared.md +++ /dev/null @@ -1,38 +0,0 @@ -# Shared - ---- - -## Object Definitions - -```c -typedef struct _kpl_shared { - bool mark; - kpl_class data; - kpl_mutex mutex; -} kpl_shared; - -_Atomic uint32_t shared_threads_makred; - -static kpl_shared *shared_mark_head, *shared_head; - -static kpl_mutex shared_head_mutex; -``` - -# Garbage Collection - -## Initiation Task - -1. Move `shared_head` to `shared_mark_head` -2. Set `shared_threads_makred` to 0 -3. Add a mark task to each of the threads - -## Mark Task(s) - -1. Run gc interface on each task in the threads queue -2. Increase `shared_threads_makred` -3. If `shared_threads_makred` is equal to `avaiable_threads` schedule sweep task - -## Sweep Task - -1. Go through `shared_mark_head` freeing anything that is not marked -2. Add anything left on `shared_mark_head` to `shared_head` diff --git a/docs/application/testing.md b/docs/application/testing.md deleted file mode 100644 index 710915c..0000000 --- a/docs/application/testing.md +++ /dev/null @@ -1,52 +0,0 @@ -# Testing - ---- - -## Macros - -```c -TEST(NAME) { - // TEST BODY -} - -ASSERT(CONDITION, FAIL_STRING) - -FAIL(FAIL_STRING) -``` - -## Object Definitions - -```c -typedef struct { - const char *name; - kpl_error *error; -} kpl_test; - -// TODO STORE ERRORS FOR PRINT AT END - -#define _TEST_FN(NAME) static void kpl_test_fn_##NAME(__attribute__(unused)) kpl_test *_test) - -#define TEST(NAME) \ - _TEST_FN(NAME); \ - static void __attribute__((constructor)) _kpl_test_constructor_##NAME(void) { \ - kpl_test _test = { .name = #NAME; .error = NULL }; \ - kpl_test_fn_##NAME(&test); \ - if (_test.error) { \ - /* TODO STORE ERROR */ \ - } \ - /* TODO PRINT STATUS */ \ - } \ - _TEST_FN(NAME) - -// TODO ASSERT - -// TODO FAIL -``` - -## `make test` - -Bundle all tests into a single executable - -## `TEST_FILES="$NAMES..." make test` - -Only build specified file(s) diff --git a/docs/application/thread.md b/docs/application/thread.md deleted file mode 100644 index 91fa168..0000000 --- a/docs/application/thread.md +++ /dev/null @@ -1,415 +0,0 @@ -# Threads - ---- - -## Object Definitions - -```c -typedef struct _kpl_task kpl_task; - -typedef void kpl_task_fn(kpl_task *t); - -#define KPL_TASK_STATE_SIZE 24 - -typedef struct _task { - task *_Atomic next, *join, *parent; - kpl_class state[KPL_TASK_STATE_SIZE]; - kpl_result result; - task_fn *fn; - uint32_t io_flags; - int32_t io_res, thread_id; - int16_t state_length; - _Atomic bool join_ready; -} task; - -#define KPL_MAIN_THREAD 0 - -typedef struct { - kpl_task *_Atomic head, *_Atomic tail; - struct { - kpl_task *_Atomic next; - } dummy; -} kpl_task_queue; - -typedef struct { - kpl_task_queue queue; - _Atomic ssize_t priority; - sem_t counter; - pthread_t thread; -} kpl_thread; -``` - -## Initialization - -On the start of each thread, set the cpu affinity to its thread id - -## Task State - -```text -0 -> length -native : arguments -process : arguments, locals -closure : arguments, locals, closure function -iterator : arguments, locals, iterator function index, iterator functions -regex : captures, function state, regex function -``` - -## Per Process Task Queue - -## Asynchronous Task Queue - -# Queuing - -## Sync - -Queue task on selected thread - -## Async - -Queue task on thread with lowest `priority` - -# Running - -## Joining - -# Thread Pool Management - -Run task to check thread pool sizes and create tasks to spread out a large pool across other threads - -# Example - -```c -// gcc -std=gnu99 -Wall -Wextra -O2 -fhardened -fno-omit-frame-pointer -o thread_queue thread_queue.c -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -#define I 50 - -#define FIB 25 - -typedef struct _task task; - -typedef void task_fn(task *t); - -#define TASK_STATE_SIZE 55 - -typedef struct _task { - task *_Atomic next, *join; - void *state[TASK_STATE_SIZE]; - void *return_value; - task_fn *fn; - int32_t thread_id; - _Atomic bool join_ready; -} task; - -#define TASK_SLAB_SIZE 50 - -typedef struct _task_slab { - size_t array_index; - struct _task_slab *next; - task array[TASK_SLAB_SIZE]; -} task_slab; - -#define QUEUE_ASYNC -1 - -#define MAIN_THREAD 0 - -typedef struct { - task *_Atomic head, *_Atomic tail; - struct { - task *_Atomic next; - } dummy; -} atomic_queue; - -typedef struct { - atomic_queue queue; - _Atomic ssize_t priority; - task_slab *slab; - task *pool; - sem_t counter; - pthread_t thread; -} thread; - -int32_t avaiable_threads = {}; - -#define MAX_THREADS 64 - -thread threads[MAX_THREADS]; - -_Atomic ssize_t total_priority = {}; - -void priority_increment(int32_t thread_id) { - threads[thread_id].priority++; - total_priority++; -} - -void priority_decrement(int32_t thread_id) { - threads[thread_id].priority--; - total_priority--; -} - -void task_slab_init(int32_t thread_id) { - task_slab *slab = calloc(1, sizeof(task_slab)); - slab->next = threads[thread_id].slab; - threads[thread_id].slab = slab; -} - -task *task_slab_get(int32_t thread_id) { - if (threads[thread_id].slab->array_index < TASK_SLAB_SIZE) - return &threads[thread_id].slab->array[threads[thread_id].slab->array_index++]; - task_slab_init(thread_id); - return task_slab_get(thread_id); -} - -void task_slab_free(int32_t thread_id) { - task_slab *slab = threads[thread_id].slab; - while (slab) { - task_slab *tmp = slab; - slab = slab->next; - free(tmp); - } -} - -void task_queue_init(int32_t thread_id) { - threads[thread_id].queue.head = (task*) &threads[thread_id].queue.dummy; - threads[thread_id].queue.tail = (task*) &threads[thread_id].queue.dummy; - threads[thread_id].queue.dummy.next = NULL; - threads[thread_id].priority = 1; - threads[thread_id].pool = NULL; -} - -void task_queue_add(int32_t thread_id, task *t) { - t->next = NULL; - task *head = __atomic_exchange_n(&threads[thread_id].queue.head, t, __ATOMIC_SEQ_CST); - head->next = t; - if (t != (task*) &threads[thread_id].queue.dummy) - priority_increment(thread_id); -} - -task *task_queue_next(int32_t thread_id) { - task *t = NULL; - for (;;) { - task *tail = threads[thread_id].queue.tail, *next = tail->next; - if (tail == (task*) &threads[thread_id].queue.dummy) { - if (!next) - break; - threads[thread_id].queue.tail = next; - tail = next; - next = tail->next; - } - if (next) { - threads[thread_id].queue.tail = next; - t = tail; - break; - } - task *head = threads[thread_id].queue.head; - if (tail != head) - continue; - task_queue_add(thread_id, (task*) &threads[thread_id].queue.dummy); - next = tail->next; - if (next) { - threads[thread_id].queue.tail = next; - t = tail; - break; - } - } - if (t) { - t->next = NULL; - priority_decrement(thread_id); - } - return t; -} - -task *task_init(task_fn *fn, int32_t thread_id) { - task *t = NULL; - if (threads[thread_id].pool) { - t = threads[thread_id].pool; - threads[thread_id].pool = threads[thread_id].pool->join; - } - if (!t) - t = task_slab_get(thread_id); - __atomic_clear(&t->join_ready, __ATOMIC_SEQ_CST); - t->thread_id = QUEUE_ASYNC; - for (ssize_t state_id = 0; state_id < TASK_STATE_SIZE; state_id++) - t->state[state_id] = NULL; - t->return_value = NULL; - t->next = NULL; - t->join = NULL; - t->fn = fn; - return t; -} - -void task_free(task *t) { - t->join = threads[t->thread_id].pool; - threads[t->thread_id].pool = t; -} - -void task_queue_async(task *t) { - int32_t queue_thread_id = 0; - ssize_t queue_priority = threads[0].priority; - for (int32_t thread_id = 1; thread_id < avaiable_threads; thread_id++) { - if (threads[thread_id].priority < queue_priority) { - queue_priority = threads[thread_id].priority; - queue_thread_id = thread_id; - } - } - task_queue_add(queue_thread_id, t); - sem_post(&threads[queue_thread_id].counter); -} - -void task_done(task *t) { - if (!__atomic_test_and_set(&t->join_ready, __ATOMIC_SEQ_CST) || !t->join) - return; - task *join = t->join; - t->join = NULL; - __atomic_clear(&t->join_ready, __ATOMIC_SEQ_CST); - if (join->thread_id == t->thread_id) - task_queue_add(t->thread_id, join); - else - task_queue_async(join); -} - -void task_join(task *restrict t, task *restrict join, task_fn *fn) { - join->fn = fn; - t->join = join; - task_done(t); -} - -void *task_loop(void *arg) { - const int32_t thread_id = (int32_t) (intptr_t) arg; - cpu_set_t cpus; - CPU_ZERO(&cpus); - CPU_SET(thread_id, &cpus); - if (pthread_setaffinity_np(pthread_self(), sizeof(cpus), &cpus)) - exit(thread_id + 1); - for (;;) { - task *t = task_queue_next(thread_id); - if (t) { - t->thread_id = thread_id; - t->fn(t); - continue; - } - priority_decrement(thread_id); - if (!total_priority) { - for (int32_t thread_id = 0; thread_id < avaiable_threads; thread_id++) - sem_post(&threads[thread_id].counter); - break; - } - sem_wait(&threads[thread_id].counter); - if (!total_priority) - break; - priority_increment(thread_id); - } - return NULL; -} - -void task_run() { - for (int32_t thread_id = 1; thread_id < avaiable_threads; thread_id++) - pthread_create(&threads[thread_id].thread, NULL, task_loop, (void*) (intptr_t) thread_id); - task_loop(MAIN_THREAD); - for (int32_t thread_id = 1; thread_id < avaiable_threads; thread_id++) - pthread_join(threads[thread_id].thread, NULL); -} - -void task_constructor(void) { - cpu_set_t cpus; - CPU_ZERO(&cpus); - sched_getaffinity(0, sizeof(cpus), &cpus); - total_priority = avaiable_threads = CPU_COUNT(&cpus); - for (int32_t thread_id = 0; thread_id < avaiable_threads; thread_id++) { - task_queue_init(thread_id); - task_slab_init(thread_id); - sem_init(&threads[thread_id].counter, 0, 1); - } -} - -void task_destructor(void) { - for (int32_t thread_id = 0; thread_id < avaiable_threads; thread_id++) { - sem_destroy(&threads[thread_id].counter); - task_slab_free(thread_id); - } -} - -void fib_c(task *t) { - task *child_a = t->state[2], *child_b = t->state[3]; - t->return_value = (void*) ((intptr_t) child_a->return_value + (intptr_t) child_b->return_value); - task_free(child_a); - task_free(child_b); - task_done(t); -} - -void fib_a(task *t); - -void fib_b(task *t) { - intptr_t arg = (intptr_t) t->state[1]; - task *child_b = t->state[3] = task_init(fib_a, t->thread_id); - child_b->state[1] = (void*) (arg - 2); - task_queue_add(t->thread_id, child_b); - task_join(child_b, t, fib_c); -} - -void fib_a(task *t) { - intptr_t arg = (intptr_t) t->state[1]; - if (arg <= 0) { - t->return_value = (void*) 0; - task_done(t); - return; - } - if (arg < 2) { - t->return_value = (void*) 1; - task_done(t); - return; - } - task *child_a = t->state[2] = task_init(fib_a, t->thread_id); - child_a->state[1] = (void*) (arg - 1); - task_queue_add(t->thread_id, child_a); - task_join(child_a, t, fib_b); -} - -_Atomic size_t counter = 0; - -void start_b(task *t) { - counter++; - task *f = t->state[(intptr_t) t->state[0]]; - intptr_t i = (intptr_t) f->state[0], arg = (intptr_t) f->state[1], ret = (intptr_t) f->return_value; - printf("i: %ld, fib(%ld) = %ld, thread: %d\n", i, arg, ret, f->thread_id); - task_free(f); - t->state[0]++; - if ((intptr_t) t->state[0] == I + 1) { - printf("Complete\n"); - task_done(t); - task_free(t); - return; - } - task_join(t->state[(intptr_t) t->state[0]], t, start_b); -} - -void start_a(task *t) { - t->state[0] = (void*) 1; - for (intptr_t i = 1; i <= I; i++) { - task *f = task_init(fib_a, t->thread_id); - f->state[0] = (void*) i; - f->state[1] = (void*) FIB; - t->state[i] = f; - task_queue_async(f); - } - task_join(t->state[(intptr_t) t->state[0]], t, start_b); -} - -int main(void) { - task_constructor(); - task *t = task_init(start_a, MAIN_THREAD); - task_queue_add(MAIN_THREAD, t); - task_run(); - task_destructor(); - assert(counter == I); - return 0; -} -``` diff --git a/docs/application/type.md b/docs/application/type.md deleted file mode 100644 index b16b70f..0000000 --- a/docs/application/type.md +++ /dev/null @@ -1,101 +0,0 @@ -# Type - ---- - -## Object Definitions - -```c -typedef enum : uint8_t { - // ... -} kpl_type_template; - -typedef enum : uint8_t { - KPL_TYPE_QUALIFIER_CONST = 1 << 0, - KPL_TYPE_QUALIFIER_EMPTY = 1 << 1, - KPL_TYPE_QUALIFIER_REF = 1 << 2, - KPL_TYPE_QUALIFIER_SHARED = 1 << 3, - KPL_TYPE_QUALIFIER_RETURN = 1 << 4 -} kpl_type_qualifiers; - -typedef struct { - kpl_type_template template; - uint8_t qualifiers; - uint16_t modifiers; -} kpl_type_header; - -typedef struct { - uint16_t length, line; - int32_t position, module_id; -} kpl_token; - -typedef enum { - KPL_NATIVE_STORAGE_NONE, - KPL_NATIVE_STORAGE_GENERAL_REGISTER, - KPL_NATIVE_STORAGE_XMM_REGISTER, - KPL_NATIVE_STORAGE_STACK -} kpl_native_storage; - -typedef struct { - uint8_t storage : 2, id : 6; -} kpl_native_id; - -typedef union { - // 64 Bytes Max -} kpl_type_body; - -typedef struct _kpl_type { - kpl_type_header header; - union { - kpl_token token; - struct { - kpl_native_id native_id; - int8_t process_state_id; // -1 not used - uint16_t tree_weight; - struct _kpl_type *list; - } var; - } meta; - _Atomic ssize_t ref_count; - struct _kpl_type *prev, *next; - kpl_type_body body; -} kpl_type; -``` - -# Type Matching - -For type checking, evaluation and Ir generation - -Match based on the templates, from end of each statement to its start - -## Op Matching - -Each Step is represented as a tree with sequential steps as sub trees - -1. Op Name -2. Op Return Type -3. Op Left -4. Op Right -5. Match Mode (Check, Eval, Ir) - -```c -typedef enum : uint8_t { - KPL_OP_MATCH_CHECK, - KPL_OP_MATCH_EVAL, - KPL_OP_MATCH_IR -} kpl_op_match_mode; - -typedef struct _kpl_op_match { - int32_t tree_weight; - union { - kpl_op_match_mode mode; - kpl_op_name op_name; - kpl_type_header header; - } value; - union { - struct _kpl_op_match *children; - union { - // TODO FUNCTION POINTERS FOR EACH MODE - } fn; - } next; - struct _kpl_op_match *tree_left, *tree_right; -} kpl_op_match; -``` diff --git a/docs/application/union.md b/docs/application/union.md deleted file mode 100644 index 984253c..0000000 --- a/docs/application/union.md +++ /dev/null @@ -1,12 +0,0 @@ -# Union - ---- - -## Object Definitions - -```c -typedef struct _kpl_union { - uint32_t tag; - kpl_class class; -} kpl_union; -``` -- cgit v1.2.3