From ba40b4b7d8b17e4951be3d6c0d6eae5f76d59218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 3 Nov 2023 17:32:33 +0100 Subject: [PATCH] Simplify multitasking (#334) --- esp-wifi/src/compat/common.rs | 2 +- esp-wifi/src/preempt/mod.rs | 31 +++++++---- esp-wifi/src/preempt/preempt_riscv.rs | 73 ++++++++------------------ esp-wifi/src/preempt/preempt_xtensa.rs | 55 ++++++------------- esp-wifi/src/timer/mod.rs | 2 + esp-wifi/src/timer/riscv.rs | 3 -- esp-wifi/src/timer/xtensa.rs | 2 - esp-wifi/src/wifi/os_adapter.rs | 2 +- 8 files changed, 64 insertions(+), 106 deletions(-) diff --git a/esp-wifi/src/compat/common.rs b/esp-wifi/src/compat/common.rs index cea404c6347..6e4320f4854 100644 --- a/esp-wifi/src/compat/common.rs +++ b/esp-wifi/src/compat/common.rs @@ -9,7 +9,7 @@ use crate::{ include::OSI_FUNCS_TIME_BLOCKING, }, memory_fence::memory_fence, - preempt::preempt::current_task, + preempt::current_task, timer::yield_task, }; diff --git a/esp-wifi/src/preempt/mod.rs b/esp-wifi/src/preempt/mod.rs index 08c87d618f7..ebd7b60171a 100644 --- a/esp-wifi/src/preempt/mod.rs +++ b/esp-wifi/src/preempt/mod.rs @@ -1,12 +1,3 @@ -use atomic_polyfill::AtomicBool; -use core::sync::atomic::Ordering; - -pub static mut FIRST_SWITCH: AtomicBool = AtomicBool::new(true); - -static mut TASK_TOP: usize = 0; - -static mut CTX_NOW: usize = 0; - macro_rules! sum { ($h:expr) => ($h); ($h:expr, $($t:expr),*) => @@ -24,6 +15,28 @@ macro_rules! task_stack { }; } +static mut TASK_TOP: usize = 1; +static mut CTX_NOW: usize = 0; + +fn allocate_task() -> usize { + unsafe { + let i = TASK_TOP - 1; + CTX_NOW = TASK_TOP; + TASK_TOP += 1; + i + } +} + +fn next_task() { + unsafe { + CTX_NOW = (CTX_NOW + 1) % TASK_TOP; + } +} + +pub fn current_task() -> usize { + unsafe { CTX_NOW } +} + #[cfg(coex)] task_stack!(8192, 8192, 8192); diff --git a/esp-wifi/src/preempt/preempt_riscv.rs b/esp-wifi/src/preempt/preempt_riscv.rs index 99bd59d9c08..67b2b7b80c2 100644 --- a/esp-wifi/src/preempt/preempt_riscv.rs +++ b/esp-wifi/src/preempt/preempt_riscv.rs @@ -49,10 +49,10 @@ static mut CTX_TASKS: [Context; MAX_TASK] = [Context { _running: false, }; MAX_TASK]; -pub fn task_create(task: extern "C" fn()) -> usize { +pub fn task_create(task: extern "C" fn()) { unsafe { - let i = TASK_TOP; - TASK_TOP += 1; + let i = allocate_task(); + CTX_TASKS[i].trap_frame.pc = task as usize; let task_stack_size = TASK_STACK_SIZE[i]; @@ -64,19 +64,6 @@ pub fn task_create(task: extern "C" fn()) -> usize { - 4; let stack_ptr = task_stack_ptr - (task_stack_ptr % 0x10); CTX_TASKS[i].trap_frame.sp = stack_ptr; - - CTX_NOW = i; - i - } -} - -fn task_create_from_mepc(mepc: usize) -> usize { - unsafe { - let i = TASK_TOP; - TASK_TOP += 1; - CTX_TASKS[i].trap_frame.pc = mepc; - CTX_NOW = i; - i } } @@ -156,42 +143,24 @@ pub fn save_task_context(id: usize, pc: usize, trap_frame: &TrapFrame) { } } -pub fn next_task() { - unsafe { - CTX_NOW = (CTX_NOW + 1) % TASK_TOP; - } -} - pub fn task_switch(trap_frame: &mut TrapFrame) { - unsafe { - let old_mepc = trap_frame.pc; - - if FIRST_SWITCH.load(Ordering::Relaxed) { - FIRST_SWITCH.store(false, Ordering::Relaxed); - let main_task = task_create_from_mepc(old_mepc); - CTX_NOW = main_task; - } - - save_task_context(CTX_NOW, old_mepc, trap_frame); - - next_task(); - - let new_pc = restore_task_context(CTX_NOW, trap_frame); - trap_frame.pc = new_pc; - - // debug aid! remove when not needed anymore!!!!! - // static mut CNT: u32 = 0; - // if CTX_NOW == 0 { - // if CNT < 5_000 { - // CNT += 1; - // } else { - // CNT = 0; - // info!("@@@ Task {} PC = {:x} {:?}", CTX_NOW, new_pc, trap_frame); - // } - // } - } -} + let old_mepc = trap_frame.pc; + + save_task_context(current_task(), old_mepc, trap_frame); + + next_task(); + + let new_pc = restore_task_context(current_task(), trap_frame); + trap_frame.pc = new_pc; -pub fn current_task() -> usize { - unsafe { CTX_NOW } + // debug aid! remove when not needed anymore!!!!! + // static mut CNT: u32 = 0; + // if CTX_NOW == 0 { + // if CNT < 5_000 { + // CNT += 1; + // } else { + // CNT = 0; + // info!("@@@ Task {} PC = {:x} {:?}", CTX_NOW, new_pc, trap_frame); + // } + // } } diff --git a/esp-wifi/src/preempt/preempt_xtensa.rs b/esp-wifi/src/preempt/preempt_xtensa.rs index 005db51e117..3f36a3bc4ca 100644 --- a/esp-wifi/src/preempt/preempt_xtensa.rs +++ b/esp-wifi/src/preempt/preempt_xtensa.rs @@ -1,4 +1,5 @@ use super::*; + use crate::hal::trapframe::TrapFrame; #[derive(Debug, Clone, Copy)] @@ -65,10 +66,9 @@ static mut CTX_TASKS: [TaskContext; MAX_TASK] = [TaskContext { }, }; MAX_TASK]; -pub fn task_create(task: extern "C" fn()) -> usize { +pub fn task_create(task: extern "C" fn()) { unsafe { - let i = TASK_TOP; - TASK_TOP += 1; + let i = allocate_task(); CTX_TASKS[i].trap_frame.PC = task as u32; @@ -90,9 +90,6 @@ pub fn task_create(task: extern "C" fn()) -> usize { *((task_stack_ptr - 8) as *mut u32) = 0; *((task_stack_ptr - 12) as *mut u32) = stack_ptr; *((task_stack_ptr - 16) as *mut u32) = 0; - - CTX_NOW = i; - i } } @@ -108,37 +105,19 @@ fn save_task_context(id: usize, trap_frame: &TrapFrame) { } } -pub fn next_task() { - unsafe { - CTX_NOW = (CTX_NOW + 1) % TASK_TOP; - } -} - pub fn task_switch(trap_frame: &mut TrapFrame) { - unsafe { - if FIRST_SWITCH.load(Ordering::Relaxed) { - FIRST_SWITCH.store(false, Ordering::Relaxed); - TASK_TOP += 1; - CTX_NOW = TASK_TOP - 1; - } - - save_task_context(CTX_NOW, trap_frame); - next_task(); - restore_task_context(CTX_NOW, trap_frame); - - // debug aid! remove when not needed anymore!!!!! - // static mut CNT: u32 = 0; - // if CTX_NOW == 0 { - // if CNT < 2_000 { - // CNT += 1; - // } else { - // CNT = 0; - // info!("@@@ Task {} {:?} ", 1, CTX_TASKS[1].trap_frame.PC); - // } - // } - }; -} - -pub fn current_task() -> usize { - unsafe { CTX_NOW } + save_task_context(current_task(), trap_frame); + next_task(); + restore_task_context(current_task(), trap_frame); + + // debug aid! remove when not needed anymore!!!!! + // static mut CNT: u32 = 0; + // if CTX_NOW == 0 { + // if CNT < 2_000 { + // CNT += 1; + // } else { + // CNT = 0; + // info!("@@@ Task {} {:?} ", 1, CTX_TASKS[1].trap_frame.PC); + // } + // } } diff --git a/esp-wifi/src/timer/mod.rs b/esp-wifi/src/timer/mod.rs index 072fa291ff3..4b1ce9bfab5 100644 --- a/esp-wifi/src/timer/mod.rs +++ b/esp-wifi/src/timer/mod.rs @@ -19,6 +19,8 @@ pub fn setup_timer_isr(timebase: TimeBase) { setup_timer(timebase); setup_multitasking(); + + yield_task(); } #[allow(unused)] diff --git a/esp-wifi/src/timer/riscv.rs b/esp-wifi/src/timer/riscv.rs index aea23e7d0d0..227898fafc5 100644 --- a/esp-wifi/src/timer/riscv.rs +++ b/esp-wifi/src/timer/riscv.rs @@ -1,5 +1,4 @@ use core::cell::RefCell; -use core::sync::atomic::Ordering; use critical_section::Mutex; @@ -56,8 +55,6 @@ pub fn setup_multitasking() { unsafe { riscv::interrupt::enable(); } - - while unsafe { crate::preempt::FIRST_SWITCH.load(Ordering::Relaxed) } {} } #[interrupt] diff --git a/esp-wifi/src/timer/xtensa.rs b/esp-wifi/src/timer/xtensa.rs index b3485138515..51ab55055a0 100644 --- a/esp-wifi/src/timer/xtensa.rs +++ b/esp-wifi/src/timer/xtensa.rs @@ -73,8 +73,6 @@ pub fn setup_multitasking() { | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level6.mask() | enabled, ); } - - while unsafe { crate::preempt::FIRST_SWITCH.load(Ordering::Relaxed) } {} } #[allow(non_snake_case)] diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index 819490e1d0a..4591623317b 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -789,7 +789,7 @@ pub unsafe extern "C" fn task_ms_to_tick(ms: u32) -> i32 { * ****************************************************************************/ pub unsafe extern "C" fn task_get_current_task() -> *mut crate::binary::c_types::c_void { - let res = crate::preempt::preempt::current_task() as *mut crate::binary::c_types::c_void; + let res = crate::preempt::current_task() as *mut crate::binary::c_types::c_void; trace!("task get current task - return {:?}", res); res