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