pw_thread/backends: Expand docs

Expands the docs for the pw_thread backends. Most notably the
ThreadX pw_thread docs are grossly expanded.

Also makes some small parallel changes to the ThreadX context and
option headers.

Change-Id: I53d35b83de8b914c566170d20f2509763ce6b4b1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/70532
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Ewout van Bekkum <ewout@google.com>
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
diff --git a/pw_thread_embos/docs.rst b/pw_thread_embos/docs.rst
index 7dd9f64..3bdbc4b 100644
--- a/pw_thread_embos/docs.rst
+++ b/pw_thread_embos/docs.rst
@@ -39,11 +39,11 @@
   void StartExampleThread() {
     pw::thread::DetachedThread(
         pw::thread::embos::Options()
-            .set_name("static_example_thread")
+            .set_name("example_thread")
             .set_priority(kFooPriority)
             .set_time_slice_interval(kFooTimeSliceInterval)
             .set_context(example_thread_context),
-        example_thread_function)
+        example_thread_function);
   }
 
 
@@ -172,8 +172,7 @@
 An ``Aborted`` error status is returned if the provided callback returns
 ``false`` to request an early termination of thread iteration.
 
-Return values
--------------
+*Return values*
 
 * ``FailedPrecondition``: Returned when ``ForEachThread()`` is run before the OS
   has been initialized.
@@ -186,8 +185,8 @@
 This ``pw_thread`` backend provides helper functions that capture embOS thread
 info to a ``pw::thread::Thread`` proto.
 
-SnapshotThread()/SnapshotThreads()
-==================================
+``SnapshotThreads()``
+=====================
 ``SnapshotThread()`` captures the thread name, state, and stack information for
 the provided embOS TCB to a ``pw::thread::Thread`` protobuf encoder. To ensure
 the most up-to-date information is captured, the stack pointer for the currently
diff --git a/pw_thread_freertos/docs.rst b/pw_thread_freertos/docs.rst
index d0f22c2..4e50030 100644
--- a/pw_thread_freertos/docs.rst
+++ b/pw_thread_freertos/docs.rst
@@ -41,7 +41,7 @@
             .set_name("static_example_thread")
             .set_priority(kFooPriority)
             .set_static_context(example_thread_context),
-        example_thread_function)
+        example_thread_function);
   }
 
 Alternatively when ``PW_THREAD_FREERTOS_CONFIG_DYNAMIC_ALLOCATION_ENABLED`` is
@@ -182,8 +182,10 @@
 from a thread.
 
 ---------
-utilities
+Utilities
 ---------
+``ForEachThread()``
+===================
 In cases where an operation must be performed for every thread,
 ``ForEachThread()`` can be used to iterate over all the created thread TCBs.
 Note that it's only safe to use this while the scheduler and interrupts are
@@ -195,8 +197,7 @@
 An ``Aborted`` error status is returned if the provided callback returns
 ``false`` to request an early termination of thread iteration.
 
-Return values
-=============
+*Return values*
 
 * ``FailedPrecondition``: Returned when ``ForEachThread()`` is run before the OS
   has been initialized.
@@ -228,8 +229,8 @@
 that this definition matches the size of FreeRTOS's ``StaticTask_T`` which is
 the public opaque TCB type.
 
-SnapshotThread()/SnapshotThreads()
-==================================
+``SnapshotThreads()``
+=====================
 ``SnapshotThread()`` captures the thread name, state, and stack information for
 the provided TCB to a ``pw::thread::Thread`` protobuf encoder. To ensure
 the most up-to-date information is captured, the stack pointer for the currently
diff --git a/pw_thread_threadx/docs.rst b/pw_thread_threadx/docs.rst
index 116d1f1..4b73a40 100644
--- a/pw_thread_threadx/docs.rst
+++ b/pw_thread_threadx/docs.rst
@@ -8,6 +8,44 @@
 .. Warning::
   This module is still under construction, the API is not yet stable.
 
