.. _module-pw_thread:

=========
pw_thread
=========
The ``pw_thread`` module contains utilities for thread creation and thread
execution.

.. Warning::
  This module is still under construction, the API is not yet stable.

---------------
Thread Sleeping
---------------
C++
===
.. cpp:function:: void pw::this_thread::sleep_for(chrono::SystemClock::duration sleep_duration)

   Blocks the execution of the current thread for at least the specified
   duration. This function may block for longer due to scheduling or resource
   contention delays.

   A sleep duration of 0 will at minimum yield, meaning it will provide a hint
   to the implementation to reschedule the execution of threads, allowing other
   threads to run.

   **Precondition:** This can only be called from a thread, meaning the
   scheduler is running.

.. cpp:function:: void pw::this_thread::sleep_until(chrono::SystemClock::time_point wakeup_time)

   Blocks the execution of the current thread until at least the specified
   time has been reached. This function may block for longer due to scheduling
   or resource contention delays.

   A sleep deadline in the past up to the current time will at minimum yield
   meaning it will provide a hint to the implementation to reschedule the
   execution of threads, allowing other threads to run.

   **Precondition:** This can only be called from a thread, meaning the
   scheduler is running.

Examples in C++
---------------
.. code-block:: cpp

  #include <chrono>

  #include "pw_chrono/system_clock.h"
  #include "pw_thread/sleep.h"

  using std::literals::chrono_literals::ms;

  void FunctionInvokedByThread() {
    pw::this_thread::sleep_for(42ms);
  }

  void AnotherFunctionInvokedByThread() {
    pw::this_thread::sleep_until(pw::chrono::SystemClock::now() + 42ms);
  }

C
=
.. cpp:function:: void pw_this_thread_SleepFor(pw_chrono_SystemClock_Duration sleep_duration)

   Invokes ``pw::this_thread::sleep_until(sleep_duration)``.

.. cpp:function:: void pw_this_thread_SleepUntil(pw_chrono_SystemClock_TimePoint wakeup_time)

   Invokes ``pw::this_thread::sleep_until(wakeup_time)``.


---------------
Thread Yielding
---------------
C++
===
.. cpp:function:: void pw::this_thread::yield() noexcept

   Provides a hint to the implementation to reschedule the execution of threads,
   allowing other threads to run.

   The exact behavior of this function depends on the implementation, in
   particular on the mechanics of the OS scheduler in use and the state of the
   system.

   **Precondition:** This can only be called from a thread, meaning the
   scheduler is running.

Example in C++
---------------
.. code-block:: cpp

  #include "pw_thread/yield.h"

  void FunctionInvokedByThread() {
    pw::this_thread::yield();
  }

C
=
.. cpp:function:: void pw_this_thread_Yield(void)

   Invokes ``pw::this_thread::yield()``.

---------------------
Thread Identification
---------------------
The class ``pw::thread::Id`` is a lightweight, trivially copyable class that
serves as a unique identifier of Thread objects.

Instances of this class may also hold the special distinct value that does
not represent any thread. Once a thread has finished, the value of its
Thread::id may be reused by another thread.

This class is designed for use as key in associative containers, both ordered
and unordered.

Although the current API is similar to C++11 STL
`std::thread::id <https://en.cppreference.com/w/cpp/thread/thread/id>`_, it is
missing the required hashing and streaming operators and may diverge further in
the future.

A thread's identification (``pw::thread::Id``) can be acquired only in C++ in
one of two ways:

1) Using the ``pw::thread::Thread`` handle's ``pw::thread::Id get_id() const``
   method.
2) While executing the thread using
   ``pw::thread::Id pw::this_thread::get_id() noexcept``.

.. cpp:function:: pw::thread::Id pw::this_thread::get_id() noexcept

   This is thread safe, not IRQ safe. It is implementation defined whether this
   is safe before the scheduler has started.


Example
=======
.. code-block:: cpp

  #include "pw_thread/id.h"

  void FunctionInvokedByThread() {
    const pw::thread::Id my_id = pw::this_thread::get_id();
  }

---------------
Thread Creation
---------------
The class ``pw::thread::Thread`` can represent a single thread of execution.
Threads allow multiple functions to execute concurrently.

The Thread's API is C++11 STL
`std::thread <https://en.cppreference.com/w/cpp/thread/thread>`_ like, meaning
the object is effectively a thread handle and not an object which contains the
thread's context. Unlike ``std::thread``, the API requires
``pw::thread::Options`` as an argument and is limited to only work with
``pw::thread::ThreadCore`` objects and functions which match the
``pw::thread::Thread::ThreadRoutine`` signature.

