From ef05233dcf337b03adcd36ca8983370d9d953ffe Mon Sep 17 00:00:00 2001 From: Max Wash Date: Tue, 17 Sep 2024 17:49:05 +0100 Subject: [PATCH] sched: allocate and assign ids to each thread --- include/socks/sched.h | 79 ++++++++++++++++++++++++------------------- sched/thread.c | 22 +++++++++--- 2 files changed, 61 insertions(+), 40 deletions(-) diff --git a/include/socks/sched.h b/include/socks/sched.h index 0704b8f..1d89e50 100644 --- a/include/socks/sched.h +++ b/include/socks/sched.h @@ -1,30 +1,31 @@ #ifndef SOCKS_SCHED_H_ #define SOCKS_SCHED_H_ -#include -#include -#include -#include #include +#include +#include +#include +#include #include -#define TASK_NAME_MAX 64 -#define PRIO_MAX 32 +#define TASK_NAME_MAX 64 +#define PRIO_MAX 32 #define THREAD_KSTACK_ORDER VM_PAGE_4K +#define THREAD_MAX 65536 -#define wait_event(wq, cond) \ - ({ \ - struct thread *self = current_thread(); \ - struct wait_item waiter; \ - wait_item_init(&waiter, self); \ - for (;;) { \ - thread_wait_begin(&waiter, wq); \ - if (cond) { \ - break; \ - } \ - schedule(SCHED_NORMAL); \ - } \ - thread_wait_end(&waiter, wq); \ +#define wait_event(wq, cond) \ + ({ \ + struct thread *self = current_thread(); \ + struct wait_item waiter; \ + wait_item_init(&waiter, self); \ + for (;;) { \ + thread_wait_begin(&waiter, wq); \ + if (cond) { \ + break; \ + } \ + schedule(SCHED_NORMAL); \ + } \ + thread_wait_end(&waiter, wq); \ }) #ifdef __cplusplus @@ -40,34 +41,34 @@ enum task_state { }; enum thread_state { - THREAD_READY = 1, + THREAD_READY = 1, THREAD_SLEEPING = 2, - THREAD_STOPPED = 3, + THREAD_STOPPED = 3, }; enum thread_flags { THREAD_F_NEED_RESCHED = 0x01u, - THREAD_F_NO_PREEMPT = 0x02u, + THREAD_F_NO_PREEMPT = 0x02u, }; enum sched_priority { - PRIO_IDLE = 4, - PRIO_SUBNORMAL = 6, - PRIO_NORMAL = 10, + PRIO_IDLE = 4, + PRIO_SUBNORMAL = 6, + PRIO_NORMAL = 10, PRIO_SUPERNORMAL = 14, - PRIO_HIGH = 18, - PRIO_REALTIME = 24, + PRIO_HIGH = 18, + PRIO_REALTIME = 24, }; enum sched_mode { /* used when calling from non-interrupt context. threads that aren't in state THREAD_READY are removed from the runqueue. */ - SCHED_NORMAL = 0, + SCHED_NORMAL = 0, /* used when calling from interrupt context. threads that aren't in state THREAD_READY are still added to the runqueue. */ - SCHED_IRQ = 1, + SCHED_IRQ = 1, }; struct task { @@ -123,7 +124,7 @@ struct timer { struct cpu_data *t_cpu; struct thread *t_owner; unsigned long t_expiry; - void(*t_callback)(struct timer *); + void (*t_callback)(struct timer *); }; struct wait_item { @@ -136,7 +137,7 @@ struct waitqueue { spin_lock_t wq_lock; }; -typedef void(*work_func_t)(struct work_item *); +typedef void (*work_func_t)(struct work_item *); struct work_item { void *w_data; @@ -174,8 +175,14 @@ extern void rq_remove_thread(struct runqueue *rq, struct thread *thr); extern struct runqueue *cpu_rq(unsigned int cpu); extern struct task *task_alloc(void); -static inline struct task *task_ref(struct task *task) { return OBJECT_CAST(struct task, t_base, object_ref(&task->t_base)); } -static inline void task_deref(struct task *task) { object_deref(&task->t_base); } +static inline struct task *task_ref(struct task *task) +{ + return OBJECT_CAST(struct task, t_base, object_ref(&task->t_base)); +} +static inline void task_deref(struct task *task) +{ + object_deref(&task->t_base); +} extern struct task *task_from_pid(unsigned int pid); extern struct task *kernel_task(void); extern struct task *idle_task(void); @@ -196,7 +203,9 @@ static inline void task_lock_irqsave(struct task *task, unsigned long *flags) object_lock_irqsave(&task->t_base, flags); } -static inline void task_unlock_irqrestore(struct task *task, unsigned long flags) +static inline void task_unlock_irqrestore( + struct task *task, + unsigned long flags) { object_unlock_irqrestore(&task->t_base, flags); } @@ -205,7 +214,7 @@ extern struct thread *thread_alloc(void); extern kern_status_t thread_init(struct thread *thr, uintptr_t ip); extern int thread_priority(struct thread *thr); extern void idle(void); -extern struct thread *create_kernel_thread(void(*fn)(void)); +extern struct thread *create_kernel_thread(void (*fn)(void)); extern struct thread *create_idle_thread(void); extern void add_timer(struct timer *timer); diff --git a/sched/thread.c b/sched/thread.c index fa0b195..f997dd9 100644 --- a/sched/thread.c +++ b/sched/thread.c @@ -1,10 +1,13 @@ -#include -#include +#include #include #include +#include +#include #define THREAD_CAST(p) OBJECT_C_CAST(struct thread, thr_base, &thread_type, p) +static DECLARE_BITMAP(thread_ids, THREAD_MAX) = {0}; + static struct object_type thread_type = { .ob_name = "thread", .ob_size = sizeof(struct thread), @@ -30,6 +33,9 @@ struct thread *thread_alloc(void) kern_status_t thread_init(struct thread *thr, uintptr_t ip) { + thr->tr_id = bitmap_lowest_clear(thread_ids, THREAD_MAX); + bitmap_set(thread_ids, thr->tr_id); + thr->tr_prio = PRIO_NORMAL; thr->tr_state = THREAD_READY; thr->tr_quantum_target = default_quantum(); @@ -39,7 +45,8 @@ kern_status_t thread_init(struct thread *thr, uintptr_t ip) return KERN_NO_MEMORY; } - thr->tr_sp = (uintptr_t)vm_page_get_vaddr(thr->tr_kstack) + vm_page_order_to_bytes(THREAD_KSTACK_ORDER); + thr->tr_sp = (uintptr_t)vm_page_get_vaddr(thr->tr_kstack) + + vm_page_order_to_bytes(THREAD_KSTACK_ORDER); thr->tr_bp = thr->tr_sp; prepare_stack(ip, &thr->tr_sp); @@ -49,7 +56,6 @@ kern_status_t thread_init(struct thread *thr, uintptr_t ip) void thread_free(struct thread *thr) { - } struct thread *current_thread(void) @@ -74,11 +80,14 @@ int thread_priority(struct thread *thr) return thr->tr_prio; } -struct thread *create_kernel_thread(void(*fn)(void)) +struct thread *create_kernel_thread(void (*fn)(void)) { struct task *kernel = kernel_task(); struct thread *thr = thread_alloc(); + thr->tr_id = 1; + bitmap_set(thread_ids, 1); + thr->tr_parent = kernel; thr->tr_prio = PRIO_NORMAL; thr->tr_state = THREAD_READY; @@ -101,6 +110,9 @@ struct thread *create_idle_thread(void) struct task *idle = idle_task(); struct thread *thr = thread_alloc(); + thr->tr_id = 0; + bitmap_set(thread_ids, 0); + thr->tr_parent = idle; thr->tr_prio = PRIO_NORMAL; thr->tr_state = THREAD_READY;