summaryrefslogtreecommitdiff
path: root/docs/application
diff options
context:
space:
mode:
authornodist <kevin.comas.git@gmail.com>2026-07-27 17:17:56 -0400
committernodist <kevin.comas.git@gmail.com>2026-07-27 17:17:56 -0400
commitbb912b081ed339e4a5419bd3d2ffd7465f2f72d3 (patch)
tree7f34b3af1a72672de1d12c8e23dda419c398dce3 /docs/application
parent003119b9f285e5610f56186bce845441409265ae (diff)
bottom up redesign
Diffstat (limited to 'docs/application')
-rw-r--r--docs/application/buffer.md25
-rw-r--r--docs/application/error.md27
-rw-r--r--docs/application/group.md13
-rw-r--r--docs/application/identifier.md17
-rw-r--r--docs/application/index.md72
-rw-r--r--docs/application/interface.md56
-rw-r--r--docs/application/io.md39
-rw-r--r--docs/application/map.md20
-rw-r--r--docs/application/memory.md39
-rw-r--r--docs/application/mutex.md24
-rw-r--r--docs/application/namespace.md169
-rw-r--r--docs/application/native.md11
-rw-r--r--docs/application/queue.md18
-rw-r--r--docs/application/shared.md38
-rw-r--r--docs/application/testing.md52
-rw-r--r--docs/application/thread.md415
-rw-r--r--docs/application/type.md101
-rw-r--r--docs/application/union.md12
18 files changed, 0 insertions, 1148 deletions
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 <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <sched.h>
-#include <assert.h>
-
-#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;
-```