1 | /* |
2 | * Copyright (c) 1993-1995, 1999-2008 Apple 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 | /* |
30 | * The timer_call system is responsible for manipulating timers that call |
31 | * callbacks at a given deadline (with or without some leeway for coalescing). |
32 | * |
33 | * Call timer_call_setup once on a timer_call structure to register the callback |
34 | * function and a context parameter that's passed to it (param0). |
35 | * |
36 | * To arm the timer to fire at a deadline, call any of the timer_call_enter |
37 | * functions. If the function used accepts a parameter, it will be passed to |
38 | * the callback function when it fires. |
39 | * |
40 | * If the timer needs to be cancelled (like if the timer_call has been armed but |
41 | * now needs to be deallocated), call timer_call_cancel. |
42 | */ |
43 | |
44 | #ifndef _KERN_TIMER_CALL_H_ |
45 | #define _KERN_TIMER_CALL_H_ |
46 | |
47 | #include <mach/mach_types.h> |
48 | #include <kern/kern_types.h> |
49 | |
50 | #ifdef XNU_KERNEL_PRIVATE |
51 | |
52 | #include <kern/simple_lock.h> |
53 | |
54 | #ifdef MACH_KERNEL_PRIVATE |
55 | #include <kern/queue.h> |
56 | #include <kern/priority_queue.h> |
57 | #include <kern/mpqueue.h> |
58 | |
59 | extern boolean_t mach_timer_coalescing_enabled; |
60 | extern void timer_call_queue_init(mpqueue_head_t *); |
61 | #endif /* MACH_KERNEL_PRIVATE */ |
62 | |
63 | #if XNU_TARGET_OS_OSX |
64 | #define TIMER_TRACE 1 |
65 | #endif |
66 | |
67 | typedef void *timer_call_param_t; |
68 | typedef void (*timer_call_func_t)( |
69 | timer_call_param_t param0, |
70 | timer_call_param_t param1); |
71 | |
72 | typedef struct timer_call { |
73 | uint64_t tc_soft_deadline; |
74 | decl_simple_lock_data(, tc_lock); /* protects tc_queue */ |
75 | struct priority_queue_entry_deadline tc_pqlink; |
76 | queue_head_t *tc_queue; |
77 | queue_chain_t tc_qlink; |
78 | timer_call_func_t tc_func; |
79 | timer_call_param_t tc_param0; |
80 | timer_call_param_t tc_param1; |
81 | uint64_t tc_ttd; /* Time to deadline at creation */ |
82 | #if TIMER_TRACE |
83 | uint64_t tc_entry_time; |
84 | #endif |
85 | uint32_t tc_flags; |
86 | /* this field is locked by the lock in the object tc_queue points at */ |
87 | bool tc_async_dequeue; |
88 | } timer_call_data_t, *timer_call_t; |
89 | |
90 | #define EndOfAllTime 0xFFFFFFFFFFFFFFFFULL |
91 | |
92 | |
93 | /* |
94 | * Flags to alter the default timer/timeout coalescing behavior |
95 | * on a per-timer_call basis. |
96 | * |
97 | * The SYS urgency classes indicate that the timer_call is not |
98 | * directly related to the current thread at the time the timer_call |
99 | * is entered, so it is ignored in the calculation entirely (only |
100 | * the subclass specified is used). |
101 | * |
102 | * The USER flags indicate that both the current thread scheduling and QoS |
103 | * attributes, in addition to the per-timer_call urgency specification, |
104 | * are used to establish coalescing behavior. |
105 | */ |
106 | #define TIMER_CALL_SYS_NORMAL TIMEOUT_URGENCY_SYS_NORMAL |
107 | #define TIMER_CALL_SYS_CRITICAL TIMEOUT_URGENCY_SYS_CRITICAL |
108 | #define TIMER_CALL_SYS_BACKGROUND TIMEOUT_URGENCY_SYS_BACKGROUND |
109 | |
110 | #define TIMER_CALL_USER_MASK TIMEOUT_URGENCY_USER_MASK |
111 | #define TIMER_CALL_USER_NORMAL TIMEOUT_URGENCY_USER_NORMAL |
112 | #define TIMER_CALL_USER_CRITICAL TIMEOUT_URGENCY_USER_CRITICAL |
113 | #define TIMER_CALL_USER_BACKGROUND TIMEOUT_URGENCY_USER_BACKGROUND |
114 | |
115 | #define TIMER_CALL_URGENCY_MASK TIMEOUT_URGENCY_MASK |
116 | |
117 | /* |
118 | * Indicate that a specific leeway value is being provided (otherwise |
119 | * the leeway parameter is ignored). This supplied value can currently |
120 | * only be used to extend the leeway calculated internally from the |
121 | * urgency class provided. |
122 | */ |
123 | #define TIMER_CALL_LEEWAY TIMEOUT_URGENCY_LEEWAY |
124 | |
125 | /* |
126 | * Non-migratable timer_call |
127 | */ |
128 | #define TIMER_CALL_LOCAL TIMEOUT_URGENCY_FIRST_AVAIL |
129 | #define TIMER_CALL_RATELIMITED TIMEOUT_URGENCY_RATELIMITED |
130 | extern boolean_t timer_call_enter( |
131 | timer_call_t call, |
132 | uint64_t deadline, |
133 | uint32_t flags); |
134 | |
135 | extern boolean_t timer_call_enter1( |
136 | timer_call_t call, |
137 | timer_call_param_t param1, |
138 | uint64_t deadline, |
139 | uint32_t flags); |
140 | |
141 | extern boolean_t timer_call_enter_with_leeway( |
142 | timer_call_t call, |
143 | timer_call_param_t param1, |
144 | uint64_t deadline, |
145 | uint64_t leeway, |
146 | uint32_t flags, |
147 | boolean_t ratelimited); |
148 | |
149 | extern boolean_t timer_call_cancel( |
150 | timer_call_t call); |
151 | |
152 | extern timer_call_t timer_call_alloc( |
153 | timer_call_func_t func, |
154 | timer_call_param_t param0); |
155 | |
156 | extern void timer_call_free( |
157 | timer_call_t call); |
158 | |
159 | extern void timer_call_setup( |
160 | timer_call_t call, |
161 | timer_call_func_t func, |
162 | timer_call_param_t param0); |
163 | |
164 | extern int timer_get_user_idle_level(void); |
165 | extern kern_return_t timer_set_user_idle_level(int ilevel); |
166 | |
167 | #define NUM_LATENCY_QOS_TIERS (6) |
168 | typedef struct { |
169 | uint32_t powergate_latency_abstime; |
170 | |
171 | uint32_t idle_entry_timer_processing_hdeadline_threshold_abstime; |
172 | uint32_t interrupt_timer_coalescing_ilat_threshold_abstime; |
173 | uint32_t timer_resort_threshold_abstime; |
174 | |
175 | int32_t timer_coalesce_rt_shift; |
176 | int32_t timer_coalesce_bg_shift; |
177 | int32_t timer_coalesce_kt_shift; |
178 | int32_t timer_coalesce_fp_shift; |
179 | int32_t timer_coalesce_ts_shift; |
180 | |
181 | uint64_t timer_coalesce_rt_abstime_max; |
182 | uint64_t timer_coalesce_bg_abstime_max; |
183 | uint64_t timer_coalesce_kt_abstime_max; |
184 | uint64_t timer_coalesce_fp_abstime_max; |
185 | uint64_t timer_coalesce_ts_abstime_max; |
186 | |
187 | uint32_t latency_qos_scale[NUM_LATENCY_QOS_TIERS]; |
188 | uint64_t latency_qos_abstime_max[NUM_LATENCY_QOS_TIERS]; |
189 | boolean_t latency_tier_rate_limited[NUM_LATENCY_QOS_TIERS]; |
190 | } timer_coalescing_priority_params_t; |
191 | extern timer_coalescing_priority_params_t tcoal_prio_params; |
192 | |
193 | /* |
194 | * Initialize the timer call subsystem during system startup. |
195 | */ |
196 | extern void timer_call_init(void); |
197 | |
198 | #if MACH_KERNEL_PRIVATE |
199 | |
200 | /* |
201 | * Handle deadlines in the past. |
202 | */ |
203 | uint64_t timer_call_past_deadline_timer_handle(uint64_t deadline, |
204 | uint64_t ctime); |
205 | |
206 | /* |
207 | * Running timers are only active for a given CPU when a non-idle thread |
208 | * is running. |
209 | */ |
210 | |
211 | enum running_timer { |
212 | RUNNING_TIMER_QUANTUM, |
213 | RUNNING_TIMER_PREEMPT, |
214 | #if KPERF |
215 | RUNNING_TIMER_KPERF, |
216 | #endif /* KPERF */ |
217 | RUNNING_TIMER_MAX, |
218 | }; |
219 | |
220 | /* |
221 | * Get the earliest active deadline for this processor. |
222 | */ |
223 | uint64_t running_timers_deadline(processor_t processor); |
224 | |
225 | /* |
226 | * Run the expire handler to process any timers past their deadline. Returns |
227 | * true if any timer was processed, and false otherwise. |
228 | */ |
229 | bool running_timers_expire(processor_t processor, uint64_t now); |
230 | |
231 | /* |
232 | * Set up a new deadline for the given running timer on the processor, but don't |
233 | * synchronize it with the hardware. A subsequent call to running_timers_sync |
234 | * is necessary. This allows thread_dispatch to batch all of the setup and only |
235 | * set the decrementer once. |
236 | */ |
237 | void running_timer_setup(processor_t processor, enum running_timer timer, |
238 | void *param, uint64_t deadline, uint64_t now); |
239 | |
240 | /* |
241 | * Synchronize the state of any running timers that have been set up with the |
242 | * hardware. |
243 | */ |
244 | void running_timers_sync(void); |
245 | |
246 | /* |
247 | * Enter a new deadline for the given running timer on the processor and put it |
248 | * into effect. |
249 | */ |
250 | void running_timer_enter(processor_t processor, enum running_timer timer, |
251 | void *param, uint64_t deadline, uint64_t now); |
252 | |
253 | /* |
254 | * Clear the deadline and parameters for the given running timer on the |
255 | * processor. |
256 | */ |
257 | void running_timer_clear(processor_t processor, enum running_timer timer); |
258 | |
259 | /* |
260 | * Cancel a running timer on the processor. |
261 | */ |
262 | void running_timer_cancel(processor_t processor, enum running_timer timer); |
263 | |
264 | /* |
265 | * Activate the running timers for the given, current processor. Should only be |
266 | * called by thread_dispatch. |
267 | */ |
268 | void running_timers_activate(processor_t processor); |
269 | |
270 | /* |
271 | * Deactivate the running timers for the given, current processor. Should only |
272 | * be called by thread_dispatch. |
273 | */ |
274 | void running_timers_deactivate(processor_t processor); |
275 | |
276 | #endif /* MACH_KERNEL_PRIVATE */ |
277 | |
278 | #endif /* XNU_KERNEL_PRIVATE */ |
279 | |
280 | #endif /* _KERN_TIMER_CALL_H_ */ |
281 | |