Skip to content

Commit

Permalink
fixup! threads: PoC multicore support for rp2040
Browse files Browse the repository at this point in the history
Only schedule a context switch if thread allocation (to a core) changed.

TODO:
Schedule the context switch on the core that is affected. In most cases,
this is the currently running cores, but not always (e.g. when on
another core a low priority thread is running that should be preempted).
  • Loading branch information
elenaf9 committed Apr 12, 2024
1 parent 9c9ede4 commit 3d8930c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 33 deletions.
46 changes: 25 additions & 21 deletions src/riot-rs-threads/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,17 +149,22 @@ impl Threads {
///
/// This function handles adding/ removing the thread to the Runqueue depending
/// on its previous or new state.
pub(crate) fn set_state(&mut self, pid: ThreadId, state: ThreadState) -> ThreadState {
pub(crate) fn set_state(
&mut self,
pid: ThreadId,
state: ThreadState,
) -> (ThreadState, Option<CoreId>) {
let thread = &mut self.threads[pid as usize];
let old_state = thread.state;
thread.state = state;
if old_state != ThreadState::Running && state == ThreadState::Running {
self.runqueue.add(thread.pid, thread.prio);
} else if old_state == ThreadState::Running && state != ThreadState::Running {
self.runqueue.del(thread.pid, thread.prio);
}

old_state
let changed_id = match (old_state, state) {
(ThreadState::Running, ThreadState::Running) => None,
(_, ThreadState::Running) => self.runqueue.add(thread.pid, thread.prio),
(ThreadState::Running, _) => self.runqueue.del(thread.pid, thread.prio),
_ => None,
};
(old_state, changed_id)
}

pub fn get_state(&self, thread_id: ThreadId) -> Option<ThreadState> {
Expand Down Expand Up @@ -298,17 +303,19 @@ fn cleanup() -> ! {
pub fn yield_same() {
THREADS.with_mut(|mut threads| {
let runqueue = threads.current().unwrap().prio;
threads.runqueue.advance(runqueue);
schedule();
if let Some(_cpuid) = threads.runqueue.advance(runqueue) {
schedule();
}
})
}

/// Suspends/ pauses the current thread's execution.
pub fn sleep() {
THREADS.with_mut(|mut threads| {
let pid = threads.current_pid().unwrap();
threads.set_state(pid, ThreadState::Paused);
schedule();
if let Some(_cpuid) = threads.set_state(pid, ThreadState::Paused).1 {
schedule();
}
});
}

Expand All @@ -317,17 +324,14 @@ pub fn sleep() {
/// Returns `false` if no paused thread exists for `thread_id`.
pub fn wakeup(thread_id: ThreadId) -> bool {
THREADS.with_mut(|mut threads| {
if let Some(state) = threads.get_state(thread_id) {
if state == ThreadState::Paused {
threads.set_state(thread_id, ThreadState::Running);
schedule();
true
} else {
false
}
} else {
false
match threads.get_state(thread_id) {
Some(ThreadState::Paused) => {}
_ => return false,
}
if let (_, Some(_cpuid)) = threads.set_state(thread_id, ThreadState::Running) {
schedule();
}
true
})
}

Expand Down
29 changes: 21 additions & 8 deletions src/riot-rs-threads/src/thread_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ impl Threads {
},
_ => false,
} {
self.set_state(thread_id, ThreadState::Running);
crate::schedule();
if let Some(_cpuid) = self.set_state(thread_id, ThreadState::Running).1 {
crate::schedule();
}
}
}

Expand All @@ -117,8 +118,12 @@ impl Threads {
Some(mask)
} else {
let thread_id = thread.pid;
self.set_state(thread_id, ThreadState::FlagBlocked(WaitMode::All(mask)));
crate::schedule();
if let Some(_cpuid) = self
.set_state(thread_id, ThreadState::FlagBlocked(WaitMode::All(mask)))
.1
{
crate::schedule();
}
None
}
}
Expand All @@ -131,8 +136,12 @@ impl Threads {
Some(res)
} else {
let thread_id = thread.pid;
self.set_state(thread_id, ThreadState::FlagBlocked(WaitMode::Any(mask)));
crate::schedule();
if let Some(_cpuid) = self
.set_state(thread_id, ThreadState::FlagBlocked(WaitMode::Any(mask)))
.1
{
crate::schedule();
}
None
}
}
Expand All @@ -147,8 +156,12 @@ impl Threads {
Some(res)
} else {
let thread_id = thread.pid;
self.set_state(thread_id, ThreadState::FlagBlocked(WaitMode::Any(mask)));
crate::schedule();
if let Some(_cpuid) = self
.set_state(thread_id, ThreadState::FlagBlocked(WaitMode::Any(mask)))
.1
{
crate::schedule();
}
None
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/riot-rs-threads/src/threadlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ impl ThreadList {
let thread_id = threads.current_pid().unwrap();
threads.thread_blocklist[thread_id as usize] = self.head;
self.head = Some(thread_id);
threads.set_state(thread_id, state);
crate::schedule();
if let Some(_cpuid) = threads.set_state(thread_id, state).1 {
crate::schedule();
}
});
}

Expand All @@ -36,8 +37,10 @@ impl ThreadList {
if let Some(head) = self.head {
let old_state = THREADS.with_mut_cs(cs, |mut threads| {
self.head = threads.thread_blocklist[head as usize].take();
let old_state = threads.set_state(head, ThreadState::Running);
crate::schedule();
let (old_state, cpuid) = threads.set_state(head, ThreadState::Running);
if let Some(_cpuid) = cpuid {
crate::schedule();
}
old_state
});
Some((head, old_state))
Expand Down

0 comments on commit 3d8930c

Please sign in to comment.