Skip to content

Commit

Permalink
feat(threads): dynamic thread priorities
Browse files Browse the repository at this point in the history
  • Loading branch information
elenaf9 committed Sep 13, 2024
1 parent 844b6a7 commit ed48734
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
13 changes: 12 additions & 1 deletion src/riot-rs-runqueue/src/runqueue.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Disable indexing lints for now
#![allow(clippy::indexing_slicing)]

use core::mem;
use core::{mem, ops::Deref};

use self::clist::CList;

Expand All @@ -24,6 +24,13 @@ impl From<RunqueueId> for usize {
}
}

impl Deref for RunqueueId {
type Target = u8;
fn deref(&self) -> &Self::Target {
&self.0
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ThreadId(u8);
Expand Down Expand Up @@ -81,6 +88,10 @@ impl<const N_QUEUES: usize, const N_THREADS: usize> RunQueue<{ N_QUEUES }, { N_T
self.queues.push(n.0, rq.0);
}

pub fn peek_head(&self, rq: RunqueueId) -> Option<ThreadId> {
self.queues.peek_head(rq.0).map(ThreadId)
}

/// Removes th head with pid `n` from runqueue number `rq`.
///
/// # Panics
Expand Down
62 changes: 59 additions & 3 deletions src/riot-rs-threads/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,16 @@ impl Threads {
}
}

// fn get_unchecked(&self, thread_id: ThreadId) -> &Thread {
// &self.threads[thread_id as usize]
// }
/// Returns access to any thread data.
///
/// # Panics
///
/// Panics if `thread_id` is >= [`THREADS_NUMOF`].
/// If the thread for this `thread_id` is in an invalid state, the
/// data in the returned [`Thread`] is undefined, i.e. empty or outdated.
fn get_unchecked(&self, thread_id: ThreadId) -> &Thread {
&self.threads[usize::from(thread_id)]
}

/// Returns mutable access to any thread data.
///
Expand Down Expand Up @@ -172,6 +179,37 @@ impl Threads {
None
}
}

fn get_priority(&self, thread_id: ThreadId) -> Option<RunqueueId> {
self.is_valid_pid(thread_id)
.then(|| self.get_unchecked(thread_id).prio)
}

/// Changes the priority of a thread.
///
/// Returns true if the thread is in the runqueue and the order might have
/// changed.
fn set_priority(&mut self, thread_id: ThreadId, prio: RunqueueId) -> bool {
if !self.is_valid_pid(thread_id) {
return false;
}
let thread = self.get_unchecked_mut(thread_id);
let old_prio = thread.prio;
if old_prio == prio {
return false;
}
thread.prio = prio;
if thread.state != ThreadState::Running {
return false;
}
if self.runqueue.peek_head(old_prio) == Some(thread_id) {
self.runqueue.pop_head(thread_id, old_prio);
} else {
self.runqueue.del(thread_id);
}
self.runqueue.add(thread_id, prio);
true
}
}

/// Starts threading.
Expand Down Expand Up @@ -322,6 +360,24 @@ pub fn wakeup(thread_id: ThreadId) -> bool {
})
}

/// Returns the priority of a thread.
///
/// Returns `None` if this is not a valid thread.
pub fn get_priority(thread_id: ThreadId) -> Option<u8> {
THREADS.with_mut(|threads| threads.get_priority(thread_id).map(|rq| *rq))
}

/// Changes the priority of a thread.
///
/// This might trigger a context switch.
pub fn set_priority(thread_id: ThreadId, prio: u8) {
THREADS.with_mut(|mut threads| {
if threads.set_priority(thread_id, RunqueueId::new(prio)) {
schedule();
}
})
}

/// Returns the size of the internal structure that holds the
/// a thread's data.
pub fn thread_struct_size() -> usize {
Expand Down

0 comments on commit ed48734

Please sign in to comment.