The cam_sim structure was being deallocated unconditionally by device
[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.13 2004/03/01 06:33:19 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     td->td_pri += TDPRI_CRIT;
46 #ifdef INVARIANTS
47     if (td->td_pri < 0)
48         crit_panic();
49 #endif
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 /*
106  * Initialize a tokref_t.  We only need to initialize the token pointer
107  * and the magic number.  We do not have to initialize tr_next, tr_gdreqnext,
108  * or tr_reqgd.
109  */
110 static __inline void
111 lwkt_tokref_init(lwkt_tokref_t ref, lwkt_token_t tok)
112 {
113     ref->tr_magic = LWKT_TOKREF_MAGIC1;
114     ref->tr_tok = tok;
115 }
116
117 /*
118  * Return whether any threads are runnable, whether they meet mp_lock
119  * requirements or not.
120  */
121 static __inline int
122 lwkt_runnable(void)
123 {
124     return (mycpu->gd_runqmask != 0);
125 }
126
127 #endif
128