Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ check_symbol_exists(VQ_UPDATE "sys/mount.h" HAVE_DECL_VQ_UPDATE)
check_symbol_exists(VQ_VERYLOWDISK "sys/mount.h" HAVE_DECL_VQ_VERYLOWDISK)
check_symbol_exists(VQ_FREE_SPACE_CHANGE "sys/mount.h" HAVE_DECL_VQ_FREE_SPACE_CHANGE)
check_symbol_exists(VQ_PURGEABLE_SPACE_CHANGE "sys/mount.h" HAVE_DECL_VQ_PURGEABLE_SPACE_CHANGE)
check_symbol_exists(VQ_IDLE_PURGE_NOTIFY "sys/mount.h" HAVE_DECL_VQ_IDLE_PURGE_NOTIFY)
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)
check_symbol_exists(program_invocation_name "errno.h" HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
if (HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
Expand Down
4 changes: 4 additions & 0 deletions cmake/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@
you don't. */
#cmakedefine01 HAVE_DECL_VQ_PURGEABLE_SPACE_CHANGE

/* Define to 1 if you have the declaration of `VQ_IDLE_PURGE_NOTIFY`, and to 0 if
you don't */
#cmakedefine01 HAVE_DECL_VQ_IDLE_PURGE_NOTIFY

/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine01 HAVE_DLFCN_H

Expand Down
4 changes: 4 additions & 0 deletions config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
* if you don't */
#define HAVE_DECL_VQ_PURGEABLE_SPACE_CHANGE 1

/* Define to 1 if you have the declaration of `VQ_IDLE_PURGE_NOTIFY`, and to 0
* if you don't */
#define HAVE_DECL_VQ_IDLE_PURGE_NOTIFY 1

/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1

Expand Down
25 changes: 25 additions & 0 deletions os/voucher_activity_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,31 @@ OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL_ALL
void *
voucher_activity_get_logging_preferences(size_t *length);

/*!
* @function voucher_activity_get_logging_preferences_with_port
*
* @abstract
* Return address and length of vm_map()ed configuration data for the logging
* subsystem using logd port.
*
* @discussion
* The data must be deallocated with vm_deallocate(). There is no initialization of firehose buffer involved.
*
* @param sendp
* The mach port for the daemon, this will be used to connect and fetch the preferences. It is the bootstrap
* port for logd.
*
* @param length
* Pointer to size_t variable, filled with length of preferences buffer.
*
* @result
* Address of preferences buffer, returns NULL on error.
*/
API_AVAILABLE(macos(16.0), ios(19.0), tvos(19.0), watchos(12.0), bridgeos(10.0))
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL_ALL
void *
voucher_activity_get_logging_preferences_with_port(mach_port_t sendp, size_t *length);

/*!
* @function voucher_activity_should_send_strings
*
Expand Down
35 changes: 35 additions & 0 deletions os/voucher_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,41 @@ voucher_t _Nullable
voucher_copy_with_persona_mach_voucher(
mach_voucher_t persona_mach_voucher);

/*!
* @function voucher_copy_with_persona_mach_voucher_and_error
*
* @abstract
* A different interface to voucher_copy_with_persona_mach_voucher that
* interacts better with ARC.
*
* @discussion
* voucher_copy_with_persona_mach_voucher returns a non-null but invalid object
* in some failure conditions (VOUCHER_INVALID), which ARC is unable to release
* or reason about. In the same failure conditions, this function will set
* *out_voucher to NULL and return an error code
*
* @param persona_mach_voucher
* mach voucher containing the new persona information
*
* @param out_voucher
* If successful, a reference to the newly created mach voucher. On failure,
* *out_voucher will be set to NULL
*
* @result
* On success, a copy of the current voucher with the new persona information
* is put in *out_voucher, and 0 is returned
* On failure, this function will return:
* - EPERM: a failure which would have caused
* voucher_copy_with_persona_mach_voucher to return VOUCHER_INVALID
* - ENOTSUP: mach vouchers are not supported on this platform
*/
SPI_AVAILABLE(macos(16), ios(19))
OS_VOUCHER_EXPORT OS_NOTHROW OS_NONNULL2
int
voucher_copy_with_persona_mach_voucher_and_error(
mach_voucher_t persona_mach_voucher,
voucher_t _Nullable * _Nonnull out_voucher);

/*!
* @function mach_voucher_persona_self
*
Expand Down
6 changes: 6 additions & 0 deletions os/workgroup_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
#define OS_WORKGROUP_ASSUME_NONNULL_BEGIN
#define OS_WORKGROUP_ASSUME_NONNULL_END
#endif
#if __has_feature(enumerator_attributes)
#define OS_WORKGROUP_ENUM_API_DEPRECATED_WITH_REPLACEMENT(...) \
API_DEPRECATED_WITH_REPLACEMENT(__VA_ARGS__)
#else
#define OS_WORKGROUP_ENUM_API_DEPRECATED_WITH_REPLACEMENT(...)
#endif
#define OS_WORKGROUP_WARN_RESULT __attribute__((__warn_unused_result__))
#define OS_WORKGROUP_EXPORT OS_EXPORT
#define OS_WORKGROUP_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED
Expand Down
91 changes: 79 additions & 12 deletions os/workgroup_interval_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,15 @@ os_workgroup_attr_set_telemetry_flavor(os_workgroup_attr_t wga,
* os_workgroup_interval_update() and os_workgroup_interval_finish() to
* indicate to the system that a specific instance of a repeatable workload
* has one of the following properties:
*
* OS_WORKGROUP_INTERVAL_DATA_COMPLEXITY_DEFAULT:
* specific instance has default complexity (same as using data initialized
* with OS_WORKGROUP_INTERVAL_DATA_INITIALIZER resp not calling
* os_workgroup_interval_data_set_flags(), or specifying NULL
* os_workgroup_interval_data_t).
* OS_WORKGROUP_INTERVAL_DATA_COMPLEXITY_HIGH:
* specific instance has high complexity. May only be called on an
* os_workgroup_interval_t created with a workload identifier that is known
* and is configured by the system to be allowed to use complexity.
*/
OS_OPTIONS(os_workgroup_interval_data_flags, uint32_t,
OS_WORKGROUP_INTERVAL_DATA_COMPLEXITY_DEFAULT = 0x0u,
OS_WORKGROUP_INTERVAL_DATA_COMPLEXITY_HIGH = 0x1u,
OS_WORKGROUP_INTERVAL_DATA_NONE = 0xffffffff,
OS_WORKGROUP_INTERVAL_DATA_COMPLEXITY_DEFAULT OS_WORKGROUP_ENUM_API_DEPRECATED_WITH_REPLACEMENT(
"Use os_workgroup_interval_data_set_complexity instead",
macos(13.0,16.0), ios(16.0,19.0), tvos(16.0,19.0), watchos(9.0,12.0)) = 0x0u,
OS_WORKGROUP_INTERVAL_DATA_COMPLEXITY_HIGH OS_WORKGROUP_ENUM_API_DEPRECATED_WITH_REPLACEMENT(
"Use os_workgroup_interval_data_set_complexity instead",
macos(13.0,16.0), ios(16.0,19.0), tvos(16.0,19.0), watchos(9.0,12.0)) = 0x1u,
);

/*
Expand Down Expand Up @@ -163,6 +158,78 @@ int
os_workgroup_interval_data_set_flags(os_workgroup_interval_data_t data,
os_workgroup_interval_data_flags_t flags);

// TODO: rdar://145714553, remove revlock avoiding flag
#define __OS_WORKGROUP_INTERVAL_DATA_HAS_CUSTOM_COMPLEXITY 1

/*
* @typedef os_workgroup_interval_data_complexity_t
*
* @abstract
* Set of flags that can be passed to os_workgroup_interval_data_set_complexity() to
* indicate to the system that a specific instance of a repeatable workload
* has one of the following properties:
*
* OS_WORKGROUP_INTERVAL_DATA_SET_COMPLEXITY_DEFAULT:
* specific instance has default complexity (same as using data initialized
* with OS_WORKGROUP_INTERVAL_DATA_INITIALIZER resp not calling
* os_workgroup_interval_data_set_flags(), or specifying NULL
* os_workgroup_interval_data_t).
* OS_WORKGROUP_INTERVAL_DATA_SET_COMPLEXITY_HIGH:
* specific instance has high complexity. May only be called on an
* os_workgroup_interval_t created with a workload identifier that is known
* and is configured by the system to be allowed to use complexity.
* OS_WORKGROUP_INTERVAL_DATA_SET_COMPLEXITY_MANUAL:
* specific instance has complexity that is being manually signalled by
* the client. May only be called on an os_workgroup_interval_t created
* with a workload identifier that is known and is configured by the system
* to be allowed to use complexity.The value interpretation is work interval
* type specific.
*/
OS_OPTIONS(os_workgroup_interval_data_complexity, uint32_t,
OS_WORKGROUP_INTERVAL_DATA_SET_COMPLEXITY_DEFAULT = 0x0u,
OS_WORKGROUP_INTERVAL_DATA_SET_COMPLEXITY_HIGH = 0x1u,
OS_WORKGROUP_INTERVAL_DATA_SET_COMPLEXITY_MANUAL = 0x2u,
);

/*
* @function os_workgroup_interval_data_set_complexity
*
* @abstract
* Setter for os_workgroup_interval_data_t, can specify a complexity value
* to indicate to the system that a specific instance of a repeatable workload
* has custom properties by passing the resulting data pointer to
* os_workgroup_interval_start(), os_workgroup_interval_update() and
* os_workgroup_interval_finish(). This value will be ignored if any
* non-default complexity flags have been set using
* os_workgroup_interval_data_set_flags().
*
* The complexity chosen for a given instance of the repeatable workload are allowed
* to be different at each of these three calls made for the instance, and they
* are determined wholly by the `data` value passed to the specific call.
*
* @discussion
* In particular this means that once a non-default flag is set with this
* function, the resulting data pointer must be passed to every subsequent
* call of update() or finish() for that instance if the goal is to keep that
* flag present (as opposed to e.g. being reset to the default by passing a
* NULL data pointer).
*
* The interpretation of this complexity value is specific to a work interval type.
*
* @param data
* Pointer to workgroup interval data structure initialized with
* OS_WORKGROUP_INTERVAL_DATA_INITIALIZER.
*
* @param complexity
* Work interval type specific complexity value.
*
*/
API_AVAILABLE(macos(16.0), ios(19.0), tvos(19.0), watchos(12.0))
OS_WORKGROUP_EXPORT
int
os_workgroup_interval_data_set_complexity(os_workgroup_interval_data_t data,
os_workgroup_interval_data_complexity_t flag, uint64_t complexity);

/*!
* @function os_workgroup_interval_data_set_flags
*
Expand Down
32 changes: 32 additions & 0 deletions private/queue_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,38 @@ void
dispatch_async_swift_job(dispatch_queue_t queue, void *swift_job,
qos_class_t qos);

/*!
* @function dispatch_queue_get_threadid_4wdt
*
* @abstract
* Returns the threadid of the thread that currently holds the drain lock of a
* serial queue.
*
* @discussion
* This SPI is intended only for debugging purposes of stuck queues. It is
* inherently racy, since the thread holding the queue's drain lock may change
* or the thread may exit while this thread is looking up the owner.
*
* @param queue
* The queue to query. The queue must be a serial queue (either a
* dispatch_serial_queue, dispatch_workloop, or the main queue).
*
* @param thread_id
* On success, the thread_id of the thread blocking queue will be stored to
* this pointer.
*
* @result
* On success, this function will return zero. Otherwise an error number will
* be returned to indicate the error:
* - EINVAL: The passed queue was invalid
* - ESRCH: The queue drainer couldn't be found, either because the queue isn't
* locked or the thread exited before we could look up its ID
*/
SPI_AVAILABLE(macos(16.0), ios(19.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2
int
dispatch_queue_get_threadid_4wdt(dispatch_queue_t queue, uint64_t *thread_id);

__END_DECLS

DISPATCH_ASSUME_NONNULL_END
Expand Down
4 changes: 4 additions & 0 deletions private/source_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ enum {
*
* @constant DISPATCH_VFS_PURGEABLE_SPACE_CHANGE
* Purgeable disk space has significantly changed
*
* @constant DISPATCH_VFS_IDLE_PURGE_NOTIFY
* Filesystem is nearly full (below DESIREDDISK level).
*/
enum {
DISPATCH_VFS_NOTRESP = 0x0001,
Expand All @@ -282,6 +285,7 @@ enum {
DISPATCH_VFS_DESIREDDISK = 0x4000,
DISPATCH_VFS_FREE_SPACE_CHANGE = 0x8000,
DISPATCH_VFS_PURGEABLE_SPACE_CHANGE = 0x10000,
DISPATCH_VFS_IDLE_PURGE_NOTIFY = 0x20000,
};

/*!
Expand Down
28 changes: 28 additions & 0 deletions private/swift_concurrency_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,34 @@ DISPATCH_EXPORT
int
dispatch_lock_override_end(qos_class_t override_to_end);

/*!
* @function dispatch_verify_current_queue_4swiftonly
*
* @abstract
* This function is invoked by the Swift Concurrency runtime when trying to warn
* about isolation mismatches in code that the Swift compiler can't statically
* prove the correctness of.
*
* @discussion
* This SPI is intended only for improving the information available in
* warnings and diagnostic messages. This function returning false does not
* guarantee that the calling context is able to call `dispatch_sync` onto
* `expected_queue` without deadlocking or crashing.
*
* THIS SHOULD NOT BE USED BY ANYONE THAT IS NOT THE SWIFT CONCURRENCY RUNTIME.
*
* @param expected_queue
* The queue that the Swift runtime expects to be running on.
*
* @return
* Returns true when libdispatch knows that the calling context is running on
* `expected_queue`, false otherwise.
*/
SPI_AVAILABLE(macos(16.0), ios(19.0))
DISPATCH_EXPORT
bool
dispatch_verify_current_queue_4swiftonly(dispatch_queue_t expected_queue);

__END_DECLS
DISPATCH_ASSUME_NONNULL_END
#endif
1 change: 1 addition & 0 deletions src/allocator.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "internal.h"
#include "allocator_internal.h"


#if DISPATCH_ALLOCATOR

#ifndef VM_MEMORY_LIBDISPATCH
Expand Down
9 changes: 8 additions & 1 deletion src/event/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ _dispatch_unote_create_without_handle(dispatch_source_type_t dst,

DISPATCH_NOINLINE
void
_dispatch_unote_dispose(dispatch_unote_t du)
_dispatch_unote_dispose(dispatch_unote_t du, bool may_defer)
{
void *ptr = du._du;
#if HAVE_MACH
Expand All @@ -117,6 +117,13 @@ _dispatch_unote_dispose(dispatch_unote_t du)
} else if (!du._du->du_is_direct) {
ptr = _dispatch_unote_get_linkage(du);
}
#if DISPATCH_HAVE_DIRECT_KNOTES
else if (may_defer && du._du->du_is_direct) {
// We may have deferred unregistration of this unote, so need to defer
// the free as well
return _dispatch_unote_dispose_defer(du);
}
#endif
free(ptr);
}

Expand Down
4 changes: 4 additions & 0 deletions src/event/event_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@
# undef HAVE_DECL_VQ_PURGEABLE_SPACE_CHANGE
# endif // VQ_PURGEABLE_SPACE_CHANGE

# ifndef VQ_IDLE_PURGE_NOTIFY
# undef HAVE_DECL_VQ_FREE_SPACE_CHANGE
# endif // VQ_IDLE_PURGE_NOTIFY

# if !defined(EVFILT_NW_CHANNEL) && defined(__APPLE__)
# define EVFILT_NW_CHANNEL (-16)
# define NOTE_FLOW_ADV_UPDATE 0x1
Expand Down
Loading