Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests/core/thread_msg: lower thread priority for consistent output order #20989

Merged
merged 1 commit into from
Nov 26, 2024

Conversation

mguetschow
Copy link
Contributor

Contribution description

For some reason, the threads are (seemingly?) scheduled differently on nrf52840dk and feather-nrf52840-sense, at least the output order is not consistent. This PR changes the child threads to have a lower priority than the main thread so that "THREADS STARTED" is always printed first.

Testing procedure

make -C tests/core/thread_msg BOARD=feather-nrf52840-sense flash test

fails on master, passes with this PR

Issues/PRs references

Encountered while working on #20980

@github-actions github-actions bot added the Area: tests Area: tests and testing framework label Nov 14, 2024
@mguetschow mguetschow added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Nov 14, 2024
@benpicco benpicco requested a review from kaspar030 November 14, 2024 14:22
@riot-ci
Copy link

riot-ci commented Nov 14, 2024

Murdock results

✔️ PASSED

149a26e tests/core/thread_msg: lower thread priority for consistent output order

Success Failures Total Runtime
132 0 133 01m:45s

Artifacts

@mguetschow mguetschow requested a review from benpicco November 15, 2024 13:51
@mguetschow mguetschow requested a review from maribu November 26, 2024 09:49
@maribu
Copy link
Member

maribu commented Nov 26, 2024

OK, I think I can explain the behavior: The threads are created with THREAD_CREATE_WOUT_YIELD, so the main thread should continue and the threads should only ever get started when the main thread yields or blocks for other reasons.

If stdio is primitive, e.g. no DMA and actively feeding data into an UART peripheral, the main thread will be busy until the msg_receive() is called, which is the first point in time it will block. Only then the scheduler is run and the others threads get scheduled.

If however stdio is fancy (e.g. UART with DMA or USB CDC ACM), the stdio access will block and the other threads get run before the printing is complete.

I think we should also drop the THREAD_CREATE_WOUT_YIELD, so that the behavior is less confusing.

@mguetschow
Copy link
Contributor Author

Thanks, that at least explains the difference between both tested boards. However, I still don't understand why changing the thread priority then fixes the order: If the main thread is busy waiting for fancy stdio, the other two threads would already be runnable and could start executing right away, too.

Maybe the explanation is actually that the fancy stdio incurs some interrupts which trigger a context switch even before the main thread blocking for stdout as per the documentation?

Purely for optimization. Any other context switch (i.e. an interrupt) can still start the thread at any time!

@maribu
Copy link
Member

maribu commented Nov 26, 2024

Maybe the explanation is actually that the fancy stdio incurs some interrupts which trigger a context switch even before the main thread blocking for stdout as per the documentation?

E.g. for UART with DMA they will cause IRQs, but I do believe that at this point the higher prio threads will already be running anyway. My mental model is for UART using DMA is:

  1. Enable an IRQ on TX completion
  2. Set up the DMA transfer to the peripheral and the peripheral to send out the data from DMA
  3. Trigger the transaction
  4. block (e.g. mutex_lock() on a locked mutex) --> Scheduling happens here, higher prio thread get run
  5. from TX complete ISR: unblock the thread (e.g. mutex_unlock())

In any case, relying on THREAD_CREATE_WOUT_YIELD for ordering is not a reliable thing to do. But if we create the threads at a lower priority than the main thread, thread_create() will not run them anyway, regardless of THREAD_CREATE_WOUT_YIELD. That is why IMHO the use of the THREAD_CREATE_WOUT_YIELD is confusing when creating threads with a lower priority than the running one.

also drop THREAD_CREATE_WOUT_YIELD flag, since it is not sensible to use when creating lower-priority threads
@mguetschow mguetschow force-pushed the tests-thread-priority branch from aa137bc to 149a26e Compare November 26, 2024 12:09
@mguetschow
Copy link
Contributor Author

I think we should also drop the THREAD_CREATE_WOUT_YIELD, so that the behavior is less confusing.

Okay, done, and directly squashed.

@maribu maribu enabled auto-merge November 26, 2024 12:09
@maribu maribu added this pull request to the merge queue Nov 26, 2024
Merged via the queue into RIOT-OS:master with commit d0e4f4d Nov 26, 2024
26 checks passed
@mguetschow
Copy link
Contributor Author

Thanks!

@mguetschow mguetschow deleted the tests-thread-priority branch November 26, 2024 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants