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