Procházet zdrojové kódy

Add new features, merge with local branch.

Taiga Develop před 1 měsícem
rodič
revize
908cbcacb5

+ 1 - 1
build-generic/make.sh

@@ -1,7 +1,7 @@
 #!/bin/bash
 
 CC=gcc
-CC_FLAGS="-O2 -Wall -Wextra"
+CC_FLAGS="-O2 -Wall -Wextra -DZIVUOS_PLATFORM_LINUX"
 
 AR=ar
 AR_FLAGS="rcs"

+ 8 - 4
headers/zivuos.h

@@ -1,9 +1,13 @@
 #ifndef CX_ZIVUOS_H_INCLUDED
 #define CX_ZIVUOS_H_INCLUDED
 
-#include "zivuos/systypes.h"
-#include "zivuos/zalloc.h"
-#include "zivuos/mutex.h"
-#include "zivuos/vector.h"
+#include "zivuos/zv_types.h"
+#include "zivuos/state.h"
+#include "zivuos/event_type.h"
+#include "zivuos/event.h"
+#include "zivuos/task.h"
+#include "zivuos/kernel.h"
+#include "zivuos/scheduler.h"
+#include "zivuos/zv_time.h"
 
 #endif

+ 46 - 0
headers/zivuos/event.h

@@ -0,0 +1,46 @@
+#ifndef CX_ZIVUOS_EVENT_H_INCLUDED
+#define CX_ZIVUOS_EVENT_H_INCLUDED
+
+#include "zv_types.h"
+#include "event_type.h"
+#include "zv_time.h"
+
+typedef union zv_event_content_u {
+    void *object;
+    zv_time_t time;
+    uint64_t unumber;
+    int64_t number;
+} zv_event_content_t;
+
+typedef struct zv_event_s {
+    zv_event_type_t type;
+    zv_event_content_t content;
+} zv_event_t;
+
+
+bool zv_event_push_number(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    int64_t content
+);
+
+bool zv_event_push_unumber(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    uint64_t content
+);
+
+bool zv_event_set_timer(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    zv_time_t time
+);
+
+bool zv_event_push_object(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    void *content
+);
+
+#endif
+

+ 12 - 0
headers/zivuos/event_type.h

@@ -0,0 +1,12 @@
+#ifndef CX_ZIVUOS_EVENT_TYPE_H_INCLUDED
+#define CX_ZIVUOS_EVENT_TYPE_H_INCLUDED
+
+typedef enum zv_event_type_e {
+    ZV_EVENT_EMPTY,
+    ZV_EVENT_TIMER,
+    ZV_EVENT_DATA,
+    ZV_EVENT_OBJECT
+} zv_event_type_t;
+
+#endif
+

+ 44 - 0
headers/zivuos/kernel.h

@@ -0,0 +1,44 @@
+#ifndef CX_ZIVUOS_KERNEL_H_INCLUDED
+#define CX_ZIVUOS_KERNEL_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "zv_types.h"
+#include "task.h"
+
+#define ZV_COUNT_TASKS(X) (sizeof(X) / sizeof(zv_task_t))
+
+typedef enum zv_scheduler_mode_e {
+    ZV_SCHEDULER_BASIC,
+    ZV_SCHEDULER_PRIORITY_STRICT,
+    ZV_SCHEDULER_PRIORITY_AGING,
+} zv_scheduler_mode_t;
+
+typedef struct zv_kernel_s {
+    zv_scheduler_mode_t scheduler;
+    zv_task_t *tasks;
+    zv_tid_t tasks_count;
+} zv_kernel_t;
+
+bool zv_kernel_init(zv_kernel_t *self, zv_task_t *tasks, zv_tid_t count);
+bool zv_kernel_boot(zv_kernel_t *self);
+
+zv_tid_t zv_kernel_create_process(
+    zv_kernel_t *self,
+    zv_worker_t worker,
+    zv_priority_t priority,
+    void *param
+);
+
+bool zv_kernel_kill_process(
+    zv_kernel_t *self,
+    zv_tid_t target
+);
+
+zv_tid_t __zv_kernel_get_empty_slot(zv_kernel_t *self);
+zv_task_t * __zv_kernel_get_task(zv_kernel_t *self, zv_tid_t target);
+zv_tid_t __zv_kernel_get_tid(zv_kernel_t *self, zv_task_t *target);
+
+#endif
+

