aboutsummaryrefslogtreecommitdiff
path: root/kernel/task/include
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/task/include')
-rw-r--r--kernel/task/include/task/idle.h6
-rw-r--r--kernel/task/include/task/lock.h19
-rw-r--r--kernel/task/include/task/sched.h63
-rw-r--r--kernel/task/include/task/task.h45
4 files changed, 133 insertions, 0 deletions
diff --git a/kernel/task/include/task/idle.h b/kernel/task/include/task/idle.h
new file mode 100644
index 0000000..3b6e40a
--- /dev/null
+++ b/kernel/task/include/task/idle.h
@@ -0,0 +1,6 @@
+#ifndef IDLE_H
+#define IDLE_H
+
+void idle_entry(char args);
+
+#endif \ No newline at end of file
diff --git a/kernel/task/include/task/lock.h b/kernel/task/include/task/lock.h
new file mode 100644
index 0000000..bfb7994
--- /dev/null
+++ b/kernel/task/include/task/lock.h
@@ -0,0 +1,19 @@
+#ifndef LOCK_H
+#define LOCK_H
+
+#include "task/shed.h"
+
+typedef char spin_lock_t;
+
+#define SPIN_LOCK_UNLOCKED 0
+
+static inline void spin_lock(struct spin_lock_t* lock) {
+ while(*lock != SPIN_LOCK_UNLOCKED) {yield();};
+ *lock = 1;
+}
+
+static inline void spin_unlock(struct spin_lock_t* lock) {
+ *lock = SPIN_LOCK_UNLOCKED;
+}
+
+#endif \ No newline at end of file
diff --git a/kernel/task/include/task/sched.h b/kernel/task/include/task/sched.h
new file mode 100644
index 0000000..9029664
--- /dev/null
+++ b/kernel/task/include/task/sched.h
@@ -0,0 +1,63 @@
+#ifndef SCHED_H
+#define SCHED_H
+
+#include "collection/list.h"
+#include "mcu/task/task.h"
+
+/**
+ * Points to currently executing task. If no scheduling has been enabled,
+ * this points to NULL
+ */
+extern struct tcb_t* volatile current;
+
+/**
+ * Queue that contains all tasks that are ready to be run, awaiting their
+ * turn from the scheduler.
+ */
+extern struct list_head ready;
+
+/**
+ * Stack pointer for operations performed out of task context, including any
+ * calls made after SAVE_CONTEXT().
+ */
+extern void* volatile kstack;
+
+/**
+ * Makes the current task sleep on a specific queue.
+ * This moves the current task to the given queue's tail.
+ */
+static inline void sleep_queue(struct list_head* queue) {
+ list_move_tail(&current->queue, queue);
+}
+
+/**
+ * Wakes all tasks waiting in the given queue.
+ * This moves all tasks contained in the queue to the ready queue.
+ */
+static inline void wake_all_queue(struct list_head* queue) {
+ list_splice_init(queue, ready.prev);
+}
+
+/**
+ * Initializes a given task and adds it to the ready queue.
+ */
+void spawn(struct tcb_t* const tcb);
+
+/**
+ * Voluntarily relinquishes control of the CPU from the current task to the scheduler.
+ */
+void yield() __attribute__ ( ( naked ) );
+
+
+/**
+ * Initializes the scheduler by setting up kstack, initializing the idle task
+ * and selecting the first task to run.
+ */
+void sched_init();
+
+/**
+ * Enters the scheduler, setting current to the next runnable task.
+ */
+void schedule();
+
+#endif
diff --git a/kernel/task/include/task/task.h b/kernel/task/include/task/task.h
new file mode 100644
index 0000000..40f18a0
--- /dev/null
+++ b/kernel/task/include/task/task.h
@@ -0,0 +1,45 @@
+#ifndef TASK_H
+#define TASK_H
+
+#include "collection/list.h"
+
+/**
+ * Task control block, contains runtime
+ * information about tasks.
+ */
+struct tcb_t {
+ /** Stack pointer of this task. (must be first in structure) */
+ char* volatile sp;
+
+ /** Lowest address of this task's memory (inclusive). */
+ char* mem_low;
+
+ /** Highest address of this task's memory (inclusive). */
+ char* mem_high;
+
+ /** Entry function of this task. */
+ void (*entry)(char);
+
+ /** Current wait queue that this task is in.*/
+ struct list_head queue;
+
+ char id;
+
+};
+
+/**
+ * Utility for declaring a task with statically allocated memory.
+ * Note: for a task to be scheduled, it must first be spawned (see spawn()).
+*/
+#define DECLARE_TASK(name, stack_size, entry_function, pid) \
+ static char _declared_stack_##name[stack_size]; \
+ static struct tcb_t name = { \
+ .sp = 0, \
+ .mem_low = _declared_stack_##name, \
+ .mem_high = _declared_stack_##name + stack_size - 1, \
+ .entry = entry_function, \
+ .queue = {}, \
+ .id = pid \
+ };
+
+#endif \ No newline at end of file