]> git.saurik.com Git - apple/libpthread.git/blob - private/dependency_private.h
77d209f2005feb8f7a5f911e18c13d069eb54c99
[apple/libpthread.git] / private / dependency_private.h
1 /*
2 * Copyright (c) 2018 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #ifndef __PTHREAD_DEPENDENCY_PRIVATE__
25 #define __PTHREAD_DEPENDENCY_PRIVATE__
26
27 #include <os/base.h>
28 #include <sys/cdefs.h>
29 #include <pthread/pthread.h>
30 #include <Availability.h>
31
32 __BEGIN_DECLS
33
34 OS_ASSUME_NONNULL_BEGIN
35
36 /*!
37 * @typedef pthread_dependency_t
38 *
39 * @abstract
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.
43 *
44 * @discussion
45 * These tokens are one-time use, and meant to be on the stack of the waiter
46 * thread.
47 *
48 * These tokens must be both fulfilled and waited on, exactly one of each.
49 */
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;
55
56 /*!
57 * @typedef pthread_dependency_attr_t
58 *
59 * @abstract
60 * An opaque type to allow for future expansion of the pthread_dependency
61 * interface.
62 */
63 typedef struct pthread_dependency_attr_s pthread_dependency_attr_t;
64
65 #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) || defined(__cplusplus)
66 /*!
67 * @macro PTHREAD_DEPENDENCY_INITIALIZER_NP
68 *
69 * @abstract
70 * Initialize a one-time dependency token.
71 *
72 * @param __pthread
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().
75 */
76 #define PTHREAD_DEPENDENCY_INITIALIZER_NP(__pthread) \
77 { pthread_mach_thread_np(__pthread), 0, 0 }
78 #endif
79
80 /*!
81 * @function pthread_dependency_init_np
82 *
83 * @abstract
84 * Initialize a dependency token.
85 *
86 * @param __dependency
87 * A pointer to a dependency token to initialize.
88 *
89 * @param __pthread
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().
92 *
93 * @param __attrs
94 * This argument is reserved for future expansion purposes, and NULL should be
95 * passed.
96 */
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);
101
102 /*!
103 * @function pthread_dependency_fulfill_np
104 *
105 * @abstract
106 * Fulfill a dependency.
107 *
108 * @discussion
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
112 * to be terminated.
113 *
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.
117 *
118 * @param __dependency
119 * A pointer to a dependency token that was previously initialized.
120 *
121 * @param __value
122 * An optional value that can be returned through the dependency token
123 * to the waiter.
124 */
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);
129
130 /*!
131 * @function pthread_dependency_wait_np
132 *
133 * @abstract
134 * Wait on a dependency.
135 *
136 * @discussion
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
140 * to be terminated.
141 *
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().
147 *
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().
151 *
152 * @returns
153 * The value that was passed to pthread_dependency_fulfill_np() as the `__value`
154 * argument.
155 */
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);
159
160 OS_ASSUME_NONNULL_END
161
162 __END_DECLS
163
164 #endif //__PTHREAD_DEPENDENCY_PRIVATE__