diff options
author | Richard Braun <rbraun@sceen.net> | 2012-12-09 23:59:47 +0100 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2012-12-09 23:59:47 +0100 |
commit | 43efe2324da8d7644cccc2ec1b354fe6bd6c4028 (patch) | |
tree | e37f076429e17857f8b50065f5ba31dd83ca53f9 /kern/thread.h | |
parent | 2ea00731678790ed5712b19ad2fb84988682aaf5 (diff) |
kern/thread: add preemption control functions
Diffstat (limited to 'kern/thread.h')
-rw-r--r-- | kern/thread.h | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/kern/thread.h b/kern/thread.h index 52c0f813..3c6395c8 100644 --- a/kern/thread.h +++ b/kern/thread.h @@ -18,9 +18,12 @@ #ifndef _KERN_THREAD_H #define _KERN_THREAD_H +#include <kern/assert.h> #include <kern/list.h> #include <kern/macros.h> +#include <kern/param.h> #include <kern/task.h> +#include <machine/cpu.h> #include <machine/tcb.h> /* @@ -38,7 +41,8 @@ */ struct thread { struct tcb tcb; - int flags; + short flags; + unsigned short preempt; struct list runq_node; struct list task_node; struct task *task; @@ -49,6 +53,16 @@ struct thread { }; /* + * Per processor run queue. + */ +struct thread_runq { + struct thread *current; + struct list threads; +} __aligned(CPU_L1_SIZE); + +extern struct thread_runq thread_runqs[MAX_CPUS]; + +/* * Initialize the thread module. */ void thread_setup(void); @@ -88,4 +102,59 @@ void thread_reschedule(void); */ void thread_tick(void); +static inline struct thread_runq * +thread_runq_local(void) +{ + return &thread_runqs[cpu_id()]; +} + +static inline struct thread * +thread_current(void) +{ + return thread_runq_local()->current; +} + +/* + * Preemption control functions. + */ + +static inline int +thread_preempt_enabled(void) +{ + return (thread_current()->preempt == 0); +} + +static inline void +thread_preempt_enable_no_resched(void) +{ + struct thread *thread; + + thread = thread_current(); + assert(thread->preempt != 0); + thread->preempt--; +} + +static inline void +thread_preempt_enable(void) +{ + struct thread *thread; + + thread = thread_current(); + assert(thread->preempt != 0); + thread->preempt--; + + if ((thread->preempt == 0) && (thread->flags & THREAD_RESCHEDULE)) + thread_schedule(); +} + +static inline void +thread_preempt_disable(void) +{ + struct thread *thread; + + thread = thread_current(); + thread->preempt++; + assert(thread->preempt != 0); +} + #endif /* _KERN_THREAD_H */ |