]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
5d5c5d0d A |
2 | * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. |
3 | * | |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
2d21ac55 A |
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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
1c79356b | 27 | */ |
55e303ae A |
28 | /*- |
29 | * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@FreeBSD.org> | |
30 | * All rights reserved. | |
1c79356b A |
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. | |
1c79356b | 40 | * |
55e303ae | 41 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
1c79356b A |
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
55e303ae | 44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
1c79356b A |
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 | * | |
55e303ae | 53 | * $FreeBSD: src/sys/sys/eventvar.h,v 1.1.2.2 2000/07/18 21:49:12 jlemon Exp $ |
1c79356b A |
54 | */ |
55 | ||
55e303ae A |
56 | #ifndef _SYS_EVENTVAR_H_ |
57 | #define _SYS_EVENTVAR_H_ | |
58 | ||
91447636 | 59 | #include <sys/event.h> |
55e303ae A |
60 | #include <sys/select.h> |
61 | #include <kern/kern_types.h> | |
3e170ce0 | 62 | #include <kern/waitq.h> |
55e303ae | 63 | |
39037602 A |
64 | #if defined(XNU_KERNEL_PRIVATE) |
65 | ||
66 | #include <kern/locks.h> | |
67 | #include <mach/thread_policy.h> | |
68 | ||
55e303ae | 69 | #define KQEXTENT 256 /* linear growth by this amount */ |
9bccf70c | 70 | |
39037602 A |
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 | */ | |
55e303ae | 78 | struct kqueue { |
39037602 A |
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 */ | |
55e303ae | 148 | }; |
9bccf70c | 149 | |
39037602 A |
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); | |
2d21ac55 | 216 | extern void kqueue_dealloc(struct kqueue *); |
91447636 | 217 | |
3e170ce0 | 218 | typedef int (*kevent_callback_t)(struct kqueue *, struct kevent_internal_s *, void *); |
b0d623f7 | 219 | typedef void (*kqueue_continue_t)(struct kqueue *, void *, int); |
91447636 | 220 | |
39037602 | 221 | extern void kevent_register(struct kqueue *, struct kevent_internal_s *, struct proc *); |
b0d623f7 | 222 | extern int kqueue_scan(struct kqueue *, kevent_callback_t, kqueue_continue_t, |
39037602 | 223 | void *, struct filt_process_s *, struct timeval *, struct proc *); |
fe8ab488 | 224 | extern int kqueue_stat(struct kqueue *, void *, int, proc_t); |
91447636 | 225 | |
39037602 A |
226 | #endif /* XNU_KERNEL_PRIVATE */ |
227 | ||
55e303ae | 228 | #endif /* !_SYS_EVENTVAR_H_ */ |
39037602 A |
229 | |
230 | ||
231 | ||
232 |