+ 0 - 17
headers/zivuos/mutex.h

@@ -1,17 +0,0 @@
-#ifndef CX_ZIVUOS_MUTEX_H_INCLUDED
-#define CX_ZIVUOS_MUTEX_H_INCLUDED
-
-#include <stdint.h>
-#include <stdbool.h>
-
-typedef volatile enum zv_mutex_e {
-    ZV_MUTEX_FREE,
-    ZV_MUTEX_LOCKED
-} zv_mutex_t;
-
-enum zv_mutex_e zv_mutex_create();
-bool zv_mutex_try_lock(zv_mutex_t *self);
-bool zv_mutex_is_free(zv_mutex_t *self);
-void zv_mutex_unlock(zv_mutex_t *self);
-
-#endif

+ 13 - 0
headers/zivuos/scheduler.h

@@ -0,0 +1,13 @@
+#ifndef CX_ZIVUOS_SCHEDULER_H_INCLUDED
+#define CX_ZIVUOS_SCHEDULER_H_INCLUDED
+
+#include "kernel.h"
+#include "task.h"
+
+void __zv_scheduler_update_tasks(zv_kernel_t *self);
+zv_task_t * __zv_scheduler_find_task(zv_kernel_t *self);
+void __zv_scheduler_run_task(zv_kernel_t *self, zv_task_t *target);
+
+#endif
+
+

+ 14 - 0
headers/zivuos/state.h

@@ -0,0 +1,14 @@
+#ifndef CX_ZIVUOS_STATE_H_INCLUDED
+#define CX_ZIVUOS_STATE_H_INCLUDED
+
+typedef enum zv_state_e {
+    ZV_TASK_EMPTY,
+    ZV_TASK_READY,
+    ZV_TASK_RUNNING,
+    ZV_TASK_ANY_EVENT_WAIT,
+    ZV_TASK_TIMER_EVENT_WAIT,
+    ZV_TASK_DATA_EVENT_WAIT
+} zv_state_t;
+
+#endif
+

+ 0 - 22
headers/zivuos/systypes.h

@@ -1,22 +0,0 @@
-#ifndef CX_ZIVUOS_SYSTYPES_H_INCLUDED
-#define CX_ZIVUOS_SYSTYPES_H_INCLUDED
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-
-typedef uint16_t zv_pid_t;
-typedef uint16_t zv_priority_t;
-
-typedef size_t zv_size_t;
-
-typedef union zv_universal_u {
-    char *string;
-    void *pointer;
-    intptr_t integer;
-    uintptr_t uinteger;
-} zv_universal_t;
-
-#define ZV_UNIVERSAL_NULL ((zv_universal_t) NULL)
-
-#endif

+ 8 - 56
headers/zivuos/task.h

@@ -1,66 +1,18 @@
 #ifndef CX_ZIVUOS_TASK_H_INCLUDED
 #define CX_ZIVUOS_TASK_H_INCLUDED
 
