diff --git a/storage/driver-block/src/lib.rs b/storage/driver-block/src/lib.rs index 5397523a37..0363228587 100644 --- a/storage/driver-block/src/lib.rs +++ b/storage/driver-block/src/lib.rs @@ -1,11 +1,12 @@ use std::cmp; -use std::future::IntoFuture; +use std::future::{Future, IntoFuture}; use std::io::{self, Read, Seek, SeekFrom}; use std::collections::BTreeMap; use std::convert::TryFrom; use std::fmt::Write; use std::str; +use std::task::Poll; use executor::LocalExecutor; use libredox::Fd; @@ -285,6 +286,22 @@ impl ExecutorTrait for FuturesExecutor { futures::executor::block_on(fut.into_future()) } } +pub struct TrivialExecutor; +impl ExecutorTrait for TrivialExecutor { + fn block_on<'a, O: 'a>(&self, fut: impl IntoFuture + 'a) -> O { + let mut fut = std::pin::pin!(fut.into_future()); + let mut cx = std::task::Context::from_waker(std::task::Waker::noop()); + loop { + match fut.as_mut().poll(&mut cx) { + Poll::Ready(v) => return v, + Poll::Pending => { + log::warn!("TrivialExecutor: future wasn't trivial"); + continue; + } + } + } + } +} impl DiskScheme { pub fn new( diff --git a/storage/ided/src/ide.rs b/storage/ided/src/ide.rs index 9748b46b93..0a14bcc99a 100644 --- a/storage/ided/src/ide.rs +++ b/storage/ided/src/ide.rs @@ -177,7 +177,8 @@ impl Disk for AtaDisk { self.size } - fn read(&mut self, start_block: u64, buffer: &mut [u8]) -> Result> { + // NOTE: not async + async fn read(&mut self, start_block: u64, buffer: &mut [u8]) -> Result { let mut count = 0; for chunk in buffer.chunks_mut(65536) { let block = start_block + (count as u64) / 512; @@ -314,10 +315,11 @@ impl Disk for AtaDisk { count += chunk.len(); } - Ok(Some(count)) + Ok(count) } - fn write(&mut self, start_block: u64, buffer: &[u8]) -> Result> { + // NOTE: not async + async fn write(&mut self, start_block: u64, buffer: &[u8]) -> Result { let mut count = 0; for chunk in buffer.chunks(65536) { let block = start_block + (count as u64) / 512; @@ -462,6 +464,6 @@ impl Disk for AtaDisk { count += chunk.len(); } - Ok(Some(count)) + Ok(count) } } diff --git a/storage/ided/src/main.rs b/storage/ided/src/main.rs index c7dd8f8746..d3509a1ba8 100644 --- a/storage/ided/src/main.rs +++ b/storage/ided/src/main.rs @@ -1,5 +1,5 @@ use common::io::Io as _; -use driver_block::{Disk, DiskScheme}; +use driver_block::{Disk, DiskScheme, ExecutorTrait, FuturesExecutor}; use event::{EventFlags, RawEventQueue}; use libredox::flag; use log::{error, info}; @@ -61,7 +61,28 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { Arc::new(Mutex::new(primary)), Arc::new(Mutex::new(secondary)), ]; - let mut disks: Vec> = Vec::new(); + enum AnyDisk { + Ata(AtaDisk), + } + impl Disk for AnyDisk { + fn block_size(&self) -> u32 { + let AnyDisk::Ata(a) = self; + a.block_size() + } + fn size(&self) -> u64 { + let AnyDisk::Ata(a) = self; + a.size() + } + async fn write(&mut self, block: u64, buffer: &[u8]) -> syscall::Result { + let AnyDisk::Ata(a) = self; + a.write(block, buffer).await + } + async fn read(&mut self, block: u64, buffer: &mut [u8]) -> syscall::Result { + let AnyDisk::Ata(a) = self; + a.read(block, buffer).await + } + } + let mut disks: Vec = Vec::new(); for (chan_i, chan_lock) in chans.iter().enumerate() { let mut chan = chan_lock.lock().unwrap(); @@ -174,7 +195,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { println!(" DMA: {}", dma); println!(" {}-bit LBA", lba_bits); - disks.push(Box::new(AtaDisk { + disks.push(AnyDisk::Ata(AtaDisk { chan: chan_lock.clone(), chan_i, dev, @@ -194,6 +215,9 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .enumerate() .map(|(i, disk)| (i as u32, disk)) .collect(), + // TODO: Should ided just use TrivialExecutor or would it be valuable to actually use a + // real executor? + &FuturesExecutor, ); let primary_irq_fd = libredox::call::open( @@ -233,7 +257,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { for event in event_queue { let event = event.unwrap(); if event.fd == scheme.event_handle().raw() { - scheme.tick().unwrap(); + FuturesExecutor.block_on(scheme.tick()).unwrap(); } else if event.fd == primary_irq_fd { let mut irq = [0; 8]; if primary_irq_file @@ -248,7 +272,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .write(&irq) .expect("ided: failed to write irq file"); - scheme.tick().unwrap(); + FuturesExecutor.block_on(scheme.tick()).unwrap(); } } else if event.fd == secondary_irq_fd { let mut irq = [0; 8]; @@ -264,7 +288,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .write(&irq) .expect("ided: failed to write irq file"); - scheme.tick().unwrap(); + FuturesExecutor.block_on(scheme.tick()).unwrap(); } } else { error!("Unknown event {}", event.fd); diff --git a/storage/lived/src/main.rs b/storage/lived/src/main.rs index f4c2ac15ff..b53452e779 100644 --- a/storage/lived/src/main.rs +++ b/storage/lived/src/main.rs @@ -8,6 +8,7 @@ use std::fs::File; use std::os::fd::AsRawFd; use driver_block::{Disk, DiskScheme}; +use driver_block::{ExecutorTrait, TrivialExecutor}; use libredox::call::MmapArgs; use libredox::flag; @@ -86,7 +87,7 @@ impl Disk for LiveDisk { self.the_data.len() as u64 } - fn read(&mut self, block: u64, buffer: &mut [u8]) -> syscall::Result> { + async fn read(&mut self, block: u64, buffer: &mut [u8]) -> syscall::Result { let block = block as usize; let block_size = self.block_size() as usize; if block * block_size + buffer.len() > self.size() as usize { @@ -94,10 +95,10 @@ impl Disk for LiveDisk { } buffer .copy_from_slice(&self.the_data[block * block_size..block * block_size + buffer.len()]); - Ok(Some(block_size)) + Ok(block_size) } - fn write(&mut self, block: u64, buffer: &[u8]) -> syscall::Result> { + async fn write(&mut self, block: u64, buffer: &[u8]) -> syscall::Result { let block = block as usize; let block_size = self.block_size() as usize; if block * block_size + buffer.len() > self.size() as usize { @@ -105,7 +106,7 @@ impl Disk for LiveDisk { } self.the_data[block * block_size..block * block_size + buffer.len()] .copy_from_slice(buffer); - Ok(Some(block_size)) + Ok(block_size) } } @@ -128,6 +129,7 @@ fn main() -> anyhow::Result<()> { std::process::exit(1) }), )]), + &TrivialExecutor, ); libredox::call::setrens(0, 0).expect("nvmed: failed to enter null namespace"); @@ -144,7 +146,7 @@ fn main() -> anyhow::Result<()> { for event in event_queue { match event.unwrap().user_data { - Event::Scheme => scheme.tick().unwrap(), + Event::Scheme => TrivialExecutor.block_on(scheme.tick()).unwrap(), } }