pw_thread_threadx: apply pw_thread_embos style changes

Change-Id: I5a22c093df0de2f1e2f0753a58cfc670490973f4
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/45422
Reviewed-by: Keir Mierle <keir@google.com>
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
Commit-Queue: Ewout van Bekkum <ewout@google.com>
diff --git a/pw_thread_threadx/BUILD b/pw_thread_threadx/BUILD
index a333d23..f69e160 100644
--- a/pw_thread_threadx/BUILD
+++ b/pw_thread_threadx/BUILD
@@ -65,6 +65,7 @@
     deps = [
         ":id",
         "//pw_assert",
+        "//pw_string",
         "//pw_thread:thread_headers",
     ],
     # TODO(pwbug/317): This should depend on ThreadX but our third parties
diff --git a/pw_thread_threadx/BUILD.gn b/pw_thread_threadx/BUILD.gn
index f7a090b..79d475a 100644
--- a/pw_thread_threadx/BUILD.gn
+++ b/pw_thread_threadx/BUILD.gn
@@ -104,6 +104,7 @@
   public_deps = [
     ":config",
     "$dir_pw_assert",
+    "$dir_pw_string",
     "$dir_pw_third_party/threadx",
     "$dir_pw_thread:id",
     "$dir_pw_thread:thread.facade",
diff --git a/pw_thread_threadx/public/pw_thread_threadx/config.h b/pw_thread_threadx/public/pw_thread_threadx/config.h
index a47e1eb..14405e2 100644
--- a/pw_thread_threadx/public/pw_thread_threadx/config.h
+++ b/pw_thread_threadx/public/pw_thread_threadx/config.h
@@ -17,8 +17,16 @@
 #include "tx_api.h"
 
 // Whether thread joining is enabled. By default this is disabled.
-// When enabled this adds a TX_EVENT_FLAGS_GROUP to every pw::thread::Thread's
-// context.
+//
+// We suggest only enabling this when thread joining is required to minimize
+// the RAM and ROM cost of threads.
+//
+// Enabling this grows the RAM footprint of every pw::thread::Thread as it adds
+// a TX_EVENT_FLAGS_GROUP to every thread's pw::thread::threadx::Context. In
+// addition, there is a minute ROM cost to construct and destroy this added
+// object.
+//
+// PW_THREAD_JOINING_ENABLED gets set to this value.
 #ifndef PW_THREAD_THREADX_CONFIG_JOINING_ENABLED
 #define PW_THREAD_THREADX_CONFIG_JOINING_ENABLED 0
 #endif  // PW_THREAD_THREADX_CONFIG_JOINING_ENABLED
@@ -28,7 +36,7 @@
 // stack size.
 #ifndef PW_THREAD_THREADX_CONFIG_DEFAULT_STACK_SIZE_WORDS
 #define PW_THREAD_THREADX_CONFIG_DEFAULT_STACK_SIZE_WORDS \
-  TX_MINIMUM_STACK / sizeof(ULONG)
+  (TX_MINIMUM_STACK / sizeof(ULONG))
 #endif  // PW_THREAD_THREADX_CONFIG_DEFAULT_STACK_SIZE_WORDS
 
 // The maximum length of a thread's name, not including null termination. By
@@ -48,7 +56,7 @@
 // The minimum priority level, this is normally based on the number of priority
 // levels.
 #ifndef PW_THREAD_THREADX_CONFIG_MIN_PRIORITY
-#define PW_THREAD_THREADX_CONFIG_MIN_PRIORITY TX_MAX_PRIORITIES - 1
+#define PW_THREAD_THREADX_CONFIG_MIN_PRIORITY (TX_MAX_PRIORITIES - 1)
 #endif  // PW_THREAD_THREADX_CONFIG_MIN_PRIORITY
 
 // The default priority level. By default this uses the minimal ThreadX
@@ -61,7 +69,7 @@
 namespace pw::thread::threadx::config {
 
 inline constexpr size_t kMaximumNameLength =
-    PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN + 1;
+    PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN;
 inline constexpr size_t kMinimumStackSizeWords =
     TX_MINIMUM_STACK / sizeof(ULONG);
 inline constexpr size_t kDefaultStackSizeWords =
diff --git a/pw_thread_threadx/public/pw_thread_threadx/context.h b/pw_thread_threadx/public/pw_thread_threadx/context.h
index 162e3b3..4d68ac5 100644
--- a/pw_thread_threadx/public/pw_thread_threadx/context.h
+++ b/pw_thread_threadx/public/pw_thread_threadx/context.h
@@ -17,6 +17,7 @@
 #include <cstring>
 #include <span>
 
+#include "pw_string/util.h"
 #include "pw_thread_threadx/config.h"
 #include "tx_api.h"
 #include "tx_thread.h"
@@ -63,17 +64,12 @@
   void set_in_use(bool in_use = true) { in_use_ = in_use; }
 
   const char* name() const { return name_.data(); }
-  void set_name(const char* name) {
-    strncpy(name_.data(), name, name_.size() - 1);
-    // Forcefully NULL terminate as strncpy does not NULL terminate if the count
-    // limit is hit.
-    name_[name_.size() - 1] = '\0';
-  }
+  void set_name(const char* name) { string::Copy(name, name_); }
 
   using ThreadRoutine = void (*)(void* arg);
   void set_thread_routine(ThreadRoutine entry, void* arg) {
-    entry_ = entry;
-    arg_ = arg;
+    user_thread_entry_function_ = entry;
+    user_thread_entry_arg_ = arg;
   }
 
   bool detached() const { return detached_; }
@@ -86,14 +82,14 @@
   TX_EVENT_FLAGS_GROUP& join_event_group() { return event_group_; }
 #endif  // PW_THREAD_JOINING_ENABLED
 
-  static void RunThread(ULONG void_context_ptr);
+  static void ThreadEntryPoint(ULONG void_context_ptr);
   static void DeleteThread(Context& context);
 
   TX_THREAD tcb_;
   std::span<ULONG> stack_span_;
 
-  ThreadRoutine entry_ = nullptr;
-  void* arg_ = nullptr;
+  ThreadRoutine user_thread_entry_function_ = nullptr;
+  void* user_thread_entry_arg_ = nullptr;
 #if PW_THREAD_JOINING_ENABLED
   // Note that the ThreadX life cycle of this event group is managed together
   // with the thread life cycle, not this object's life cycle.
@@ -104,8 +100,8 @@
   bool thread_done_ = false;
 
   // The TCB does not have storage for the name, ergo we provide storage for
-  // the thread's name which can be truncated down to just a null delimeter.
-  std::array<char, config::kMaximumNameLength> name_;
+  // the thread's name which can be truncated down to just a null delimiter.
+  std::array<char, config::kMaximumNameLength + 1> name_;
 };
 
 // Static thread context allocation including the stack along with the Context.
diff --git a/pw_thread_threadx/thread.cc b/pw_thread_threadx/thread.cc
index b3ed29a..673a3ca 100644
--- a/pw_thread_threadx/thread.cc
+++ b/pw_thread_threadx/thread.cc
@@ -30,9 +30,11 @@
 #endif  // PW_THREAD_JOINING_ENABLED
 }  // namespace
 