-#include "systypes.h"
-
-/** 
- * @brief That enum store task type.
- *
- * Task is container for more than one type of logic. 
- * - Coroutine is function which run in loop. Could not being scheduled. 
- * - Oneshot is coroutine which is executed only once. 
- * - Process is task which could being scheduled.
- */
-typedef enum zv_task_type_e {
-    ZV_COROUTINE_TASK,
-    ZV_PROCESS_TASK,
-    ZV_ONESHOT_TASK
-} zv_task_type_t;
-
-/**
- * @brief That enum store task state.
- */
-typedef enum zv_state_e {
-    ZV_KILLED,
-    ZV_RUNNING,
-    ZV_READY,
-    ZV_SLEEP
-} zv_state_t;
-
-/* That declaration is required for worker. */
-struct zv_kernel_s;
-
-/**
- * @brief That is worker, which is function for task.
- */
-typedef zv_state_t (*zv_worker_t) (struct zv_kernel_t *, zv_pid_t);
-
-typedef struct zv_coroutine_s {
-    zv_worker_t worker;
-    zv_universal_t param;
-} zv_coroutine_t;
-
-typedef struct zv_process_s {
-} zv_process_t;
-
-typedef struct zv_oneshot_s {
-    zv_worker_t worker;
-    zv_universal_t param;
-} zv_oneshot_t;
-
-typedef union zv_task_selector_u {
-    zv_coroutine_t coroutine;
-    zv_process_t process;
-    zv_oneshot_t oneshot;
-} zv_task_selector_t;
+#include "zv_types.h"
+#include "state.h"
+#include "event.h"
 
 typedef struct zv_task_s {
-    zv_pid_t pid;
     zv_state_t state;
+    void *param;
+    zv_event_t event;
+    zv_worker_t worker;
+    zv_priority_t age;
     zv_priority_t priority;
-    zv_task_type_t type;
-
-    zv_task_selector_t selector;
 } zv_task_t;
 
 #endif
+

+ 0 - 41
headers/zivuos/vector.h

@@ -1,41 +0,0 @@
-#ifndef CX_ZIVUOS_VECTOR_H_INCLUDED
-#define CX_ZIVUOS_VECTOR_H_INCLUDED
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-
-#include "systypes.h"
-#include "zalloc.h"
-
-typedef struct zv_vector_container_s {
-    zv_universal_t content;
-    
-    struct zv_vector_container_s *next;
-    struct zv_vector_container_s *previous;
-} zv_vector_container_t;
-
-typedef struct zv_vector_container_s * zv_vector_t;
-
-typedef int32_t zv_vector_count_t;
-
-zv_vector_t * zv_vector_create(void);
-void zv_vector_clear(zv_vector_t *self);
-void zv_vector_remove(zv_vector_t *self);
-zv_vector_count_t zv_vector_length(zv_vector_t *self);
-
-zv_universal_t zv_vector_pop(zv_vector_t *self);
-bool zv_vector_append(zv_vector_t *self, zv_universal_t content);
-
-zv_universal_t zv_vector_indexed_pop(
-    zv_vector_t *self, 
-    zv_vector_count_t index
-);
-
-bool zv_vector_insert(
-    zv_vector_t *self, 
-    zv_universal_t content, 
-    zv_vector_count_t index
-);
-
-#endif

+ 0 - 12
headers/zivuos/zalloc.h

@@ -1,12 +0,0 @@
-#ifndef CX_ZIVUOS_ZALLOC_H_INCLUDED
-#define CX_ZIVUOS_ZALLOC_H_INCLUDED
-
-#include <stdbool.h>
-
-#include "systypes.h"
-
-void * zv_malloc(zv_size_t size);
-void zv_free(void *pointer);
-bool zv_malloc_avairable(void);
-
-#endif

+ 10 - 0
headers/zivuos/zv_time.h

@@ -0,0 +1,10 @@
+#ifndef CX_ZIVUOS_TIME_H_INCLUDED
+#define CX_ZIVUOS_TIME_H_INCLUDED
+
+#include "zv_types.h"
+
+typedef uint64_t zv_time_t;
+
+zv_time_t zv_platform_get_time();
+
+#endif

+ 27 - 0
headers/zivuos/zv_types.h

@@ -0,0 +1,27 @@
+#ifndef CX_ZIVUOS_TYPES_H_INCLUDED
+#define CX_ZIVUOS_TYPES_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef uint16_t zv_tid_t;
+typedef uint16_t zv_priority_t;
+typedef uint64_t zv_systime_t;
+
+#define ZV_TID_NULL ((zv_tid_t) -1)
+
+struct zv_task_s;
+struct zv_kernel_s;
+struct zv_event_s;
+
+enum zv_state_e;
+enum zv_event_type_e;
+
+typedef enum zv_state_e (*zv_worker_t) (
+    struct zv_kernel_s *kernel,
+    struct zv_event_s *received,
+    zv_tid_t tid,
+    void *param
+);
+
+#endif

