1POSIX Threads Support 2===================== 3 4Overview 5-------- 6 7ESP-IDF is based on FreeRTOS but offers a range of POSIX-compatible APIs that allow easy porting of third party code. This includes support for common parts of the POSIX Threads "pthreads" API. 8 9POSIX Threads are implemented in ESP-IDF as wrappers around equivalent FreeRTOS features. The runtime memory or performance overhead of using the pthreads API is quite low, but not every feature available in either pthreads or FreeRTOS is available via the ESP-IDF pthreads support. 10 11Pthreads can be used in ESP-IDF by including standard ``pthread.h`` header, which is included in the toolchain libc. An additional ESP-IDF specific header, ``esp_pthread.h``, provides additional non-POSIX APIs for using some ESP-IDF features with pthreads. 12 13C++ Standard Library implementations for ``std::thread``, ``std::mutex``, ``std::condition_variable``, etc. are implemented using pthreads (via GCC libstdc++). Therefore, restrictions mentioned here also apply to the equivalent C++ standard library functionality. 14 15RTOS Integration 16---------------- 17 18Unlike many operating systems using POSIX Threads, ESP-IDF is a real-time operating system with a real-time scheduler. This means that a thread will only stop running if a higher priority task is ready to run, the thread blocks on an OS synchronization structure like a mutex, or the thread calls any of the functions ``sleep``, :cpp:func:`vTaskDelay`, or ``usleep``. 19 20.. note:: 21 22 If calling a standard libc or C++ sleep function, such as ``usleep`` defined in ``unistd.h``, then the task will only block and yield the CPU if the sleep time is longer than :ref:`one FreeRTOS tick period <CONFIG_FREERTOS_HZ>`. If the time is shorter, the thread will busy-wait instead of yielding to another RTOS task. 23 24By default all POSIX Threads have the same RTOS priority, but it is possible to change this by calling a :ref:`custom API <esp-pthread>`. 25 26Standard features 27----------------- 28 29The following standard APIs are implemented in ESP-IDF. 30 31Refer to standard POSIX Threads documentation, or pthread.h, for details about the standard arguments and behaviour of each function. Differences or limitations compared to the standard APIs are noted below. 32 33Thread APIs 34^^^^^^^^^^^ 35 36* ``pthread_create()`` 37 - The ``attr`` argument is supported for setting stack size and detach state only. Other attribute fields are ignored. 38 - Unlike FreeRTOS task functions, the ``start_routine`` function is allowed to return. A "detached" type thread is automatically deleted if the function returns. The default "joinable" type thread will be suspended until pthread_join() is called on it. 39* ``pthread_join()`` 40* ``pthread_detach()`` 41* ``pthread_exit()`` 42* ``sched_yield()`` 43* ``pthread_self()`` 44 - An assert will fail if this function is called from a FreeRTOS task which is not a pthread. 45* ``pthread_equal()`` 46 47Thread Attributes 48^^^^^^^^^^^^^^^^^ 49 50* ``pthread_attr_init()`` 51* ``pthread_attr_destroy()`` 52 - This function doesn't need to free any resources and instead resets the ``attr`` structure to defaults (implementation is same as ``pthread_attr_init()``). 53* ``pthread_attr_getstacksize()`` / ``pthread_attr_setstacksize()`` 54* ``pthread_attr_getdetachstate()`` / ``pthread_attr_setdetachstate()`` 55 56Once 57^^^^ 58 59* ``pthread_once()`` 60 61Static initializer constant ``PTHREAD_ONCE_INIT`` is supported. 62 63.. note:: This function can be called from tasks created using either pthread or FreeRTOS APIs 64 65Mutexes 66^^^^^^^ 67 68POSIX Mutexes are implemented as FreeRTOS Mutex Semaphores (normal type for "fast" or "error check" mutexes, and Recursive type for "recursive" mutexes). This means that they have the same priority inheritance behaviour as mutexes created with :cpp:func:`xSemaphoreCreateMutex`. 69 70* ``pthread_mutex_init()`` 71* ``pthread_mutex_destroy()`` 72* ``pthread_mutex_lock()`` 73* ``pthread_mutex_timedlock()`` 74* ``pthread_mutex_trylock()`` 75* ``pthread_mutex_unlock()`` 76* ``pthread_mutexattr_init()`` 77* ``pthread_mutexattr_destroy()`` 78* ``pthread_mutexattr_gettype()`` / ``pthread_mutexattr_settype()`` 79 80Static initializer constant ``PTHREAD_MUTEX_INITIALIZER`` is supported, but the non-standard static initializer constants for other mutex types are not supported. 81 82.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs 83 84Condition Variables 85^^^^^^^^^^^^^^^^^^^ 86 87* ``pthread_cond_init()`` 88 - The ``attr`` argument is not implemented and is ignored. 89* ``pthread_cond_destroy()`` 90* ``pthread_cond_signal()`` 91* ``pthread_cond_broadcast()`` 92* ``pthread_cond_wait()`` 93* ``pthread_cond_timedwait()`` 94 95Static initializer constant ``PTHREAD_COND_INITIALIZER`` is supported. 96 97* The resolution of ``pthread_cond_timedwait()`` timeouts is the RTOS tick period (see :ref:`CONFIG_FREERTOS_HZ`). Timeouts may be delayed up to one tick period after the requested timeout. 98 99.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs 100 101Read/Write Locks 102^^^^^^^^^^^^^^^^ 103 104* ``pthread_rwlock_init()`` 105 - The ``attr`` argument is not implemented and is ignored. 106* ``pthread_rwlock_destroy()`` 107* ``pthread_rwlock_rdlock()`` 108* ``pthread_rwlock_wrlock()`` 109* ``pthread_rwlock_unlock()`` 110 111Static initializer constant ``PTHREAD_RWLOCK_INITIALIZER`` is supported. 112 113 114.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs. Note also that the current pthread reader-writer-locks implementation is based on the condition variable API. The performance is not optimal when locking only for a minimal amount of time like e.g. accessing a simple variable. In these cases with minimal locking time, a simple mutex might be faster. 115 116Thread-Specific Data 117^^^^^^^^^^^^^^^^^^^^ 118 119* ``pthread_key_create()`` 120 - The ``destr_function`` argument is supported and will be called if a thread function exits normally, calls ``pthread_exit()``, or if the underlying task is deleted directly using the FreeRTOS function :cpp:func:`vTaskDelete`. 121* ``pthread_key_delete()`` 122* ``pthread_setspecific()`` / ``pthread_getspecific()`` 123 124.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs 125 126.. note:: There are other options for thread local storage in ESP-IDF, including options with higher performance. See :doc:`/api-guides/thread-local-storage`. 127 128Not Implemented 129--------------- 130 131The ``pthread.h`` header is a standard header and includes additional APIs and features which are not implemented in ESP-IDF. These include: 132 133* ``pthread_cancel()`` returns ``ENOSYS`` if called. 134* ``pthread_condattr_init()`` returns ``ENOSYS`` if called. 135 136Other POSIX Threads functions (not listed here) are not implemented and will produce either a compiler or a linker error if referenced from an ESP-IDF application. If you identify a useful API that you would like to see implemented in ESP-IDF, please open a `feature request on GitHub <https://github.com/espressif/esp-idf/issues>` with the details. 137 138.. _esp-pthread: 139 140ESP-IDF Extensions 141------------------ 142 143The API :cpp:func:`esp_pthread_set_cfg` defined in the ``esp_pthreads.h`` header offers custom extensions to control how subsequent calls to ``pthread_create()`` will behave. Currently the following configuration can be set: 144 145.. list:: 146 - Default stack size of new threads, if not specified when calling ``pthread_create()`` (overrides :ref:`CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT`). 147 - RTOS priority of new threads (overrides :ref:`CONFIG_PTHREAD_TASK_PRIO_DEFAULT`). 148 :not CONFIG_FREERTOS_UNICORE: - Core affinity / core pinning of new threads (overrides :ref:`CONFIG_PTHREAD_TASK_CORE_DEFAULT`). 149 - FreeRTOS task name for new threads (overrides :ref:`CONFIG_PTHREAD_TASK_NAME_DEFAULT`) 150 151This configuration is scoped to the calling thread (or FreeRTOS task), meaning that :cpp:func:`esp_pthread_set_cfg` can be called independently in different threads or tasks. If the ``inherit_cfg`` flag is set in the current configuration then any new thread created will inherit the creator's configuration (if that thread calls ``pthread_create()`` recursively), otherwise the new thread will have the default configuration. 152 153Examples 154-------- 155 156- :example:`system/pthread` demonstrates using the pthreads API to create threads 157- :example:`cxx/pthread` demonstrates using C++ Standard Library functions with threads 158 159 160API Reference 161------------- 162 163.. include-build-file:: inc/esp_pthread.inc 164 165