]> git.saurik.com Git - apple/xnu.git/blob - bsd/sys/eventvar.h
xnu-3789.1.32.tar.gz
[apple/xnu.git] / bsd / sys / eventvar.h
1 /*
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*-
29 * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@FreeBSD.org>
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * $FreeBSD: src/sys/sys/eventvar.h,v 1.1.2.2 2000/07/18 21:49:12 jlemon Exp $
54 */
55
56 #ifndef _SYS_EVENTVAR_H_
57 #define _SYS_EVENTVAR_H_
58
59 #include <sys/event.h>
60 #include <sys/select.h>
61 #include <kern/kern_types.h>
62 #include <kern/waitq.h>
63
64 #if defined(XNU_KERNEL_PRIVATE)
65
66 #include <kern/locks.h>
67 #include <mach/thread_policy.h>
68
69 #define KQEXTENT 256 /* linear growth by this amount */
70
71 /*
72 * kqueue - common core definition of a kqueue
73 *
74 * No real structures are allocated of this type. They are
75 * either kqfile objects or kqworkq objects - each of which is
76 * derived from this definition.
77 */
78 struct kqueue {
79 struct waitq_set kq_wqs; /* private waitq set */
80 lck_spin_t kq_lock; /* kqueue lock */
81 uint16_t kq_state; /* state of the kq */
82 uint16_t kq_level; /* nesting level of the kq */
83 uint32_t kq_count; /* number of queued events */
84 struct proc *kq_p; /* process containing kqueue */
85 struct kqtailq kq_queue[1]; /* variable array of kqtailq structs */
86 };
87
88 #define KQ_SEL 0x001 /* select was recorded for kq */
89 #define KQ_SLEEP 0x002 /* thread is waiting for events */
90 #define KQ_PROCWAIT 0x004 /* thread waiting for processing */
91 #define KQ_KEV32 0x008 /* kq is used with 32-bit events */
92 #define KQ_KEV64 0x010 /* kq is used with 64-bit events */
93 #define KQ_KEV_QOS 0x020 /* kq events carry QoS info */
94 #define KQ_WORKQ 0x040 /* KQ is bould to process workq */
95 #define KQ_PROCESSING 0x080 /* KQ is being processed */
96 #define KQ_DRAIN 0x100 /* kq is draining */
97 #define KQ_WAKEUP 0x200 /* kq awakened while processing */
98
99 /*
100 * kqfile - definition of a typical kqueue opened as a file descriptor
101 * via the kqueue() system call.
102 *
103 * Adds selinfo support to the base kqueue definition, as these
104 * fds can be fed into select().
105 */
106 struct kqfile {
107 struct kqueue kqf_kqueue; /* common kqueue core */
108 struct kqtailq kqf_suppressed; /* suppression queue */
109 struct selinfo kqf_sel; /* parent select/kqueue info */
110 };
111
112 #define kqf_wqs kqf_kqueue.kq_wqs
113 #define kqf_lock kqf_kqueue.kq_lock
114 #define kqf_state kqf_kqueue.kq_state
115 #define kqf_level kqf_kqueue.kq_level
116 #define kqf_count kqf_kqueue.kq_count
117 #define kqf_p kqf_kqueue.kq_p
118 #define kqf_queue kqf_kqueue.kq_queue
119
120 #define QOS_INDEX_KQFILE 0 /* number of qos levels in a file kq */
121
122 /*
123 * WorkQ kqueues need to request threads to service the triggered
124 * knotes in the queue. These threads are brought up on a
125 * effective-requested-QoS basis. Knotes are segregated based on
126 * that value - calculated by computing max(event-QoS, kevent-QoS).
127 * Only one servicing thread is requested at a time for all the
128 * knotes at a given effective-requested-QoS.
129 */
130
131 #if !defined(KQWQ_QOS_MANAGER)
132 #define KQWQ_QOS_MANAGER (THREAD_QOS_LAST)
133 #endif
134
135 #if !defined(KQWQ_NQOS)
136 #define KQWQ_NQOS (KQWQ_QOS_MANAGER + 1)
137 #endif
138
139
140 /*
141 * kqrequest - per-QoS thread request status
142 */
143 struct kqrequest {
144 struct kqtailq kqr_suppressed; /* Per-QoS suppression queues */
145 thread_t kqr_thread; /* thread to satisfy request */
146 uint8_t kqr_state; /* KQ/workq interaction state */
147 uint8_t kqr_override_delta; /* current override delta */
148 };
149
150 /*
151 * Workq thread start out a particular effective-requested-QoS, but
152 * additional events processed by the filters may represent
153 * backlogged events that may themselves have a higher requested-QoS.
154 * To represent this, the filter may apply an override to a knote's
155 * requested QoS.
156 *
157 * We further segregate these overridden knotes into different buckets
158 * by <requested, override> grouping. This allows easy matching of
159 * knotes to process vs. the highest workq thread override applied.
160 *
161 * Only certain override patterns need to be supported. A knote
162 * cannot have an effective-requested-QoS of UNSPECIFIED - because
163 * the kevent->qos (when canonicalized) will always be above that
164 * or indicate manager. And we don't allow an override to specify
165 * manager. This results in the following buckets being needed:
166 *
167 * Effective-Requested QoS
168 * MAINT BG UTIL DEFAULT UINIT UINTER MANAGER
169 * override:
170 * MAINT 0
171 * BG 1 6
172 * UTILITY 2 7 11
173 * DEFAULT 3 8 12 15
174 * UINIT 4 9 13 16 18
175 * UINTER 5 10 14 17 19 20
176 * 21
177 */
178 #if !defined(KQWQ_NBUCKETS)
179 #define KQWQ_NBUCKETS 22
180 #endif
181
182 /*
183 * kqworkq - definition of a private kqueue used to coordinate event
184 * handling for pthread work queues.
185 *
186 * These have per-qos processing queues and state to coordinate with
187 * the pthread kext to ask for threads at corresponding pthread priority
188 * values.
189 */
190 struct kqworkq {
191 struct kqueue kqwq_kqueue;
192 struct kqtailq kqwq_queuecont[KQWQ_NBUCKETS-1]; /* continue array of queues */
193 struct kqrequest kqwq_request[KQWQ_NQOS]; /* per-QoS request states */
194 lck_spin_t kqwq_reqlock; /* kqueue request lock */
195 };
196
197 #define kqwq_wqs kqwq_kqueue.kq_wqs
198 #define kqwq_lock kqwq_kqueue.kq_lock
199 #define kqwq_state kqwq_kqueue.kq_state
200 #define kqwq_level kqwq_kqueue.kq_level
201 #define kqwq_count kqwq_kqueue.kq_count
202 #define kqwq_p kqwq_kqueue.kq_p
203 #define kqwq_queue kqwq_kqueue.kq_queue
204
205 #define kqwq_req_lock(kqwq) (lck_spin_lock(&kqwq->kqwq_reqlock))
206 #define kqwq_req_unlock(kqwq) (lck_spin_unlock(&kqwq->kqwq_reqlock))
207 #define kqwq_req_held(kqwq) (lck_spin_held(&kqwq->kqwq_reqlock))
208
209 #define KQWQ_PROCESSING 0x01 /* running the kq in workq mode */
210 #define KQWQ_THREQUESTED 0x02 /* thread requested from workq */
211 #define KQWQ_THMANAGER 0x04 /* expect manager thread to run the queue */
212 #define KQWQ_HOOKCALLED 0x10 /* hook called during processing */
213 #define KQWQ_WAKEUP 0x20 /* wakeup called during processing */
214
215 extern struct kqueue *kqueue_alloc(struct proc *, unsigned int);
216 extern void kqueue_dealloc(struct kqueue *);
217
218 typedef int (*kevent_callback_t)(struct kqueue *, struct kevent_internal_s *, void *);
219 typedef void (*kqueue_continue_t)(struct kqueue *, void *, int);
220
221 extern void kevent_register(struct kqueue *, struct kevent_internal_s *, struct proc *);
222 extern int kqueue_scan(struct kqueue *, kevent_callback_t, kqueue_continue_t,
223 void *, struct filt_process_s *, struct timeval *, struct proc *);
224 extern int kqueue_stat(struct kqueue *, void *, int, proc_t);
225
226 #endif /* XNU_KERNEL_PRIVATE */
227
228 #endif /* !_SYS_EVENTVAR_H_ */
229
230
231
232