workgroup_object.h (12495B) - Raw
1 /* 2 * Copyright (c) 2020 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20 21 #ifndef __OS_WORKGROUP_OBJECT__ 22 #define __OS_WORKGROUP_OBJECT__ 23 24 #ifndef __OS_WORKGROUP_INDIRECT__ 25 #error "Please #include <os/workgroup.h> instead of this file directly." 26 #include <os/workgroup_base.h> // For header doc 27 #endif 28 29 __BEGIN_DECLS 30 31 OS_WORKGROUP_ASSUME_NONNULL_BEGIN 32 OS_WORKGROUP_ASSUME_ABI_SINGLE_BEGIN 33 34 /*! 35 * @typedef os_workgroup_t 36 * 37 * @abstract 38 * A reference counted os object representing a workload that needs to 39 * be distinctly recognized and tracked by the system. The workgroup 40 * tracks a collection of threads all working cooperatively. An os_workgroup 41 * object - when not an instance of a specific os_workgroup_t subclass - 42 * represents a generic workload and makes no assumptions about the kind of 43 * work done. 44 * 45 * @discussion 46 * Threads can explicitly join an os_workgroup_t to mark themselves as 47 * participants in the workload. 48 */ 49 OS_WORKGROUP_DECL(os_workgroup, WorkGroup); 50 51 52 /* Attribute creation and specification */ 53 54 /*! 55 * @typedef os_workgroup_attr_t 56 * 57 * @abstract 58 * Pointer to an opaque structure for describing attributes that can be 59 * configured on a workgroup at creation. 60 */ 61 typedef struct os_workgroup_attr_opaque_s os_workgroup_attr_s; 62 typedef struct os_workgroup_attr_opaque_s *os_workgroup_attr_t; 63 64 /* os_workgroup_t attributes need to be initialized before use. This initializer 65 * allows you to create a workgroup with the system default attributes. */ 66 #define OS_WORKGROUP_ATTR_INITIALIZER_DEFAULT \ 67 { .sig = _OS_WORKGROUP_ATTR_SIG_DEFAULT_INIT } 68 69 70 71 /* The main use of the workgroup API is through instantiations of the concrete 72 * subclasses - please refer to os/workgroup_interval.h and 73 * os/workgroup_parallel.h for more information on creating workgroups. 74 * 75 * The functions below operate on all subclasses of os_workgroup_t. 76 */ 77 78 /*! 79 * @function os_workgroup_copy_port 80 * 81 * @abstract 82 * Returns a reference to a send right representing this workgroup that is to be 83 * sent to other processes. This port is to be passed to 84 * os_workgroup_create_with_port() to create a workgroup object. 85 * 86 * It is the client's responsibility to release the send right reference. 87 * 88 * If an error is encountered, errno is set and returned. 89 */ 90 API_AVAILABLE(macos(11.0)) 91 API_UNAVAILABLE(ios, tvos, watchos) 92 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT OS_WORKGROUP_WARN_RESULT 93 int 94 os_workgroup_copy_port(os_workgroup_t wg, mach_port_t *mach_port_out); 95 96 /*! 97 * @function os_workgroup_create_with_port 98 * 99 * @abstract 100 * Create an os_workgroup_t object from a send right returned by a previous 101 * call to os_workgroup_copy_port, potentially in a different process. 102 * 103 * A newly created os_workgroup_t has no initial member threads - in particular 104 * the creating thread does not join the os_workgroup_t implicitly. 105 * 106 * @param name 107 * A client specified string for labelling the workgroup. This parameter is 108 * optional and can be NULL. 109 * 110 * @param mach_port 111 * The send right to create the workgroup from. No reference is consumed 112 * on the specified send right. 113 */ 114 API_AVAILABLE(macos(11.0)) 115 API_UNAVAILABLE(ios, tvos, watchos) 116 OS_SWIFT_NAME(WorkGroup.init(__name:port:)) OS_WORKGROUP_EXPORT OS_WORKGROUP_RETURNS_RETAINED 117 os_workgroup_t _Nullable 118 os_workgroup_create_with_port(const char *OS_WORKGROUP_UNSAFE_INDEXABLE _Nullable name, mach_port_t mach_port); 119 120 /*! 121 * @function os_workgroup_create_with_workgroup 122 * 123 * @abstract 124 * Create a new os_workgroup object from an existing os_workgroup. 125 * 126 * The newly created os_workgroup has no initial member threads - in particular 127 * the creating threaad does not join the os_workgroup_t implicitly. 128 * 129 * @param name 130 * A client specified string for labelling the workgroup. This parameter is 131 * optional and can be NULL. 132 * 133 * @param wg 134 * The existing workgroup to create a new workgroup object from. 135 */ 136 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 137 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT OS_WORKGROUP_RETURNS_RETAINED 138 os_workgroup_t _Nullable 139 os_workgroup_create_with_workgroup(const char * OS_WORKGROUP_UNSAFE_INDEXABLE _Nullable name, os_workgroup_t wg); 140 141 /*! 142 * @typedef os_workgroup_join_token, os_workgroup_join_token_t 143 * 144 * @abstract 145 * An opaque join token which the client needs to pass to os_workgroup_join 146 * and os_workgroup_leave 147 */ 148 OS_REFINED_FOR_SWIFT 149 typedef struct os_workgroup_join_token_opaque_s os_workgroup_join_token_s; 150 OS_REFINED_FOR_SWIFT 151 typedef struct os_workgroup_join_token_opaque_s *os_workgroup_join_token_t; 152 153 154 /*! 155 * @function os_workgroup_join 156 * 157 * @abstract 158 * Joins the current thread to the specified workgroup and populates the join 159 * token that has been passed in. This API is real-time safe. 160 * 161 * @param wg 162 * The workgroup that the current thread would like to join 163 * 164 * @param token_out 165 * Pointer to a client allocated struct which the function will populate 166 * with the join token. This token must be passed in by the thread when it calls 167 * os_workgroup_leave(). 168 * 169 * Errors will be returned in the following cases: 170 * 171 * EALREADY The thread is already part of a workgroup that the specified 172 * workgroup does not nest with 173 * EINVAL The workgroup has been cancelled 174 */ 175 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 176 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT OS_WORKGROUP_WARN_RESULT 177 int 178 os_workgroup_join(os_workgroup_t wg, os_workgroup_join_token_t token_out); 179 180 /*! 181 * @function os_workgroup_leave 182 * 183 * @abstract 184 * This removes the current thread from a workgroup it has previously 185 * joined. Threads must leave all workgroups in the reverse order that they 186 * have joined them. Failing to do so before exiting will result in undefined 187 * behavior. 188 * 189 * If the join token is malformed, the process will be aborted. 190 * 191 * This API is real time safe. 192 * 193 * @param wg 194 * The workgroup that the current thread would like to leave. 195 * 196 * @param token 197 * This is the join token populated by the most recent call to 198 * os_workgroup_join(). 199 */ 200 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 201 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT 202 void 203 os_workgroup_leave(os_workgroup_t wg, os_workgroup_join_token_t token); 204 205 /* Working Arena index of a thread in a workgroup */ 206 typedef uint32_t os_workgroup_index; 207 /* Destructor for Working Arena */ 208 typedef void (*os_workgroup_working_arena_destructor_t)(void * _Nullable); 209 210 /*! 211 * @function os_workgroup_set_working_arena 212 * 213 * @abstract 214 * Associates a client defined working arena with the workgroup. The arena 215 * is local to the workgroup object in the process. This is intended for 216 * distributing a manually managed memory allocation between member threads 217 * of the workgroup. 218 * 219 * This function can be called multiple times and the client specified 220 * destructor will be called on the previously assigned arena, if any. This 221 * function can only be called when no threads have currently joined the 222 * workgroup and all workloops associated with the workgroup are idle. 223 * 224 * @param wg 225 * The workgroup to associate the working arena with 226 * 227 * @param arena 228 * The client managed arena to associate with the workgroup. This value can 229 * be NULL. 230 * 231 * @param max_workers 232 * The maximum number of threads that will ever query the workgroup for the 233 * arena and request an index into it. If the arena is not used to partition 234 * work amongst member threads, then this field can be 0. 235 * 236 * @param destructor 237 * A destructor to call on the previously assigned working arena, if any 238 */ 239 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 240 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT OS_WORKGROUP_WARN_RESULT 241 int 242 os_workgroup_set_working_arena(os_workgroup_t wg, void * _Nullable arena, 243 uint32_t max_workers, os_workgroup_working_arena_destructor_t destructor); 244 245 /*! 246 * @function os_workgroup_get_working_arena 247 * 248 * @abstract 249 * Returns the working arena associated with the workgroup and the current 250 * thread's index in the workgroup. This function can only be called by a member 251 * of the workgroup. Multiple calls to this API by a member thread will return 252 * the same arena and index until the thread leaves the workgroup. 253 * 254 * For workloops with an associated workgroup, every work item on the workloop 255 * will receive the same index in the arena. 256 * 257 * This method returns NULL if no arena is set on the workgroup. The index 258 * returned by this function is zero-based and is namespaced per workgroup 259 * object in the process. The indices provided are strictly monotonic and never 260 * reused until a future call to os_workgroup_set_working_arena. 261 * 262 * @param wg 263 * The workgroup to get the working arena from. 264 * 265 * @param index_out 266 * A pointer to a os_workgroup_index which will be populated by the caller's 267 * index in the workgroup. 268 */ 269 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 270 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT 271 void * _Nullable 272 os_workgroup_get_working_arena(os_workgroup_t wg, 273 os_workgroup_index * _Nullable index_out); 274 275 /*! 276 * @function os_workgroup_cancel 277 * 278 * @abstract 279 * This API invalidates a workgroup and indicates to the system that the 280 * workload is no longer relevant to the caller. 281 * 282 * No new work should be initiated for a cancelled workgroup and 283 * work that is already underway should periodically check for 284 * cancellation with os_workgroup_testcancel and initiate cleanup if needed. 285 * 286 * Threads currently in the workgroup continue to be tracked together but no 287 * new threads may join this workgroup - the only possible operation allowed is 288 * to leave the workgroup. Other actions may have undefined behavior or 289 * otherwise fail. 290 * 291 * This API is idempotent. Cancellation is local to the workgroup object 292 * it is called on and does not affect other workgroups. 293 * 294 * @param wg 295 * The workgroup that that the thread would like to cancel 296 */ 297 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 298 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT 299 void 300 os_workgroup_cancel(os_workgroup_t wg); 301 302 /*! 303 * @function os_workgroup_testcancel 304 * 305 * @abstract 306 * Returns true if the workgroup object has been cancelled. See also 307 * os_workgroup_cancel 308 */ 309 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 310 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT 311 bool 312 os_workgroup_testcancel(os_workgroup_t wg); 313 314 /*! 315 * @typedef os_workgroup_max_parallel_threads_attr_t 316 * 317 * @abstract 318 * A pointer to a structure describing the set of properties of a workgroup to 319 * override with the explicitly specified values in the structure. 320 * 321 * See also os_workgroup_max_parallel_threads. 322 */ 323 OS_REFINED_FOR_SWIFT 324 typedef struct os_workgroup_max_parallel_threads_attr_s os_workgroup_mpt_attr_s; 325 OS_REFINED_FOR_SWIFT 326 typedef struct os_workgroup_max_parallel_threads_attr_s *os_workgroup_mpt_attr_t; 327 328 /*! 329 * @function os_workgroup_max_parallel_threads 330 * 331 * @abstract 332 * Returns the system's recommendation for maximum number of threads the client 333 * should make for a multi-threaded workload in a given workgroup. 334 * 335 * This API takes into consideration the current hardware the code is running on 336 * and the attributes of the workgroup. It does not take into consideration the 337 * current load of the system and therefore always provides the most optimal 338 * recommendation for the workload. 339 * 340 * @param wg 341 * The workgroup in which the multi-threaded workload will be performed in. The 342 * threads performing the multi-threaded workload are expected to join this 343 * workgroup. 344 * 345 * @param attr 346 * This value is currently unused and should be NULL. 347 */ 348 API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0)) 349 OS_REFINED_FOR_SWIFT OS_WORKGROUP_EXPORT 350 int 351 os_workgroup_max_parallel_threads(os_workgroup_t wg, os_workgroup_mpt_attr_t 352 _Nullable attr); 353 354 OS_WORKGROUP_ASSUME_ABI_SINGLE_END 355 OS_WORKGROUP_ASSUME_NONNULL_END 356 357 __END_DECLS 358 359 #endif /* __OS_WORKGROUP_OBJECT__ */