diff --git a/arch/x86_64/asm-offset.c b/arch/x86_64/asm-offset.c index 9424c0f..eac20f3 100644 --- a/arch/x86_64/asm-offset.c +++ b/arch/x86_64/asm-offset.c @@ -1,10 +1,11 @@ -#include #include +#include +#include -//size_t THREAD_sp = offsetof(struct thread, tr_sp); +// size_t THREAD_sp = offsetof(struct thread, tr_sp); -/* Use %a0 instead of %0 to prevent gcc from emitting a $ before the symbol value - in the generated assembly. +/* Use %a0 instead of %0 to prevent gcc from emitting a $ before the symbol + value in the generated assembly. emitting .set TASK_sp, $56 diff --git a/arch/x86_64/pmap.c b/arch/x86_64/pmap.c index ac42ffc..3fb28e1 100644 --- a/arch/x86_64/pmap.c +++ b/arch/x86_64/pmap.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/ds/ringbuffer.c b/ds/ringbuffer.c index 3f7fdbc..797532d 100644 --- a/ds/ringbuffer.c +++ b/ds/ringbuffer.c @@ -1,5 +1,6 @@ #include #include +#include size_t ringbuffer_unread(struct ringbuffer *ring_buffer) { diff --git a/include/kernel/cpu.h b/include/kernel/cpu.h index 47c7d39..b0efc8e 100644 --- a/include/kernel/cpu.h +++ b/include/kernel/cpu.h @@ -1,10 +1,11 @@ #ifndef KERNEL_CPU_H_ #define KERNEL_CPU_H_ -#include #include -#include #include +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/kernel/object.h b/include/kernel/object.h index 55db392..03bdc81 100644 --- a/include/kernel/object.h +++ b/include/kernel/object.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/include/kernel/ringbuffer.h b/include/kernel/ringbuffer.h index 9c362c0..32c696b 100644 --- a/include/kernel/ringbuffer.h +++ b/include/kernel/ringbuffer.h @@ -1,8 +1,10 @@ #ifndef KERNEL_RINGBUFFER_H_ #define KERNEL_RINGBUFFER_H_ +#include #include -#include +#include +#include struct ringbuffer { unsigned char *r_buffer; diff --git a/include/kernel/sched.h b/include/kernel/sched.h index 40d5c9a..47a5e22 100644 --- a/include/kernel/sched.h +++ b/include/kernel/sched.h @@ -4,32 +4,11 @@ #include #include #include -#include -#include -#include #include +#include #include -#define TASK_NAME_MAX 64 -#define PRIO_MAX 32 -#define PID_MAX 99999 -#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 PRIO_MAX 32 #ifdef __cplusplus extern "C" { @@ -37,23 +16,6 @@ extern "C" { struct channel; struct runqueue; -struct work_item; - -enum task_state { - TASK_RUNNING, - TASK_STOPPED, -}; - -enum thread_state { - THREAD_READY = 1, - THREAD_SLEEPING = 2, - THREAD_STOPPED = 3, -}; - -enum thread_flags { - THREAD_F_NEED_RESCHED = 0x01u, - THREAD_F_NO_PREEMPT = 0x02u, -}; enum sched_priority { PRIO_IDLE = 4, @@ -75,55 +37,6 @@ enum sched_mode { SCHED_IRQ = 1, }; -struct task { - struct object t_base; - - struct task *t_parent; - long t_id; - enum task_state t_state; - char t_name[TASK_NAME_MAX]; - - pmap_t t_pmap; - struct vm_region *t_address_space; - spin_lock_t t_handles_lock; - struct handle_table *t_handles; - struct btree b_channels; - - struct btree_node t_tasklist; - struct queue_entry t_child_entry; - - size_t t_next_thread_id; - struct queue t_threads; - struct queue t_children; -}; - -struct thread { - struct object thr_base; - - enum thread_state tr_state; - enum thread_flags tr_flags; - struct task *tr_parent; - - unsigned int tr_id; - unsigned int tr_prio; - - cycles_t tr_charge_period_start; - cycles_t tr_quantum_cycles, tr_quantum_target; - cycles_t tr_total_cycles; - - virt_addr_t tr_ip, tr_sp, tr_bp; - virt_addr_t tr_cpu_user_sp, tr_cpu_kernel_sp; - - struct runqueue *tr_rq; - struct msg tr_msg; - - struct queue_entry tr_parent_entry; - struct queue_entry tr_rqentry; - - struct vm_page *tr_kstack; - struct vm_object *tr_ustack; -}; - struct runqueue { struct queue rq_queues[PRIO_MAX]; uint32_t rq_readybits; @@ -141,34 +54,6 @@ struct timer { void (*t_callback)(struct timer *); }; -struct wait_item { - struct thread *w_thread; - struct queue_entry w_entry; -}; - -struct waitqueue { - struct queue wq_waiters; - spin_lock_t wq_lock; -}; - -typedef void (*work_func_t)(struct work_item *); - -struct work_item { - void *w_data; - work_func_t w_func; - struct queue_entry w_head; -}; - -struct worker_pool { - struct thread **wp_workers; - size_t wp_nworkers; -}; - -struct workqueue { - spin_lock_t wq_lock; - struct queue wq_queue; /* list of struct work_item */ -}; - extern kern_status_t sched_init(void); extern void schedule(enum sched_mode mode); extern void preempt_disable(void); @@ -188,38 +73,6 @@ static inline void rq_unlock(struct runqueue *rq, unsigned long flags) 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); -extern struct task *task_cast(struct object *obj); -extern struct task *task_create(const char *name, size_t name_len); -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_unref(struct task *task) -{ - object_unref(&task->t_base); -} -extern kern_status_t task_add_child(struct task *parent, struct task *child); -extern kern_status_t task_add_channel( - struct task *task, - struct channel *channel, - unsigned int id); -extern struct channel *task_get_channel(struct task *task, unsigned int id); -extern struct task *task_from_tid(tid_t id); -extern kern_status_t task_open_handle( - struct task *task, - struct object *obj, - handle_flags_t flags, - kern_handle_t *out); -extern kern_status_t task_resolve_handle( - struct task *task, - kern_handle_t handle, - struct object **out_obj, - handle_flags_t *out_flags); -extern kern_status_t task_close_handle(struct task *task, kern_handle_t handle); -extern struct thread *task_create_thread(struct task *parent); -extern struct task *kernel_task(void); -extern struct task *idle_task(void); extern cycles_t default_quantum(void); extern bool need_resched(void); @@ -232,45 +85,12 @@ extern void schedule_thread_on_cpu(struct thread *thr); extern void start_charge_period(void); extern void end_charge_period(void); -DEFINE_OBJECT_LOCK_FUNCTION(task, t_base) - -extern struct thread *thread_alloc(void); -extern struct thread *thread_cast(struct object *obj); -extern kern_status_t thread_init_kernel(struct thread *thr, virt_addr_t ip); -extern kern_status_t thread_init_user( - struct thread *thr, - virt_addr_t ip, - virt_addr_t sp, - const uintptr_t *args, - size_t nr_args); -extern int thread_priority(struct thread *thr); -extern void thread_awaken(struct thread *thr); -extern void idle(void); -extern struct thread *create_kernel_thread(void (*fn)(void)); -extern struct thread *create_idle_thread(void); - extern void add_timer(struct timer *timer); extern void remove_timer(struct timer *timer); extern unsigned long schedule_timeout(unsigned long clock_ticks); extern unsigned long milli_sleep(unsigned long ms); extern void sleep_forever(void); -extern void wait_item_init(struct wait_item *item, struct thread *thr); -extern void thread_wait_begin(struct wait_item *waiter, struct waitqueue *q); -extern void thread_wait_end(struct wait_item *waiter, struct waitqueue *q); -extern void wait_on_queue(struct waitqueue *q); -extern void wakeup_queue(struct waitqueue *q); -extern void wakeup_one(struct waitqueue *q); - -extern void work_item_init(work_func_t func, void *data, struct work_item *out); -extern void workqueue_init(struct workqueue *wq); -extern struct worker_pool *worker_pool_create(size_t nworkers); -extern struct worker_pool *global_worker_pool(void); -extern bool schedule_work_on(struct workqueue *wq, struct work_item *work); -extern bool schedule_work(struct work_item *work); - -extern void wake_workers(struct workqueue *wq, struct worker_pool *pool); - #ifdef __cplusplus } #endif diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h index b1b4373..4bbcdb8 100644 --- a/include/kernel/syscall.h +++ b/include/kernel/syscall.h @@ -2,7 +2,7 @@ #define KERNEL_SYSCALL_H_ #include -#include +#include #include #include #include diff --git a/include/kernel/task.h b/include/kernel/task.h new file mode 100644 index 0000000..3b57c70 --- /dev/null +++ b/include/kernel/task.h @@ -0,0 +1,75 @@ +#ifndef KERNEL_TASK_H_ +#define KERNEL_TASK_H_ + +#include +#include +#include + +#define TASK_NAME_MAX 64 +#define PID_MAX 99999 + +struct channel; + +enum task_state { + TASK_RUNNING, + TASK_STOPPED, +}; + +struct task { + struct object t_base; + + struct task *t_parent; + long t_id; + enum task_state t_state; + char t_name[TASK_NAME_MAX]; + + pmap_t t_pmap; + struct vm_region *t_address_space; + spin_lock_t t_handles_lock; + struct handle_table *t_handles; + struct btree b_channels; + + struct btree_node t_tasklist; + struct queue_entry t_child_entry; + + size_t t_next_thread_id; + struct queue t_threads; + struct queue t_children; +}; + +extern struct task *task_alloc(void); +extern struct task *task_cast(struct object *obj); +extern struct task *task_create(const char *name, size_t name_len); +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_unref(struct task *task) +{ + object_unref(&task->t_base); +} +extern kern_status_t task_add_child(struct task *parent, struct task *child); +extern kern_status_t task_add_channel( + struct task *task, + struct channel *channel, + unsigned int id); +extern struct channel *task_get_channel(struct task *task, unsigned int id); +extern struct task *task_from_tid(tid_t id); +extern kern_status_t task_open_handle( + struct task *task, + struct object *obj, + handle_flags_t flags, + kern_handle_t *out); +extern kern_status_t task_resolve_handle( + struct task *task, + kern_handle_t handle, + struct object **out_obj, + handle_flags_t *out_flags); +extern kern_status_t task_close_handle(struct task *task, kern_handle_t handle); +extern struct thread *task_create_thread(struct task *parent); +extern struct task *kernel_task(void); +extern struct task *idle_task(void); + +DEFINE_OBJECT_LOCK_FUNCTION(task, t_base) + +#endif diff --git a/include/kernel/thread.h b/include/kernel/thread.h new file mode 100644 index 0000000..619fe17 --- /dev/null +++ b/include/kernel/thread.h @@ -0,0 +1,64 @@ +#ifndef KERNEL_THREAD_H_ +#define KERNEL_THREAD_H_ + +#include +#include +#include + +#define THREAD_KSTACK_ORDER VM_PAGE_4K + +enum thread_state { + THREAD_READY = 1, + THREAD_SLEEPING = 2, + THREAD_STOPPED = 3, +}; + +enum thread_flags { + THREAD_F_NEED_RESCHED = 0x01u, + THREAD_F_NO_PREEMPT = 0x02u, +}; + +struct thread { + struct object thr_base; + + enum thread_state tr_state; + enum thread_flags tr_flags; + struct task *tr_parent; + + unsigned int tr_id; + unsigned int tr_prio; + + cycles_t tr_charge_period_start; + cycles_t tr_quantum_cycles, tr_quantum_target; + cycles_t tr_total_cycles; + + virt_addr_t tr_ip, tr_sp, tr_bp; + virt_addr_t tr_cpu_user_sp, tr_cpu_kernel_sp; + + struct runqueue *tr_rq; + struct msg tr_msg; + struct page_request tr_page_req; + + struct queue_entry tr_parent_entry; + struct queue_entry tr_rqentry; + + struct vm_page *tr_kstack; + struct vm_object *tr_ustack; +}; + +extern struct thread *thread_alloc(void); +extern struct thread *thread_cast(struct object *obj); +extern kern_status_t thread_init_kernel(struct thread *thr, virt_addr_t ip); +extern kern_status_t thread_init_user( + struct thread *thr, + virt_addr_t ip, + virt_addr_t sp, + const uintptr_t *args, + size_t nr_args); +extern int thread_priority(struct thread *thr); +extern void thread_awaken(struct thread *thr); +extern void idle(void); +extern struct thread *create_kernel_thread(void (*fn)(void)); +extern struct thread *create_idle_thread(void); + +#endif diff --git a/include/kernel/wait.h b/include/kernel/wait.h new file mode 100644 index 0000000..07af1d5 --- /dev/null +++ b/include/kernel/wait.h @@ -0,0 +1,39 @@ +#ifndef KERNEL_WAIT_H_ +#define KERNEL_WAIT_H_ + +#include +#include + +#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); \ + }) + +struct wait_item { + struct thread *w_thread; + struct queue_entry w_entry; +}; + +struct waitqueue { + struct queue wq_waiters; + spin_lock_t wq_lock; +}; + +extern void wait_item_init(struct wait_item *item, struct thread *thr); +extern void thread_wait_begin(struct wait_item *waiter, struct waitqueue *q); +extern void thread_wait_end(struct wait_item *waiter, struct waitqueue *q); +extern void wait_on_queue(struct waitqueue *q); +extern void wakeup_queue(struct waitqueue *q); +extern void wakeup_one(struct waitqueue *q); + +#endif diff --git a/include/kernel/work.h b/include/kernel/work.h new file mode 100644 index 0000000..ef83f54 --- /dev/null +++ b/include/kernel/work.h @@ -0,0 +1,37 @@ +#ifndef KERNEL_WORK_H_ +#define KERNEL_WORK_H_ + +#include +#include +#include + +struct work_item; + +typedef void (*work_func_t)(struct work_item *); + +struct work_item { + void *w_data; + work_func_t w_func; + struct queue_entry w_head; +}; + +struct worker_pool { + struct thread **wp_workers; + size_t wp_nworkers; +}; + +struct workqueue { + spin_lock_t wq_lock; + struct queue wq_queue; /* list of struct work_item */ +}; + +extern void work_item_init(work_func_t func, void *data, struct work_item *out); +extern void workqueue_init(struct workqueue *wq); +extern struct worker_pool *worker_pool_create(size_t nworkers); +extern struct worker_pool *global_worker_pool(void); +extern bool schedule_work_on(struct workqueue *wq, struct work_item *work); +extern bool schedule_work(struct work_item *work); + +extern void wake_workers(struct workqueue *wq, struct worker_pool *pool); + +#endif diff --git a/init/main.c b/init/main.c index 4bc55dd..c4c9eab 100644 --- a/init/main.c +++ b/init/main.c @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include #include diff --git a/kernel/bsp.c b/kernel/bsp.c index dabb2a5..3a4cc6d 100644 --- a/kernel/bsp.c +++ b/kernel/bsp.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/kernel/channel.c b/kernel/channel.c index 4fa349e..dea8c80 100644 --- a/kernel/channel.c +++ b/kernel/channel.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include diff --git a/kernel/object.c b/kernel/object.c index c05339d..3caa310 100644 --- a/kernel/object.c +++ b/kernel/object.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #define HAS_OP(obj, opname) ((obj)->ob_type->ob_ops.opname) diff --git a/kernel/panic.c b/kernel/panic.c index 6efe0f5..9dc9a8c 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -2,7 +2,8 @@ #include #include #include -#include +#include +#include #include static int has_panicked = 0; diff --git a/kernel/port.c b/kernel/port.c index df36293..cd4364e 100644 --- a/kernel/port.c +++ b/kernel/port.c @@ -1,5 +1,6 @@ #include #include +#include #include #define PORT_CAST(p) OBJECT_C_CAST(struct port, p_base, &port_type, p) diff --git a/sched/core.c b/sched/core.c index dfe8a7d..3746677 100644 --- a/sched/core.c +++ b/sched/core.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include extern kern_status_t setup_kernel_task(void); diff --git a/sched/runqueue.c b/sched/runqueue.c index 168db04..ca076b3 100644 --- a/sched/runqueue.c +++ b/sched/runqueue.c @@ -1,8 +1,9 @@ -#include -#include #include +#include +#include +#include -#define PRIO_MASK(p) (((uint32_t)1) << (p)) +#define PRIO_MASK(p) (((uint32_t)1) << (p)) #define FIRST_PRIO(m) (m > 0 ? (PRIO_MAX - __builtin_clz(m) - 1) : -1) void rq_init(struct runqueue *rq) diff --git a/sched/task.c b/sched/task.c index 2c5d8dc..1f0ad6a 100644 --- a/sched/task.c +++ b/sched/task.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include diff --git a/sched/thread.c b/sched/thread.c index 781847b..3e3e675 100644 --- a/sched/thread.c +++ b/sched/thread.c @@ -2,7 +2,8 @@ #include #include #include -#include +#include +#include #define THREAD_CAST(p) OBJECT_C_CAST(struct thread, thr_base, &thread_type, p) diff --git a/sched/timer.c b/sched/timer.c index 67055b8..e865e3e 100644 --- a/sched/timer.c +++ b/sched/timer.c @@ -1,7 +1,8 @@ -#include -#include -#include #include +#include +#include +#include +#include static void timeout_expiry(struct timer *timer) { diff --git a/sched/wait.c b/sched/wait.c index 63b62a6..06f7ea9 100644 --- a/sched/wait.c +++ b/sched/wait.c @@ -1,5 +1,7 @@ #include #include +#include +#include void wait_item_init(struct wait_item *item, struct thread *thr) { diff --git a/sched/workqueue.c b/sched/workqueue.c index 7374e81..16befb0 100644 --- a/sched/workqueue.c +++ b/sched/workqueue.c @@ -1,7 +1,8 @@ -#include -#include -#include #include +#include +#include +#include +#include static struct worker_pool *__global_worker_pool = NULL; diff --git a/syscall/log.c b/syscall/log.c index 328fac6..2567f05 100644 --- a/syscall/log.c +++ b/syscall/log.c @@ -1,5 +1,6 @@ #include #include +#include kern_status_t sys_kern_log(const char *s) { diff --git a/syscall/msg.c b/syscall/msg.c index 65c12e7..d42e412 100644 --- a/syscall/msg.c +++ b/syscall/msg.c @@ -3,6 +3,7 @@ #include #include #include +#include #include kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out) diff --git a/syscall/task.c b/syscall/task.c index 444423e..c425015 100644 --- a/syscall/task.c +++ b/syscall/task.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include extern kern_status_t sys_task_exit(int status) diff --git a/vm/vm-object.c b/vm/vm-object.c index 3ad1a9f..b09e1c3 100644 --- a/vm/vm-object.c +++ b/vm/vm-object.c @@ -1,4 +1,5 @@ #include +#include #include #include