-void Context::RunThread(ULONG void_context_ptr) {
+void Context::ThreadEntryPoint(ULONG void_context_ptr) {
   Context& context = *reinterpret_cast<Context*>(void_context_ptr);
-  context.entry_(context.arg_);
+
+  // Invoke the user's thread function. This may never return.
+  context.user_thread_entry_function_(context.user_thread_entry_arg_);
 
   // Raise our preemption threshold as a thread only critical section to guard
   // against join() and detach().
@@ -50,8 +52,9 @@
     context.set_in_use(false);
 
 #if PW_THREAD_JOINING_ENABLED
-    // Just in case someone abused our API, ensure their use of the event group
-    // is properly handled by the kernel regardless.
+    // If the thread handle was detached before the thread finished execution,
+    // i.e. got here, then we are responsible for cleaning up the join event
+    // group.
     const UINT event_group_result =
         tx_event_flags_delete(&context.join_event_group());
     PW_DCHECK_UINT_EQ(TX_SUCCESS,
@@ -144,7 +147,7 @@
   const UINT thread_result =
       tx_thread_create(&options.context()->tcb(),
                        const_cast<char*>(native_type_->name()),
-                       Context::RunThread,
+                       Context::ThreadEntryPoint,
                        reinterpret_cast<ULONG>(native_type_),
                        options.context()->stack().data(),
                        options.context()->stack().size_bytes(),
@@ -164,12 +167,12 @@
   tx_thread_resume(&native_type_->tcb());
 
   if (thread_done) {
-    // The task finished (hit end of Context::RunThread) before we invoked
-    // detach, clean up the thread.
+    // The task finished (hit end of Context::ThreadEntryPoint) before we
+    // invoked detach, clean up the thread.
     Context::DeleteThread(*native_type_);
   } else {
     // We're detaching before the task finished, defer cleanup to the task at
-    // the end of Context::RunThread.
+    // the end of Context::ThreadEntryPoint.
   }
 
   // Update to no longer represent a thread of execution.