]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/timer_call.h
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / kern / timer_call.h
index d3beccfc7c2510dd2c6554d88836461819257b9d..37bf58b6fd4bd98428c0493470bdf5faa479cfd6 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * Copyright (c) 1993-1995, 1999-2000 Apple Computer, Inc.
- * All rights reserved.
+ * 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
  * 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,
  * 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@
  */
+
 /*
- * Declarations for timer interrupt callouts.
+ * The timer_call system is responsible for manipulating timers that call
+ * callbacks at a given deadline (with or without some leeway for coalescing).
  *
- * HISTORY
+ * 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).
  *
- * 20 December 2000 (debo)
- *     Created.
+ * 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
 
-typedef struct call_entry      *timer_call_t;
-typedef void                           *timer_call_param_t;
-typedef void                           (*timer_call_func_t)(
-                                                                       timer_call_param_t              param0,
-                                                                       timer_call_param_t              param1);
+#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
 
-boolean_t
-timer_call_enter(
-       timer_call_t                    call,
-       uint64_t                                deadline);
+#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);
 
-boolean_t
-timer_call_enter1(
-       timer_call_t                    call,
-       timer_call_param_t              param1,
-       uint64_t                                deadline);
+extern boolean_t        timer_call_enter1(
+       timer_call_t            call,
+       timer_call_param_t      param1,
+       uint64_t                deadline,
+       uint32_t                flags);
 
-boolean_t
-timer_call_cancel(
-       timer_call_t                    call);
+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);
 
-boolean_t
-timer_call_is_delayed(
-       timer_call_t                    call,
-       uint64_t                                *deadline);
+extern boolean_t        timer_call_cancel(
+       timer_call_t    call);
 
-#include <kern/call_entry.h>
+extern void             timer_call_setup(
+       timer_call_t            call,
+       timer_call_func_t       func,
+       timer_call_param_t      param0);
 
-typedef struct call_entry      timer_call_data_t;
+extern int timer_get_user_idle_level(void);
+extern kern_return_t timer_set_user_idle_level(int ilevel);
 
-void
-timer_call_initialize(void);
+#define NUM_LATENCY_QOS_TIERS (6)
+typedef struct {
+       uint32_t powergate_latency_abstime;
 
-void
-timer_call_setup(
-       timer_call_t                    call,
-       timer_call_func_t               func,
-       timer_call_param_t              param0);
+       uint32_t idle_entry_timer_processing_hdeadline_threshold_abstime;
+       uint32_t interrupt_timer_coalescing_ilat_threshold_abstime;
+       uint32_t timer_resort_threshold_abstime;
 
-void
-timer_call_shutdown(
-       processor_t                     processor);
+       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_ */