|
@@ -4,7 +4,12 @@ use crate::{
|
|
|
PhysAddr, Result,
|
|
|
};
|
|
|
use alloc::{sync::Arc, vec::Vec};
|
|
|
-use core::{any::TypeId, ptr::NonNull, time::Duration};
|
|
|
+use core::{
|
|
|
+ any::TypeId,
|
|
|
+ ptr::NonNull,
|
|
|
+ sync::atomic::{AtomicBool, Ordering},
|
|
|
+ time::Duration,
|
|
|
+};
|
|
|
use std::{sync::Mutex, thread};
|
|
|
|
|
|
/// A fake implementation of [`Transport`] for unit tests.
|
|
@@ -35,7 +40,9 @@ impl<C> Transport for FakeTransport<C> {
|
|
|
}
|
|
|
|
|
|
fn notify(&mut self, queue: u16) {
|
|
|
- self.state.lock().unwrap().queues[queue as usize].notified = true;
|
|
|
+ self.state.lock().unwrap().queues[queue as usize]
|
|
|
+ .notified
|
|
|
+ .store(true, Ordering::SeqCst);
|
|
|
}
|
|
|
|
|
|
fn get_status(&self) -> DeviceStatus {
|
|
@@ -171,18 +178,20 @@ impl State {
|
|
|
|
|
|
/// Waits until the given queue is notified.
|
|
|
pub fn wait_until_queue_notified(state: &Mutex<Self>, queue_index: u16) {
|
|
|
- while !state.lock().unwrap().queues[usize::from(queue_index)].notified {
|
|
|
+ while !state.lock().unwrap().queues[usize::from(queue_index)]
|
|
|
+ .notified
|
|
|
+ .swap(false, Ordering::SeqCst)
|
|
|
+ {
|
|
|
thread::sleep(Duration::from_millis(10));
|
|
|
}
|
|
|
- state.lock().unwrap().queues[usize::from(queue_index)].notified = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
|
|
+#[derive(Debug, Default)]
|
|
|
pub struct QueueStatus {
|
|
|
pub size: u32,
|
|
|
pub descriptors: PhysAddr,
|
|
|
pub driver_area: PhysAddr,
|
|
|
pub device_area: PhysAddr,
|
|
|
- pub notified: bool,
|
|
|
+ pub notified: AtomicBool,
|
|
|
}
|