X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/9bccf70c0258c7cac2dcb80011b2a964d884c552..490019cf9519204c5fb36b2fba54ceb983bb6b72:/osfmk/kern/thread_call.h?ds=sidebyside diff --git a/osfmk/kern/thread_call.h b/osfmk/kern/thread_call.h index 952265dd9..c44561f63 100644 --- a/osfmk/kern/thread_call.h +++ b/osfmk/kern/thread_call.h @@ -1,165 +1,340 @@ /* - * Copyright (c) 1993-1995, 1999-2000 Apple Computer, Inc. - * All rights reserved. + * Copyright (c) 1993-1995, 1999-2008 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * 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. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * 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 OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * 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_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ -/* - * Declarations for thread-based callouts. - * - * HISTORY - * - * 10 July 1999 (debo) - * Pulled into Mac OS X (microkernel). - * - * 3 July 1993 (debo) - * Created. + +/*! + @header thread_call.h + @discussion Facilities for executing work asynchronously. */ #ifndef _KERN_THREAD_CALL_H_ #define _KERN_THREAD_CALL_H_ -#include - #include #include -typedef struct call_entry *thread_call_t; -typedef void *thread_call_param_t; -typedef void (*thread_call_func_t)( - thread_call_param_t param0, - thread_call_param_t param1); - -boolean_t -thread_call_enter( - thread_call_t call -); -boolean_t -thread_call_enter1( - thread_call_t call, - thread_call_param_t param1 -); -boolean_t -thread_call_enter_delayed( - thread_call_t call, - uint64_t deadline -); -boolean_t -thread_call_enter1_delayed( - thread_call_t call, - thread_call_param_t param1, - uint64_t deadline -); -boolean_t -thread_call_cancel( - thread_call_t call -); -boolean_t -thread_call_is_delayed( - thread_call_t call, - uint64_t *deadline -); - -thread_call_t -thread_call_allocate( - thread_call_func_t func, - thread_call_param_t param0 -); -boolean_t -thread_call_free( - thread_call_t call -); - -#ifdef __APPLE_API_PRIVATE - -#ifdef __APPLE_API_OBSOLETE +#include + +struct thread_call; +typedef struct thread_call *thread_call_t; + +typedef void *thread_call_param_t; +typedef void (*thread_call_func_t)( + thread_call_param_t param0, + thread_call_param_t param1); +/*! + @enum thread_call_priority_t + @discussion Thread call priorities should not be assumed to have any specific + numerical value; they should be interpreted as importances or roles for work + items, priorities for which will be reasonably managed by the subsystem. + @constant THREAD_CALL_PRIORITY_HIGH Importance above everything but realtime. + Thread calls allocated with this priority execute at extremely high priority, + above everything but realtime threads. They are generally executed in serial. + Though they may execute concurrently under some circumstances, no fan-out is implied. + These work items should do very small amounts of work or risk disrupting system + responsiveness. + @constant THREAD_CALL_PRIORITY_KERNEL Importance similar to that of normal kernel + threads. + @constant THREAD_CALL_PRIORITY_USER Importance similar to that of normal user threads. + @constant THREAD_CALL_PRIORITY_LOW Very low importance. + */ +typedef enum { + THREAD_CALL_PRIORITY_HIGH = 0, + THREAD_CALL_PRIORITY_KERNEL = 1, + THREAD_CALL_PRIORITY_USER = 2, + THREAD_CALL_PRIORITY_LOW = 3 +} thread_call_priority_t; + +__BEGIN_DECLS + +/*! + @function thread_call_enter + @abstract Submit a thread call work item for immediate execution. + @discussion If the work item is already scheduled for delayed execution, and it has + not yet begun to run, that delayed invocation will be cancelled. Note that if a + thread call is rescheduled from its own callback, then multiple invocations of the + callback may be in flight at the same time. + @result TRUE if the call was already pending for either delayed or immediate + execution, FALSE otherwise. + @param call The thread call to execute. + */ +extern boolean_t thread_call_enter( + thread_call_t call); +/*! + @function thread_call_enter1 + @abstract Submit a thread call work item for immediate execution, with an extra parameter. + @discussion This routine is identical to thread_call_enter(), except that + the second parameter to the callback is specified. + @result TRUE if the call was already pending for either delayed or immediate + execution, FALSE otherwise. + @param call The thread call to execute. + @param param1 Parameter to pass callback. + */ +extern boolean_t thread_call_enter1( + thread_call_t call, + thread_call_param_t param1); + +/*! + @function thread_call_enter_delayed + @abstract Submit a thread call to be executed at some point in the future. + @discussion If the work item is already scheduled for delayed or immediate execution, + and it has not yet begun to run, that invocation will be cancelled in favor of execution + at the newly specified time. Note that if a thread call is rescheduled from its own callback, + then multiple invocations of the callback may be in flight at the same time. + @result TRUE if the call was already pending for either delayed or immediate + execution, FALSE otherwise. + @param call The thread call to execute. + @param deadline Time, in absolute time units, at which to execute callback. + */ +extern boolean_t thread_call_enter_delayed( + thread_call_t call, + uint64_t deadline); +/*! + @function thread_call_enter1_delayed + @abstract Submit a thread call to be executed at some point in the future, with an extra parameter. + @discussion This routine is identical to thread_call_enter_delayed(), + except that a second parameter to the callback is specified. + @result TRUE if the call was already pending for either delayed or immediate + execution, FALSE otherwise. + @param call The thread call to execute. + @param param1 Second parameter to callback. + @param deadline Time, in absolute time units, at which to execute callback. + */ +extern boolean_t thread_call_enter1_delayed( + thread_call_t call, + thread_call_param_t param1, + uint64_t deadline); +#ifdef XNU_KERNEL_PRIVATE /* - * This portion of the interface - * is OBSOLETE and DEPRECATED. It - * will disappear shortly. + * Flags to alter the default timer/timeout coalescing behavior + * on a per-thread_call basis. + * + * The SYS urgency classes indicate that the thread_call is not + * directly related to the current thread at the time the thread_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-thread_call urgency specification, + * are used to establish coalescing behavior. */ +#define THREAD_CALL_DELAY_SYS_NORMAL TIMEOUT_URGENCY_SYS_NORMAL +#define THREAD_CALL_DELAY_SYS_CRITICAL TIMEOUT_URGENCY_SYS_CRITICAL +#define THREAD_CALL_DELAY_SYS_BACKGROUND TIMEOUT_URGENCY_SYS_BACKGROUND + +#define THREAD_CALL_DELAY_USER_MASK TIMEOUT_URGENCY_USER_MASK +#define THREAD_CALL_DELAY_USER_NORMAL TIMEOUT_URGENCY_USER_NORMAL +#define THREAD_CALL_DELAY_USER_CRITICAL TIMEOUT_URGENCY_USER_CRITICAL +#define THREAD_CALL_DELAY_USER_BACKGROUND TIMEOUT_URGENCY_USER_BACKGROUND + +#define THREAD_CALL_DELAY_URGENCY_MASK TIMEOUT_URGENCY_MASK + +/* + * Indicate that a specific leeway value is being provided (otherwise + * the leeway parameter is ignored). The supplied value can currently + * only be used to extend the leeway calculated internally from the + * urgency class provided. + */ +#define THREAD_CALL_DELAY_LEEWAY TIMEOUT_URGENCY_LEEWAY + +/*! + @function thread_call_enter_delayed_with_leeway + @abstract Submit a thread call to be executed at some point in the future. + @discussion If the work item is already scheduled for delayed or immediate execution, + and it has not yet begun to run, that invocation will be cancelled in favor of execution + at the newly specified time. Note that if a thread call is rescheduled from its own callback, + then multiple invocations of the callback may be in flight at the same time. + @result TRUE if the call was already pending for either delayed or immediate + execution, FALSE otherwise. + @param call The thread call to execute. + @param param1 Second parameter to callback. + @param deadline Time, in absolute time units, at which to execute callback. + @param leeway Time delta, in absolute time units, which sets range of time allowing kernel + to decide appropriate time to run. + @param flags configuration for timers in kernel. + */ +extern boolean_t thread_call_enter_delayed_with_leeway( + thread_call_t call, + thread_call_param_t param1, + uint64_t deadline, + uint64_t leeway, + uint32_t flags); + +#endif /* XNU_KERNEL_PRIVATE */ + +/*! + @function thread_call_cancel + @abstract Attempt to cancel a pending invocation of a thread call. + @discussion Attempt to cancel a thread call which has been scheduled + for execution with a thread_call_enter* variant. If the call has not + yet begun executing, the pending invocation will be cancelled and TRUE + will be returned. If the work item has already begun executing, + thread_call_cancel will return FALSE immediately; the callback may be + about to run, currently running, or already done executing. + @result TRUE if the call was successfully cancelled, FALSE otherwise. + */ +extern boolean_t thread_call_cancel( + thread_call_t call); +/*! + @function thread_call_cancel_wait + @abstract Attempt to cancel a pending invocation of a thread call. + If unable to cancel, wait for current invocation to finish. + @discussion Attempt to cancel a thread call which has been scheduled + for execution with a thread_call_enter* variant. If the call has not + yet begun executing, the pending invocation will be cancelled and TRUE + will be returned. If the work item has already begun executing, + thread_call_cancel_wait waits for the most recent invocation to finish. When + called on a work item which has already finished, it will return FALSE immediately. + Note that this routine can only be used on thread calls set up with either + thread_call_allocate or thread_call_allocate_with_priority, and that invocations + of the thread call after the current invocation may be in flight when + thread_call_cancel_wait returns. + @result TRUE if the call was successfully cancelled, FALSE otherwise. + */ +extern boolean_t thread_call_cancel_wait( + thread_call_t call); + + /*! + @function thread_call_allocate + @abstract Allocate a thread call to execute with default (high) priority. + @discussion Allocates a thread call that will run with properties of + THREAD_CALL_PRIORITY_HIGH, binding the first parameter to the callback. + @param func Callback to invoke when thread call is scheduled. + @param param0 First argument ot pass to callback. + @result Thread call which can be passed to thread_call_enter variants. + */ +extern thread_call_t thread_call_allocate( + thread_call_func_t func, + thread_call_param_t param0); + + /*! + @function thread_call_allocate_with_priority + @abstract Allocate a thread call to execute with a specified priority. + @discussion Identical to thread_call_allocate, except that priority + is specified by caller. + @param func Callback to invoke when thread call is scheduled. + @param param0 First argument to pass to callback. + @param pri Priority of item. + @result Thread call which can be passed to thread_call_enter variants. + */ +extern thread_call_t thread_call_allocate_with_priority( + thread_call_func_t func, + thread_call_param_t param0, + thread_call_priority_t pri); + +/*! + @function thread_call_free + @abstract Release a thread call. + @discussion Should only be used on thread calls allocated with thread_call_allocate + or thread_call_allocate_with_priority. Once thread_call_free has been called, + no other operations may be performed on a thread call. If the thread call is + currently pending, thread_call_free will return FALSE and will have no effect. + Calling thread_call_free from a thread call's own callback is safe; the work + item is not considering "pending" at that point. + @result TRUE if the thread call has been successfully released, else FALSE. + @param call The thread call to release. + */ +extern boolean_t thread_call_free( + thread_call_t call); + +/*! + @function thread_call_isactive + @abstract Determine whether a thread call is pending or currently executing. + @param call Thread call to examine. + @result TRUE if the thread call is either scheduled for execution (immediately + or at some point in the future) or is currently executing. + */ +boolean_t thread_call_isactive( + thread_call_t call); +__END_DECLS + +#ifdef MACH_KERNEL_PRIVATE -void -thread_call_func( - thread_call_func_t func, - thread_call_param_t param, - boolean_t unique_call -); -void -thread_call_func_delayed( - thread_call_func_t func, - thread_call_param_t param, - uint64_t deadline -); - -boolean_t -thread_call_func_cancel( - thread_call_func_t func, - thread_call_param_t param, - boolean_t cancel_all -); - -/* End OBSOLETE and DEPRECATED */ - -#endif /* __APPLE_API_OBSOLETE */ - -#ifdef MACH_KERNEL_PRIVATE #include -typedef struct call_entry thread_call_data_t; +struct thread_call { + struct call_entry tc_call; /* Must be first */ + uint64_t tc_submit_count; + uint64_t tc_finish_count; + uint64_t ttd; /* Time to deadline at creation */ + uint64_t tc_soft_deadline; + thread_call_priority_t tc_pri; + uint32_t tc_flags; + int32_t tc_refs; +}; -void -thread_call_initialize(void); +#define THREAD_CALL_ALLOC 0x01 +#define THREAD_CALL_WAIT 0x02 +#define THREAD_CALL_DELAYED 0x04 +#define THREAD_CALL_RATELIMITED TIMEOUT_URGENCY_RATELIMITED -void -thread_call_setup( - thread_call_t call, - thread_call_func_t func, - thread_call_param_t param0 -); +typedef struct thread_call thread_call_data_t; -void -call_thread_block(void), -call_thread_unblock(void); +extern void thread_call_initialize(void); -#endif /* MACH_KERNEL_PRIVATE */ +extern void thread_call_setup( + thread_call_t call, + thread_call_func_t func, + thread_call_param_t param0); -#endif /* __APPLE_API_PRIVATE */ +extern void thread_call_delayed_timer_rescan_all(void); +#endif /* MACH_KERNEL_PRIVATE */ -#if !defined(MACH_KERNEL_PRIVATE) && !defined(ABSOLUTETIME_SCALAR_TYPE) +#ifdef XNU_KERNEL_PRIVATE -#include +__BEGIN_DECLS -#define thread_call_enter_delayed(a, b) \ - thread_call_enter_delayed((a), __OSAbsoluteTime(b)) +/* + * These routines are equivalent to their thread_call_enter_XXX + * variants, only the thread_call_t is allocated out of a + * fixed preallocated pool of memory, and will panic if the pool + * is exhausted. + */ -#define thread_call_enter1_delayed(a, b, c) \ - thread_call_enter1_delayed((a), (b), __OSAbsoluteTime(c)) +extern void thread_call_func_delayed( + thread_call_func_t func, + thread_call_param_t param, + uint64_t deadline); -#define thread_call_is_delayed(a, b) \ - thread_call_is_delayed((a), __OSAbsoluteTimePtr(b)) +extern void thread_call_func_delayed_with_leeway( + thread_call_func_t func, + thread_call_param_t param, + uint64_t deadline, + uint64_t leeway, + uint32_t flags); -#define thread_call_func_delayed(a, b, c) \ - thread_call_func_delayed((a), (b), __OSAbsoluteTime(c)) +extern boolean_t thread_call_func_cancel( + thread_call_func_t func, + thread_call_param_t param, + boolean_t cancel_all); +__END_DECLS -#endif +#endif /* XNU_KERNEL_PRIVATE */ -#endif /* _KERN_THREAD_CALL_H_ */ +#endif /* _KERN_THREAD_CALL_H_ */