mirror of
https://github.com/darlinghq/darling-newlkm.git
synced 2024-11-26 21:40:43 +00:00
Add Back dthread
Folder
This commit is contained in:
parent
ee2b311299
commit
de165b2874
4
dthread/README.md
Normal file
4
dthread/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# dthread
|
||||
This directory is home to Darling's port of Apple's pthread kext. The original source is from libpthread-416.60.2
|
||||
|
||||
The goal here is to have Apple's pthread code work with our LKM with as few modifications as possible.
|
1
dthread/include/kern/kern_internal.h
Symbolic link
1
dthread/include/kern/kern_internal.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../kern_internal.h
|
1
dthread/include/kern/kern_trace.h
Symbolic link
1
dthread/include/kern/kern_trace.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../kern_trace.h
|
1
dthread/include/kern/synch_internal.h
Symbolic link
1
dthread/include/kern/synch_internal.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../synch_internal.h
|
1
dthread/include/kern/workqueue_internal.h
Symbolic link
1
dthread/include/kern/workqueue_internal.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../workqueue_internal.h
|
225
dthread/include/private/qos_private.h
Normal file
225
dthread/include/private/qos_private.h
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_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. 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_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef _QOS_PRIVATE_H
|
||||
#define _QOS_PRIVATE_H
|
||||
|
||||
#include <pthread/qos.h>
|
||||
#include <pthread/priority_private.h>
|
||||
#include <sys/qos.h> /* qos_class_t */
|
||||
#include <sys/qos_private.h>
|
||||
|
||||
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
|
||||
// allow __DARWIN_C_LEVEL to turn off the use of mach_port_t
|
||||
#include <mach/port.h>
|
||||
#endif
|
||||
|
||||
// redeffed here to avoid leaving __QOS_ENUM defined in the public header
|
||||
#define __QOS_ENUM(name, type, ...) enum { __VA_ARGS__ }; typedef type name##_t
|
||||
#define __QOS_AVAILABLE_10_10
|
||||
#define __QOS_AVAILABLE_10_11
|
||||
#define __QOS_AVAILABLE_10_12
|
||||
#ifdef __DARLING__
|
||||
// i'm pretty sure Apple should be defining this too
|
||||
#define __QOS_AVAILABLE_10_15_1
|
||||
#endif
|
||||
|
||||
#if defined(__has_feature) && defined(__has_extension)
|
||||
#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
|
||||
#undef __QOS_ENUM
|
||||
#define __QOS_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t
|
||||
#endif
|
||||
#if __has_feature(enumerator_attributes)
|
||||
#undef __QOS_AVAILABLE_10_10
|
||||
#define __QOS_AVAILABLE_10_10 __API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
#undef __QOS_AVAILABLE_10_11
|
||||
#define __QOS_AVAILABLE_10_11 __API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0), watchos(2.0))
|
||||
#undef __QOS_AVAILABLE_10_12
|
||||
#define __QOS_AVAILABLE_10_12 __API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
#undef __QOS_AVAILABLE_10_15_1
|
||||
#define __QOS_AVAILABLE_10_15_1 __API_AVAILABLE(macos(10.15.1), ios(13.2), tvos(13.2), watchos(6.2))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This enum matches workq_set_self_flags in
|
||||
// xnu's workqueue_internal.h.
|
||||
__QOS_ENUM(_pthread_set_flags, unsigned int,
|
||||
_PTHREAD_SET_SELF_QOS_FLAG __QOS_AVAILABLE_10_10 = 0x1,
|
||||
_PTHREAD_SET_SELF_VOUCHER_FLAG __QOS_AVAILABLE_10_10 = 0x2,
|
||||
_PTHREAD_SET_SELF_FIXEDPRIORITY_FLAG __QOS_AVAILABLE_10_11 = 0x4,
|
||||
_PTHREAD_SET_SELF_TIMESHARE_FLAG __QOS_AVAILABLE_10_11 = 0x8,
|
||||
_PTHREAD_SET_SELF_WQ_KEVENT_UNBIND __QOS_AVAILABLE_10_12 = 0x10,
|
||||
_PTHREAD_SET_SELF_ALTERNATE_AMX __QOS_AVAILABLE_10_15_1 = 0x20,
|
||||
);
|
||||
|
||||
#undef __QOS_ENUM
|
||||
#undef __QOS_AVAILABLE_10_10
|
||||
#undef __QOS_AVAILABLE_10_11
|
||||
#undef __QOS_AVAILABLE_10_12
|
||||
|
||||
#ifndef KERNEL
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function pthread_set_qos_class_np
|
||||
*
|
||||
* @abstract
|
||||
* Sets the requested QOS class and relative priority of the current thread.
|
||||
*
|
||||
* @discussion
|
||||
* The QOS class and relative priority represent an overall combination of
|
||||
* system quality of service attributes on a thread.
|
||||
*
|
||||
* Subsequent calls to interfaces such as pthread_setschedparam() that are
|
||||
* incompatible or in conflict with the QOS class system will unset the QOS
|
||||
* class requested with this interface and pthread_get_qos_class_np() will
|
||||
* return QOS_CLASS_UNSPECIFIED thereafter. A thread so modified is permanently
|
||||
* opted-out of the QOS class system and calls to this function to request a QOS
|
||||
* class for such a thread will fail and return EPERM.
|
||||
*
|
||||
* @param __pthread
|
||||
* The current thread as returned by pthread_self().
|
||||
* EINVAL will be returned if any other thread is provided.
|
||||
*
|
||||
* @param __qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* - QOS_CLASS_MAINTENANCE
|
||||
* EINVAL will be returned if any other value is provided.
|
||||
*
|
||||
* @param __relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative offset
|
||||
* from the maximum supported scheduler priority for the given class.
|
||||
* EINVAL will be returned if the value is greater than zero or less than
|
||||
* QOS_MIN_RELATIVE_PRIORITY.
|
||||
*
|
||||
* @return
|
||||
* Zero if successful, othwerise an errno value.
|
||||
*/
|
||||
__API_DEPRECATED_WITH_REPLACEMENT("pthread_set_qos_class_self_np", macos(10.10, 10.10), ios(8.0, 8.0))
|
||||
int
|
||||
pthread_set_qos_class_np(pthread_t __pthread,
|
||||
qos_class_t __qos_class,
|
||||
int __relative_priority);
|
||||
|
||||
/* Private interfaces for libdispatch to encode/decode specific values of pthread_priority_t. */
|
||||
|
||||
// Encode a class+priority pair into a pthread_priority_t,
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
pthread_priority_t
|
||||
_pthread_qos_class_encode(qos_class_t qos_class, int relative_priority, unsigned long flags);
|
||||
|
||||
// Decode a pthread_priority_t into a class+priority pair.
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
qos_class_t
|
||||
_pthread_qos_class_decode(pthread_priority_t priority, int *relative_priority, unsigned long *flags);
|
||||
|
||||
// Encode a legacy workqueue API priority into a pthread_priority_t. This API
|
||||
// is deprecated and can be removed when the simulator no longer uses it.
|
||||
__API_DEPRECATED("no longer used", macos(10.10, 10.13), ios(8.0, 11.0))
|
||||
pthread_priority_t
|
||||
_pthread_qos_class_encode_workqueue(int queue_priority, unsigned long flags);
|
||||
|
||||
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
|
||||
|
||||
// Set QoS or voucher, or both, on pthread_self()
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
_pthread_set_properties_self(_pthread_set_flags_t flags, pthread_priority_t priority, mach_port_t voucher);
|
||||
|
||||
// Set self to fixed priority without disturbing QoS or priority
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
pthread_set_fixedpriority_self(void);
|
||||
|
||||
// Inverse of pthread_set_fixedpriority_self()
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
pthread_set_timeshare_self(void);
|
||||
|
||||
// Set self to avoid running on the same AMX as
|
||||
// other work in this group.
|
||||
// Only allowed on non-workqueue pthreads
|
||||
__API_AVAILABLE(macos(10.15.1), ios(13.2), tvos(13.2), watchos(6.2))
|
||||
int
|
||||
pthread_prefer_alternate_amx_self(void);
|
||||
|
||||
/*!
|
||||
* @const PTHREAD_MAX_PARALLELISM_PHYSICAL
|
||||
* Flag that can be used with pthread_qos_max_parallelism() and
|
||||
* pthread_time_constraint_max_parallelism() to ask for a count of physical
|
||||
* compute units available for parallelism (default is logical).
|
||||
*/
|
||||
#define PTHREAD_MAX_PARALLELISM_PHYSICAL 0x1
|
||||
|
||||
/*!
|
||||
* @function pthread_qos_max_parallelism
|
||||
*
|
||||
* @abstract
|
||||
* Returns the number of compute units available for parallel computation at
|
||||
* a specified QoS class.
|
||||
*
|
||||
* @param qos
|
||||
* The specified QoS class.
|
||||
*
|
||||
* @param flags
|
||||
* 0 or PTHREAD_MAX_PARALLELISM_PHYSICAL.
|
||||
*
|
||||
* @return
|
||||
* The number of compute units available for parallel computation for the
|
||||
* specified QoS, or -1 on failure (with errno set accordingly).
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
int
|
||||
pthread_qos_max_parallelism(qos_class_t qos, unsigned long flags);
|
||||
|
||||
/*!
|
||||
* @function pthread_time_constraint_max_parallelism()
|
||||
*
|
||||
* @abstract
|
||||
* Returns the number of compute units available for parallel computation on
|
||||
* realtime threads.
|
||||
*
|
||||
* @param flags
|
||||
* 0 or PTHREAD_MAX_PARALLELISM_PHYSICAL.
|
||||
*
|
||||
* @return
|
||||
* The number of compute units available for parallel computation on realtime
|
||||
* threads, or -1 on failure (with errno set accordingly).
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
int
|
||||
pthread_time_constraint_max_parallelism(unsigned long flags);
|
||||
|
||||
#endif // __DARWIN_C_LEVEL >= __DARWIN_C_FULL
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // KERNEL
|
||||
|
||||
#endif //_QOS_PRIVATE_H
|
304
dthread/include/pthread/qos.h
Normal file
304
dthread/include/pthread/qos.h
Normal file
@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_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. 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_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef _PTHREAD_QOS_H
|
||||
#define _PTHREAD_QOS_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_pthread/_pthread_attr_t.h> /* pthread_attr_t */
|
||||
#include <sys/_pthread/_pthread_t.h> /* pthread_t */
|
||||
#include <Availability.h>
|
||||
|
||||
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
|
||||
|
||||
#include <sys/qos.h>
|
||||
|
||||
#ifndef KERNEL
|
||||
|
||||
#if __has_feature(assume_nonnull)
|
||||
_Pragma("clang assume_nonnull begin")
|
||||
#endif
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function pthread_attr_set_qos_class_np
|
||||
*
|
||||
* @abstract
|
||||
* Sets the QOS class and relative priority of a pthread attribute structure
|
||||
* which may be used to specify the requested QOS class of newly created
|
||||
* threads.
|
||||
*
|
||||
* @discussion
|
||||
* The QOS class and relative priority represent an overall combination of
|
||||
* system quality of service attributes on a thread.
|
||||
*
|
||||
* Subsequent calls to interfaces such as pthread_attr_setschedparam() that are
|
||||
* incompatible or in conflict with the QOS class system will unset the QOS
|
||||
* class requested with this interface and pthread_attr_get_qos_class_np() will
|
||||
* return QOS_CLASS_UNSPECIFIED.
|
||||
*
|
||||
* @param __attr
|
||||
* The pthread attribute structure to modify.
|
||||
*
|
||||
* @param __qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* EINVAL will be returned if any other value is provided.
|
||||
*
|
||||
* @param __relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative offset
|
||||
* from the maximum supported scheduler priority for the given class.
|
||||
* EINVAL will be returned if the value is greater than zero or less than
|
||||
* QOS_MIN_RELATIVE_PRIORITY.
|
||||
*
|
||||
* @return
|
||||
* Zero if successful, otherwise an errno value.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
pthread_attr_set_qos_class_np(pthread_attr_t *__attr,
|
||||
qos_class_t __qos_class, int __relative_priority);
|
||||
|
||||
/*!
|
||||
* @function pthread_attr_get_qos_class_np
|
||||
*
|
||||
* @abstract
|
||||
* Gets the QOS class and relative priority of a pthread attribute structure.
|
||||
*
|
||||
* @param __attr
|
||||
* The pthread attribute structure to inspect.
|
||||
*
|
||||
* @param __qos_class
|
||||
* On output, a QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* - QOS_CLASS_UNSPECIFIED
|
||||
* This value may be NULL in which case no value is returned.
|
||||
*
|
||||
* @param __relative_priority
|
||||
* On output, a relative priority offset within the QOS class.
|
||||
* This value may be NULL in which case no value is returned.
|
||||
*
|
||||
* @return
|
||||
* Zero if successful, otherwise an errno value.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
pthread_attr_get_qos_class_np(pthread_attr_t * __restrict __attr,
|
||||
qos_class_t * _Nullable __restrict __qos_class,
|
||||
int * _Nullable __restrict __relative_priority);
|
||||
|
||||
/*!
|
||||
* @function pthread_set_qos_class_self_np
|
||||
*
|
||||
* @abstract
|
||||
* Sets the requested QOS class and relative priority of the current thread.
|
||||
*
|
||||
* @discussion
|
||||
* The QOS class and relative priority represent an overall combination of
|
||||
* system quality of service attributes on a thread.
|
||||
*
|
||||
* Subsequent calls to interfaces such as pthread_setschedparam() that are
|
||||
* incompatible or in conflict with the QOS class system will unset the QOS
|
||||
* class requested with this interface and pthread_get_qos_class_np() will
|
||||
* return QOS_CLASS_UNSPECIFIED thereafter. A thread so modified is permanently
|
||||
* opted-out of the QOS class system and calls to this function to request a QOS
|
||||
* class for such a thread will fail and return EPERM.
|
||||
*
|
||||
* @param __qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* EINVAL will be returned if any other value is provided.
|
||||
*
|
||||
* @param __relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative offset
|
||||
* from the maximum supported scheduler priority for the given class.
|
||||
* EINVAL will be returned if the value is greater than zero or less than
|
||||
* QOS_MIN_RELATIVE_PRIORITY.
|
||||
*
|
||||
* @return
|
||||
* Zero if successful, otherwise an errno value.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
pthread_set_qos_class_self_np(qos_class_t __qos_class,
|
||||
int __relative_priority);
|
||||
|
||||
/*!
|
||||
* @function pthread_get_qos_class_np
|
||||
*
|
||||
* @abstract
|
||||
* Gets the requested QOS class and relative priority of a thread.
|
||||
*
|
||||
* @param __pthread
|
||||
* The target thread to inspect.
|
||||
*
|
||||
* @param __qos_class
|
||||
* On output, a QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* - QOS_CLASS_UNSPECIFIED
|
||||
* This value may be NULL in which case no value is returned.
|
||||
*
|
||||
* @param __relative_priority
|
||||
* On output, a relative priority offset within the QOS class.
|
||||
* This value may be NULL in which case no value is returned.
|
||||
*
|
||||
* @return
|
||||
* Zero if successful, otherwise an errno value.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
pthread_get_qos_class_np(pthread_t __pthread,
|
||||
qos_class_t * _Nullable __restrict __qos_class,
|
||||
int * _Nullable __restrict __relative_priority);
|
||||
|
||||
/*!
|
||||
* @typedef pthread_override_t
|
||||
*
|
||||
* @abstract
|
||||
* An opaque object representing a QOS class override of a thread.
|
||||
*
|
||||
* @discussion
|
||||
* A QOS class override of a target thread expresses that an item of pending
|
||||
* work classified with a specific QOS class and relative priority depends on
|
||||
* the completion of the work currently being executed by the thread (e.g. due
|
||||
* to ordering requirements).
|
||||
*
|
||||
* While overrides are in effect, the target thread will execute at the maximum
|
||||
* QOS class and relative priority of all overrides and of the QOS class
|
||||
* requested by the thread itself.
|
||||
*
|
||||
* A QOS class override does not modify the target thread's requested QOS class
|
||||
* value and the effect of an override is not visible to the qos_class_self()
|
||||
* and pthread_get_qos_class_np() interfaces.
|
||||
*/
|
||||
|
||||
typedef struct pthread_override_s* pthread_override_t;
|
||||
|
||||
/*!
|
||||
* @function pthread_override_qos_class_start_np
|
||||
*
|
||||
* @abstract
|
||||
* Starts a QOS class override of the specified target thread.
|
||||
*
|
||||
* @discussion
|
||||
* Starting a QOS class override of the specified target thread expresses that
|
||||
* an item of pending work classified with the specified QOS class and relative
|
||||
* priority depends on the completion of the work currently being executed by
|
||||
* the thread (e.g. due to ordering requirements).
|
||||
*
|
||||
* While overrides are in effect, the specified target thread will execute at
|
||||
* the maximum QOS class and relative priority of all overrides and of the QOS
|
||||
* class requested by the thread itself.
|
||||
*
|
||||
* Starting a QOS class override does not modify the target thread's requested
|
||||
* QOS class value and the effect of an override is not visible to the
|
||||
* qos_class_self() and pthread_get_qos_class_np() interfaces.
|
||||
*
|
||||
* The returned newly allocated override object is intended to be associated
|
||||
* with the item of pending work in question. Once the dependency has been
|
||||
* satisfied and enabled that work to begin executing, the QOS class override
|
||||
* must be ended by passing the associated override object to
|
||||
* pthread_override_qos_class_end_np(). Failure to do so will result in the
|
||||
* associated resources to be leaked and the target thread to be permanently
|
||||
* executed at an inappropriately elevated QOS class.
|
||||
*
|
||||
* @param __pthread
|
||||
* The target thread to modify.
|
||||
*
|
||||
* @param __qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* NULL will be returned if any other value is provided.
|
||||
*
|
||||
* @param __relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative offset
|
||||
* from the maximum supported scheduler priority for the given class.
|
||||
* NULL will be returned if the value is greater than zero or less than
|
||||
* QOS_MIN_RELATIVE_PRIORITY.
|
||||
*
|
||||
* @return
|
||||
* A newly allocated override object if successful, or NULL if the override
|
||||
* could not be started.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
pthread_override_t
|
||||
pthread_override_qos_class_start_np(pthread_t __pthread,
|
||||
qos_class_t __qos_class, int __relative_priority);
|
||||
|
||||
/*!
|
||||
* @function pthread_override_qos_class_end_np
|
||||
*
|
||||
* @abstract
|
||||
* Ends a QOS class override.
|
||||
*
|
||||
* @discussion
|
||||
* Passing an override object returned by pthread_override_qos_class_start_np()
|
||||
* ends the QOS class override started by that call and deallocates all
|
||||
* associated resources as well as the override object itself.
|
||||
*
|
||||
* The thread starting and the thread ending a QOS class override need not be
|
||||
* identical. If the thread ending the override is the the target thread of the
|
||||
* override itself, it should take care to elevate its requested QOS class
|
||||
* appropriately with pthread_set_qos_class_self_np() before ending the
|
||||
* override.
|
||||
*
|
||||
* @param __override
|
||||
* An override object returned by pthread_override_qos_class_start_np().
|
||||
*
|
||||
* @return
|
||||
* Zero if successful, otherwise an errno value.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
int
|
||||
pthread_override_qos_class_end_np(pthread_override_t __override);
|
||||
|
||||
__END_DECLS
|
||||
#if __has_feature(assume_nonnull)
|
||||
_Pragma("clang assume_nonnull end")
|
||||
#endif
|
||||
|
||||
#endif // KERNEL
|
||||
|
||||
#endif // __DARWIN_C_LEVEL >= __DARWIN_C_FULL
|
||||
|
||||
#endif // _PTHREAD_QOS_H
|
32
dthread/include/sys/_pthread/_pthread_attr_t.h
Normal file
32
dthread/include/sys/_pthread/_pthread_attr_t.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2012 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@
|
||||
*/
|
||||
#ifndef _PTHREAD_ATTR_T
|
||||
#define _PTHREAD_ATTR_T
|
||||
#include <sys/_pthread/_pthread_types.h> /* __darwin_pthread_attr_t */
|
||||
typedef __darwin_pthread_attr_t pthread_attr_t;
|
||||
#endif /* _PTHREAD_ATTR_T */
|
32
dthread/include/sys/_pthread/_pthread_t.h
Normal file
32
dthread/include/sys/_pthread/_pthread_t.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2012 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@
|
||||
*/
|
||||
#ifndef _PTHREAD_T
|
||||
#define _PTHREAD_T
|
||||
#include <sys/_pthread/_pthread_types.h> /* __darwin_pthread_t */
|
||||
typedef __darwin_pthread_t pthread_t;
|
||||
#endif /* _PTHREAD_T */
|
120
dthread/include/sys/_pthread/_pthread_types.h
Normal file
120
dthread/include/sys/_pthread/_pthread_types.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2013 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@
|
||||
*/
|
||||
|
||||
#ifndef _SYS__PTHREAD_TYPES_H_
|
||||
#define _SYS__PTHREAD_TYPES_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
// pthread opaque structures
|
||||
#if defined(__LP64__)
|
||||
#define __PTHREAD_SIZE__ 8176
|
||||
#define __PTHREAD_ATTR_SIZE__ 56
|
||||
#define __PTHREAD_MUTEXATTR_SIZE__ 8
|
||||
#define __PTHREAD_MUTEX_SIZE__ 56
|
||||
#define __PTHREAD_CONDATTR_SIZE__ 8
|
||||
#define __PTHREAD_COND_SIZE__ 40
|
||||
#define __PTHREAD_ONCE_SIZE__ 8
|
||||
#define __PTHREAD_RWLOCK_SIZE__ 192
|
||||
#define __PTHREAD_RWLOCKATTR_SIZE__ 16
|
||||
#else // !__LP64__
|
||||
#define __PTHREAD_SIZE__ 4088
|
||||
#define __PTHREAD_ATTR_SIZE__ 36
|
||||
#define __PTHREAD_MUTEXATTR_SIZE__ 8
|
||||
#define __PTHREAD_MUTEX_SIZE__ 40
|
||||
#define __PTHREAD_CONDATTR_SIZE__ 4
|
||||
#define __PTHREAD_COND_SIZE__ 24
|
||||
#define __PTHREAD_ONCE_SIZE__ 4
|
||||
#define __PTHREAD_RWLOCK_SIZE__ 124
|
||||
#define __PTHREAD_RWLOCKATTR_SIZE__ 12
|
||||
#endif // !__LP64__
|
||||
|
||||
struct __darwin_pthread_handler_rec {
|
||||
void (*__routine)(void *); // Routine to call
|
||||
void *__arg; // Argument to pass
|
||||
struct __darwin_pthread_handler_rec *__next;
|
||||
};
|
||||
|
||||
struct _opaque_pthread_attr_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_ATTR_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_cond_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_COND_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_condattr_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_CONDATTR_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_mutex_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_MUTEX_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_mutexattr_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_MUTEXATTR_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_once_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_ONCE_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_rwlock_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_RWLOCK_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_rwlockattr_t {
|
||||
long __sig;
|
||||
char __opaque[__PTHREAD_RWLOCKATTR_SIZE__];
|
||||
};
|
||||
|
||||
struct _opaque_pthread_t {
|
||||
long __sig;
|
||||
struct __darwin_pthread_handler_rec *__cleanup_stack;
|
||||
char __opaque[__PTHREAD_SIZE__];
|
||||
};
|
||||
|
||||
typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t;
|
||||
typedef struct _opaque_pthread_cond_t __darwin_pthread_cond_t;
|
||||
typedef struct _opaque_pthread_condattr_t __darwin_pthread_condattr_t;
|
||||
typedef unsigned long __darwin_pthread_key_t;
|
||||
typedef struct _opaque_pthread_mutex_t __darwin_pthread_mutex_t;
|
||||
typedef struct _opaque_pthread_mutexattr_t __darwin_pthread_mutexattr_t;
|
||||
typedef struct _opaque_pthread_once_t __darwin_pthread_once_t;
|
||||
typedef struct _opaque_pthread_rwlock_t __darwin_pthread_rwlock_t;
|
||||
typedef struct _opaque_pthread_rwlockattr_t __darwin_pthread_rwlockattr_t;
|
||||
typedef struct _opaque_pthread_t *__darwin_pthread_t;
|
||||
|
||||
#endif // _SYS__PTHREAD_TYPES_H_
|
200
dthread/include/sys/qos.h
Normal file
200
dthread/include/sys/qos.h
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_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. 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_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QOS_H
|
||||
#define _SYS_QOS_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <Availability.h>
|
||||
|
||||
/*!
|
||||
* @typedef qos_class_t
|
||||
*
|
||||
* @abstract
|
||||
* An abstract thread quality of service (QOS) classification.
|
||||
*
|
||||
* @discussion
|
||||
* Thread quality of service (QOS) classes are ordered abstract representations
|
||||
* of the nature of work that is expected to be performed by a pthread, dispatch
|
||||
* queue, or NSOperation. Each class specifies a maximum thread scheduling
|
||||
* priority for that band (which may be used in combination with a relative
|
||||
* priority offset within the band), as well as quality of service
|
||||
* characteristics for timer latency, CPU throughput, I/O throughput, network
|
||||
* socket traffic management behavior and more.
|
||||
*
|
||||
* A best effort is made to allocate available system resources to every QOS
|
||||
* class. Quality of service degredation only occurs during system resource
|
||||
* contention, proportionally to the QOS class. That said, QOS classes
|
||||
* representing user-initiated work attempt to achieve peak throughput while
|
||||
* QOS classes for other work attempt to achieve peak energy and thermal
|
||||
* efficiency, even in the absence of contention. Finally, the use of QOS
|
||||
* classes does not allow threads to supersede any limits that may be applied
|
||||
* to the overall process.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @constant QOS_CLASS_USER_INTERACTIVE
|
||||
* @abstract A QOS class which indicates work performed by this thread
|
||||
* is interactive with the user.
|
||||
* @discussion Such work is requested to run at high priority relative to other
|
||||
* work on the system. Specifying this QOS class is a request to run with
|
||||
* nearly all available system CPU and I/O bandwidth even under contention.
|
||||
* This is not an energy-efficient QOS class to use for large tasks. The use of
|
||||
* this QOS class should be limited to critical interaction with the user such
|
||||
* as handling events on the main event loop, view drawing, animation, etc.
|
||||
*
|
||||
* @constant QOS_CLASS_USER_INITIATED
|
||||
* @abstract A QOS class which indicates work performed by this thread
|
||||
* was initiated by the user and that the user is likely waiting for the
|
||||
* results.
|
||||
* @discussion Such work is requested to run at a priority below critical user-
|
||||
* interactive work, but relatively higher than other work on the system. This
|
||||
* is not an energy-efficient QOS class to use for large tasks. Its use
|
||||
* should be limited to operations of short enough duration that the user is
|
||||
* unlikely to switch tasks while waiting for the results. Typical
|
||||
* user-initiated work will have progress indicated by the display of
|
||||
* placeholder content or modal user interface.
|
||||
*
|
||||
* @constant QOS_CLASS_DEFAULT
|
||||
* @abstract A default QOS class used by the system in cases where more specific
|
||||
* QOS class information is not available.
|
||||
* @discussion Such work is requested to run at a priority below critical user-
|
||||
* interactive and user-initiated work, but relatively higher than utility and
|
||||
* background tasks. Threads created by pthread_create() without an attribute
|
||||
* specifying a QOS class will default to QOS_CLASS_DEFAULT. This QOS class
|
||||
* value is not intended to be used as a work classification, it should only be
|
||||
* set when propagating or restoring QOS class values provided by the system.
|
||||
*
|
||||
* @constant QOS_CLASS_UTILITY
|
||||
* @abstract A QOS class which indicates work performed by this thread
|
||||
* may or may not be initiated by the user and that the user is unlikely to be
|
||||
* immediately waiting for the results.
|
||||
* @discussion Such work is requested to run at a priority below critical user-
|
||||
* interactive and user-initiated work, but relatively higher than low-level
|
||||
* system maintenance tasks. The use of this QOS class indicates the work
|
||||
* should be run in an energy and thermally-efficient manner. The progress of
|
||||
* utility work may or may not be indicated to the user, but the effect of such
|
||||
* work is user-visible.
|
||||
*
|
||||
* @constant QOS_CLASS_BACKGROUND
|
||||
* @abstract A QOS class which indicates work performed by this thread was not
|
||||
* initiated by the user and that the user may be unaware of the results.
|
||||
* @discussion Such work is requested to run at a priority below other work.
|
||||
* The use of this QOS class indicates the work should be run in the most energy
|
||||
* and thermally-efficient manner.
|
||||
*
|
||||
* @constant QOS_CLASS_UNSPECIFIED
|
||||
* @abstract A QOS class value which indicates the absence or removal of QOS
|
||||
* class information.
|
||||
* @discussion As an API return value, may indicate that threads or pthread
|
||||
* attributes were configured with legacy API incompatible or in conflict with
|
||||
* the QOS class system.
|
||||
*/
|
||||
|
||||
#define __QOS_ENUM(name, type, ...) enum { __VA_ARGS__ }; typedef type name##_t
|
||||
#define __QOS_CLASS_AVAILABLE(...)
|
||||
|
||||
#if defined(__cplusplus) || defined(__OBJC__) || __LP64__
|
||||
#if defined(__has_feature) && defined(__has_extension)
|
||||
#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
|
||||
#undef __QOS_ENUM
|
||||
#define __QOS_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t
|
||||
#endif
|
||||
#endif
|
||||
#if __has_feature(enumerator_attributes)
|
||||
#undef __QOS_CLASS_AVAILABLE
|
||||
#define __QOS_CLASS_AVAILABLE __API_AVAILABLE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__QOS_ENUM(qos_class, unsigned int,
|
||||
QOS_CLASS_USER_INTERACTIVE
|
||||
__QOS_CLASS_AVAILABLE(macos(10.10), ios(8.0)) = 0x21,
|
||||
QOS_CLASS_USER_INITIATED
|
||||
__QOS_CLASS_AVAILABLE(macos(10.10), ios(8.0)) = 0x19,
|
||||
QOS_CLASS_DEFAULT
|
||||
__QOS_CLASS_AVAILABLE(macos(10.10), ios(8.0)) = 0x15,
|
||||
QOS_CLASS_UTILITY
|
||||
__QOS_CLASS_AVAILABLE(macos(10.10), ios(8.0)) = 0x11,
|
||||
QOS_CLASS_BACKGROUND
|
||||
__QOS_CLASS_AVAILABLE(macos(10.10), ios(8.0)) = 0x09,
|
||||
QOS_CLASS_UNSPECIFIED
|
||||
__QOS_CLASS_AVAILABLE(macos(10.10), ios(8.0)) = 0x00,
|
||||
);
|
||||
|
||||
#undef __QOS_ENUM
|
||||
|
||||
/*!
|
||||
* @constant QOS_MIN_RELATIVE_PRIORITY
|
||||
* @abstract The minimum relative priority that may be specified within a
|
||||
* QOS class. These priorities are relative only within a given QOS class
|
||||
* and meaningful only for the current process.
|
||||
*/
|
||||
#define QOS_MIN_RELATIVE_PRIORITY (-15)
|
||||
|
||||
/* Userspace (only) definitions */
|
||||
|
||||
#ifndef KERNEL
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function qos_class_self
|
||||
*
|
||||
* @abstract
|
||||
* Returns the requested QOS class of the current thread.
|
||||
*
|
||||
* @return
|
||||
* One of the QOS class values in qos_class_t.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
qos_class_t
|
||||
qos_class_self(void);
|
||||
|
||||
/*!
|
||||
* @function qos_class_main
|
||||
*
|
||||
* @abstract
|
||||
* Returns the initial requested QOS class of the main thread.
|
||||
*
|
||||
* @discussion
|
||||
* The QOS class that the main thread of a process is created with depends on
|
||||
* the type of process (e.g. application or daemon) and on how it has been
|
||||
* launched.
|
||||
*
|
||||
* This function returns that initial requested QOS class value chosen by the
|
||||
* system to enable propagation of that classification to matching work not
|
||||
* executing on the main thread.
|
||||
*
|
||||
* @return
|
||||
* One of the QOS class values in qos_class_t.
|
||||
*/
|
||||
__API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
qos_class_t
|
||||
qos_class_main(void);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // KERNEL
|
||||
|
||||
#endif // _SYS_QOS_H
|
40
dthread/include/sys/qos_private.h
Normal file
40
dthread/include/sys/qos_private.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_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. 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_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef _QOS_SYS_PRIVATE_H
|
||||
#define _QOS_SYS_PRIVATE_H
|
||||
|
||||
/*!
|
||||
* @constant QOS_CLASS_MAINTENANCE
|
||||
* @abstract A QOS class which indicates work performed by this thread was not
|
||||
* initiated by the user and that the user may be unaware of the results.
|
||||
* @discussion Such work is requested to run at a priority far below other work
|
||||
* including significant I/O throttling. The use of this QOS class indicates
|
||||
* the work should be run in the most energy and thermally-efficient manner
|
||||
* possible, and may be deferred for a long time in order to preserve
|
||||
* system responsiveness for the user.
|
||||
* This is SPI for use by Spotlight and Time Machine only.
|
||||
*/
|
||||
#define QOS_CLASS_MAINTENANCE ((qos_class_t)0x05)
|
||||
|
||||
#endif //_QOS_SYS_PRIVATE_H
|
65
dthread/kern_init.c
Normal file
65
dthread/kern_init.c
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// pthread.c
|
||||
// pthread
|
||||
//
|
||||
// Created by Matt Wright on 9/13/12.
|
||||
// Copyright (c) 2012 Matt Wright. All rights reserved.
|
||||
//
|
||||
|
||||
#include <kern/thread.h>
|
||||
#include <kern/debug.h>
|
||||
#include "kern_internal.h"
|
||||
|
||||
kern_return_t pthread_start(kmod_info_t * ki, void *d);
|
||||
kern_return_t pthread_stop(kmod_info_t *ki, void *d);
|
||||
|
||||
pthread_callbacks_t pthread_kern;
|
||||
|
||||
const struct pthread_functions_s pthread_internal_functions = {
|
||||
.pthread_init = _pthread_init,
|
||||
.pth_proc_hashinit = _pth_proc_hashinit,
|
||||
.pth_proc_hashdelete = _pth_proc_hashdelete,
|
||||
.bsdthread_create = _bsdthread_create,
|
||||
.bsdthread_register = _bsdthread_register,
|
||||
.bsdthread_terminate = _bsdthread_terminate,
|
||||
.thread_selfid = _thread_selfid,
|
||||
|
||||
.psynch_mutexwait = _psynch_mutexwait,
|
||||
.psynch_mutexdrop = _psynch_mutexdrop,
|
||||
.psynch_cvbroad = _psynch_cvbroad,
|
||||
.psynch_cvsignal = _psynch_cvsignal,
|
||||
.psynch_cvwait = _psynch_cvwait,
|
||||
.psynch_cvclrprepost = _psynch_cvclrprepost,
|
||||
.psynch_rw_longrdlock = _psynch_rw_longrdlock,
|
||||
.psynch_rw_rdlock = _psynch_rw_rdlock,
|
||||
.psynch_rw_unlock = _psynch_rw_unlock,
|
||||
.psynch_rw_wrlock = _psynch_rw_wrlock,
|
||||
.psynch_rw_yieldwrlock = _psynch_rw_yieldwrlock,
|
||||
|
||||
.pthread_find_owner = _pthread_find_owner,
|
||||
.pthread_get_thread_kwq = _pthread_get_thread_kwq,
|
||||
|
||||
.workq_create_threadstack = workq_create_threadstack,
|
||||
.workq_destroy_threadstack = workq_destroy_threadstack,
|
||||
.workq_setup_thread = workq_setup_thread,
|
||||
.workq_handle_stack_events = workq_handle_stack_events,
|
||||
.workq_markfree_threadstack = workq_markfree_threadstack,
|
||||
};
|
||||
|
||||
kern_return_t pthread_start(__unused kmod_info_t * ki, __unused void *d)
|
||||
{
|
||||
pthread_kext_register((pthread_functions_t)&pthread_internal_functions, &pthread_kern);
|
||||
return KERN_SUCCESS;
|
||||
}
|
||||
|
||||
kern_return_t pthread_stop(__unused kmod_info_t *ki, __unused void *d)
|
||||
{
|
||||
return KERN_FAILURE;
|
||||
}
|
||||
|
||||
struct uthread*
|
||||
current_uthread(void)
|
||||
{
|
||||
thread_t th = current_thread();
|
||||
return pthread_kern->get_bsdthread_info(th);
|
||||
}
|
227
dthread/kern_internal.h
Normal file
227
dthread/kern_internal.h
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 Apple Computer, 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@
|
||||
*/
|
||||
|
||||
// header name modified for Darling
|
||||
#ifndef _DTHREAD_KERN_INTERNAL_H
|
||||
#define _DTHREAD_KERN_INTERNAL_H
|
||||
|
||||
#include <pthread/bsdthread_private.h>
|
||||
#include <pthread/priority_private.h>
|
||||
#include <pthread/workqueue_syscalls.h>
|
||||
|
||||
#ifdef KERNEL
|
||||
struct ksyn_waitq_element;
|
||||
#include <stdatomic.h>
|
||||
#include <kern/thread_call.h>
|
||||
#include <kern/kcdata.h>
|
||||
#ifdef __DARLING__
|
||||
#include <kern/thread.h>
|
||||
#else
|
||||
#include <sys/pthread_shims.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <sys/proc_info.h>
|
||||
|
||||
#ifdef __arm64__
|
||||
#define PTHREAD_INLINE_RMW_ATOMICS 0
|
||||
#else
|
||||
#define PTHREAD_INLINE_RMW_ATOMICS 1
|
||||
#endif
|
||||
#endif // KERNEL
|
||||
|
||||
#include "kern/synch_internal.h"
|
||||
#include "kern/workqueue_internal.h"
|
||||
#include "kern/kern_trace.h"
|
||||
#include "pthread/qos.h"
|
||||
#include "private/qos_private.h"
|
||||
|
||||
/* pthread userspace SPI feature checking, these constants are returned from bsdthread_register,
|
||||
* as a bitmask, to inform userspace of the supported feature set. Old releases of OS X return
|
||||
* from this call either zero or -1, allowing us to return a positive number for feature bits.
|
||||
*/
|
||||
#define PTHREAD_FEATURE_DISPATCHFUNC 0x01 /* same as WQOPS_QUEUE_NEWSPISUPP, checks for dispatch function support */
|
||||
#define PTHREAD_FEATURE_FINEPRIO 0x02 /* are fine grained prioirities available */
|
||||
#define PTHREAD_FEATURE_BSDTHREADCTL 0x04 /* is the bsdthread_ctl syscall available */
|
||||
#define PTHREAD_FEATURE_SETSELF 0x08 /* is the BSDTHREAD_CTL_SET_SELF command of bsdthread_ctl available */
|
||||
#define PTHREAD_FEATURE_QOS_MAINTENANCE 0x10 /* is QOS_CLASS_MAINTENANCE available */
|
||||
#define PTHREAD_FEATURE_RESERVED 0x20 /* burnt, shipped in OSX 10.11 & iOS 9 with partial kevent delivery support */
|
||||
#define PTHREAD_FEATURE_KEVENT 0x40 /* supports direct kevent delivery */
|
||||
#define PTHREAD_FEATURE_WORKLOOP 0x80 /* supports workloops */
|
||||
#define PTHREAD_FEATURE_QOS_DEFAULT 0x40000000 /* the kernel supports QOS_CLASS_DEFAULT */
|
||||
|
||||
/* userspace <-> kernel registration struct, for passing data to/from the kext during main thread init. */
|
||||
struct _pthread_registration_data {
|
||||
/*
|
||||
* version == sizeof(struct _pthread_registration_data)
|
||||
*
|
||||
* The structure can only grow, so we use its size as the version.
|
||||
* Userspace initializes this to the size of its structure and the kext
|
||||
* will copy out the version that was actually consumed.
|
||||
*
|
||||
* n.b. you must make sure the size of this structure isn't LP64-dependent
|
||||
*/
|
||||
uint64_t version;
|
||||
|
||||
uint64_t dispatch_queue_offset; /* copy-in */
|
||||
uint64_t /* pthread_priority_t */ main_qos; /* copy-out */
|
||||
uint32_t tsd_offset; /* copy-in */
|
||||
uint32_t return_to_kernel_offset; /* copy-in */
|
||||
uint32_t mach_thread_self_offset; /* copy-in */
|
||||
mach_vm_address_t stack_addr_hint; /* copy-out */
|
||||
uint32_t mutex_default_policy; /* copy-out */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* "error" flags returned by fail condvar syscalls
|
||||
*/
|
||||
#define ECVCLEARED 0x100
|
||||
#define ECVPREPOST 0x200
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
/* The set of features, from the feature bits above, that we support. */
|
||||
#define PTHREAD_FEATURE_SUPPORTED ( \
|
||||
PTHREAD_FEATURE_DISPATCHFUNC | \
|
||||
PTHREAD_FEATURE_FINEPRIO | \
|
||||
PTHREAD_FEATURE_BSDTHREADCTL | \
|
||||
PTHREAD_FEATURE_SETSELF | \
|
||||
PTHREAD_FEATURE_QOS_MAINTENANCE | \
|
||||
PTHREAD_FEATURE_QOS_DEFAULT | \
|
||||
PTHREAD_FEATURE_KEVENT | \
|
||||
PTHREAD_FEATURE_WORKLOOP )
|
||||
|
||||
#ifdef __DARLING__
|
||||
// since we had to move the `pthread_shims.h` include down, we need to declare this differently
|
||||
struct pthread_callbacks_s;
|
||||
extern const struct pthread_callbacks_s* pthread_kern;
|
||||
#else
|
||||
extern pthread_callbacks_t pthread_kern;
|
||||
#endif
|
||||
|
||||
struct ksyn_waitq_element {
|
||||
TAILQ_ENTRY(ksyn_waitq_element) kwe_list; /* link to other list members */
|
||||
void * kwe_kwqqueue; /* queue blocked on */
|
||||
thread_t kwe_thread;
|
||||
uint16_t kwe_state; /* state */
|
||||
uint16_t kwe_flags;
|
||||
uint32_t kwe_lockseq; /* the sequence of the entry */
|
||||
uint32_t kwe_count; /* upper bound on number of matches still pending */
|
||||
uint32_t kwe_psynchretval; /* thread retval */
|
||||
void *kwe_uth; /* uthread */
|
||||
};
|
||||
typedef struct ksyn_waitq_element * ksyn_waitq_element_t;
|
||||
|
||||
#define PTH_DEFAULT_STACKSIZE 512*1024
|
||||
#define MAX_PTHREAD_SIZE 64*1024
|
||||
|
||||
/* exported from the kernel but not present in any headers. */
|
||||
extern thread_t port_name_to_thread(mach_port_name_t port_name);
|
||||
|
||||
/* function declarations for pthread_kext.c */
|
||||
void pthread_init(void);
|
||||
void psynch_zoneinit(void);
|
||||
void _pth_proc_hashinit(proc_t p);
|
||||
void _pth_proc_hashdelete(proc_t p);
|
||||
void pth_global_hashinit(void);
|
||||
void psynch_wq_cleanup(void*, void*);
|
||||
|
||||
void _pthread_init(void);
|
||||
int _fill_procworkqueue(proc_t p, struct proc_workqueueinfo * pwqinfo);
|
||||
uint32_t _get_pwq_state_kdp(proc_t p);
|
||||
void _workqueue_exit(struct proc *p);
|
||||
void _workqueue_mark_exiting(struct proc *p);
|
||||
void _workqueue_thread_yielded(void);
|
||||
sched_call_t _workqueue_get_sched_callback(void);
|
||||
|
||||
int _bsdthread_create(struct proc *p, user_addr_t user_func, user_addr_t user_funcarg, user_addr_t user_stack, user_addr_t user_pthread, uint32_t flags, user_addr_t *retval);
|
||||
int _bsdthread_register(struct proc *p, user_addr_t threadstart, user_addr_t wqthread, int pthsize, user_addr_t dummy_value, user_addr_t targetconc_ptr, uint64_t dispatchqueue_offset, int32_t *retval);
|
||||
int _bsdthread_terminate(struct proc *p, user_addr_t stackaddr, size_t size, uint32_t kthport, uint32_t sem, int32_t *retval);
|
||||
int _bsdthread_ctl_set_qos(struct proc *p, user_addr_t cmd, mach_port_name_t kport, user_addr_t tsd_priority_addr, user_addr_t arg3, int *retval);
|
||||
int _bsdthread_ctl_set_self(struct proc *p, user_addr_t cmd, pthread_priority_t priority, mach_port_name_t voucher, _pthread_set_flags_t flags, int *retval);
|
||||
int _bsdthread_ctl_qos_override_start(struct proc *p, user_addr_t cmd, mach_port_name_t kport, pthread_priority_t priority, user_addr_t resource, int *retval);
|
||||
int _bsdthread_ctl_qos_override_end(struct proc *p, user_addr_t cmd, mach_port_name_t kport, user_addr_t resource, user_addr_t arg3, int *retval);
|
||||
int _bsdthread_ctl_qos_override_dispatch(struct proc __unused *p, user_addr_t __unused cmd, mach_port_name_t kport, pthread_priority_t priority, user_addr_t arg3, int __unused *retval);
|
||||
int _bsdthread_ctl_qos_override_reset(struct proc __unused *p, user_addr_t __unused cmd, user_addr_t arg1, user_addr_t arg2, user_addr_t arg3, int __unused *retval);
|
||||
int _bsdthread_ctl_qos_dispatch_asynchronous_override_add(struct proc __unused *p, user_addr_t __unused cmd, mach_port_name_t kport, pthread_priority_t priority, user_addr_t resource, int __unused *retval);
|
||||
int _bsdthread_ctl_qos_dispatch_asynchronous_override_reset(struct proc __unused *p, user_addr_t __unused cmd, int reset_all, user_addr_t resource, user_addr_t arg3, int __unused *retval);
|
||||
int _bsdthread_ctl(struct proc *p, user_addr_t cmd, user_addr_t arg1, user_addr_t arg2, user_addr_t arg3, int *retval);
|
||||
int _thread_selfid(__unused struct proc *p, uint64_t *retval);
|
||||
int _workq_kernreturn(struct proc *p, int options, user_addr_t item, int arg2, int arg3, int32_t *retval);
|
||||
int _workq_open(struct proc *p, int32_t *retval);
|
||||
|
||||
int _psynch_mutexwait(proc_t p, user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags, uint32_t * retval);
|
||||
int _psynch_mutexdrop(proc_t p, user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags, uint32_t * retval);
|
||||
int _psynch_cvbroad(proc_t p, user_addr_t cv, uint64_t cvlsgen, uint64_t cvudgen, uint32_t flags, user_addr_t mutex, uint64_t mugen, uint64_t tid, uint32_t *retval);
|
||||
int _psynch_cvsignal(proc_t p, user_addr_t cv, uint64_t cvlsgen, uint32_t cvugen, int thread_port, user_addr_t mutex, uint64_t mugen, uint64_t tid, uint32_t flags, uint32_t * retval);
|
||||
int _psynch_cvwait(proc_t p, user_addr_t cv, uint64_t cvlsgen, uint32_t cvugen, user_addr_t mutex, uint64_t mugen, uint32_t flags, int64_t sec, uint32_t nsec, uint32_t * retval);
|
||||
int _psynch_cvclrprepost(proc_t p, user_addr_t cv, uint32_t cvgen, uint32_t cvugen, uint32_t cvsgen, uint32_t prepocnt, uint32_t preposeq, uint32_t flags, int *retval);
|
||||
int _psynch_rw_longrdlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t * retval);
|
||||
int _psynch_rw_rdlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval);
|
||||
int _psynch_rw_unlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval);
|
||||
int _psynch_rw_wrlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval);
|
||||
int _psynch_rw_yieldwrlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval);
|
||||
|
||||
void _pthread_find_owner(thread_t thread, struct stackshot_thread_waitinfo *waitinfo);
|
||||
void * _pthread_get_thread_kwq(thread_t thread);
|
||||
|
||||
extern lck_grp_attr_t *pthread_lck_grp_attr;
|
||||
extern lck_grp_t *pthread_lck_grp;
|
||||
extern lck_attr_t *pthread_lck_attr;
|
||||
extern lck_mtx_t *pthread_list_mlock;
|
||||
extern thread_call_t psynch_thcall;
|
||||
|
||||
struct uthread* current_uthread(void);
|
||||
|
||||
int
|
||||
workq_create_threadstack(proc_t p, vm_map_t vmap, mach_vm_offset_t *out_addr);
|
||||
|
||||
int
|
||||
workq_destroy_threadstack(proc_t p, vm_map_t vmap, mach_vm_offset_t stackaddr);
|
||||
|
||||
void
|
||||
workq_setup_thread(proc_t p, thread_t th, vm_map_t map, user_addr_t stackaddr,
|
||||
mach_port_name_t kport, int th_qos, int setup_flags, int upcall_flags);
|
||||
|
||||
int
|
||||
workq_handle_stack_events(proc_t p, thread_t th, vm_map_t map,
|
||||
user_addr_t stackaddr, mach_port_name_t kport,
|
||||
user_addr_t events, int nevents, int upcall_flags);
|
||||
|
||||
void
|
||||
workq_markfree_threadstack(proc_t p, thread_t th, vm_map_t vmap,
|
||||
user_addr_t stackaddr);
|
||||
|
||||
#ifdef __DARLING__
|
||||
// move it down here because it needs `struct ksyn_waitq_element` to be defined
|
||||
#include <sys/pthread_shims.h>
|
||||
#endif
|
||||
|
||||
#endif // KERNEL
|
||||
|
||||
#endif // _DTHREAD_KERN_INTERNAL_H
|
||||
|
1020
dthread/kern_support.c
Normal file
1020
dthread/kern_support.c
Normal file
File diff suppressed because it is too large
Load Diff
2835
dthread/kern_synch.c
Normal file
2835
dthread/kern_synch.c
Normal file
File diff suppressed because it is too large
Load Diff
164
dthread/kern_trace.h
Normal file
164
dthread/kern_trace.h
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 Apple Computer, 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@
|
||||
*/
|
||||
|
||||
#ifndef _KERN_TRACE_H_
|
||||
#define _KERN_TRACE_H_
|
||||
|
||||
/* pthread kext, or userspace, kdebug trace points. Defined here and output to
|
||||
* /usr/share/misc/pthread.codes during build.
|
||||
*/
|
||||
|
||||
// userspace trace points force slow-paths, so must be compiled in
|
||||
#define ENABLE_USERSPACE_TRACE 0
|
||||
|
||||
// pthread tracing subclasses
|
||||
# define _TRACE_SUB_DEFAULT 0
|
||||
# define _TRACE_SUB_WORKQUEUE 1
|
||||
// WQ_TRACE_REQUESTS_SUBCLASS is 2, in xnu
|
||||
# define _TRACE_SUB_MUTEX 3
|
||||
# define _TRACE_SUB_CONDVAR 4
|
||||
|
||||
#ifndef _PTHREAD_BUILDING_CODES_
|
||||
|
||||
#include <sys/kdebug.h>
|
||||
|
||||
#ifndef DBG_PTHREAD
|
||||
#define DBG_PTHREAD DBG_WORKQUEUE
|
||||
#endif
|
||||
|
||||
#if KERNEL
|
||||
#include <vm/vm_kern.h>
|
||||
|
||||
extern uint32_t pthread_debug_tracing;
|
||||
|
||||
static __unused void*
|
||||
VM_UNSLIDE(void* ptr)
|
||||
{
|
||||
vm_offset_t unslid_ptr;
|
||||
vm_kernel_unslide_or_perm_external(ptr, &unslid_ptr);
|
||||
return (void*)unslid_ptr;
|
||||
}
|
||||
|
||||
# define PTHREAD_TRACE(x,a,b,c,d) \
|
||||
{ if (pthread_debug_tracing) { KERNEL_DEBUG_CONSTANT(TRACE_##x, a, b, c, d, 0); } }
|
||||
|
||||
# define PTHREAD_TRACE_WQ(x,a,b,c,d) \
|
||||
{ if (pthread_debug_tracing) { KERNEL_DEBUG_CONSTANT(TRACE_##x, VM_UNSLIDE(a), b, c, d, 0); } }
|
||||
|
||||
# define PTHREAD_TRACE_WQ_REQ(x,a,b,c,d,e) \
|
||||
{ if (pthread_debug_tracing) { KERNEL_DEBUG_CONSTANT(TRACE_##x, VM_UNSLIDE(a), VM_UNSLIDE(b), c, d, e); } }
|
||||
|
||||
#else // KERNEL
|
||||
|
||||
#if ENABLE_USERSPACE_TRACE
|
||||
# include <sys/kdebug.h>
|
||||
# define PTHREAD_TRACE(x, a, b, c, d) kdebug_trace(TRACE_##x, a, b, c, d)
|
||||
#else // ENABLE_USERSPACE_TRACE
|
||||
# define PTHREAD_TRACE(x, a, b, c, d) do { } while(0)
|
||||
#endif // ENABLE_USERSPACE_TRACE
|
||||
|
||||
#endif // KERNEL
|
||||
|
||||
# define TRACE_CODE(name, subclass, code) \
|
||||
static const int TRACE_##name = KDBG_CODE(DBG_PTHREAD, subclass, code)
|
||||
|
||||
#else // _PTHREAD_BUILDING_CODES_
|
||||
/* When not included as a header, this file is pre-processed into perl source to generate
|
||||
* the pthread.codes file during build.
|
||||
*/
|
||||
# define DBG_PTHREAD 9
|
||||
# define STR(x) #x
|
||||
|
||||
# define TRACE_CODE(name, subclass, code) \
|
||||
printf("0x%x\t%s\n", ((DBG_PTHREAD << 24) | ((subclass & 0xff) << 16) | ((code & 0x3fff) << 2)), STR(name))
|
||||
#endif // _PTHREAD_BUILDING_CODES_
|
||||
|
||||
/* These defines translate into TRACE_<name> when used in source code, and are
|
||||
* pre-processed out to a codes file by the build system.
|
||||
*/
|
||||
|
||||
// "default" trace points
|
||||
TRACE_CODE(pthread_thread_create, _TRACE_SUB_DEFAULT, 0x10);
|
||||
TRACE_CODE(pthread_thread_terminate, _TRACE_SUB_DEFAULT, 0x20);
|
||||
TRACE_CODE(pthread_set_qos_self, _TRACE_SUB_DEFAULT, 0x30);
|
||||
|
||||
// workqueue trace points
|
||||
TRACE_CODE(wq_pthread_exit, _TRACE_SUB_WORKQUEUE, 0x01);
|
||||
TRACE_CODE(wq_workqueue_exit, _TRACE_SUB_WORKQUEUE, 0x02);
|
||||
TRACE_CODE(wq_runthread, _TRACE_SUB_WORKQUEUE, 0x03);
|
||||
TRACE_CODE(wq_runitem, _TRACE_SUB_WORKQUEUE, 0x04);
|
||||
TRACE_CODE(wq_thread_block, _TRACE_SUB_WORKQUEUE, 0x9);
|
||||
TRACE_CODE(wq_thactive_update, _TRACE_SUB_WORKQUEUE, 0xa);
|
||||
TRACE_CODE(wq_add_timer, _TRACE_SUB_WORKQUEUE, 0xb);
|
||||
TRACE_CODE(wq_start_add_timer, _TRACE_SUB_WORKQUEUE, 0x0c);
|
||||
TRACE_CODE(wq_override_start, _TRACE_SUB_WORKQUEUE, 0x12);
|
||||
TRACE_CODE(wq_override_end, _TRACE_SUB_WORKQUEUE, 0x13);
|
||||
TRACE_CODE(wq_override_dispatch, _TRACE_SUB_WORKQUEUE, 0x14);
|
||||
TRACE_CODE(wq_override_reset, _TRACE_SUB_WORKQUEUE, 0x15);
|
||||
TRACE_CODE(wq_thread_create_failed, _TRACE_SUB_WORKQUEUE, 0x1d);
|
||||
TRACE_CODE(wq_thread_create, _TRACE_SUB_WORKQUEUE, 0x1f);
|
||||
TRACE_CODE(wq_run_threadreq, _TRACE_SUB_WORKQUEUE, 0x20);
|
||||
TRACE_CODE(wq_run_threadreq_mgr_merge, _TRACE_SUB_WORKQUEUE, 0x21);
|
||||
TRACE_CODE(wq_run_threadreq_req_select, _TRACE_SUB_WORKQUEUE, 0x22);
|
||||
TRACE_CODE(wq_run_threadreq_thread_select, _TRACE_SUB_WORKQUEUE, 0x23);
|
||||
TRACE_CODE(wq_thread_reset_priority, _TRACE_SUB_WORKQUEUE, 0x24);
|
||||
TRACE_CODE(wq_constrained_admission, _TRACE_SUB_WORKQUEUE, 0x25);
|
||||
TRACE_CODE(wq_wqops_reqthreads, _TRACE_SUB_WORKQUEUE, 0x26);
|
||||
TRACE_CODE(wq_kevent_reqthreads, _TRACE_SUB_WORKQUEUE, 0x27);
|
||||
TRACE_CODE(wq_thread_park, _TRACE_SUB_WORKQUEUE, 0x28);
|
||||
TRACE_CODE(wq_thread_squash, _TRACE_SUB_WORKQUEUE, 0x29);
|
||||
|
||||
// synch trace points
|
||||
TRACE_CODE(psynch_mutex_ulock, _TRACE_SUB_MUTEX, 0x0);
|
||||
TRACE_CODE(psynch_mutex_utrylock_failed, _TRACE_SUB_MUTEX, 0x1);
|
||||
TRACE_CODE(psynch_mutex_uunlock, _TRACE_SUB_MUTEX, 0x2);
|
||||
TRACE_CODE(psynch_ksyn_incorrect_owner, _TRACE_SUB_MUTEX, 0x3);
|
||||
TRACE_CODE(psynch_mutex_lock_updatebits, _TRACE_SUB_MUTEX, 0x4);
|
||||
TRACE_CODE(psynch_mutex_unlock_updatebits, _TRACE_SUB_MUTEX, 0x5);
|
||||
TRACE_CODE(psynch_mutex_clearprepost, _TRACE_SUB_MUTEX, 0x6);
|
||||
TRACE_CODE(psynch_mutex_kwqallocate, _TRACE_SUB_MUTEX, 0x7);
|
||||
TRACE_CODE(psynch_mutex_kwqdeallocate, _TRACE_SUB_MUTEX, 0x8);
|
||||
TRACE_CODE(psynch_mutex_kwqprepost, _TRACE_SUB_MUTEX, 0x9);
|
||||
TRACE_CODE(psynch_mutex_markprepost, _TRACE_SUB_MUTEX, 0x10);
|
||||
TRACE_CODE(psynch_mutex_kwqcollision, _TRACE_SUB_MUTEX, 0x11);
|
||||
TRACE_CODE(psynch_ffmutex_lock_updatebits, _TRACE_SUB_MUTEX, 0x12);
|
||||
TRACE_CODE(psynch_ffmutex_unlock_updatebits, _TRACE_SUB_MUTEX, 0x13);
|
||||
TRACE_CODE(psynch_ffmutex_wake, _TRACE_SUB_MUTEX, 0x14);
|
||||
TRACE_CODE(psynch_mutex_kwqsignal, _TRACE_SUB_MUTEX, 0x15);
|
||||
TRACE_CODE(psynch_ffmutex_wait, _TRACE_SUB_MUTEX, 0x16);
|
||||
TRACE_CODE(psynch_mutex_kwqwait, _TRACE_SUB_MUTEX, 0x17);
|
||||
|
||||
TRACE_CODE(psynch_cvar_kwait, _TRACE_SUB_CONDVAR, 0x0);
|
||||
TRACE_CODE(psynch_cvar_clrprepost, _TRACE_SUB_CONDVAR, 0x1);
|
||||
TRACE_CODE(psynch_cvar_freeitems, _TRACE_SUB_CONDVAR, 0x2);
|
||||
TRACE_CODE(psynch_cvar_signal, _TRACE_SUB_CONDVAR, 0x3);
|
||||
TRACE_CODE(psynch_cvar_broadcast, _TRACE_SUB_CONDVAR, 0x5);
|
||||
TRACE_CODE(psynch_cvar_zeroed, _TRACE_SUB_CONDVAR, 0x6);
|
||||
TRACE_CODE(psynch_cvar_updateval, _TRACE_SUB_CONDVAR, 0x7);
|
||||
|
||||
#endif // _KERN_TRACE_H_
|
201
dthread/pthread_kext.c
Normal file
201
dthread/pthread_kext.c
Normal file
@ -0,0 +1,201 @@
|
||||
/**
|
||||
* a brief rationale on why we need this
|
||||
* ---
|
||||
*
|
||||
* so, sometime around the release of macOS 10.9 (with xnu-2422.1.72),
|
||||
* Apple decided to stuff pthread support in-kernel into a kext (pthread.kext)
|
||||
*
|
||||
* we already have most of the functions implemented in `psync_support.c`, this file just takes care of the rest
|
||||
* and the necessary plumbing for XNU's `pthread_shims.c` so that we can use XNU's own interface as much as possible
|
||||
*
|
||||
* ignore the following; i've actually decided against building `pthread_workqueue.c`
|
||||
* (turns out its usage in `turnstile.c` only matters when workqueues are already being used for something else)
|
||||
*
|
||||
* > up until recently, we didn't really build any parts of XNU that needed it
|
||||
* >
|
||||
* > however, the new turnstile subsystem requires functions that are implemented in `pthread_workqueue.c`,
|
||||
* > and it's relatively simple to build that file by adding support for the functions it calls out to
|
||||
* > (and easy enough that it's better than stubbing them)
|
||||
*
|
||||
* so like i said, that reason is no longer valid. i decided to leave this in anyways because i had already completely
|
||||
* added it in and it works so ¯\_(ツ)_/¯
|
||||
*/
|
||||
|
||||
#include <duct/duct.h>
|
||||
|
||||
#include <duct/duct_pre_xnu.h>
|
||||
#include <kern/kern_types.h>
|
||||
#include <sys/proc.h>
|
||||
#include "kern_internal.h"
|
||||
#include <duct/duct_post_xnu.h>
|
||||
|
||||
#include "pthread_kext.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* `pthread_shims.c` plumbing
|
||||
*
|
||||
*/
|
||||
|
||||
static const struct pthread_functions_s _darling_pthread_functions = {
|
||||
.pthread_init = _pthread_init,
|
||||
|
||||
.pth_proc_hashinit = _pth_proc_hashinit,
|
||||
.pth_proc_hashdelete = _pth_proc_hashdelete,
|
||||
|
||||
.bsdthread_create = _bsdthread_create,
|
||||
.bsdthread_register = _bsdthread_register,
|
||||
.bsdthread_terminate = _bsdthread_terminate,
|
||||
|
||||
.thread_selfid = _thread_selfid,
|
||||
|
||||
.psynch_mutexwait = _psynch_mutexwait,
|
||||
.psynch_mutexdrop = _psynch_mutexdrop,
|
||||
.psynch_cvbroad = _psynch_cvbroad,
|
||||
.psynch_cvsignal = _psynch_cvsignal,
|
||||
.psynch_cvwait = _psynch_cvwait,
|
||||
.psynch_cvclrprepost = _psynch_cvclrprepost,
|
||||
.psynch_rw_longrdlock = _psynch_rw_longrdlock,
|
||||
.psynch_rw_rdlock = _psynch_rw_rdlock,
|
||||
.psynch_rw_unlock = _psynch_rw_unlock,
|
||||
.psynch_rw_wrlock = _psynch_rw_wrlock,
|
||||
.psynch_rw_yieldwrlock = _psynch_rw_yieldwrlock,
|
||||
|
||||
.pthread_find_owner = _pthread_find_owner,
|
||||
.pthread_get_thread_kwq = _pthread_get_thread_kwq,
|
||||
|
||||
.workq_create_threadstack = workq_create_threadstack,
|
||||
.workq_destroy_threadstack = workq_destroy_threadstack,
|
||||
.workq_setup_thread = workq_setup_thread,
|
||||
.workq_handle_stack_events = workq_handle_stack_events,
|
||||
.workq_markfree_threadstack = workq_markfree_threadstack,
|
||||
};
|
||||
|
||||
// called by our kernel module during initialization
|
||||
//
|
||||
// this is different from `darling_pthread_init`, because this function is the one that sets up
|
||||
// the pthread kext plumbing, while the `pthread_init` is only called by some BSD code after the kext has already been set up
|
||||
void darling_pthread_kext_init(void) {
|
||||
// we don't really need the callbacks, since we're not actually a kext and we have full access to the whole kernel,
|
||||
// but it's easier to provide the callbacks than it is to modify every instance of `pthread_kern->whatever(...)`.
|
||||
// plus, `pthread_shims.c` won't take "no" for an answer (it'll panic if we give it `NULL`).
|
||||
// we have this a local variable though, because since we *aren't* a kext, we have `pthread_kern` already defined in `pthread_shims.c`
|
||||
pthread_callbacks_t callbacks = NULL;
|
||||
|
||||
pthread_kext_register(&_darling_pthread_functions, &callbacks);
|
||||
};
|
||||
|
||||
// called by our kernel module when it's going to be unloaded
|
||||
void darling_pthread_kext_exit(void) {};
|
||||
|
||||
// temporarily copied over from kern_support.c (until we start building that file)
|
||||
// <copied from="libpthread://416.60.2/kern/kern_support.c" modified="true">
|
||||
#ifdef __DARLING__
|
||||
uint32_t pthread_debug_tracing = 0;
|
||||
#else
|
||||
uint32_t pthread_debug_tracing = 1;
|
||||
#endif
|
||||
|
||||
#ifdef __DARLING__
|
||||
static lck_grp_attr_t the_real_pthread_lck_grp_attr;
|
||||
static lck_grp_t the_real_pthread_lck_grp;
|
||||
static lck_attr_t the_real_pthread_lck_attr;
|
||||
static lck_mtx_t the_real_pthread_list_mlock;
|
||||
|
||||
lck_grp_attr_t* pthread_lck_grp_attr = &the_real_pthread_lck_grp_attr;
|
||||
lck_grp_t* pthread_lck_grp = &the_real_pthread_lck_grp;
|
||||
lck_attr_t* pthread_lck_attr = &the_real_pthread_lck_attr;
|
||||
#else
|
||||
lck_grp_attr_t *pthread_lck_grp_attr;
|
||||
lck_grp_t *pthread_lck_grp;
|
||||
lck_attr_t *pthread_lck_attr;
|
||||
#endif
|
||||
|
||||
void
|
||||
_pthread_init(void)
|
||||
{
|
||||
#ifdef __DARLING__
|
||||
lck_grp_attr_setdefault(pthread_lck_grp_attr);
|
||||
lck_grp_init(pthread_lck_grp, "pthread", pthread_lck_grp_attr);
|
||||
|
||||
lck_attr_setdefault(pthread_lck_attr);
|
||||
pthread_list_mlock = &the_real_pthread_list_mlock;
|
||||
lck_mtx_init(pthread_list_mlock, pthread_lck_grp, pthread_lck_attr);
|
||||
#else
|
||||
pthread_lck_grp_attr = lck_grp_attr_alloc_init();
|
||||
pthread_lck_grp = lck_grp_alloc_init("pthread", pthread_lck_grp_attr);
|
||||
|
||||
/*
|
||||
* allocate the lock attribute for pthread synchronizers
|
||||
*/
|
||||
pthread_lck_attr = lck_attr_alloc_init();
|
||||
pthread_list_mlock = lck_mtx_alloc_init(pthread_lck_grp, pthread_lck_attr);
|
||||
#endif
|
||||
|
||||
pth_global_hashinit();
|
||||
psynch_thcall = thread_call_allocate(psynch_wq_cleanup, NULL);
|
||||
psynch_zoneinit();
|
||||
|
||||
#ifndef __DARLING__
|
||||
int policy_bootarg;
|
||||
if (PE_parse_boot_argn("pthread_mutex_default_policy", &policy_bootarg, sizeof(policy_bootarg))) {
|
||||
pthread_mutex_default_policy = policy_bootarg;
|
||||
}
|
||||
|
||||
sysctl_register_oid(&sysctl__kern_pthread_mutex_default_policy);
|
||||
#endif
|
||||
}
|
||||
// </copied>
|
||||
|
||||
/**
|
||||
* stubbed functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* nobody really needs this next set of functions right now,
|
||||
* so we can just stub them for now
|
||||
*/
|
||||
|
||||
int _bsdthread_create(proc_t p, user_addr_t user_func, user_addr_t user_funcarg, user_addr_t user_stack, user_addr_t user_pthread, uint32_t flags, user_addr_t* retval) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
int _bsdthread_register(proc_t p, user_addr_t threadstart, user_addr_t wqthread, int pthsize, user_addr_t dummy_value, user_addr_t targetconc_ptr, uint64_t dispatchqueue_offset, int32_t* retval) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
int _bsdthread_terminate(proc_t p, user_addr_t stackaddr, size_t size, uint32_t kthport, uint32_t sem, int32_t* retval) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
int _thread_selfid(proc_t p, uint64_t* retval) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
int _bsdthread_register2(proc_t p, user_addr_t threadstart, user_addr_t wqthread, uint32_t flags, user_addr_t stack_addr_hint, user_addr_t targetconc_ptr, uint32_t dispatchqueue_offset, uint32_t tsd_offset, int32_t* retval) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
/**
|
||||
* now these are actually needed by `pthread_workqueue.c`
|
||||
*/
|
||||
|
||||
int workq_handle_stack_events(proc_t p, thread_t th, vm_map_t map, user_addr_t stackaddr, mach_port_name_t kport, user_addr_t events, int nevents, int upcall_flags) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
int workq_create_threadstack(proc_t p, vm_map_t vmap, mach_vm_offset_t* out_addr) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
int workq_destroy_threadstack(proc_t p, vm_map_t vmap, mach_vm_offset_t stackaddr) {
|
||||
return ENOTSUP;
|
||||
};
|
||||
|
||||
void workq_setup_thread(proc_t p, thread_t th, vm_map_t map, user_addr_t stackaddr, mach_port_name_t kport, int th_qos, int setup_flags, int upcall_flags) {
|
||||
|
||||
};
|
||||
|
||||
void workq_markfree_threadstack(proc_t p, thread_t th, vm_map_t map, user_addr_t stackaddr) {
|
||||
|
||||
};
|
7
dthread/pthread_kext.h
Normal file
7
dthread/pthread_kext.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _DARLING_LKM_PTHREAD_KEXT_H_
|
||||
#define _DARLING_LKM_PTHREAD_KEXT_H_
|
||||
|
||||
void darling_pthread_kext_init(void);
|
||||
void darling_pthread_kext_exit(void);
|
||||
|
||||
#endif // _DARLING_LKM_PTHREAD_KEXT_H_
|
173
dthread/synch_internal.h
Normal file
173
dthread/synch_internal.h
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_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. 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_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __SYNCH_INTERNAL_H__
|
||||
#define __SYNCH_INTERNAL_H__
|
||||
|
||||
// kwe_state
|
||||
enum {
|
||||
KWE_THREAD_INWAIT = 1,
|
||||
KWE_THREAD_PREPOST,
|
||||
KWE_THREAD_BROADCAST,
|
||||
};
|
||||
|
||||
#define _PTHREAD_MTX_OPT_PSHARED 0x010
|
||||
#define _PTHREAD_MTX_OPT_NOTIFY 0x1000 /* notify to drop mutex handling in cvwait */
|
||||
#define _PTHREAD_MTX_OPT_MUTEX 0x2000 /* this is a mutex type */
|
||||
|
||||
|
||||
#define PTHRW_COUNT_SHIFT 8
|
||||
#define PTHRW_INC (1 << PTHRW_COUNT_SHIFT)
|
||||
#define PTHRW_BIT_MASK ((1 << PTHRW_COUNT_SHIFT) - 1)
|
||||
#define PTHRW_COUNT_MASK ((uint32_t)~PTHRW_BIT_MASK)
|
||||
#define PTHRW_MAX_READERS PTHRW_COUNT_MASK
|
||||
|
||||
// L word
|
||||
#define PTH_RWL_KBIT 0x01 // cannot acquire in user mode
|
||||
#define PTH_RWL_EBIT 0x02 // exclusive lock in progress
|
||||
#define PTH_RWL_WBIT 0x04 // write waiters pending in kernel
|
||||
#define PTH_RWL_PBIT 0x04 // prepost (cv) pending in kernel
|
||||
|
||||
#define PTH_RWL_MTX_WAIT 0x20 // in cvar in mutex wait
|
||||
#define PTH_RWL_UBIT 0x40 // lock is unlocked (no readers or writers)
|
||||
#define PTH_RWL_MBIT 0x40 // overlapping grants from kernel (only in updateval)
|
||||
#define PTH_RWL_IBIT 0x80 // lock reset, held until first successful unlock
|
||||
|
||||
#define PTHRW_RWL_INIT PTH_RWL_IBIT // reset on the lock bits (U)
|
||||
#define PTHRW_RWLOCK_INIT (PTH_RWL_IBIT | PTH_RWL_UBIT) // reset on the lock bits (U)
|
||||
|
||||
// S word
|
||||
#define PTH_RWS_SBIT 0x01 // kernel transition seq not set yet
|
||||
#define PTH_RWS_IBIT 0x02 // Sequence is not set on return from kernel
|
||||
|
||||
#define PTH_RWS_CV_CBIT PTH_RWS_SBIT // kernel has cleared all info w.r.s.t CV
|
||||
#define PTH_RWS_CV_PBIT PTH_RWS_IBIT // kernel has prepost/fake structs only,no waiters
|
||||
#define PTH_RWS_CV_BITSALL (PTH_RWS_CV_CBIT | PTH_RWS_CV_PBIT)
|
||||
#define PTH_RWS_CV_MBIT PTH_RWL_MBIT // to indicate prepost return from kernel
|
||||
#define PTH_RWS_CV_RESET_PBIT ((uint32_t)~PTH_RWS_CV_PBIT)
|
||||
|
||||
#define PTH_RWS_WSVBIT 0x04 // save W bit
|
||||
|
||||
#define PTHRW_RWS_SAVEMASK (PTH_RWS_WSVBIT) // save bits mask
|
||||
|
||||
#define PTHRW_RWS_INIT PTH_RWS_SBIT // reset on the lock bits (U)
|
||||
|
||||
// rw_flags
|
||||
#define PTHRW_KERN_PROCESS_SHARED 0x10
|
||||
#define PTHRW_KERN_PROCESS_PRIVATE 0x20
|
||||
|
||||
#define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1
|
||||
|
||||
// L word tests
|
||||
#define is_rwl_ebit_set(x) (((x) & PTH_RWL_EBIT) != 0)
|
||||
#define is_rwl_wbit_set(x) (((x) & PTH_RWL_WBIT) != 0)
|
||||
#define is_rwl_ebit_clear(x) (((x) & PTH_RWL_EBIT) == 0)
|
||||
#define is_rwl_readoverlap(x) (((x) & PTH_RWL_MBIT) != 0)
|
||||
|
||||
// S word tests
|
||||
#define is_rws_sbit_set(x) (((x) & PTH_RWS_SBIT) != 0)
|
||||
#define is_rws_unlockinit_set(x) (((x) & PTH_RWS_IBIT) != 0)
|
||||
#define is_rws_savemask_set(x) (((x) & PTHRW_RWS_SAVEMASK) != 0)
|
||||
#define is_rws_pbit_set(x) (((x) & PTH_RWS_CV_PBIT) != 0)
|
||||
|
||||
// kwe_flags
|
||||
#define KWE_FLAG_LOCKPREPOST 0x1 // cvwait caused a lock prepost
|
||||
|
||||
static inline int
|
||||
is_seqlower(uint32_t x, uint32_t y)
|
||||
{
|
||||
x &= PTHRW_COUNT_MASK;
|
||||
y &= PTHRW_COUNT_MASK;
|
||||
if (x < y) {
|
||||
return ((y - x) < (PTHRW_MAX_READERS / 2));
|
||||
} else {
|
||||
return ((x - y) > (PTHRW_MAX_READERS / 2));
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_seqlower_eq(uint32_t x, uint32_t y)
|
||||
{
|
||||
if ((x & PTHRW_COUNT_MASK) == (y & PTHRW_COUNT_MASK)) {
|
||||
return 1;
|
||||
} else {
|
||||
return is_seqlower(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_seqhigher(uint32_t x, uint32_t y)
|
||||
{
|
||||
x &= PTHRW_COUNT_MASK;
|
||||
y &= PTHRW_COUNT_MASK;
|
||||
if (x > y) {
|
||||
return ((x - y) < (PTHRW_MAX_READERS / 2));
|
||||
} else {
|
||||
return ((y - x) > (PTHRW_MAX_READERS / 2));
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_seqhigher_eq(uint32_t x, uint32_t y)
|
||||
{
|
||||
if ((x & PTHRW_COUNT_MASK) == (y & PTHRW_COUNT_MASK)) {
|
||||
return 1;
|
||||
} else {
|
||||
return is_seqhigher(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
diff_genseq(uint32_t x, uint32_t y)
|
||||
{
|
||||
x &= PTHRW_COUNT_MASK;
|
||||
y &= PTHRW_COUNT_MASK;
|
||||
if (x == y) {
|
||||
return 0;
|
||||
} else if (x > y) {
|
||||
return x - y;
|
||||
} else {
|
||||
return ((PTHRW_MAX_READERS - y) + x + PTHRW_INC);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
find_diff(uint32_t upto, uint32_t lowest)
|
||||
{
|
||||
uint32_t diff;
|
||||
|
||||
if (upto == lowest)
|
||||
return(0);
|
||||
#if 0
|
||||
diff = diff_genseq(upto, lowest);
|
||||
#else
|
||||
if (is_seqlower(upto, lowest) != 0)
|
||||
diff = diff_genseq(lowest, upto);
|
||||
else
|
||||
diff = diff_genseq(upto, lowest);
|
||||
#endif
|
||||
diff = (diff >> PTHRW_COUNT_SHIFT);
|
||||
return(diff);
|
||||
}
|
||||
|
||||
#endif /* __SYNCH_INTERNAL_H__ */
|
54
dthread/workqueue_internal.h
Normal file
54
dthread/workqueue_internal.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Apple Computer, 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@
|
||||
*/
|
||||
|
||||
#ifndef DTHREAD_WORKQUEUE_INTERNAL_H // header name changed for Darling
|
||||
#define DTHREAD_WORKQUEUE_INTERNAL_H
|
||||
|
||||
#ifdef __DARLING__
|
||||
#include <pthread/workqueue_internal.h>
|
||||
#endif
|
||||
|
||||
/* These definitions are shared between the kext and userspace inside the pthread project. Consolidating
|
||||
* duplicate definitions that used to exist in both projects, when separate.
|
||||
*/
|
||||
|
||||
// Sometimes something gets passed a bucket number and we need a way to express
|
||||
// that it's actually the event manager. Use the (0)th bucket for that.
|
||||
#define WORKQ_THREAD_QOS_MIN (THREAD_QOS_MAINTENANCE)
|
||||
#define WORKQ_THREAD_QOS_MAX (THREAD_QOS_LAST - 1)
|
||||
#define WORKQ_THREAD_QOS_CLEANUP (THREAD_QOS_LEGACY)
|
||||
#define WORKQ_THREAD_QOS_MANAGER (THREAD_QOS_LAST) // outside of MIN/MAX
|
||||
|
||||
#define WORKQ_NUM_QOS_BUCKETS (WORKQ_THREAD_QOS_MAX)
|
||||
#define WORKQ_NUM_BUCKETS (WORKQ_THREAD_QOS_MAX + 1)
|
||||
#define WORKQ_IDX(qos) ((qos) - 1) // 0 based index
|
||||
|
||||
// magical `nkevents` values for _pthread_wqthread
|
||||
#define WORKQ_EXIT_THREAD_NKEVENT (-1)
|
||||
|
||||
#endif // DTHREAD_WORKQUEUE_INTERNAL_H
|
Loading…
Reference in New Issue
Block a user