2 * Copyright (c) 2018 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #ifndef __PTHREAD_DEPENDENCY_PRIVATE__
25 #define __PTHREAD_DEPENDENCY_PRIVATE__
28 #include <sys/cdefs.h>
29 #include <pthread/pthread.h>
30 #include <Availability.h>
34 OS_ASSUME_NONNULL_BEGIN
37 * @typedef pthread_dependency_t
40 * A pthread dependency is a one-time dependency between a thread producing
41 * a value and a waiter thread, expressed to the system in a way
42 * that priority inversion avoidance can be applied if necessary.
45 * These tokens are one-time use, and meant to be on the stack of the waiter
48 * These tokens must be both fulfilled and waited on, exactly one of each.
50 typedef struct pthread_dependency_s
{
51 uint32_t __pdep_owner
;
52 uint32_t __pdep_opaque1
;
53 uint64_t __pdep_opaque2
;
54 } pthread_dependency_t
;
57 * @typedef pthread_dependency_attr_t
60 * An opaque type to allow for future expansion of the pthread_dependency
63 typedef struct pthread_dependency_attr_s pthread_dependency_attr_t
;
65 #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(__cplusplus)
67 * @macro PTHREAD_DEPENDENCY_INITIALIZER_NP
70 * Initialize a one-time dependency token.
73 * The thread that will be waited on for this dependency to be fulfilled.
74 * It is expected that this thread will call pthread_dependency_fulfill_np().
76 #define PTHREAD_DEPENDENCY_INITIALIZER_NP(__pthread) \
77 { pthread_mach_thread_np(__pthread), 0, 0 }
81 * @function pthread_dependency_init_np
84 * Initialize a dependency token.
87 * A pointer to a dependency token to initialize.
90 * The thread that will be waited on for this dependency to be fulfilled.
91 * It is expected that this thread will call pthread_dependency_fulfill_np().
94 * This argument is reserved for future expansion purposes, and NULL should be
97 __API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
98 OS_NONNULL1 OS_NONNULL2 OS_NOTHROW
99 void pthread_dependency_init_np(pthread_dependency_t
*__dependency
,
100 pthread_t __pthread
, pthread_dependency_attr_t
*_Nullable __attrs
);
103 * @function pthread_dependency_fulfill_np
106 * Fulfill a dependency.
109 * Calling pthread_dependency_fulfill_np() with a token that hasn't been
110 * initialized yet, or calling pthread_dependency_fulfill_np() on the same
111 * dependency token more than once is undefined and will cause the process
114 * The thread that calls pthread_dependency_fulfill_np() must be the same
115 * as the pthread_t that was specified when initializing the token. Not doing so
116 * is undefined and will cause the process to be terminated.
118 * @param __dependency
119 * A pointer to a dependency token that was previously initialized.
122 * An optional value that can be returned through the dependency token
125 __API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
126 OS_NONNULL1 OS_NOTHROW
127 void pthread_dependency_fulfill_np(pthread_dependency_t
*__dependency
,
128 void * _Nullable __value
);
131 * @function pthread_dependency_wait_np
134 * Wait on a dependency.
137 * Calling pthread_dependency_wait_np() with a token that hasn't been
138 * initialized yet, or calling pthread_dependency_wait_np() on the same
139 * dependency token more than once is undefined and will cause the process
142 * If the dependency is not fulfilled yet when this function is called, priority
143 * inversion avoidance will be applied to the thread that was specified when
144 * initializing the token, to ensure that it can call
145 * pthread_dependency_fulfill_np() without causing a priority inversion for the
146 * thread calling pthread_dependency_wait_np().
148 * @param __dependency
149 * A pointer to a dependency token that was previously initialized with
150 * PTHREAD_DEPENDENCY_INITIALIZER_NP() or pthread_dependency_init_np().
153 * The value that was passed to pthread_dependency_fulfill_np() as the `__value`
156 __API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
157 OS_NONNULL1 OS_NOTHROW
158 void *_Nullable
pthread_dependency_wait_np(pthread_dependency_t
*__dependency
);
160 OS_ASSUME_NONNULL_END
164 #endif //__PTHREAD_DEPENDENCY_PRIVATE__