Cixo Develop hace 6 meses
padre
commit
64b372ad95

+ 1 - 1
build-generic/make.sh

@@ -19,7 +19,7 @@ for count in $SOURCE/*.c; do
     file_full_name=$file_name.c
     output_name=$file_name.o
 
-    echo "Creating $file_full_name..."
+    echo "Building $file_full_name..."
     $CC $CC_FLAGS $SOURCE/$file_full_name -c -o $BUILD/$output_name -I$HEADERS
 done
 

+ 15 - 10
headers/zivuos/kernel.h

@@ -7,13 +7,8 @@
 
 #include "models.h"
 #include "process.h"
-
-typedef enum zv_scheduler_mode_e {
-    ZV_FIRST_MATCH,
-    ZV_ROUND_ROBIN_FIRST_MATCH,
-    ZV_BALANCED_PRIORITY,
-    ZV_NON_BALANCED_PRIORITY
-} zv_scheduler_mode_t;
+#include "scheduler.h"
+#include "result.h"
 
 typedef struct zv_kernel_s {
     size_t processes_count;
@@ -37,10 +32,20 @@ zv_pid_t zv_kernel_add_process(
     zv_priority_t
 );
 
-bool zv_kernel_scheduler(zv_kernel_t *);
-void zv_kernel_clean_balance(zv_kernel_t *);
-
+void __zv_kernel_clean_balance(zv_kernel_t *);
 void zv_idle_task();
+zv_result_t zv_kernel_trigger_process(zv_kernel_t *, zv_pid_t);
+
+static inline zv_process_t * __zv_kernel_get_process(
+    zv_kernel_t *self, 
+    zv_pid_t target
+) {
+    if (self->processes_count <= target) {
+        return NULL;
+    }
+
+    return self->processes + target;
+}
 
 static inline zv_pid_t zv_kernel_get_pid(
     zv_kernel_t *self, 

+ 0 - 1
headers/zivuos/models.h

@@ -4,7 +4,6 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-
 typedef uint16_t zv_pid_t;
 typedef uint8_t zv_priority_t;
 

+ 3 - 0
headers/zivuos/process.h

@@ -26,6 +26,9 @@ static inline zv_priority_t _zv_process_calc_priority(zv_process_t *self) {
     return self->priority + self->balance;
 }
 
+zv_result_t zv_process_change_param(zv_process_t *, zv_universal_t);
+zv_result_t zv_process_change_worker(zv_process_t *, zv_worker_t);
+
 #define ZV_COUNT_PROCESSES(X) ((sizeof(X) / sizeof(zv_process_t)))
 
 #endif

+ 14 - 0
headers/zivuos/result.h

@@ -0,0 +1,14 @@
+#ifndef CX_ZIVUOS_RESULT_H_INCLUDED
+#define CX_ZIVUOS_RESULT_H_INCLUDED
+
+typedef enum zv_result_e {
+    ZV_SUCCESS = 0,
+    ZV_ERROR = 1,
+    ZV_ALREADY_TRIGGERED = 2,
+    ZV_IN_USE = 3,
+    ZV_NOT_EXISTS = 4,
+    ZV_NOT_READY = 6,
+    ZV_BAD_STATE
+} zv_result_t;
+
+#endif

+ 15 - 4
headers/zivuos/scheduler.h

@@ -1,11 +1,22 @@
 #ifndef CX_ZIVUOS_SCHEDULER_H_INCLUDED
 #define CX_ZIVUOS_SCHEDULER_H_INCLUDED
 
+#include "models.h"
 #include "process.h"
-#include "kernel.h"
 
-zv_process_t * zv_kernel_round_first_match(zv_kernel_t *);
-zv_process_t * zv_kernel_balanced_priority(zv_kernel_t *);
-zv_process_t * zv_kernel_non_balanced_priority(zv_kernel_t *);
+typedef enum zv_scheduler_mode_e {
+    ZV_FIRST_MATCH,
+    ZV_ROUND_ROBIN_FIRST_MATCH,
+    ZV_BALANCED_PRIORITY,
+    ZV_NON_BALANCED_PRIORITY
+} zv_scheduler_mode_t;
+
+void zv_kernel_scheduler(struct zv_kernel_s *);
+zv_process_t * zv_kernel_round_first_match(struct zv_kernel_s *);
+zv_process_t * zv_kernel_balanced_priority(struct zv_kernel_s *);
+zv_process_t * zv_kernel_non_balanced_priority(struct zv_kernel_s *);
+zv_process_t * zv_kernel_basic_scheduler(struct zv_kernel_s *);
+zv_process_t * zv_kernel_scheduler_mode_selector(struct zv_kernel_s *);
+zv_process_t * zv_kernel_scheduler_select_interrupted(struct zv_kernel_s *);
 
 #endif

+ 9 - 1
sources/balanced_priority_scheduler.c

@@ -1,6 +1,8 @@
 #include "kernel.h"
 #include "scheduler.h"
 
+#ifndef ZV_FULL_DISABLE_BALANCED_PRIORITY
+
 zv_process_t * zv_kernel_balanced_priority(zv_kernel_t *self) {
     zv_process_t *selected = NULL;
     zv_process_t *last = self->processes + self->last;
@@ -46,7 +48,7 @@ zv_process_t * zv_kernel_balanced_priority(zv_kernel_t *self) {
     }
 
     if (full_round) {
-        zv_kernel_clean_balance(self);
+        __zv_kernel_clean_balance(self);
         return zv_kernel_balanced_priority(self);
     }
 
@@ -57,5 +59,11 @@ zv_process_t * zv_kernel_balanced_priority(zv_kernel_t *self) {
     return selected;
 }
 
+#else
+
+zv_process_t * zv_kernel_balanced_priority(zv_kernel_t *self) {
+    return NULL;
+}
 
+#endif
 

+ 24 - 0
sources/basic_scheduler.c

@@ -0,0 +1,24 @@
+#include "kernel.h"
+#include "scheduler.h"
+
+#ifndef ZV_BASIC_SCHEDULER_UNUSED
+
+zv_process_t * zv_kernel_basic_scheduler(zv_kernel_t *self) {
+    for (zv_pid_t count = 0; count < self->processes_count; ++count) {
+        zv_process_t *current = self->processes + count;
+        
+        if (zv_process_is_ready(current)) {
+            return current;
+        }
+    }
+
+    return NULL;
+}
+
+#else
+
+zv_process_t * zv_kernel_basic_scheduler(zv_kernel_t *self) {
+    return NULL;
+}
+
+#endif

+ 1 - 1
sources/idle_task.c

@@ -1,6 +1,6 @@
 #ifndef ZV_OVERRIDE_IDLE_TASK
 
-void zv_idle_task() {
+void zv_kernel_idle_task() {
     return;   
 }
 

+ 19 - 0
sources/interrupt_scheduler.c

@@ -0,0 +1,19 @@
+#include "kernel.h"
+#include "process.h"
+#include "scheduler.h"
+
+zv_process_t * zv_kernel_scheduler_select_interrupted(zv_kernel_t *self) {
+    zv_process_t *selected = self->processes;
+
+    while (selected != (self->processes + self->processes_count)) {
+        if (selected->state == ZV_INTERRUPTED) {
+            return selected;
+        }
+
+        ++selected;
+    }
+
+    return NULL;
+}
+
+

+ 33 - 1
sources/kernel.c

@@ -47,11 +47,43 @@ zv_pid_t zv_kernel_add_process(
     return ZV_ERROR_PID;
 }
 
-void zv_kernel_clean_balance(zv_kernel_t *self) {
+void __zv_kernel_clean_balance(zv_kernel_t *self) {
     for (zv_pid_t count = 0; count < self->processes_count; ++count) {
         zv_process_t *current = self->processes + count;
         current->balance = 0;
     }
 }
 
+zv_result_t zv_kernel_trigger_process(zv_kernel_t *self, zv_pid_t target) {
+    zv_process_t *current = __zv_kernel_get_process(self, target);
+    
+    if (current == NULL || current->state == ZV_EMPTY) {
+        return ZV_NOT_EXISTS;
+    }
+
+    if (current->state != ZV_INTERRUPT_WAITING) {
+        return ZV_BAD_STATE;
+    }
+
+    ++self->interrupts;
+    self->processes->state = ZV_INTERRUPTED;
+
+    return ZV_SUCCESS;
+}  
+
+zv_result_t zv_kernel_awake_process(zv_kernel_t *self, zv_pid_t target) {
+    zv_process_t *current = __zv_kernel_get_process(self, target);
+    
+    if (current == NULL || current->state == ZV_EMPTY) {
+        return ZV_NOT_EXISTS;
+    }
+    
+    if (current->state != ZV_WAITING) {
+        return ZV_BAD_STATE;
+    }
+
+    current->state = ZV_READY;
+    return ZV_SUCCESS;
+}
+
 

+ 10 - 0
sources/non_balanced_priority_scheduler.c

@@ -1,6 +1,8 @@
 #include "kernel.h"
 #include "scheduler.h"
 
+#ifndef ZV_FULL_DISABLE_NON_BALANCED_PRIORITY
+
 zv_process_t * zv_kernel_non_balanced_priority(zv_kernel_t *self) {
     zv_process_t *selected = NULL;
 
@@ -26,3 +28,11 @@ zv_process_t * zv_kernel_non_balanced_priority(zv_kernel_t *self) {
 
     return selected;
 }
+
+#else
+
+zv_process_t * zv_kernel_non_balanced_priority(zv_kernel_t *self) {
+    return NULL;
+}
+
+#endif

+ 16 - 0
sources/process.c

@@ -0,0 +1,16 @@
+#include "process.h"
+#include "result.h"
+
+zv_result_t zv_process_change_worker(zv_process_t *self, zv_worker_t target) {
+    self->worker = target;
+    return ZV_SUCCESS;
+}
+
+zv_result_t zv_process_change_param(
+    zv_process_t *self, 
+    zv_universal_t target
+) {
+    self->param = target;
+    return ZV_SUCCESS;
+}
+

+ 8 - 0
sources/round_roubin_first_match_scheduler.c

@@ -1,6 +1,8 @@
 #include "kernel.h"
 #include "scheduler.h"
 
+#ifndef ZV_FULL_DISABLE_ROUND_ROUBIN_FIRST_MATCH
+
 zv_process_t * zv_kernel_round_first_match(zv_kernel_t *self) {
     zv_pid_t size = self->processes_count;
     zv_pid_t count = (self->last + 1) % size;
@@ -18,4 +20,10 @@ zv_process_t * zv_kernel_round_first_match(zv_kernel_t *self) {
     return NULL;
 }
 
+#else
+
+zv_process_t * zv_kernel_round_first_match(zv_kernel_t *self) {
+    return NULL;
+}
 
+#endif

+ 13 - 33
sources/scheduler.c

@@ -1,20 +1,6 @@
 #include "kernel.h"
 #include "scheduler.h"
 
-static inline zv_process_t * zv_kernel_select_interrupted(zv_kernel_t *self) {
-    zv_process_t *selected = self->processes;
-
-    while (selected != (self->processes + self->processes_count)) {
-        if (selected->state == ZV_INTERRUPTED) {
-            return selected;
-        }
-
-        ++selected;
-    }
-
-    return NULL;
-}
-
 static inline void zv_kernel_exec_process(
     zv_kernel_t *self,
     zv_process_t *target
@@ -41,7 +27,7 @@ static inline void zv_kernel_exec_process(
 
 static inline zv_process_t * zv_kernel_select_process(zv_kernel_t *self) {
     if (self->interrupts > 0) {
-        zv_process_t *selected = zv_kernel_select_interrupted(self);
+        zv_process_t *selected = zv_kernel_scheduler_select_interrupted(self);
 
         if (selected != NULL) {
             return selected;
@@ -50,31 +36,25 @@ static inline zv_process_t * zv_kernel_select_process(zv_kernel_t *self) {
         self->interrupts = 0;
     }
 
-    switch (self->mode) {
-        case ZV_FIRST_MATCH:
-        case ZV_ROUND_ROBIN_FIRST_MATCH:
-            return zv_kernel_round_first_match(self);
+    return zv_kernel_scheduler_mode_selector(self);
+}
+
+void zv_kernel_scheduler_single_loop(zv_kernel_t *self) {
+    zv_process_t *selected = zv_kernel_select_process(self);
 
-        case ZV_BALANCED_PRIORITY:
-            return zv_kernel_balanced_priority(self);
-        
-        case ZV_NON_BALANCED_PRIORITY:
-            return zv_kernel_non_balanced_priority(self);
+    if (selected == NULL) {
+        zv_kernel_idle_task();
+        return;
     }
 
-    return NULL;
+    zv_kernel_exec_process(self, selected);
+    self->last = zv_kernel_get_pid(self, selected);
 }
 
-
-bool zv_kernel_scheduler(zv_kernel_t *self) {
+void zv_kernel_scheduler(zv_kernel_t *self) {
     while (true) {
-        zv_process_t *selected = zv_kernel_select_process(self);
-        zv_kernel_exec_process(self, selected);
-
-        self->last = zv_kernel_get_pid(self, selected);
+        zv_kernel_scheduler_single_loop(self);
     }
-
-    return true;
 }
 
 

+ 62 - 0
sources/scheduler_mode_selector.c

@@ -0,0 +1,62 @@
+#include "process.h"
+#include "kernel.h"
+#include "scheduler.h"
+
+#ifndef ZV_ONLY_BALANCED_PRIORITY_SCHEDULER_MODE
+#ifndef ZV_ONLY_NON_BALANCED_PRIORITY_SCHEDULER_MODE
+#ifndef ZV_ONLY_ROUND_ROUBIN_FIRST_MATCH_SCHEDULER_MODE
+
+zv_process_t * zv_kernel_scheduler_mode_selector(zv_kernel_t *self) {
+    switch (self->mode) {
+
+        #ifndef ZV_FULL_DISABLE_ROUND_ROUBIN_FIRST_MATCH
+        case ZV_FIRST_MATCH:
+        case ZV_ROUND_ROBIN_FIRST_MATCH:
+            return zv_kernel_round_first_match(self);
+        #endif
+
+        #ifndef ZV_FULL_DISABLE_BALANCED_PRIORITY
+        case ZV_BALANCED_PRIORITY:
+            return zv_kernel_balanced_priority(self);
+        #endif
+    
+        #ifndef ZV_FULL_DISABLE_NON_BALANCED_PRIORITY
+        case ZV_NON_BALANCED_PRIORITY:
+            return zv_kernel_non_balanced_priority(self);
+        #endif
+
+        default:
+            break;
+
+    }
+
+    return zv_kernel_basic_scheduler(self);
+}
+
+#endif
+#endif
+#endif
+
+#ifdef ZV_ONLY_BALANCED_PRIORITY_SCHEDULER_MODE
+
+zv_process_t * zv_kernel_scheduler_mode_selector(zv_kernel_t *self) {
+    return zv_kernel_balanced_priority(self);
+}
+
+#endif
+
+#ifdef ZV_ONLY_NON_BALANCED_PRIORITY_SCHEDULER_MODE
+
+zv_process_t * zv_kernel_scheduler_mode_selector(zv_kernel_t *self) {
+    return zv_kernel_non_balanced_priority(self);
+}
+
+#endif
+
+#ifdef ZV_ONLY_ROUND_ROUBIN_FIRST_MATCH_SCHEDULER_MODE
+
+zv_process_t * zv_kernel_scheduler_mode_selector(zv_kernel_t *self) {
+    return zv_kernel_round_first_match(self);
+}
+
+#endif