We recognize that the C++11's STL ``std::thread``` API has some drawbacks where
it is easy to forget to join or detach the thread handle. Because of this, we
offer helper wrappers like the ``pw::thread::DetachedThread``. Soon we will
extend this by also adding a ``pw::thread::JoiningThread`` helper wrapper which
will also have a lighter weight C++20 ``std::jthread`` like cooperative
cancellation contract to make joining safer and easier.

Threads may begin execution immediately upon construction of the associated
thread object (pending any OS scheduling delays), starting at the top-level
function provided as a constructor argument. The return value of the
top-level function is ignored. The top-level function may communicate its
return value by modifying shared variables (which may require
synchronization, see :ref:`module-pw_sync`)

Thread objects may also be in the state that does not represent any thread
(after default construction, move from, detach, or join), and a thread of
execution may be not associated with any thread objects (after detach).

No two Thread objects may represent the same thread of execution; Thread is
not CopyConstructible or CopyAssignable, although it is MoveConstructible and
MoveAssignable.

.. list-table::

  * - *Supported on*
    - *Backend module*
  * - FreeRTOS
    - :ref:`module-pw_thread_freertos`
  * - ThreadX
    - :ref:`module-pw_thread_threadx`
  * - embOS
    - :ref:`module-pw_thread_embos`
  * - STL
    - :ref:`module-pw_thread_stl`
  * - Zephyr
    - Planned
  * - CMSIS-RTOS API v2 & RTX5
    - Planned

Module Configuration Options
============================
The following configurations can be adjusted via compile-time configuration of
this module, see the
:ref:`module documentation <module-structure-compile-time-configuration>` for
more details.

.. c:macro:: PW_THREAD_CONFIG_LOG_LEVEL

  The log level to use for this module. Logs below this level are omitted.

Options
=======
The ``pw::thread::Options`` contains the parameters or attributes needed for a
thread to start.

Pigweed does not generalize options, instead we strive to give you full control
where we provide helpers to do this.

Options are backend specific and ergo the generic base class cannot be
directly instantiated.

The attributes which can be set through the options are backend specific
but may contain things like the thread name, priority, scheduling policy,
core/processor affinity, and/or an optional reference to a pre-allocated
Context (the collection of memory allocations needed for a thread to run).

Options shall NOT permit starting as detached, this must be done explicitly
through the Thread API.

Options must not contain any memory needed for a thread to run (TCB,
stack, etc.). The Options may be deleted or re-used immediately after
starting a thread.

Options subclass must contain non-default explicit constructor (parametrized or
not), e.g. ``constexpr Options() {}``. It is not enough to have them as
``= default`` ones, because C++17 considers subclasses like ``stl::Options`` as
aggregate classes if they have a default constructor and requires base class
constructor to be public (which is not the case for the ``thread::Options``) for
``Options{}`` syntax.

Please see the thread creation backend documentation for how their Options work.

Portable Thread Creation
========================
Due to the fact that ``pw::thread::Options`` cannot be created in portable code,
some extra work must be done in order to permit portable thread creation.
Namely, a reference to the portable ``pw::thread::Options`` base class interface
must be provided through a header or extern which points to an instantiation in
non-portable code.

This can be most easily done through a facade and set of backends. This approach
can be powerful; enabling multithreaded unit/integration testing which can run
on both the host and on a device with the device's exact thread options.

Alternatively, it can also be be injected at build time by instantiating backend
specific build rule which share the same common portable source file(s) but
select backend specific source files and/or dependencies which provide the
non-portable option instantiations.

As an example, let's say we want to create a thread on the host and on a device
running FreeRTOS. They could use a facade which contains a ``threads.h`` header
with the following contents:

.. code-block:: cpp

  // Contents of my_app/threads.h
  #pragma once

  #include "pw_thread/options.h"

  namespace my_app {

  const pw::thread::Options& HellowWorldThreadOptions();

  }  // namespace my_app

This could then be backed by two different backend implementations based on
the thread backend. For example for the STL the backend's ``stl_threads.cc``
source file may look something like:

.. code-block:: cpp

  // Contents of my_app/stl_threads.cc
  #include "my_app/threads.h"
  #include "pw_thread_stl/options.h"

  namespace my_app {

  const pw::thread::Options& HelloWorldThreadOptions() {
    static constexpr auto options = pw::thread::stl::Options();
    return options;
  }

  }  // namespace my_app

While for FreeRTOS the backend's ``freertos_threads.cc`` source file may look
something like:

