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

core: make idle thread optional #14224

Merged
merged 7 commits into from
Jun 26, 2020

Conversation

kaspar030
Copy link
Contributor

@kaspar030 kaspar030 commented Jun 8, 2020

Contribution description

This PR makes the idle thread optional, if the architecture implements support for that.
In order to do that, an architecture needs to implement sched_arch_idle() and disable the module core_idle_thread.

The main benefits are:

  • saving a full thread context and stack
  • faster and shorter sleep transitions (no need to schedule idle thread first)

The PR includes an implementation for CortexM3 and higher (M0+ doesn't support dynamically changing IRQ priorities, which the current implementation relies on).

Testing procedure

Any threading application obviously still needs to work. Also, the pm machinery needs to work as before.

Any shell test should confirm that the scheduler is idling (not switching to any thread if there's no runnable) and reacting to ISR (react to uart input and re-schedule shell thread).

I tested power management using tests/periph_pm, confirming that unblocking the right mode for a while makes the shell unresponsive (power mode has been set), and that when the RTC interrupt triggers, shell works again.

edit the commit history looks a bit scary due to #13825 being included. The new logic of this PR is contained in the latest two commits (one for basic support in core, one for the cortexm implementation).

Issues/PRs references

This PR needs #13825, which re-writes the Cortex-M PendSV logic so it can handle the case where there's no thread to save on entry.

@kaspar030 kaspar030 added Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: core Area: RIOT kernel. Handle PRs marked with this with care! Type: new feature The issue requests / The PR implemements a new feature for RIOT CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR Process: needs >1 ACK Integration Process: This PR requires more than one ACK labels Jun 8, 2020
@kaspar030 kaspar030 requested review from maribu and bergzand June 8, 2020 11:05
@bergzand
Copy link
Member

bergzand commented Jun 8, 2020

This breaks the schedstatistics module 😢

@maribu
Copy link
Member

maribu commented Jun 8, 2020

disable the module core_idle_thread.

I would like to inverse the logic. Could we instead have a feature (and corresponding module) such as thread_less_idling, which would always be in FEATURS_OPTIONAL?

Providing a feature instead of disabling a module seems more natural to me.

@kaspar030
Copy link
Contributor Author

Providing a feature instead of disabling a module seems more natural to me.

done

@kaspar030
Copy link
Contributor Author

This breaks the schedstatistics module cry

This'll need reworking the sched_cb logic: sched_cb(sched_active_pid, next_thread->pid); expects ending of one and starting the next thread to happen at the same time.

core/sched.c Outdated
@@ -80,11 +80,14 @@ int __attribute__((used)) sched_run(void)
{
sched_context_switch_request = 0;

#ifndef MODULE_CORE_IDLE_THREAD
while (!runqueue_bitcache) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to self: as is, the compiler must assume that sched_arch_idle() calls a function that modifies runqueue_bitcache (it is static in this compilation unit). With LTO, it might come to a different result. need to make this atomic or volatile.

@kaspar030 kaspar030 added State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet and removed CI: run tests If set, CI server will run tests on hardware for the labeled PR labels Jun 8, 2020
@kaspar030
Copy link
Contributor Author

I marked this WIP, as there's some code that expects that there's always an active thread (e.g., most of the IPC code due to sched_switch()).

@fjmolinas
Copy link
Contributor

this one needs a rebase now :)

@kaspar030 kaspar030 removed the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label Jun 17, 2020
@kaspar030
Copy link
Contributor Author

I marked this WIP, as there's some code that expects that there's always an active thread (e.g., most of the IPC code due to sched_switch()).

It seems to me that all that code is actually called when within thread context, meaning that having no active thread won't happen. So I've removed WIP.

@kaspar030
Copy link
Contributor Author

Turns out the unittest hard fault was caused by too a too small stack for main. I've added a commit to increase it slightly. (stack is also small on master, depending on compiler, it hard faults there without increase. This was unnoticed as the crash happens after finishing the tests).

@kaspar030 kaspar030 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jun 25, 2020
@bergzand bergzand added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR labels Jun 25, 2020
@miri64
Copy link
Member

miri64 commented Jun 26, 2020

This PR still needs two ACKs to be merged before soft feature freeze (which I will anounce in a few hours) ;-).

Copy link
Member

@bergzand bergzand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first ACK!

Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK!

@bergzand bergzand merged commit 279f2ae into RIOT-OS:master Jun 26, 2020
@bergzand
Copy link
Member

And go!

@kaspar030 kaspar030 deleted the cortexm_remove_idle_thread branch June 26, 2020 09:22
@kaspar030
Copy link
Contributor Author

And go!

Thanks for reviewing!

@miri64
Copy link
Member

miri64 commented Jun 26, 2020

Now let's rethink making the main thread optional 😜

miri64 added a commit that referenced this pull request Jul 15, 2020
With #14224 the idle thread became
optional, so the main thread can have either 1 or 2 as PID, depending
if the idle thread is included or not. As this might also change in the
future, it is probably the best to just expect any number.
@fjmolinas
Copy link
Contributor

fjmolinas commented Jul 15, 2020

Bisecting I have 0ff9e55 causing tests/xtimer_periodic_wakeup to get stuck on nucleo-l152re.

Testing interval 25... (now=4054509)
Testing interval 24... (now=4057901)
Testing interval 23... (now=4061293)
Testing interval 22... (now=4064686)
Testing interval 21... (now=4068078)
Testing interval 20... (now=4071461)
Testing interval 19... (now=4074844)
Testing interval 18... (now=4078229)
Testing interval 17... (now=4081612)
Testing interval 16... (now=4084996)
# gets stuck here

miri64 added a commit to miri64/RIOT that referenced this pull request Jul 15, 2020
With RIOT-OS#14224 the idle thread became
optional, so the main thread can have either 1 or 2 as PID, depending
if the idle thread is included or not. As this might also change in the
future, it is probably the best to just expect any number.

(cherry picked from commit 5599b06)
miri64 added a commit to miri64/RIOT that referenced this pull request Jul 15, 2020
With RIOT-OS#14224 the idle thread became
optional, so the main thread can have either 1 or 2 as PID, depending
if the idle thread is included or not. As this might also change in the
future, it is probably the best to just expect any number.

(cherry picked from commit 5599b06)
miri64 added a commit to miri64/RIOT that referenced this pull request Jul 15, 2020
With RIOT-OS#14224 the idle thread became
optional, so the main thread can have either 1 or 2 as PID, depending
if the idle thread is included or not. As this might also change in the
future, it is probably the best to just expect any number.

(cherry picked from commit 5599b06)
@bergzand
Copy link
Member

Totally not related to #14557, some measurements on the same54-xpro with bench_mutex_pingpong:

idle thread no_idle_thread impact
GCC 262582 251572 4.1%
GCC+LTO 272109 252631 7.1%
LLVM 260303 244897 5.9%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: core Area: RIOT kernel. Handle PRs marked with this with care! CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Impact: major The PR changes a significant part of the code base. It should be reviewed carefully Platform: ARM Platform: This PR/issue effects ARM-based platforms Process: needs >1 ACK Integration Process: This PR requires more than one ACK Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants