X-Git-Url: https://git.saurik.com/apple/libpthread.git/blobdiff_plain/45deb508575711c47d78d19e326a9a26e43e63e0..c1f56ec94c29e576da2d6d7164bee1bdb2f02471:/include/pthread/introspection.h?ds=sidebyside diff --git a/include/pthread/introspection.h b/include/pthread/introspection.h new file mode 100644 index 0000000..7aa9f41 --- /dev/null +++ b/include/pthread/introspection.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2013, 2016 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_INTROSPECTION__ +#define __PTHREAD_INTROSPECTION__ + +#include +#include +#include + +/*! + * @header + * + * @abstract + * Introspection API for libpthread. + * + * This should only be used for introspection and debugging tools. Do not rely + * on it in shipping code. + */ + +__BEGIN_DECLS + +/*! + * @typedef pthread_introspection_hook_t + * + * @abstract + * A function pointer called at various points in a PThread's lifetime. The + * function must be able to be called in contexts with invalid thread state. + * + * @param event + * One of the events in pthread_introspection_event_t. + * + * @param thread + * pthread_t associated with the event. + * + * @param addr + * Address associated with the event, e.g. stack address. + * + * @param size + * Size associated with the event, e.g. stack size. + */ +typedef void (*pthread_introspection_hook_t)(unsigned int event, + pthread_t thread, void *addr, size_t size); + +/*! + * @enum pthread_introspection_event_t + * Events sent by libpthread about threads lifetimes. + * + * @const PTHREAD_INTROSPECTION_THREAD_CREATE + * The specified pthread_t was created, and there will be a paired + * PTHREAD_INTROSPECTION_THREAD_DESTROY event. However, there may not be + * a START/TERMINATE pair of events for this pthread_t. + * + * Starting with macOS 10.14, and iOS 12, this event is always sent before + * PTHREAD_INTROSPECTION_THREAD_START is sent. This event is however not sent + * for the main thread. + * + * This event may not be sent from the context of the passed in pthread_t. + * + * Note that all properties of this thread may not be functional yet, and it is + * not permitted to call functions on this thread past observing its address. + * + * @const PTHREAD_INTROSPECTION_THREAD_START + * Thread has started and its stack was allocated. There will be a matching + * PTHREAD_INTROSPECTION_THREAD_TERMINATE event. + * + * This event is always sent from the context of the passed in pthread_t. + * + * @const PTHREAD_INTROSPECTION_THREAD_TERMINATE + * Thread is about to be terminated and stack will be deallocated. This always + * matches a PTHREAD_INTROSPECTION_THREAD_START event. + * + * This event is always sent from the context of the passed in pthread_t. + * + * @const PTHREAD_INTROSPECTION_THREAD_DESTROY + * pthread_t is about to be destroyed. This always matches + * a PTHREAD_INTROSPECTION_THREAD_CREATE event, but there may not have been + * a START/TERMINATE pair of events for this pthread_t. + * + * This event may not be sent from the context of the passed in pthread_t. + */ +enum { + PTHREAD_INTROSPECTION_THREAD_CREATE = 1, + PTHREAD_INTROSPECTION_THREAD_START, + PTHREAD_INTROSPECTION_THREAD_TERMINATE, + PTHREAD_INTROSPECTION_THREAD_DESTROY, +}; + +/*! + * @function pthread_introspection_hook_install + * + * @abstract + * Install introspection hook function into libpthread. + * + * @discussion + * The caller is responsible for implementing chaining to the hook that was + * previously installed (if any). + * + * @param hook + * Pointer to hook function. + * + * @result + * Previously installed hook function or NULL. + */ + +__API_AVAILABLE(macos(10.9), ios(7.0)) +__attribute__((__nonnull__, __warn_unused_result__)) +extern pthread_introspection_hook_t +pthread_introspection_hook_install(pthread_introspection_hook_t hook); + +/*! + * @function pthread_introspection_setspecific_np + * + * @abstract + * Performs the moral equivalent of pthread_setspecific() on a target thread + * during the @c PTHREAD_INTROSPECTION_START callback. + * + * @description + * This function is only valid to call during the delivery + * of an @c PTHREAD_INTROSPECTION_THREAD_CREATE introspection hook. + * + * Using this function outside of this context is undefined. + * + * If the created thread is started, then the destructor for this key + * will be called when the thread is terminated. However if the thread + * is not started, it will not be called, and + * pthread_introspection_getspecific_np() must be called manually during + * the @c PTHREAD_INTROSPECTION_THREAD_DESTROY callback to perform manual + * cleanup. + */ +__API_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0)) +int +pthread_introspection_setspecific_np(pthread_t thread, + pthread_key_t key, const void * _Nullable value); + +/*! + * @function pthread_introspection_getspecific_np + * + * @abstract + * Performs the moral equivalent of pthread_getspecific() on a target thread + * during the @c PTHREAD_INTROSPECTION_THREAD_DESTROY callback. + * + * @description + * This function is only valid to call during the delivery + * of an @c PTHREAD_INTROSPECTION_THREAD_DESTROY introspection hook. + * + * If the thread was started then this will always return NULL even + * when pthread_introspection_setspecific_np() was used. + */ +__API_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0)) +void * _Nullable +pthread_introspection_getspecific_np(pthread_t _Nonnull thread, + pthread_key_t key); + +__END_DECLS + +#endif