/ duct-tape / xnu / osfmk / kern / timer_call.h
timer_call.h
  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 void             timer_call_setup(
153  	timer_call_t            call,
154  	timer_call_func_t       func,
155  	timer_call_param_t      param0);
156  
157  extern int timer_get_user_idle_level(void);
158  extern kern_return_t timer_set_user_idle_level(int ilevel);
159  
160  #define NUM_LATENCY_QOS_TIERS (6)
161  typedef struct {
162  	uint32_t powergate_latency_abstime;
163  
164  	uint32_t idle_entry_timer_processing_hdeadline_threshold_abstime;
165  	uint32_t interrupt_timer_coalescing_ilat_threshold_abstime;
166  	uint32_t timer_resort_threshold_abstime;
167  
168  	int32_t timer_coalesce_rt_shift;
169  	int32_t timer_coalesce_bg_shift;
170  	int32_t timer_coalesce_kt_shift;
171  	int32_t timer_coalesce_fp_shift;
172  	int32_t timer_coalesce_ts_shift;
173  
174  	uint64_t timer_coalesce_rt_abstime_max;
175  	uint64_t timer_coalesce_bg_abstime_max;
176  	uint64_t timer_coalesce_kt_abstime_max;
177  	uint64_t timer_coalesce_fp_abstime_max;
178  	uint64_t timer_coalesce_ts_abstime_max;
179  
180  	uint32_t latency_qos_scale[NUM_LATENCY_QOS_TIERS];
181  	uint64_t latency_qos_abstime_max[NUM_LATENCY_QOS_TIERS];
182  	boolean_t latency_tier_rate_limited[NUM_LATENCY_QOS_TIERS];
183  } timer_coalescing_priority_params_t;
184  extern timer_coalescing_priority_params_t tcoal_prio_params;
185  
186  /*
187   * Initialize the timer call subsystem during system startup.
188   */
189  extern void timer_call_init(void);
190  
191  #if MACH_KERNEL_PRIVATE
192  
193  /*
194   * Handle deadlines in the past.
195   */
196  uint64_t timer_call_past_deadline_timer_handle(uint64_t deadline,
197      uint64_t ctime);
198  
199  /*
200   * Running timers are only active for a given CPU when a non-idle thread
201   * is running.
202   */
203  
204  enum running_timer {
205  	RUNNING_TIMER_QUANTUM,
206  #if KPERF
207  	RUNNING_TIMER_KPERF,
208  #endif /* KPERF */
209  	RUNNING_TIMER_MAX,
210  };
211  
212  /*
213   * Get the earliest active deadline for this processor.
214   */
215  uint64_t running_timers_deadline(processor_t processor);
216  
217  /*
218   * Run the expire handler to process any timers past their deadline.  Returns
219   * true if any timer was processed, and false otherwise.
220   */
221  bool running_timers_expire(processor_t processor, uint64_t now);
222  
223  /*
224   * Set up a new deadline for the given running timer on the processor, but don't
225   * synchronize it with the hardware.  A subsequent call to running_timers_sync
226   * is necessary.  This allows thread_dispatch to batch all of the setup and only
227   * set the decrementer once.
228   */
229  void running_timer_setup(processor_t processor, enum running_timer timer,
230      void *param, uint64_t deadline, uint64_t now);
231  
232  /*
233   * Synchronize the state of any running timers that have been set up with the
234   * hardware.
235   */
236  void running_timers_sync(void);
237  
238  /*
239   * Enter a new deadline for the given running timer on the processor and put it
240   * into effect.
241   */
242  void running_timer_enter(processor_t processor, enum running_timer timer,
243      void *param, uint64_t deadline, uint64_t now);
244  
245  /*
246   * Clear the deadline and parameters for the given running timer on the
247   * processor.
248   */
249  void running_timer_clear(processor_t processor, enum running_timer timer);
250  
251  /*
252   * Cancel a running timer on the processor.
253   */
254  void running_timer_cancel(processor_t processor, enum running_timer timer);
255  
256  /*
257   * Activate the running timers for the given, current processor.  Should only be
258   * called by thread_dispatch.
259   */
260  void running_timers_activate(processor_t processor);
261  
262  /*
263   * Deactivate the running timers for the given, current processor.  Should only
264   * be called by thread_dispatch.
265   */
266  void running_timers_deactivate(processor_t processor);
267  
268  #endif /* MACH_KERNEL_PRIVATE */
269  
270  #endif /* XNU_KERNEL_PRIVATE */
271  
272  #endif /* _KERN_TIMER_CALL_H_ */