+ 90 - 0
sources/event.c

@@ -0,0 +1,90 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "zv_types.h"
+#include "kernel.h"
+#include "task.h"
+#include "event.h"
+#include "zv_time.h"
+
+static inline bool __zv_event_empty(zv_event_t *self) {
+    return self->type == ZV_EVENT_EMPTY;
+}
+
+bool zv_event_push_number(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    int64_t content
+) {
+    zv_task_t *task = __zv_kernel_get_task(self, target);
+    zv_event_t *event = &task->event;
+
+    if (!__zv_event_empty(event)) {
+        return false;
+    }
+
+    event->type = ZV_EVENT_DATA;
+    event->content.number = content;
+
+    return true;
+}
+
+bool zv_event_push_unumber(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    uint64_t content
+) {
+    zv_task_t *task = __zv_kernel_get_task(self, target);
+    zv_event_t *event = &task->event;
+
+    if (!__zv_event_empty(event)) {
+        return false;
+    }
+
+    event->type = ZV_EVENT_DATA;
+    event->content.unumber = content;
+
+    return true;
+}
+
+bool zv_event_set_timer(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    zv_time_t time
+) {
+    zv_task_t *task = __zv_kernel_get_task(self, target);
+    zv_event_t *event = &task->event;
+
+    if (!__zv_event_empty(event)) {
+        return false;
+    }
+
+    zv_time_t current_time = zv_platform_get_time();
+    zv_time_t final_time = current_time + time;
+
+    event->type = ZV_EVENT_TIMER;
+    event->content.time = final_time;
+    return true;
+}
+
+bool zv_event_push_object(
+    struct zv_kernel_s *self,
+    zv_tid_t target,
+    void *content
+) {
+    if (content == NULL) {
+        return false;
+    }
+
+    zv_task_t *task = __zv_kernel_get_task(self, target);
+    zv_event_t *event = &task->event;
+
+    if (!__zv_event_empty(event)) {
+        return false;
+    }
+
+    event->type = ZV_EVENT_OBJECT;
+    event->content.object = content;
+    return true;
+}

+ 113 - 0
sources/kernel.c

@@ -0,0 +1,113 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#include "task.h"
+#include "kernel.h"
+#include "scheduler.h"
+
+bool zv_kernel_init(zv_kernel_t *self, zv_task_t *tasks, zv_tid_t count) {
+    if (self == NULL || tasks == NULL || count < 1) {
+        return false;
+    }
+
+    self->tasks = tasks;
+    self->tasks_count = count;
+    self->scheduler = ZV_SCHEDULER_PRIORITY_AGING;
+
+    for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
+        zv_task_t *current = self->tasks + count;
+        current->state = ZV_TASK_EMPTY;
+    }
+    
+    return true;
+}
+
+
+bool zv_kernel_boot(zv_kernel_t *self) {
+    if (self == NULL || self->tasks == NULL || self->tasks_count < 1) {
+        return false;
+    }
+
+    while (true) {
+        __zv_scheduler_update_tasks(self);
+        zv_task_t *next = __zv_scheduler_find_task(self);
+
+        if (next == NULL) {
+            break;
+        }
+
+        __zv_scheduler_run_task(self, next);
+    }   
+    
+    return true;
+}
+
+zv_tid_t __zv_kernel_get_empty_slot(zv_kernel_t *self) {
+    for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
+        zv_task_t *current = self->tasks + count;
+        
+        if (current->state == ZV_TASK_EMPTY) {
+            return count;
+        }
+    }
+
+    return ZV_TID_NULL;
+}
+
+zv_task_t *__zv_kernel_get_task(zv_kernel_t *self, zv_tid_t target) {
+    if (self->tasks_count <= target) {
+        return NULL;
+    }
+
+    return self->tasks + target;
+}
+
+zv_tid_t zv_kernel_create_process(
+    zv_kernel_t *self,
+    zv_worker_t worker,
+    zv_priority_t priority,
+    void *param
+) {
+    if (self == NULL || worker == NULL) {
+        return ZV_TID_NULL;
+    }
+
+    zv_tid_t target_tid = __zv_kernel_get_empty_slot(self);
+    zv_task_t *target = __zv_kernel_get_task(self, target_tid);
+
+    if (target == NULL) {
+        return ZV_TID_NULL;
+    }
+
+    target->worker = worker;
+    target->param = param;
+    target->priority = priority;
+    
+    target->event.type = ZV_EVENT_EMPTY;
+    target->event.content.unumber = 0x00;
+    
+    target->state = ZV_TASK_READY;
+    return target_tid;
+}
+
+bool zv_kernel_kill_process(
+    zv_kernel_t *self,
+    zv_tid_t target_tid
+) {
+    if (self == NULL) {
+        return false;
+    }
+
+    zv_task_t *target = __zv_kernel_get_task(self, target_tid);
+
+    if (target == NULL) {
+        return false;
+    }
+
+    target->state = ZV_TASK_EMPTY;
+    return true;
+}
+
+zv_tid_t __zv_kernel_get_tid(zv_kernel_t *self, zv_task_t *target) {
+    return target - self->tasks;
+}

