4 * Implements inline procedure support for the LWKT subsystem.
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
11 * $DragonFly: src/sys/sys/thread2.h,v 1.17 2004/10/12 19:29:29 dillon Exp $
14 #ifndef _SYS_THREAD2_H_
15 #define _SYS_THREAD2_H_
18 * Userland will have its own globaldata which it includes prior to this.
20 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
21 #ifndef _SYS_GLOBALDATA_H_
22 #include <sys/globaldata.h>
24 #ifndef _MACHINE_CPUFUNC_H_
25 #include <machine/cpufunc.h>
30 * Critical sections prevent preemption by raising a thread's priority
31 * above the highest possible interrupting priority. Additionally, the
32 * current cpu will not be able to schedule a new thread but will instead
33 * place it on a pending list (with interrupts physically disabled) and
34 * set mycpu->gd_reqflags to indicate that work needs to be done, which
35 * lwkt_yield_quick() takes care of.
37 * Some of these routines take a struct thread pointer as an argument. This
38 * pointer MUST be curthread and is only passed as an optimization.
40 * Synchronous switching and blocking is allowed while in a critical section.
46 struct thread *td = curthread;
48 td->td_pri += TDPRI_CRIT;
56 crit_enter_quick(struct thread *curtd)
58 curtd->td_pri += TDPRI_CRIT;
62 crit_enter_gd(globaldata_t mygd)
64 crit_enter_quick(mygd->gd_curthread);
68 crit_exit_noyield(struct thread *curtd)
70 curtd->td_pri -= TDPRI_CRIT;
72 if (curtd->td_pri < 0)
80 thread_t td = curthread;
82 td->td_pri -= TDPRI_CRIT;
87 cpu_mb1(); /* must flush td_pri before checking gd_reqflags */
88 if (td->td_gd->gd_reqflags && td->td_pri < TDPRI_CRIT)
93 crit_exit_quick(struct thread *curtd)
95 globaldata_t gd = curtd->td_gd;
97 curtd->td_pri -= TDPRI_CRIT;
98 cpu_mb1(); /* must flush td_pri before checking gd_reqflags */
99 if (gd->gd_reqflags && curtd->td_pri < TDPRI_CRIT)
104 crit_exit_gd(globaldata_t mygd)
106 crit_exit_quick(mygd->gd_curthread);
110 crit_panic_save(void)
112 thread_t td = curthread;
113 int pri = td->td_pri;
114 td->td_pri = td->td_pri & TDPRI_MASK;
119 crit_panic_restore(int cpri)
121 curthread->td_pri = cpri;
125 crit_test(thread_t td)
127 return(td->td_pri >= TDPRI_CRIT);
131 * Initialize a tokref_t. We only need to initialize the token pointer
132 * and the magic number. We do not have to initialize tr_next, tr_gdreqnext,
136 lwkt_tokref_init(lwkt_tokref_t ref, lwkt_token_t tok)
138 ref->tr_magic = LWKT_TOKREF_MAGIC1;
143 * Return whether any threads are runnable, whether they meet mp_lock
144 * requirements or not.
149 return (mycpu->gd_runqmask != 0);
153 lwkt_getpri(thread_t td)
155 return(td->td_pri & TDPRI_MASK);
159 lwkt_getpri_self(void)
161 return(lwkt_getpri(curthread));