xref: /dragonfly/sys/sys/thread2.h (revision 38a690d7)
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.9 2003/07/25 05:51:19 dillon Exp $
12  */
13 
14 #ifndef _SYS_THREAD2_H_
15 #define _SYS_THREAD2_H_
16 
17 /*
18  * Critical sections prevent preemption by raising a thread's priority
19  * above the highest possible interrupting priority.  Additionally, the
20  * current cpu will not be able to schedule a new thread but will instead
21  * place it on a pending list (with interrupts physically disabled) and
22  * set mycpu->gd_reqflags to indicate that work needs to be done, which
23  * lwkt_yield_quick() takes care of.
24  *
25  * Some of these routines take a struct thread pointer as an argument.  This
26  * pointer MUST be curthread and is only passed as an optimization.
27  *
28  * Synchronous switching and blocking is allowed while in a critical section.
29  */
30 
31 static __inline void
32 crit_enter(void)
33 {
34     struct thread *td = curthread;
35 
36 #ifdef INVARIANTS
37     if (td->td_pri < 0)
38 	crit_panic();
39 #endif
40     td->td_pri += TDPRI_CRIT;
41 }
42 
43 static __inline void
44 crit_enter_quick(struct thread *curtd)
45 {
46     curtd->td_pri += TDPRI_CRIT;
47 }
48 
49 static __inline void
50 crit_exit_noyield(struct thread *curtd)
51 {
52     curtd->td_pri -= TDPRI_CRIT;
53 #ifdef INVARIANTS
54     if (curtd->td_pri < 0)
55 	crit_panic();
56 #endif
57 }
58 
59 static __inline void
60 crit_exit(void)
61 {
62     thread_t td = curthread;
63 
64     td->td_pri -= TDPRI_CRIT;
65 #ifdef INVARIANTS
66     if (td->td_pri < 0)
67 	crit_panic();
68 #endif
69     if (td->td_pri < TDPRI_CRIT && td->td_gd->gd_reqflags)
70 	lwkt_yield_quick();
71 }
72 
73 static __inline void
74 crit_exit_quick(struct thread *curtd)
75 {
76     curtd->td_pri -= TDPRI_CRIT;
77     if (curtd->td_pri < TDPRI_CRIT && curtd->td_gd->gd_reqflags)
78 	lwkt_yield_quick();
79 }
80 
81 static __inline int
82 crit_panic_save(void)
83 {
84     thread_t td = curthread;
85     int pri = td->td_pri;
86     td->td_pri = td->td_pri & TDPRI_MASK;
87     return(pri);
88 }
89 
90 static __inline void
91 crit_panic_restore(int cpri)
92 {
93     curthread->td_pri = cpri;
94 }
95 
96 static __inline int
97 lwkt_havetoken(lwkt_token_t tok)
98 {
99     return (tok->t_cpu == mycpu->gd_cpuid);
100 }
101 
102 /*
103  * Return whether any threads are runnable, whether they meet mp_lock
104  * requirements or not.
105  */
106 static __inline int
107 lwkt_runnable(void)
108 {
109     return (mycpu->gd_runqmask != 0);
110 }
111 
112 #endif
113 
114