1#![no_std]
3
4use core::{
5 mem::offset_of,
6 sync::atomic::{AtomicU32, AtomicUsize, Ordering},
7};
8
9#[derive(Default)]
13#[repr(C)]
14pub struct TaskBase {
15 stack: AtomicUsize,
17 thread_addr_limit: AtomicUsize,
19 thread_flags: AtomicU32,
21 thread_preempt: AtomicU32,
23}
24
25impl TaskBase {
26 pub const fn new() -> Self {
28 Self {
29 stack: AtomicUsize::new(0),
30 thread_addr_limit: AtomicUsize::new(0),
31 thread_flags: AtomicU32::new(0),
32 thread_preempt: AtomicU32::new(0),
33 }
34 }
35
36 pub fn set_stack(&self, stack_base: usize) {
38 self.stack.store(stack_base, Ordering::Relaxed);
39 }
40
41 #[inline(always)]
43 pub fn stack(&self) -> usize {
44 self.stack.load(Ordering::Relaxed)
45 }
46
47 #[inline(always)]
49 pub fn set_preempt(&self, val: u32) {
50 self.thread_preempt.store(val, Ordering::Relaxed);
51 }
52
53 #[inline(always)]
55 pub fn preempt(&self) -> u32 {
56 self.thread_preempt.load(Ordering::Relaxed)
57 }
58
59 #[inline(always)]
61 pub fn preempt_add(&self, val: u32) {
62 self.thread_preempt.fetch_add(val, Ordering::Relaxed);
63 }
64
65 #[inline(always)]
67 pub fn preempt_sub(&self, val: u32) {
68 self.thread_preempt.fetch_sub(val, Ordering::Relaxed);
69 }
70
71 #[inline(always)]
73 pub fn set_flags(&self, flags: u32) {
74 self.thread_flags.store(flags, Ordering::Relaxed);
75 }
76
77 #[inline(always)]
79 pub fn set_flags_bit(&self, bit: u32) {
80 self.thread_flags.fetch_or(1 << bit, Ordering::Relaxed);
81 }
82
83 #[inline(always)]
85 pub fn flags(&self) -> u32 {
86 self.thread_flags.load(Ordering::Relaxed)
87 }
88
89 #[inline(always)]
91 pub fn test_flags_bit(&self, bit: u32) -> bool {
92 self.thread_flags.load(Ordering::Relaxed) & (1 << bit) != 0
93 }
94}
95
96pub const TSK_STACK: usize = offset_of!(TaskBase, stack);
98pub const TSK_TI_ADDR_LIMIT: usize = offset_of!(TaskBase, thread_addr_limit);
100pub const TSK_TI_FLAGS: usize = offset_of!(TaskBase, thread_flags);
102pub const TSK_TI_PREEMPT: usize = offset_of!(TaskBase, thread_preempt);
104
105#[cfg(test)]
106mod test {
107 use super::*;
108
109 #[test]
110 fn test() {
111 assert_eq!(TSK_STACK, 0);
112 assert_eq!(TSK_TI_ADDR_LIMIT, 8);
113 assert_eq!(TSK_TI_FLAGS, 16);
114 assert_eq!(TSK_TI_PREEMPT, 20);
115 }
116}