+ 0 - 31
sources/mutex.c

@@ -1,31 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "mutex.h"
-
-enum zv_mutex_e zv_mutex_create() {
-    return ZV_MUTEX_FREE;
-}
-
-bool zv_mutex_try_lock(zv_mutex_t *self) {
-    zv_mutex_t required = ZV_MUTEX_FREE;
-
-    return __atomic_compare_exchange_n(
-        self, 
-        (void *) &required, 
-        ZV_MUTEX_LOCKED, 
-        false, 
-        __ATOMIC_ACQ_REL, 
-        __ATOMIC_ACQUIRE
-    );
-}
-
-bool zv_mutex_is_free(zv_mutex_t *self) {
-    return __atomic_load_n(self, __ATOMIC_ACQUIRE) == ZV_MUTEX_FREE; 
-}
-
-void zv_mutex_unlock(zv_mutex_t *self) {
-    __atomic_store_n(self, ZV_MUTEX_FREE, __ATOMIC_RELEASE);
-}
-
-

+ 33 - 0
sources/platform_linux.c

@@ -0,0 +1,33 @@
+#ifdef ZIVUOS_PLATFORM_LINUX
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include <math.h>
+#include <time.h>
+
+#include "zv_types.h"
+#include "zv_time.h"
+
+zv_time_t zv_platform_get_time() {
+    struct timespec current_time;
+
+    clock_gettime(CLOCK_REALTIME, &current_time);
+
+    time_t seconds = current_time.tv_sec;
+    long nanoseconds = current_time.tv_nsec;
+    long miliseconds = round(nanoseconds / 1000000);
+
+    if (miliseconds > 999) {
+        miliseconds = 0;
+        ++seconds;
+    }
+
+    zv_time_t result = seconds * 1000;
+    result += miliseconds;
+    
+    return result;
+}
+
+#endif

+ 148 - 0
sources/scheduler.c