.. code-block:: cpp

  // Contents of my_app/freertos_threads.cc
  #include "FreeRTOS.h"
  #include "my_app/threads.h"
  #include "pw_thread_freertos/context.h"
  #include "pw_thread_freertos/options.h"
  #include "task.h"

  namespace my_app {

  StaticContextWithStack<kHelloWorldStackWords> hello_world_thread_context;
  const pw::thread::Options& HelloWorldThreadOptions() {
    static constexpr auto options =
        pw::thread::freertos::Options()
            .set_name("HelloWorld")
            .set_static_context(hello_world_thread_context)
            .set_priority(kHelloWorldThreadPriority);
    return options;
  }

  }  // namespace my_app


Detaching & Joining
===================
The ``Thread::detach()`` API is always available, to let you separate the
thread of execution from the thread object, allowing execution to continue
independently.

The joining API, more specifically ``Thread::join()``, is conditionally
available depending on the selected backend for thread creation and how it is
configured. The backend is responsible for providing the
``PW_THREAD_JOINING_ENABLED`` macro through
``pw_thread_backend/thread_native.h``. This ensures that any users which include
``pw_thread/thread.h`` can use this macro if needed.

Please see the selected thread creation backend documentation for how to
enable joining if it's not already enabled by default.

.. Warning::
  A constructed ``pw::thread::Thread`` which represents a thread of execution
  must be EITHER detached or joined, else the destructor will assert!

DetachedThread
==============
To make it slightly easier and cleaner to spawn detached threads without having
to worry about thread handles, a wrapper ``DetachedThread()`` function is
provided which creates a ``Thread`` and immediately detaches it. For example
instead of:

.. code-block:: cpp

  Thread(options, foo).detach();

You can instead use this helper wrapper to:

.. code-block:: cpp

   DetachedThread(options, foo);

The arguments are directly forwarded to the Thread constructor and ergo exactly
match the Thread constuctor arguments for creating a thread of execution.


ThreadRoutine & ThreadCore
==========================
Threads must either be invoked through a
``pw::thread::Thread::ThreadRoutine``` style function or implement the
``pw::thread::ThreadCore`` interface.

.. code-block:: cpp

  namespace pw::thread {

  // This function may return.
  using Thread::ThreadRoutine = void (*)(void* arg);

  class ThreadCore {
   public:
    virtual ~ThreadCore() = default;

    // The public API to start a ThreadCore, note that this may return.
    void Start() { Run(); }

   private:
    // This function may return.
    virtual void Run() = 0;
  };

  }  // namespace pw::thread;


To use the ``pw::thread::Thread::ThreadRoutine``, your function must have the
following signature:

.. code-block:: cpp

  void example_thread_entry_function(void *arg);


To invoke a member method of a class a static lambda closure can be used
to ensure the dispatching closure is not destructed before the thread is
done executing. For example:

.. code-block:: cpp

  class Foo {
   public:
    void DoBar() {}
  };
  Foo foo;

  static auto invoke_foo_do_bar = [](void *void_foo_ptr) {
      //  If needed, additional arguments could be set here.
      static_cast<Foo*>(void_foo_ptr)->DoBar();
  };

  // Now use the lambda closure as the thread entry, passing the foo's
  // this as the argument.
  Thread thread(options, invoke_foo_do_bar, &foo);
  thread.detach();


Alternatively, the aforementioned ``pw::thread::ThreadCore`` interface can be
be implemented by an object by overriding the private
``void ThreadCore::Run();`` method. This makes it easier to create a thread, as
a static lambda closure or function is not needed to dispatch to a member
function without arguments. For example:

.. code-block:: cpp

  class Foo : public ThreadCore {
   private:
    void Run() override {}
  };
  Foo foo;

  // Now create the thread, using foo directly.
  Thread(options, foo).detach();

.. Warning::
  Because the thread may start after the pw::Thread creation, an object which
  implements the ThreadCore MUST meet or exceed the lifetime of its thread of
  execution!

-----------------------
pw_snapshot integration
-----------------------
``pw_thread`` provides some light, optional integration with pw_snapshot through
helper functions for populating a ``pw::thread::Thread`` proto. Some of these
are directly integrated into the RTOS thread backends to simplify the thread
state capturing for snapshots.

SnapshotStack()
===============
The ``SnapshotStack()`` helper captures stack metadata (stack pointer and
bounds) into a ``pw::thread::Thread`` proto. After the stack bounds are
captured, execution is passed off to the thread stack collection callback to
capture a backtrace or stack dump. Note that this function does NOT capture the
thread name: that metadata is only required in cases where a stack overflow or
underflow is detected.

Python processor
================
Threads captured as a Thread proto message can be dumped or further analyzed
using using ``pw_thread``'s Python module. This is directly integrated into
pw_snapshot's processor tool to automatically provide rich thread state dumps.

The ``ThreadSnapshotAnalyzer`` class may also be used directly to identify the
currently running thread and produce symbolized thread dumps.

.. Warning::
  Snapshot integration is a work-in-progress and may see significant API
  changes.
