Skip to content

Commit

Permalink
pw_thread_freertos/thread: Require INCLUDE_xTaskGetSchedulerState == 1
Browse files Browse the repository at this point in the history
Updates the FreeRTOS pw_thread backend to require
INCLUDE_xTaskGetSchedulerState == 1, as vTaskSuspendAll and
vTaskResumeAll are not safe to run before the scheduler has been
started.

Also corrects a typo in an #error for pw_sync_freertos.

Change-Id: Ic7f788c2341ca4ab537fab9b2b324ed4eb2aecd4
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/126214
Pigweed-Auto-Submit: Ewout van Bekkum <[email protected]>
Commit-Queue: Auto-Submit <[email protected]>
Reviewed-by: Wyatt Hepler <[email protected]>
  • Loading branch information
Ewout van Bekkum authored and CQ Bot Account committed Jan 6, 2023
1 parent eebe54a commit 034d827
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pw_sync_freertos/interrupt_spin_lock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
namespace pw::sync {

#if (INCLUDE_xTaskGetSchedulerState != 1) && (configUSE_TIMERS != 1)
#error "xTaskGetScheduler is required for pw_sync_freertos:interrupt_spin_lock"
#error "xTaskGetSchedulerState is required for pw::sync::InterruptSpinLock"
#endif

void InterruptSpinLock::lock() {
Expand Down
4 changes: 4 additions & 0 deletions pw_thread_freertos/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ Optional dynamic allocation for threads is supported using ``xTaskCreate()``.
Optional joining support is enabled via an ``StaticEventGroup_t`` in each
thread's context.

.. Note::
Scheduler State API support is required in your FreeRTOS Configuration, i.e.
``INCLUDE_xTaskGetSchedulerState == 1``.

This backend always permits users to start threads where static contexts are
passed in as an option. As a quick example, a detached thread can be created as
follows:
Expand Down
23 changes: 12 additions & 11 deletions pw_thread_freertos/thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ using pw::thread::freertos::Context;

namespace pw::thread {
namespace {

#if (INCLUDE_xTaskGetSchedulerState != 1) && (configUSE_TIMERS != 1)
#error "xTaskGetSchedulerState is required for pw::thread::Thread"
#endif

#if PW_THREAD_JOINING_ENABLED
constexpr EventBits_t kThreadDoneBit = 1 << 0;
#endif // PW_THREAD_JOINING_ENABLED
Expand Down Expand Up @@ -188,27 +193,23 @@ Thread::Thread(const thread::Options& facade_options,
void Thread::detach() {
PW_CHECK(joinable());

#if (INCLUDE_vTaskSuspend == 1) && (INCLUDE_xTaskGetSchedulerState == 1)
// No need to suspend extra tasks.
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
#if (INCLUDE_vTaskSuspend == 1)
// No need to suspend extra tasks.
vTaskSuspend(native_type_->task_handle());
}
#else
// Safe to suspend all tasks while scheduler is not running.
vTaskSuspendAll();
vTaskSuspendAll();
#endif // INCLUDE_vTaskSuspend == 1
}
native_type_->set_detached();
const bool thread_done = native_type_->thread_done();
#if (INCLUDE_vTaskSuspend == 1) && (INCLUDE_xTaskGetSchedulerState == 1)
// No need to suspend extra tasks, but only safe to call once scheduler is
// running.
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
#if (INCLUDE_vTaskSuspend == 1)
vTaskResume(native_type_->task_handle());
}
#else
// Safe to resume all tasks while scheduler is not running.
xTaskResumeAll();
xTaskResumeAll();
#endif // INCLUDE_vTaskSuspend == 1
}

if (thread_done) {
// The task finished (hit end of Context::ThreadEntryPoint) before we
Expand Down

0 comments on commit 034d827

Please sign in to comment.