@@ -0,0 +1,148 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#include "task.h"
+#include "kernel.h"
+#include "scheduler.h"
+#include "zv_time.h"
+
+static bool __zv_scheduler_event_ready(
+    zv_kernel_t *,
+    zv_task_t *target
+) {
+    zv_event_t *event = &target->event;
+
+    if (event->type == ZV_EVENT_OBJECT || event->type == ZV_EVENT_DATA) {
+        return true;
+    }
+
+    if (event->type == ZV_EVENT_TIMER) {
+        zv_time_t current_time = zv_platform_get_time();
+
+        if (event->content.time <= current_time) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static void __zv_scheduler_update_single_task(
+    zv_kernel_t *self, 
+    zv_task_t *target
+) {
+    if (__zv_scheduler_event_ready(self, target)) {
+        target->state = ZV_TASK_READY;
+    }
+
+    if (target->state == ZV_TASK_READY) {
+        ++target->age;
+    }
+}
+
+void __zv_scheduler_update_tasks(zv_kernel_t *self) {
+    for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
+        __zv_scheduler_update_single_task(self, self->tasks + count);
+    }
+}
+
+static zv_task_t * __zv_scheduler_basic(zv_kernel_t *self) {
+    for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
+        zv_task_t *current = self->tasks + count;
+
+        if (current->state == ZV_TASK_READY) {
+            return current;
+        }
+    }
+
+    return NULL;
+}
+
+static zv_task_t * __zv_scheduler_priority_strict(zv_kernel_t *self) {
+    zv_task_t *found = NULL;
+
+    for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
+        zv_task_t *current = self->tasks + count;
+        
+        if (current->state != ZV_TASK_READY) {
+            continue;
+        }
+
+        if (found == NULL) {
+            found = current;
+            continue;
+        }
+        
+        if (found->priority < current->priority) {
+            found = current;
+            continue;
+        }
+    }
+
+    return found;
+}
+
+static zv_task_t * __zv_scheduler_priority_aging(zv_kernel_t *self) {
+    zv_task_t *found = NULL;
+    zv_priority_t found_priority;
+
+    for (zv_tid_t count = 0; count < self->tasks_count; ++count) {
+        zv_task_t *current = self->tasks + count;
+        
+        if (current->state != ZV_TASK_READY) {
+            continue;
+        }
+
+        if (found == NULL) {
+            found = current;
+            found_priority = found->priority + found->age;
+            continue;
+        }
+        
+        if (found_priority < (current->priority + current->age)) {
+            found = current;
+            found_priority = found->priority + found->age;
+            continue;
+        }
+    }
+
+    return found;
+}
+
+zv_task_t * __zv_scheduler_find_task(zv_kernel_t *self) {
+    switch (self->scheduler) {
+        case ZV_SCHEDULER_BASIC:
+            return __zv_scheduler_basic(self);
+
+        case ZV_SCHEDULER_PRIORITY_STRICT:
+            return __zv_scheduler_priority_strict(self);
+
+        case ZV_SCHEDULER_PRIORITY_AGING:
+            return __zv_scheduler_priority_aging(self);
+
+        default:
+            return NULL;
+    }
+}
+
+void __zv_scheduler_run_task(zv_kernel_t *self, zv_task_t *target) {
+    target->state = ZV_TASK_RUNNING;
+    zv_event_t event_copy = target->event;
+    
+    target->event.type = ZV_EVENT_EMPTY;
+    target->event.content.unumber = 0;
+
+    zv_state_t result = target->worker(
+        self,
+        &event_copy,
+        __zv_kernel_get_tid(self, target),
+        target->param
+    );
+
+    if (result == ZV_TASK_READY || result == ZV_TASK_RUNNING) {
+        result = ZV_TASK_READY;
+    }
+
+    target->state = result;
+    target->age = 0x00;
+}

+ 0 - 143
sources/vector.c

