From 3e954b1e130526a528afa04f3f8684314731de49 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 9 Mar 2023 19:55:52 +0000 Subject: [PATCH] sched: add task and thread alloc functions --- include/socks/sched.h | 57 ++++++++++++++++++++++++++++----- sched/sched.c | 21 ++++++------- sched/task.c | 73 +++++++++++++++++++++++++++++++++++++++++++ sched/thread.c | 29 +++++++++++++++++ 4 files changed, 161 insertions(+), 19 deletions(-) create mode 100644 sched/task.c create mode 100644 sched/thread.c diff --git a/include/socks/sched.h b/include/socks/sched.h index a58d3c2..354bb71 100644 --- a/include/socks/sched.h +++ b/include/socks/sched.h @@ -2,25 +2,40 @@ #define SOCKS_SCHED_H_ #include +#include #include +#include #include #include +#define TASK_NAME_MAX 64 +#define PRIO_MAX 32 + typedef enum task_state { TASK_RUNNING, TASK_STOPPED, } task_state_t; -typedef enum task_thread_state { - TASK_THREAD_READY, - TASK_THREAD_SLEEPING, - TASK_THREAD_STOPPED, -} task_thread_state_t; +typedef enum thread_state { + THREAD_READY, + THREAD_SLEEPING, + THREAD_STOPPED, +} thread_state_t; + +typedef enum sched_priority { + PRIO_IDLE = 4, + PRIO_SUBNORMAL = 6, + PRIO_NORMAL = 10, + PRIO_SUPERNORMAL = 14, + PRIO_HIGH = 18, + PRIO_REALTIME = 24, +} sched_priority_t; typedef struct task { struct task *t_parent; unsigned int t_id; task_state_t t_state; + char t_name[TASK_NAME_MAX]; pmap_t t_pmap; @@ -29,15 +44,41 @@ typedef struct task { queue_t t_children; } task_t; -typedef struct task_thread { - task_thread_state_t tr_state; +typedef struct thread { + thread_state_t tr_state; + task_t *tr_parent; + unsigned int tr_id; unsigned int tr_prio; queue_entry_t tr_threads; + queue_entry_t tr_rqentry; void *tr_kstack; -} task_thread_t; +} thread_t; + +typedef struct runqueue { + queue_t rq_queues[PRIO_MAX]; + uint32_t rq_readybits; + spin_lock_t rq_lock; +} runqueue_t; extern kern_status_t sched_init(void); +extern task_t *task_alloc(void); +static inline task_t *task_ref(task_t *task) { return object_data(object_ref(object_header(task))); } +static inline void task_deref(task_t *task) { object_deref(object_header(task)); } +extern task_t *task_from_pid(unsigned int pid); + +static inline void task_lock_irqsave(task_t *task, unsigned long *flags) +{ + object_lock(object_header(task), flags); +} + +static inline void task_unlock_irqrestore(task_t *task, unsigned long flags) +{ + object_unlock(object_header(task), flags); +} + +extern thread_t *thread_alloc(void); + #endif diff --git a/sched/sched.c b/sched/sched.c index 8ad9cd0..5103c23 100644 --- a/sched/sched.c +++ b/sched/sched.c @@ -2,26 +2,25 @@ #include #include -static object_type_t task_type = { - .ob_name = "task", - .ob_size = sizeof(task_t), -}; - -static object_type_t thread_type = { - .ob_name = "thread", - .ob_size = sizeof(task_thread_t), -}; +extern kern_status_t setup_kernel_task(void); +extern kern_status_t task_object_type_init(void); +extern kern_status_t thread_object_type_init(void); kern_status_t sched_init(void) { kern_status_t status = KERN_OK; - status = object_type_register(&task_type); + status = task_object_type_init(); if (status != KERN_OK) { return status; } - status = object_type_register(&thread_type); + status = thread_object_type_init(); + if (status != KERN_OK) { + return status; + } + + status = setup_kernel_task(); if (status != KERN_OK) { return status; } diff --git a/sched/task.c b/sched/task.c new file mode 100644 index 0000000..0c513fb --- /dev/null +++ b/sched/task.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include + +static object_type_t task_type = { + .ob_name = "task", + .ob_size = sizeof(task_t), +}; + +static task_t *kernel_task; + +static spin_lock_t task_list_lock; +static btree_t task_list; + +BTREE_DEFINE_SIMPLE_GET(task_t, unsigned int, t_tasklist, t_id, task_list_get) +BTREE_DEFINE_SIMPLE_INSERT(task_t, t_tasklist, t_id, task_list_insert) + +kern_status_t setup_kernel_task(void) +{ + kernel_task = task_alloc(); + if (!kernel_task) { + return KERN_NO_MEMORY; + } + + kernel_task->t_id = 0; + kernel_task->t_pmap = get_kernel_pmap(); + kernel_task->t_state = TASK_RUNNING; + + snprintf(kernel_task->t_name, sizeof kernel_task->t_name, "kernel_task"); + + thread_t *kernel_thread = thread_alloc(); + kernel_thread->tr_id = 0; + kernel_thread->tr_prio = PRIO_NORMAL; + kernel_thread->tr_state = THREAD_READY; + + unsigned long flags; + task_lock_irqsave(kernel_task, &flags); + queue_push_back(&kernel_task->t_threads, &kernel_thread->tr_threads); + task_unlock_irqrestore(kernel_task, flags); + + spin_lock_irqsave(&task_list_lock, &flags); + task_list_insert(&task_list, kernel_task); + spin_unlock_irqrestore(&task_list_lock, flags); + + return KERN_OK; +} + +kern_status_t task_object_type_init(void) +{ + return object_type_register(&task_type); +} + +task_t *task_alloc(void) +{ + object_t *task_obj = object_create(&task_type); + if (!task_obj) { + return NULL; + } + + task_t *t = object_data(task_obj); + memset(t, 0x00, sizeof *t); + return t; +} + +task_t *task_from_pid(unsigned int pid) +{ + unsigned long flags; + spin_lock_irqsave(&task_list_lock, &flags); + task_t *t = task_list_get(&task_list, pid); + spin_unlock_irqrestore(&task_list_lock, flags); + return t; +} diff --git a/sched/thread.c b/sched/thread.c new file mode 100644 index 0000000..fcf0ed4 --- /dev/null +++ b/sched/thread.c @@ -0,0 +1,29 @@ +#include +#include + +static object_type_t thread_type = { + .ob_name = "thread", + .ob_size = sizeof(thread_t), +}; + +kern_status_t thread_object_type_init(void) +{ + return object_type_register(&thread_type); +} + +thread_t *thread_alloc(void) +{ + object_t *thread_obj = object_create(&thread_type); + if (!thread_obj) { + return NULL; + } + + thread_t *t = object_data(thread_obj); + memset(t, 0x00, sizeof *t); + return t; +} + +void thread_free(thread_t *thr) +{ + +}