+-----------------------
+Thread Creation Backend
+-----------------------
+A backend for ``pw::thread::Thread`` is offered using ``tx_thread_create``.
+Optional joining support is enabled via an ``TX_EVENT_FLAGS_GROUP`` in each
+thread's context.
+
+This backend permits users to start threads where contexts must be explicitly
+allocated and passed in as an option. As a quick example, a detached thread can
+be created as follows:
+
+.. code-block:: cpp
+
+  #include "pw_thread/detached_thread.h"
+  #include "pw_thread_threadx/config.h"
+  #include "pw_thread_threadx/context.h"
+  #include "pw_thread_threadx/options.h"
+  #include "tx_api.h"
+
+  constexpr UINT kFooPriority =
+      pw::thread::threadx::config::kDefaultPriority;
+  constexpr ULONG kFooTimeSliceInterval =
+      pw::thread::threadx::config::kDefaultTimeSliceInterval;
+  constexpr size_t kFooStackSizeWords =
+      pw::thread::threadx::config::kDefaultStackSizeWords;
+
+  pw::thread::threadx::ContextWithStack<kFooStackSizeWords>
+      example_thread_context;
+  void StartExampleThread() {
+    pw::thread::DetachedThread(
+        pw::thread::threadx::Options()
+            .set_name("example_thread")
+            .set_priority(kFooPriority)
+            .set_time_slice_interval(kFooTimeSliceInterval)
+            .set_context(example_thread_context),
+        example_thread_function);
+  }
+
 .. list-table::
 
   * - :ref:`module-pw_thread` Facade
@@ -78,9 +116,98 @@
 
   The log level to use for this module. Logs below this level are omitted.
 
+ThreadX Thread Options
+======================
+.. cpp:class:: pw::thread::threadx::Options
+
+  .. cpp:function:: set_name(const char* name)
+
+     Sets the name for the ThreadX thread, note that this will be deep copied
+     into the context and may be truncated based on
+     ``PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN``.
+
+  .. cpp:function:: set_priority(UINT priority)
+
+     Sets the priority for the ThreadX thread from 0 through 31, where a value
+     of 0 represents the highest priority, see ThreadX tx_thread_create for
+     more detail.
+
+     **Precondition**: priority <= ``PW_THREAD_THREADX_CONFIG_MIN_PRIORITY``.
+
+  .. cpp:function:: set_preemption_threshold(UINT preemption_threshold)
+
+     Optionally sets the preemption threshold for the ThreadX thread from 0
+     through 31.
+
+     Only priorities higher than this level (i.e. lower number) are allowed to
+     preempt this thread. In other words this allows the thread to specify the
+     priority ceiling for disabling preemption. Threads that have a higher
+     priority than the ceiling are still allowed to preempt while those with
+     less than the ceiling are not allowed to preempt.
+
+     Not setting the preemption threshold or explicitly specifying a value
+     equal to the priority disables preemption threshold.
+
+     Time slicing is disabled while the preemption threshold is enabled, i.e.
+     not equal to the priority, even if a time slice interval was specified.
+
+     The preemption threshold can be adjusted at run time, this only sets the
+     initial threshold.
+
+     **Precondition**: preemption_threshold <= priority
+
+  .. cpp:function:: set_time_slice_interval(UINT time_slice_interval)
+
+     Sets the number of ticks this thread is allowed to run before other ready
+     threads of the same priority are given a chance to run.
+
+     Time slicing is disabled while the preemption threshold is enabled, i.e.
+     not equal to the priority, even if a time slice interval was specified.
+
+     A value of ``TX_NO_TIME_SLICE`` (a value of 0) disables time-slicing of
+     this thread.
+
+     Using time slicing results in a slight amount of system overhead, threads
+     with a unique priority should consider ``TX_NO_TIME_SLICE``.
+
+
+  .. cpp:function:: set_context(pw::thread::embos::Context& context)
+
+     Set the pre-allocated context (all memory needed to run a thread). Note
+     that this is required for this thread creation backend! The Context can
+     either be constructed with an externally provided ``std::span<ULONG>``
+     stack or the templated form of ``ContextWihtStack<kStackSizeWords`` can be
+     used.
+
+-----------------------------
+Thread Identification Backend
+-----------------------------
+A backend for ``pw::thread::Id`` and ``pw::thread::get_id()`` is offerred using
+``tx_thread_identify()``. It uses ``DASSERT`` to ensure that a thread is
+executing via ``TX_THREAD_GET_SYSTEM_STATE()``.
+
+--------------------
+Thread Sleep Backend
+--------------------
+A backend for ``pw::thread::sleep_for()`` and ``pw::thread::sleep_until()`` is
+offerred using ``tx_thread_sleep()`` if the duration is at least one tick, else
+``tx_thread_relinquish()`` is used. It uses
+``pw::this_thread::get_id() != thread::Id()`` to ensure it invoked only from a
+thread.
+
+--------------------
+Thread Yield Backend
+--------------------
+A backend for ``pw::thread::yield()`` is offered using via
+``tx_thread_relinquish()``. It uses
+``pw::this_thread::get_id() != thread::Id()`` to ensure it invoked only from a
+thread.
+
 ---------