@@ -1,143 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-
-#include "zalloc.h"
-#include "systypes.h"
-
-#include "vector.h"
-
-zv_vector_t * zv_vector_create(void) {
-    return (zv_vector_t *) zv_malloc(sizeof(zv_vector_t));
-}
-
-void zv_vector_clear(zv_vector_t *self) {
-    if (*self == NULL) {
-        return;
-    }
-}
-
-void zv_vector_remove(zv_vector_t *self) {
-    zv_vector_clear(self);
-
-    zv_free(self);
-}
-
-zv_vector_count_t zv_vector_length(zv_vector_t *self) {
-    if (*self == NULL) {
-        return 0;
-    }
-
-    zv_vector_container_t *first = *self;
-    zv_vector_container_t *current = first;
-    zv_vector_count_t size = 1;
-
-    while (current->next != first) {
-        ++size;
-        current = current->next;
-    }
-
-    return size;
-}
-
-zv_vector_container_t * zv_vector_get_container(
-    zv_vector_t *self, 
-    zv_vector_count_t index
-) {
-    if (*self == NULL) {
-        return NULL;
-    }
-
-    zv_vector_container_t *current = *self;
-
-    while (index > 0 && current != NULL) {
-        current = current->next;
-        --index;
-    }
-
-    while (index < 0 && current != NULL) {
-        current = current->previous;
-        ++index;
-    }
-
-    return current;
-}
-
-zv_universal_t zv_vector_pop(zv_vector_t *self) {
-    return zv_vector_indexed_pop(self, -1);
-}
-
-zv_universal_t zv_vector_indexed_pop(
-    zv_vector_t *self, 
-    zv_vector_count_t index
-) {
-    if (*self == NULL) {
-        return ZV_UNIVERSAL_NULL;
-    }
-
-    zv_vector_container_t *current = *self;
-
-    if (current->next == current) {
-        *self = NULL;
-    }
-
-    return ZV_UNIVERSAL_NULL;
-}
-
-bool zv_vector_insert(
-    zv_vector_t *self, 
-    zv_universal_t content, 
-    zv_vector_count_t index
-) {
-    zv_vector_container_t *target = zv_malloc(sizeof(zv_vector_container_t));
-
-    if (target == NULL) {
-        return false;
-    }
-
-    target->content = content;
-    
-    if (*self == NULL) {
-        *self = target;
-        target->next = target;
-        target->previous = target;
-
-        return true;
-    }
-
-    zv_vector_container_t *current = *self;
-    bool overwrite_handler = (index == 0);
-
-    while (index > 0 && current != NULL) {
-        current = current->next;
-        --index;
-    }
-
-    while (index < -1 && current != NULL) {
-        current = current->previous;
-        ++index;
-    }
-
-    if (current == NULL) {
-        zv_free(target);
-        return false;
-    }
-    
-    target->next = current;
-    target->previous = current->previous;
-
-    current->previous->next = target;
-    current->previous = target;
-
-    if (overwrite_handler) {
-        *self = target;
-    }
-
-    return true;
-}
-
-bool zv_vector_append(zv_vector_t *self, zv_universal_t content) {
-    return zv_vector_insert(self, content, -1);
-}
-
-

+ 0 - 42
sources/zalloc.c

@@ -1,42 +0,0 @@
-#include <stddef.h>
-#include <stdbool.h>
-
-#include "zalloc.h"
-#include "systypes.h"
-
-#ifndef ZV_DISABLE_DYNAMIC
-#define ZV_USE_STD_MALLOC
-#endif
-
-#ifdef ZV_USE_STD_MALLOC
-
-#include <malloc.h>
-
-void * zv_malloc(zv_size_t size) {
-    return malloc(size);
-}
-
-void zv_free(void *pointer) {
-    free(pointer);
-}
-
-bool zv_malloc_avairable(void) {
-    return true;
-}
-
-#endif
-
-#ifdef ZV_DISABLE_DYNAMIC
-
-bool zv_malloc_avairable(void) {
-    return false;
-}
-
-void * zv_malloc(zv_size_t size) {
-    return NULL;
-}
-
-void zv_free(void *pointer) {
-}
-
-#endif

+ 0 - 0
tests/001-mutex/run.sh → tests/001-first_boot/run.sh


+ 43 - 0
tests/001-first_boot/testing.c

