From 5dafde0c1a4a9d9f41b0d6165259e75f0428e1fa Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 22 Mar 2021 11:26:06 +0100 Subject: [PATCH] new interface to network driver the new interface is required for hermitcore/rusty-hermit#117 --- src/drivers/net/mod.rs | 88 +++--------------------------------------- src/syscalls/mod.rs | 13 ++----- src/syscalls/tasks.rs | 12 ++++-- 3 files changed, 18 insertions(+), 95 deletions(-) diff --git a/src/drivers/net/mod.rs b/src/drivers/net/mod.rs index c18a492493..ba351eed1f 100644 --- a/src/drivers/net/mod.rs +++ b/src/drivers/net/mod.rs @@ -16,10 +16,7 @@ use crate::arch::kernel::irq::ExceptionStackFrame; #[cfg(feature = "pci")] use crate::arch::kernel::pci; use crate::arch::kernel::percore::*; -use crate::scheduler::task::TaskHandle; use crate::synch::semaphore::*; -use crate::synch::spinlock::SpinlockIrqSave; -use alloc::collections::BTreeMap; use core::sync::atomic::{AtomicBool, Ordering}; /// A trait for accessing the network interface @@ -45,100 +42,25 @@ pub trait NetworkInterface { } static NET_SEM: Semaphore = Semaphore::new(0); -static NIC_QUEUE: SpinlockIrqSave> = - SpinlockIrqSave::new(BTreeMap::new()); static POLLING: AtomicBool = AtomicBool::new(false); -/// period (in usec) to check, if the driver should still use the polling mode -const POLL_PERIOD: u64 = 20_000; - /// set driver in polling mode and threads will not be blocked -fn set_polling_mode(value: bool) { +pub fn set_polling_mode(value: bool) { // is the driver already in polling mode? if POLLING.swap(value, Ordering::SeqCst) != value { #[cfg(feature = "pci")] if let Some(driver) = crate::arch::kernel::pci::get_network_driver() { driver.lock().set_polling_mode(value) } - - // wakeup network thread to sleep for longer time - NET_SEM.release(); } } -pub fn netwakeup() { - NET_SEM.release(); +pub fn netwait() { + NET_SEM.acquire(None); } -pub fn netwait_and_wakeup(handles: &[usize], millis: Option) { - // do we have to wakeup a thread? - if handles.len() > 0 { - let mut guard = NIC_QUEUE.lock(); - - for i in handles { - if let Some(task) = guard.remove(i) { - core_scheduler().custom_wakeup(task); - } - } - } - - let mut reset_nic = false; - - // check if the driver should be in the polling mode - while POLLING.swap(false, Ordering::SeqCst) == true { - reset_nic = true; - - let core_scheduler = core_scheduler(); - let wakeup_time = Some(crate::arch::processor::get_timer_ticks() + POLL_PERIOD); - - core_scheduler.block_current_task(wakeup_time); - - // Switch to the next task. - core_scheduler.reschedule(); - } - - if reset_nic { - #[cfg(feature = "pci")] - if let Some(driver) = crate::arch::kernel::pci::get_network_driver() { - driver.lock().set_polling_mode(false); - }; - } else { - NET_SEM.acquire(millis); - } -} - -pub fn netwait(handle: usize, millis: Option) { - // smoltcp want to poll the nic - let is_polling = if let Some(t) = millis { t == 0 } else { false }; - - if is_polling { - set_polling_mode(true); - } else { - let wakeup_time = match millis { - Some(ms) => Some(crate::arch::processor::get_timer_ticks() + ms * 1000), - _ => None, - }; - let mut guard = NIC_QUEUE.lock(); - let core_scheduler = core_scheduler(); - - // Block the current task and add it to the wakeup queue. - core_scheduler.block_current_task(wakeup_time); - guard.insert(handle, core_scheduler.get_current_task_handle()); - - // release lock - drop(guard); - - // Switch to the next task. - core_scheduler.reschedule(); - - // if the timer is expired, we have still the task in the btreemap - // => remove it from the btreemap - if millis.is_some() { - let mut guard = NIC_QUEUE.lock(); - - guard.remove(&handle); - } - } +pub fn netwakeup() { + NET_SEM.release(); } #[cfg(target_arch = "x86_64")] diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index b52d47fa47..d928f93a38 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -142,21 +142,16 @@ pub fn sys_rx_buffer_consumed(handle: usize) -> Result<(), ()> { kernel_function!(__sys_rx_buffer_consumed(handle)) } -#[cfg(not(feature = "newlib"))] -fn __sys_netwait(handle: usize, millis: Option) { - netwait(handle, millis) -} - #[cfg(not(feature = "newlib"))] #[no_mangle] -pub fn sys_netwait(handle: usize, millis: Option) { - kernel_function!(__sys_netwait(handle, millis)); +pub extern "C" fn sys_netwait() { + kernel_function!(netwait()); } #[cfg(not(feature = "newlib"))] #[no_mangle] -pub fn sys_netwait_and_wakeup(handles: &[usize], millis: Option) { - kernel_function!(netwait_and_wakeup(handles, millis)); +pub extern "C" fn sys_set_network_polling_mode(value: bool) { + kernel_function!(set_polling_mode(value)); } pub fn __sys_shutdown(arg: i32) -> ! { diff --git a/src/syscalls/tasks.rs b/src/syscalls/tasks.rs index 7ec804d0d5..60ed3e087d 100644 --- a/src/syscalls/tasks.rs +++ b/src/syscalls/tasks.rs @@ -289,19 +289,25 @@ pub extern "C" fn sys_join(id: Tid) -> i32 { /// Mapping between TaskID and TaskHandle static TASKS: SpinlockIrqSave> = SpinlockIrqSave::new(BTreeMap::new()); -fn __sys_block_current_task() { +fn __sys_block_current_task(timeout: Option) { let core_scheduler = core_scheduler(); let handle = core_scheduler.get_current_task_handle(); let tid = core_scheduler.get_current_task_id(); TASKS.lock().insert(tid, handle); - core_scheduler.block_current_task(None); + core_scheduler.block_current_task(timeout); } /// Set the current task state to `blocked` #[no_mangle] pub extern "C" fn sys_block_current_task() { - kernel_function!(__sys_block_current_task()) + kernel_function!(__sys_block_current_task(None)) +} + +/// Set the current task state to `blocked` +#[no_mangle] +pub fn sys_block_current_task_with_timeout(timeout: Option) { + kernel_function!(__sys_block_current_task(timeout)) } fn __sys_wakeup_task(id: Tid) {