Do some fairly major include file cleanups to further separate kernelland
[dragonfly.git] / sys / sys / thread2.h
1 /*
2  * SYS/THREAD2.H
3  *
4  *      Implements inline procedure support for the LWKT subsystem. 
5  *
6  *      Generally speaking these routines only operate on threads associated
7  *      with the current cpu.  For example, a higher priority thread pending
8  *      on a different cpu will not be immediately scheduled by a yield() on
9  *      this cpu.
10  *
11  * $DragonFly: src/sys/sys/thread2.h,v 1.10 2003/11/21 22:46:13 dillon Exp $
12  */
13
14 #ifndef _SYS_THREAD2_H_
15 #define _SYS_THREAD2_H_
16
17 /*
18  * Userland will have its own globaldata which it includes prior to this.
19  */
20 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
21 #ifndef _SYS_GLOBALDATA_H_
22 #include <sys/globaldata.h>
23 #endif
24 #endif
25
26 /*
27  * Critical sections prevent preemption by raising a thread's priority
28  * above the highest possible interrupting priority.  Additionally, the
29  * current cpu will not be able to schedule a new thread but will instead
30  * place it on a pending list (with interrupts physically disabled) and
31  * set mycpu->gd_reqflags to indicate that work needs to be done, which
32  * lwkt_yield_quick() takes care of.
33  *
34  * Some of these routines take a struct thread pointer as an argument.  This
35  * pointer MUST be curthread and is only passed as an optimization.
36  *
37  * Synchronous switching and blocking is allowed while in a critical section.
38  */
39
40 static __inline void
41 crit_enter(void)
42 {
43     struct thread *td = curthread;
44
45 #ifdef INVARIANTS
46     if (td->td_pri < 0)
47         crit_panic();
48 #endif
49     td->td_pri += TDPRI_CRIT;
50 }
51
52 static __inline void
53 crit_enter_quick(struct thread *curtd)
54 {
55     curtd->td_pri += TDPRI_CRIT;
56 }
57
58 static __inline void
59 crit_exit_noyield(struct thread *curtd)
60 {
61     curtd->td_pri -= TDPRI_CRIT;
62 #ifdef INVARIANTS
63     if (curtd->td_pri < 0)
64         crit_panic();
65 #endif
66 }
67
68 static __inline void
69 crit_exit(void)
70 {
71     thread_t td = curthread;
72
73     td->td_pri -= TDPRI_CRIT;
74 #ifdef INVARIANTS
75     if (td->td_pri < 0)
76         crit_panic();
77 #endif
78     if (td->td_pri < TDPRI_CRIT && td->td_gd->gd_reqflags)
79         lwkt_yield_quick();
80 }
81
82 static __inline void
83 crit_exit_quick(struct thread *curtd)
84 {
85     curtd->td_pri -= TDPRI_CRIT;
86     if (curtd->td_pri < TDPRI_CRIT && curtd->td_gd->gd_reqflags)
87         lwkt_yield_quick();
88 }
89
90 static __inline int
91 crit_panic_save(void)
92 {
93     thread_t td = curthread;
94     int pri = td->td_pri;
95     td->td_pri = td->td_pri & TDPRI_MASK;
96     return(pri);
97 }
98
99 static __inline void
100 crit_panic_restore(int cpri)
101 {
102     curthread->td_pri = cpri;
103 }
104
105 static __inline int
106 lwkt_havetoken(lwkt_token_t tok)
107 {
108     return (tok->t_cpu == mycpu->gd_cpuid);
109 }
110
111 /*
112  * Return whether any threads are runnable, whether they meet mp_lock
113  * requirements or not.
114  */
115 static __inline int
116 lwkt_runnable(void)
117 {
118     return (mycpu->gd_runqmask != 0);
119 }
120
121 #endif
122