@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <zivuos.h>
+
+zv_state_t task_worker(zv_kernel_t *kernel, zv_event_t *event, zv_tid_t self, void *param) {
+    puts("Task run.");
+    printf("Task TID: %u. ", self);
+    puts("Finish!");
+
+    return ZV_TASK_RUNNING;
+}
+
+int main() {
+    puts("ZivuOS basic scheduler test unit.");
+
+    zv_kernel_t kernel[1];
+    zv_task_t tasks[10];
+
+    if (zv_kernel_init(kernel, tasks, ZV_COUNT_TASKS(tasks)) == false) {
+        puts("KERNEL INIT ERROR.");
+    }
+
+    if (zv_kernel_create_process(
+        kernel, 
+        task_worker, 
+        0x02, 
+        NULL
+    ) == ZV_TID_NULL) {
+        puts("CREATE PROCESS ERROR.");
+    }
+    
+    if (zv_kernel_create_process(
+        kernel, 
+        task_worker, 
+        0x01, 
+        NULL
+    ) == ZV_TID_NULL) {
+        puts("CREATE PROCESS ERROR.");
+    }
+
+    zv_kernel_boot(kernel);
+
+    return 0;
+}

+ 0 - 39
tests/001-mutex/testing.c

@@ -1,39 +0,0 @@
-#include <stdio.h>
-#include <zivuos.h>
-
-void check(zv_mutex_t *self) {
-    if (zv_mutex_is_free(self)) {
-        puts("Mutex is free.");
-    } else {
-        puts("Mutex is locked.");
-    }
-}
-
-void catch(zv_mutex_t *self) {
-    if (zv_mutex_try_lock(self)) {
-        puts("Locking mutex.");
-    } else {
-        puts("Mutex is already locker.");
-    }
-}
-
-int main() {
-    puts("ZivuOS default test unit.");
-
-    zv_mutex_t lock = zv_mutex_create();
-
-    check(&lock);
-    catch(&lock);
-    catch(&lock);
-    check(&lock);
-
-    zv_mutex_unlock(&lock);
-
-    check(&lock);
-    catch(&lock);
-    check(&lock);
-
-    zv_mutex_unlock(&lock);
-
-    return 0;
-}

+ 0 - 0
tests/002-vector/run.sh → tests/002-event/run.sh


+ 38 - 0
tests/002-event/testing.c

@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <zivuos.h>
+
+zv_state_t task_worker(
+    zv_kernel_t *kernel,
+    zv_event_t *event,
+    zv_tid_t self,
+    void *param
+) {
+    printf("Current time: %li\n", zv_platform_get_time());
+
+    zv_event_set_timer(kernel, self, 500);
+    return ZV_TASK_ANY_EVENT_WAIT;
+}
+
+zv_state_t task_idle(
+    zv_kernel_t *,
+    zv_event_t *,
+    zv_tid_t,
+    void *
+) {
+    return ZV_TASK_READY;
+}
+
+int main() {
+    puts("ZivuOS event test unit.");
+
+    zv_kernel_t kernel[1];
+    zv_task_t tasks[10];
+
+    zv_kernel_init(kernel, tasks, ZV_COUNT_TASKS(tasks));
+    zv_kernel_create_process(kernel, task_worker, 0x01, NULL);
+    zv_kernel_create_process(kernel, task_idle, 0x00, NULL);
+
+    zv_kernel_boot(kernel);
+
+    return 0;
+}

+ 0 - 38
tests/002-vector/testing.c

@@ -1,38 +0,0 @@
-#include <stdio.h>
-#include <zivuos.h>
-
-void dump(zv_vector_t *self) {
-    zv_vector_count_t length = zv_vector_length(self);
-
-    printf("Vector length: %u\n", length);
-    
-    zv_vector_container_t *current = *self;
-    size_t count = 0;
-
-    while (count < length) {
-        printf("Item %u: %s\n", count++, current->content.string);
-        current = current->next;        
-    }
-    
-    puts("Dump end");
-    puts("");
-}
-
-int main() {
-    puts("ZivuOS vector test unit.");
-
-    zv_universal_t first = { .string = "UwU" };
-    zv_universal_t second = { .string = "OwO" };
-
-    zv_vector_t *test = zv_vector_create();
-
-    dump(test);
-
-    zv_vector_append(test, first); 
-    zv_vector_append(test, second);
-    zv_vector_append(test, second);
-
-    dump(test);
-
-    return 0;
-}