X-Git-Url: https://git.saurik.com/apple/libpthread.git/blobdiff_plain/45deb508575711c47d78d19e326a9a26e43e63e0..c1f56ec94c29e576da2d6d7164bee1bdb2f02471:/private/pthread/dependency_private.h diff --git a/private/pthread/dependency_private.h b/private/pthread/dependency_private.h new file mode 100644 index 0000000..77d209f --- /dev/null +++ b/private/pthread/dependency_private.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2018 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_DEPENDENCY_PRIVATE__ +#define __PTHREAD_DEPENDENCY_PRIVATE__ + +#include +#include +#include +#include + +__BEGIN_DECLS + +OS_ASSUME_NONNULL_BEGIN + +/*! + * @typedef pthread_dependency_t + * + * @abstract + * A pthread dependency is a one-time dependency between a thread producing + * a value and a waiter thread, expressed to the system in a way + * that priority inversion avoidance can be applied if necessary. + * + * @discussion + * These tokens are one-time use, and meant to be on the stack of the waiter + * thread. + * + * These tokens must be both fulfilled and waited on, exactly one of each. + */ +typedef struct pthread_dependency_s { + uint32_t __pdep_owner; + uint32_t __pdep_opaque1; + uint64_t __pdep_opaque2; +} pthread_dependency_t; + +/*! + * @typedef pthread_dependency_attr_t + * + * @abstract + * An opaque type to allow for future expansion of the pthread_dependency + * interface. + */ +typedef struct pthread_dependency_attr_s pthread_dependency_attr_t; + +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(__cplusplus) +/*! + * @macro PTHREAD_DEPENDENCY_INITIALIZER_NP + * + * @abstract + * Initialize a one-time dependency token. + * + * @param __pthread + * The thread that will be waited on for this dependency to be fulfilled. + * It is expected that this thread will call pthread_dependency_fulfill_np(). + */ +#define PTHREAD_DEPENDENCY_INITIALIZER_NP(__pthread) \ + { pthread_mach_thread_np(__pthread), 0, 0 } +#endif + +/*! + * @function pthread_dependency_init_np + * + * @abstract + * Initialize a dependency token. + * + * @param __dependency + * A pointer to a dependency token to initialize. + * + * @param __pthread + * The thread that will be waited on for this dependency to be fulfilled. + * It is expected that this thread will call pthread_dependency_fulfill_np(). + * + * @param __attrs + * This argument is reserved for future expansion purposes, and NULL should be + * passed. + */ +__API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) +OS_NONNULL1 OS_NONNULL2 OS_NOTHROW +void pthread_dependency_init_np(pthread_dependency_t *__dependency, + pthread_t __pthread, pthread_dependency_attr_t *_Nullable __attrs); + +/*! + * @function pthread_dependency_fulfill_np + * + * @abstract + * Fulfill a dependency. + * + * @discussion + * Calling pthread_dependency_fulfill_np() with a token that hasn't been + * initialized yet, or calling pthread_dependency_fulfill_np() on the same + * dependency token more than once is undefined and will cause the process + * to be terminated. + * + * The thread that calls pthread_dependency_fulfill_np() must be the same + * as the pthread_t that was specified when initializing the token. Not doing so + * is undefined and will cause the process to be terminated. + * + * @param __dependency + * A pointer to a dependency token that was previously initialized. + * + * @param __value + * An optional value that can be returned through the dependency token + * to the waiter. + */ +__API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) +OS_NONNULL1 OS_NOTHROW +void pthread_dependency_fulfill_np(pthread_dependency_t *__dependency, + void * _Nullable __value); + +/*! + * @function pthread_dependency_wait_np + * + * @abstract + * Wait on a dependency. + * + * @discussion + * Calling pthread_dependency_wait_np() with a token that hasn't been + * initialized yet, or calling pthread_dependency_wait_np() on the same + * dependency token more than once is undefined and will cause the process + * to be terminated. + * + * If the dependency is not fulfilled yet when this function is called, priority + * inversion avoidance will be applied to the thread that was specified when + * initializing the token, to ensure that it can call + * pthread_dependency_fulfill_np() without causing a priority inversion for the + * thread calling pthread_dependency_wait_np(). + * + * @param __dependency + * A pointer to a dependency token that was previously initialized with + * PTHREAD_DEPENDENCY_INITIALIZER_NP() or pthread_dependency_init_np(). + * + * @returns + * The value that was passed to pthread_dependency_fulfill_np() as the `__value` + * argument. + */ +__API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) +OS_NONNULL1 OS_NOTHROW +void *_Nullable pthread_dependency_wait_np(pthread_dependency_t *__dependency); + +OS_ASSUME_NONNULL_END + +__END_DECLS + +#endif //__PTHREAD_DEPENDENCY_PRIVATE__