-utilities
+Utilities
 ---------
+``ForEachThread()``
+===================
 In cases where an operation must be performed for every thread,
 ``ForEachThread()`` can be used to iterate over all the created thread TCBs.
 Note that it's only safe to use this while the scheduler is disabled.
@@ -88,8 +215,7 @@
 An ``Aborted`` error status is returned if the provided callback returns
 ``false`` to request an early termination of thread iteration.
 
-Return values
-=============
+*Return values*
 
 * ``Aborted``: The callback requested an early-termination of thread iteration.
 * ``OkStatus``: The callback has been successfully run with every thread.
@@ -100,8 +226,8 @@
 This ``pw_thread`` backend provides helper functions that capture ThreadX thread
 state to a ``pw::thread::Thread`` proto.
 
-SnapshotThread()/SnapshotThreads()
-==================================
+``SnapshotThreads()``
+=====================
 ``SnapshotThread()`` captures the thread name, state, and stack information for
 the provided ThreadX TCB to a ``pw::thread::Thread`` protobuf encoder. To ensure
 the most up-to-date information is captured, the stack pointer for the currently
diff --git a/pw_thread_threadx/public/pw_thread_threadx/context.h b/pw_thread_threadx/public/pw_thread_threadx/context.h
index b36c420..8d5c87c 100644
--- a/pw_thread_threadx/public/pw_thread_threadx/context.h
+++ b/pw_thread_threadx/public/pw_thread_threadx/context.h
@@ -38,12 +38,12 @@
 //   std::array<ULONG, kFooStackSizeWords> example_thread_stack;
 //   pw::thread::threadx::Context example_thread_context(example_thread_stack);
 //   void StartExampleThread() {
-//      pw::thread::Thread(
+//      pw::thread::DetachedThread(
 //        pw::thread::threadx::Options()
-//            .set_name("static_example_thread")
+//            .set_name("example_thread")
 //            .set_priority(kFooPriority)
-//            .set_static_context(example_thread_context),
-//        example_thread_function).detach();
+//            .set_context(example_thread_context),
+//        example_thread_function);
 //   }
 class Context {
  public:
diff --git a/pw_thread_threadx/public/pw_thread_threadx/options.h b/pw_thread_threadx/public/pw_thread_threadx/options.h
index 7c130a1..079b587 100644
--- a/pw_thread_threadx/public/pw_thread_threadx/options.h
+++ b/pw_thread_threadx/public/pw_thread_threadx/options.h
@@ -31,7 +31,7 @@
 //   pw::thread::Thread example_thread(
 //     pw::thread::threadx::Options()
 //         .set_name("example_thread"),
-//         .set_context(static_example_thread_context),
+//         .set_context(example_thread_context),
 //     example_thread_function);
 //
 //   // Specifies the name, priority, time slice interval, and pre-allocated
@@ -41,7 +41,7 @@
 //         .set_name("static_example_thread")
 //         .set_priority(kFooPriority)
 //         .set_time_slice_interval(1)
-//         .set_context(static_example_thread_context),
+//         .set_context(example_thread_context),
 //     example_thread_function);
 //
 class Options : public thread::Options {
@@ -61,6 +61,8 @@
   // Sets the priority for the ThreadX thread from 0 through 31, where a value
   // of 0 represents the highest priority, see ThreadX tx_thread_create for
   // more detail.
+  //
+  // Precondition: priority <= PW_THREAD_THREADX_CONFIG_MIN_PRIORITY
   constexpr Options& set_priority(UINT priority) {
     PW_DASSERT(priority <= PW_THREAD_THREADX_CONFIG_MIN_PRIORITY);
     priority_ = priority;
@@ -108,8 +110,10 @@
     return *this;
   }
 
-  // Set the pre-allocated context (all memory needed to run a thread), see the
-  // pw::thread::threadx::Context for more detail.
+  // Set the pre-allocated context (all memory needed to run a thread). Note
+  // that this is required for this thread creation backend! The Context can
+  // either be constructed with an externally provided std::span<ULONG> stack
+  // or the templated form of ContextWihtStack<kStackSizeWords> can be used.
   constexpr Options& set_context(Context& context) {
     context_ = &context;
     return *this;