Change sendfile() to use the new m_ext callback scheme for cleaning up after
[dragonfly.git] / sys / sys / thread2.h
CommitLineData
f1d1c3fa
MD
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 *
234d4a62 11 * $DragonFly: src/sys/sys/thread2.h,v 1.16 2004/07/29 08:55:48 dillon Exp $
f1d1c3fa
MD
12 */
13
14#ifndef _SYS_THREAD2_H_
15#define _SYS_THREAD2_H_
16
05220613
MD
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
853ae338
MD
24#ifndef _MACHINE_CPUFUNC_H_
25#include <machine/cpufunc.h>
26#endif
05220613
MD
27#endif
28
f1d1c3fa
MD
29/*
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
235957ed 34 * set mycpu->gd_reqflags to indicate that work needs to be done, which
f1d1c3fa
MD
35 * lwkt_yield_quick() takes care of.
36 *
7966cb69
MD
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.
39 *
f1d1c3fa
MD
40 * Synchronous switching and blocking is allowed while in a critical section.
41 */
57c254db 42
f1d1c3fa
MD
43static __inline void
44crit_enter(void)
45{
26a0694b
MD
46 struct thread *td = curthread;
47
00062018 48 td->td_pri += TDPRI_CRIT;
7966cb69 49#ifdef INVARIANTS
26a0694b
MD
50 if (td->td_pri < 0)
51 crit_panic();
7966cb69 52#endif
f1d1c3fa
MD
53}
54
55static __inline void
7966cb69 56crit_enter_quick(struct thread *curtd)
f1d1c3fa 57{
7966cb69
MD
58 curtd->td_pri += TDPRI_CRIT;
59}
f1d1c3fa 60
37af14fe
MD
61static __inline void
62crit_enter_gd(globaldata_t mygd)
63{
64 crit_enter_quick(mygd->gd_curthread);
65}
66
7966cb69
MD
67static __inline void
68crit_exit_noyield(struct thread *curtd)
69{
70 curtd->td_pri -= TDPRI_CRIT;
71#ifdef INVARIANTS
72 if (curtd->td_pri < 0)
26a0694b 73 crit_panic();
7966cb69 74#endif
f1d1c3fa
MD
75}
76
77static __inline void
78crit_exit(void)
79{
80 thread_t td = curthread;
81
82 td->td_pri -= TDPRI_CRIT;
7966cb69 83#ifdef INVARIANTS
26a0694b
MD
84 if (td->td_pri < 0)
85 crit_panic();
7966cb69 86#endif
853ae338
MD
87 cpu_mb1(); /* must flush td_pri before checking gd_reqflags */
88 if (td->td_gd->gd_reqflags && td->td_pri < TDPRI_CRIT)
7966cb69
MD
89 lwkt_yield_quick();
90}
91
92static __inline void
93crit_exit_quick(struct thread *curtd)
94{
853ae338
MD
95 globaldata_t gd = curtd->td_gd;
96
7966cb69 97 curtd->td_pri -= TDPRI_CRIT;
853ae338
MD
98 cpu_mb1(); /* must flush td_pri before checking gd_reqflags */
99 if (gd->gd_reqflags && curtd->td_pri < TDPRI_CRIT)
f1d1c3fa
MD
100 lwkt_yield_quick();
101}
102
37af14fe
MD
103static __inline void
104crit_exit_gd(globaldata_t mygd)
105{
106 crit_exit_quick(mygd->gd_curthread);
107}
108
8a8d5d85
MD
109static __inline int
110crit_panic_save(void)
111{
112 thread_t td = curthread;
113 int pri = td->td_pri;
114 td->td_pri = td->td_pri & TDPRI_MASK;
115 return(pri);
116}
117
118static __inline void
119crit_panic_restore(int cpri)
120{
121 curthread->td_pri = cpri;
122}
123
41a01a4d
MD
124/*
125 * Initialize a tokref_t. We only need to initialize the token pointer
126 * and the magic number. We do not have to initialize tr_next, tr_gdreqnext,
127 * or tr_reqgd.
128 */
129static __inline void
130lwkt_tokref_init(lwkt_tokref_t ref, lwkt_token_t tok)
f1d1c3fa 131{
41a01a4d
MD
132 ref->tr_magic = LWKT_TOKREF_MAGIC1;
133 ref->tr_tok = tok;
f1d1c3fa
MD
134}
135
96728c05
MD
136/*
137 * Return whether any threads are runnable, whether they meet mp_lock
138 * requirements or not.
139 */
f1d1c3fa 140static __inline int
4b5f931b 141lwkt_runnable(void)
f1d1c3fa 142{
4b5f931b 143 return (mycpu->gd_runqmask != 0);
f1d1c3fa
MD
144}
145
234d4a62
MD
146static __inline int
147lwkt_getpri(thread_t td)
148{
149 return(td->td_pri & TDPRI_MASK);
150}
151
152static __inline int
153lwkt_getpri_self(void)
154{
155 return(lwkt_getpri(curthread));
156}
157
f1d1c3fa
MD
158#endif
159