mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 12:36:46 +00:00
Support T:?Sized as type parameter for Mutex, SpinLock, RwLock, and RwMutex
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
92a9f5616e
commit
dac41e9a2f
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use alloc::{boxed::Box, sync::Arc};
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
@ -11,7 +11,7 @@ pub mod ioapic;
|
|||||||
pub mod x2apic;
|
pub mod x2apic;
|
||||||
pub mod xapic;
|
pub mod xapic;
|
||||||
|
|
||||||
pub static APIC_INSTANCE: Once<Arc<Mutex<Box<dyn Apic + 'static>>>> = Once::new();
|
pub static APIC_INSTANCE: Once<Arc<Mutex<dyn Apic + 'static>>> = Once::new();
|
||||||
|
|
||||||
pub trait Apic: ApicTimer + Sync + Send {
|
pub trait Apic: ApicTimer + Sync + Send {
|
||||||
fn id(&self) -> u32;
|
fn id(&self) -> u32;
|
||||||
@ -71,7 +71,7 @@ pub fn init() -> Result<(), ApicInitError> {
|
|||||||
version & 0xff,
|
version & 0xff,
|
||||||
(version >> 16) & 0xff
|
(version >> 16) & 0xff
|
||||||
);
|
);
|
||||||
APIC_INSTANCE.call_once(|| Arc::new(Mutex::new(Box::new(x2apic))));
|
APIC_INSTANCE.call_once(|| Arc::new(Mutex::new(x2apic)));
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if let Some(mut xapic) = xapic::XApic::new() {
|
} else if let Some(mut xapic) = xapic::XApic::new() {
|
||||||
xapic.enable();
|
xapic.enable();
|
||||||
@ -82,7 +82,7 @@ pub fn init() -> Result<(), ApicInitError> {
|
|||||||
version & 0xff,
|
version & 0xff,
|
||||||
(version >> 16) & 0xff
|
(version >> 16) & 0xff
|
||||||
);
|
);
|
||||||
APIC_INSTANCE.call_once(|| Arc::new(Mutex::new(Box::new(xapic))));
|
APIC_INSTANCE.call_once(|| Arc::new(Mutex::new(xapic)));
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Not found x2APIC or xAPIC");
|
log::warn!("Not found x2APIC or xAPIC");
|
||||||
|
@ -10,22 +10,24 @@ use core::{
|
|||||||
use super::WaitQueue;
|
use super::WaitQueue;
|
||||||
|
|
||||||
/// A mutex with waitqueue.
|
/// A mutex with waitqueue.
|
||||||
pub struct Mutex<T> {
|
pub struct Mutex<T: ?Sized> {
|
||||||
val: UnsafeCell<T>,
|
|
||||||
lock: AtomicBool,
|
lock: AtomicBool,
|
||||||
queue: WaitQueue,
|
queue: WaitQueue,
|
||||||
|
val: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Mutex<T> {
|
impl<T> Mutex<T> {
|
||||||
/// Create a new mutex.
|
/// Create a new mutex.
|
||||||
pub const fn new(val: T) -> Self {
|
pub const fn new(val: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
val: UnsafeCell::new(val),
|
|
||||||
lock: AtomicBool::new(false),
|
lock: AtomicBool::new(false),
|
||||||
queue: WaitQueue::new(),
|
queue: WaitQueue::new(),
|
||||||
|
val: UnsafeCell::new(val),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Mutex<T> {
|
||||||
/// Acquire the mutex.
|
/// Acquire the mutex.
|
||||||
///
|
///
|
||||||
/// This method runs in a block way until the mutex can be acquired.
|
/// This method runs in a block way until the mutex can be acquired.
|
||||||
@ -57,27 +59,27 @@ impl<T> Mutex<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for Mutex<T> {
|
impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.val, f)
|
fmt::Debug::fmt(&self.val, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: Send> Send for Mutex<T> {}
|
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
|
||||||
unsafe impl<T: Send> Sync for Mutex<T> {}
|
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
|
||||||
|
|
||||||
#[clippy::has_significant_drop]
|
#[clippy::has_significant_drop]
|
||||||
pub struct MutexGuard<'a, T> {
|
pub struct MutexGuard<'a, T: ?Sized> {
|
||||||
mutex: &'a Mutex<T>,
|
mutex: &'a Mutex<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> MutexGuard<'a, T> {
|
impl<'a, T: ?Sized> MutexGuard<'a, T> {
|
||||||
fn new(mutex: &'a Mutex<T>) -> MutexGuard<'a, T> {
|
fn new(mutex: &'a Mutex<T>) -> MutexGuard<'a, T> {
|
||||||
MutexGuard { mutex }
|
MutexGuard { mutex }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for MutexGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -85,24 +87,24 @@ impl<'a, T> Deref for MutexGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> DerefMut for MutexGuard<'a, T> {
|
impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *self.mutex.val.get() }
|
unsafe { &mut *self.mutex.val.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for MutexGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
|
impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&**self, f)
|
fmt::Debug::fmt(&**self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> !Send for MutexGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for MutexGuard<'a, T> {}
|
||||||
|
|
||||||
unsafe impl<T: Sync> Sync for MutexGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
|
||||||
|
@ -96,14 +96,14 @@ use crate::{
|
|||||||
/// assert_eq!(*w2, 7);
|
/// assert_eq!(*w2, 7);
|
||||||
/// } // write lock is dropped at this point
|
/// } // write lock is dropped at this point
|
||||||
/// ```
|
/// ```
|
||||||
pub struct RwLock<T> {
|
pub struct RwLock<T: ?Sized> {
|
||||||
val: UnsafeCell<T>,
|
|
||||||
/// The internal representation of the lock state is as follows:
|
/// The internal representation of the lock state is as follows:
|
||||||
/// - **Bit 63:** Writer lock.
|
/// - **Bit 63:** Writer lock.
|
||||||
/// - **Bit 62:** Upgradeable reader lock.
|
/// - **Bit 62:** Upgradeable reader lock.
|
||||||
/// - **Bit 61:** Indicates if an upgradeable reader is being upgraded.
|
/// - **Bit 61:** Indicates if an upgradeable reader is being upgraded.
|
||||||
/// - **Bits 60-0:** Reader lock count.
|
/// - **Bits 60-0:** Reader lock count.
|
||||||
lock: AtomicUsize,
|
lock: AtomicUsize,
|
||||||
|
val: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const READER: usize = 1;
|
const READER: usize = 1;
|
||||||
@ -120,7 +120,9 @@ impl<T> RwLock<T> {
|
|||||||
lock: AtomicUsize::new(0),
|
lock: AtomicUsize::new(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> RwLock<T> {
|
||||||
/// Acquire a read lock while disabling the local IRQs and spin-wait
|
/// Acquire a read lock while disabling the local IRQs and spin-wait
|
||||||
/// until it can be acquired.
|
/// until it can be acquired.
|
||||||
///
|
///
|
||||||
@ -386,7 +388,7 @@ impl<T> RwLock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
|
impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.val, f)
|
fmt::Debug::fmt(&self.val, f)
|
||||||
}
|
}
|
||||||
@ -394,17 +396,17 @@ impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
|
|||||||
|
|
||||||
/// Because there can be more than one readers to get the T's immutable ref,
|
/// Because there can be more than one readers to get the T's immutable ref,
|
||||||
/// so T must be Sync to guarantee the sharing safety.
|
/// so T must be Sync to guarantee the sharing safety.
|
||||||
unsafe impl<T: Send> Send for RwLock<T> {}
|
unsafe impl<T: ?Sized + Send> Send for RwLock<T> {}
|
||||||
unsafe impl<T: Send + Sync> Sync for RwLock<T> {}
|
unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
|
||||||
|
|
||||||
impl<'a, T> !Send for RwLockWriteGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for RwLockWriteGuard<'a, T> {}
|
||||||
unsafe impl<T: Sync> Sync for RwLockWriteGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for RwLockWriteGuard<'_, T> {}
|
||||||
|
|
||||||
impl<'a, T> !Send for RwLockReadGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for RwLockReadGuard<'a, T> {}
|
||||||
unsafe impl<T: Sync> Sync for RwLockReadGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
|
||||||
|
|
||||||
impl<'a, T> !Send for RwLockUpgradeableGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for RwLockUpgradeableGuard<'a, T> {}
|
||||||
unsafe impl<T: Sync> Sync for RwLockUpgradeableGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for RwLockUpgradeableGuard<'_, T> {}
|
||||||
|
|
||||||
enum InnerGuard {
|
enum InnerGuard {
|
||||||
IrqGuard(DisabledLocalIrqGuard),
|
IrqGuard(DisabledLocalIrqGuard),
|
||||||
@ -412,12 +414,12 @@ enum InnerGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A guard that provides immutable data access.
|
/// A guard that provides immutable data access.
|
||||||
pub struct RwLockReadGuard<'a, T> {
|
pub struct RwLockReadGuard<'a, T: ?Sized> {
|
||||||
inner: &'a RwLock<T>,
|
|
||||||
inner_guard: InnerGuard,
|
inner_guard: InnerGuard,
|
||||||
|
inner: &'a RwLock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for RwLockReadGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for RwLockReadGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -425,25 +427,25 @@ impl<'a, T> Deref for RwLockReadGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for RwLockReadGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner.lock.fetch_sub(READER, Release);
|
self.inner.lock.fetch_sub(READER, Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: fmt::Debug> fmt::Debug for RwLockReadGuard<'a, T> {
|
impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&**self, f)
|
fmt::Debug::fmt(&**self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A guard that provides mutable data access.
|
/// A guard that provides mutable data access.
|
||||||
pub struct RwLockWriteGuard<'a, T> {
|
pub struct RwLockWriteGuard<'a, T: ?Sized> {
|
||||||
inner: &'a RwLock<T>,
|
|
||||||
inner_guard: InnerGuard,
|
inner_guard: InnerGuard,
|
||||||
|
inner: &'a RwLock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for RwLockWriteGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -451,19 +453,19 @@ impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> DerefMut for RwLockWriteGuard<'a, T> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *self.inner.val.get() }
|
unsafe { &mut *self.inner.val.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner.lock.fetch_and(!WRITER, Release);
|
self.inner.lock.fetch_and(!WRITER, Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
|
impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&**self, f)
|
fmt::Debug::fmt(&**self, f)
|
||||||
}
|
}
|
||||||
@ -471,12 +473,12 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
|
|||||||
|
|
||||||
/// A guard that provides immutable data access but can be atomically
|
/// A guard that provides immutable data access but can be atomically
|
||||||
/// upgraded to `RwLockWriteGuard`.
|
/// upgraded to `RwLockWriteGuard`.
|
||||||
pub struct RwLockUpgradeableGuard<'a, T> {
|
pub struct RwLockUpgradeableGuard<'a, T: ?Sized> {
|
||||||
inner: &'a RwLock<T>,
|
|
||||||
inner_guard: InnerGuard,
|
inner_guard: InnerGuard,
|
||||||
|
inner: &'a RwLock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> RwLockUpgradeableGuard<'a, T> {
|
impl<'a, T: ?Sized> RwLockUpgradeableGuard<'a, T> {
|
||||||
/// Upgrade this upread guard to a write guard atomically.
|
/// Upgrade this upread guard to a write guard atomically.
|
||||||
///
|
///
|
||||||
/// After calling this method, subsequent readers will be blocked
|
/// After calling this method, subsequent readers will be blocked
|
||||||
@ -517,7 +519,7 @@ impl<'a, T> RwLockUpgradeableGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for RwLockUpgradeableGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for RwLockUpgradeableGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -525,13 +527,13 @@ impl<'a, T> Deref for RwLockUpgradeableGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for RwLockUpgradeableGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwLockUpgradeableGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner.lock.fetch_sub(UPGRADEABLE_READER, Release);
|
self.inner.lock.fetch_sub(UPGRADEABLE_READER, Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: fmt::Debug> fmt::Debug for RwLockUpgradeableGuard<'a, T> {
|
impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for RwLockUpgradeableGuard<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&**self, f)
|
fmt::Debug::fmt(&**self, f)
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,7 @@ use super::WaitQueue;
|
|||||||
/// assert_eq!(*w2, 7);
|
/// assert_eq!(*w2, 7);
|
||||||
/// } // write mutex is dropped at this point
|
/// } // write mutex is dropped at this point
|
||||||
/// ```
|
/// ```
|
||||||
pub struct RwMutex<T> {
|
pub struct RwMutex<T: ?Sized> {
|
||||||
val: UnsafeCell<T>,
|
|
||||||
/// The internal representation of the mutex state is as follows:
|
/// The internal representation of the mutex state is as follows:
|
||||||
/// - **Bit 63:** Writer mutex.
|
/// - **Bit 63:** Writer mutex.
|
||||||
/// - **Bit 62:** Upgradeable reader mutex.
|
/// - **Bit 62:** Upgradeable reader mutex.
|
||||||
@ -94,6 +93,7 @@ pub struct RwMutex<T> {
|
|||||||
lock: AtomicUsize,
|
lock: AtomicUsize,
|
||||||
/// Threads that fail to acquire the mutex will sleep on this waitqueue.
|
/// Threads that fail to acquire the mutex will sleep on this waitqueue.
|
||||||
queue: WaitQueue,
|
queue: WaitQueue,
|
||||||
|
val: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const READER: usize = 1;
|
const READER: usize = 1;
|
||||||
@ -111,7 +111,9 @@ impl<T> RwMutex<T> {
|
|||||||
queue: WaitQueue::new(),
|
queue: WaitQueue::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> RwMutex<T> {
|
||||||
/// Acquire a read mutex and sleep until it can be acquired.
|
/// Acquire a read mutex and sleep until it can be acquired.
|
||||||
///
|
///
|
||||||
/// The calling thread will sleep until there are no writers or upgrading
|
/// The calling thread will sleep until there are no writers or upgrading
|
||||||
@ -188,7 +190,7 @@ impl<T> RwMutex<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for RwMutex<T> {
|
impl<T: ?Sized + fmt::Debug> fmt::Debug for RwMutex<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.val, f)
|
fmt::Debug::fmt(&self.val, f)
|
||||||
}
|
}
|
||||||
@ -196,24 +198,24 @@ impl<T: fmt::Debug> fmt::Debug for RwMutex<T> {
|
|||||||
|
|
||||||
/// Because there can be more than one readers to get the T's immutable ref,
|
/// Because there can be more than one readers to get the T's immutable ref,
|
||||||
/// so T must be Sync to guarantee the sharing safety.
|
/// so T must be Sync to guarantee the sharing safety.
|
||||||
unsafe impl<T: Send> Send for RwMutex<T> {}
|
unsafe impl<T: ?Sized + Send> Send for RwMutex<T> {}
|
||||||
unsafe impl<T: Send + Sync> Sync for RwMutex<T> {}
|
unsafe impl<T: ?Sized + Send + Sync> Sync for RwMutex<T> {}
|
||||||
|
|
||||||
impl<'a, T> !Send for RwMutexWriteGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for RwMutexWriteGuard<'a, T> {}
|
||||||
unsafe impl<T: Sync> Sync for RwMutexWriteGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for RwMutexWriteGuard<'_, T> {}
|
||||||
|
|
||||||
impl<'a, T> !Send for RwMutexReadGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for RwMutexReadGuard<'a, T> {}
|
||||||
unsafe impl<T: Sync> Sync for RwMutexReadGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for RwMutexReadGuard<'_, T> {}
|
||||||
|
|
||||||
impl<'a, T> !Send for RwMutexUpgradeableGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for RwMutexUpgradeableGuard<'a, T> {}
|
||||||
unsafe impl<T: Sync> Sync for RwMutexUpgradeableGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for RwMutexUpgradeableGuard<'_, T> {}
|
||||||
|
|
||||||
/// A guard that provides immutable data access.
|
/// A guard that provides immutable data access.
|
||||||
pub struct RwMutexReadGuard<'a, T> {
|
pub struct RwMutexReadGuard<'a, T: ?Sized> {
|
||||||
inner: &'a RwMutex<T>,
|
inner: &'a RwMutex<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for RwMutexReadGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for RwMutexReadGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -221,7 +223,7 @@ impl<'a, T> Deref for RwMutexReadGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for RwMutexReadGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwMutexReadGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// When there are no readers, wake up a waiting writer.
|
// When there are no readers, wake up a waiting writer.
|
||||||
if self.inner.lock.fetch_sub(READER, Release) == READER {
|
if self.inner.lock.fetch_sub(READER, Release) == READER {
|
||||||
@ -231,11 +233,11 @@ impl<'a, T> Drop for RwMutexReadGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A guard that provides mutable data access.
|
/// A guard that provides mutable data access.
|
||||||
pub struct RwMutexWriteGuard<'a, T> {
|
pub struct RwMutexWriteGuard<'a, T: ?Sized> {
|
||||||
inner: &'a RwMutex<T>,
|
inner: &'a RwMutex<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for RwMutexWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for RwMutexWriteGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -243,13 +245,13 @@ impl<'a, T> Deref for RwMutexWriteGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> DerefMut for RwMutexWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> DerefMut for RwMutexWriteGuard<'a, T> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *self.inner.val.get() }
|
unsafe { &mut *self.inner.val.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for RwMutexWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwMutexWriteGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner.lock.fetch_and(!WRITER, Release);
|
self.inner.lock.fetch_and(!WRITER, Release);
|
||||||
|
|
||||||
@ -263,11 +265,11 @@ impl<'a, T> Drop for RwMutexWriteGuard<'a, T> {
|
|||||||
|
|
||||||
/// A guard that provides immutable data access but can be atomically
|
/// A guard that provides immutable data access but can be atomically
|
||||||
/// upgraded to `RwMutexWriteGuard`.
|
/// upgraded to `RwMutexWriteGuard`.
|
||||||
pub struct RwMutexUpgradeableGuard<'a, T> {
|
pub struct RwMutexUpgradeableGuard<'a, T: ?Sized> {
|
||||||
inner: &'a RwMutex<T>,
|
inner: &'a RwMutex<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> RwMutexUpgradeableGuard<'a, T> {
|
impl<'a, T: ?Sized> RwMutexUpgradeableGuard<'a, T> {
|
||||||
/// Upgrade this upread guard to a write guard atomically.
|
/// Upgrade this upread guard to a write guard atomically.
|
||||||
///
|
///
|
||||||
/// After calling this method, subsequent readers will be blocked
|
/// After calling this method, subsequent readers will be blocked
|
||||||
@ -307,7 +309,7 @@ impl<'a, T> RwMutexUpgradeableGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for RwMutexUpgradeableGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for RwMutexUpgradeableGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -315,7 +317,7 @@ impl<'a, T> Deref for RwMutexUpgradeableGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for RwMutexUpgradeableGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwMutexUpgradeableGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let res = self.inner.lock.fetch_sub(UPGRADEABLE_READER, Release);
|
let res = self.inner.lock.fetch_sub(UPGRADEABLE_READER, Release);
|
||||||
if res == 0 {
|
if res == 0 {
|
||||||
|
@ -13,20 +13,22 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// A spin lock.
|
/// A spin lock.
|
||||||
pub struct SpinLock<T> {
|
pub struct SpinLock<T: ?Sized> {
|
||||||
val: UnsafeCell<T>,
|
|
||||||
lock: AtomicBool,
|
lock: AtomicBool,
|
||||||
|
val: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SpinLock<T> {
|
impl<T> SpinLock<T> {
|
||||||
/// Creates a new spin lock.
|
/// Creates a new spin lock.
|
||||||
pub const fn new(val: T) -> Self {
|
pub const fn new(val: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
val: UnsafeCell::new(val),
|
|
||||||
lock: AtomicBool::new(false),
|
lock: AtomicBool::new(false),
|
||||||
|
val: UnsafeCell::new(val),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> SpinLock<T> {
|
||||||
/// Acquire the spin lock with disabling the local IRQs. This is the most secure
|
/// Acquire the spin lock with disabling the local IRQs. This is the most secure
|
||||||
/// locking way.
|
/// locking way.
|
||||||
///
|
///
|
||||||
@ -102,15 +104,15 @@ impl<T> SpinLock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for SpinLock<T> {
|
impl<T: ?Sized + fmt::Debug> fmt::Debug for SpinLock<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.val, f)
|
fmt::Debug::fmt(&self.val, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safety. Only a single lock holder is permitted to access the inner data of Spinlock.
|
// Safety. Only a single lock holder is permitted to access the inner data of Spinlock.
|
||||||
unsafe impl<T: Send> Send for SpinLock<T> {}
|
unsafe impl<T: ?Sized + Send> Send for SpinLock<T> {}
|
||||||
unsafe impl<T: Send> Sync for SpinLock<T> {}
|
unsafe impl<T: ?Sized + Send> Sync for SpinLock<T> {}
|
||||||
|
|
||||||
enum InnerGuard {
|
enum InnerGuard {
|
||||||
IrqGuard(DisabledLocalIrqGuard),
|
IrqGuard(DisabledLocalIrqGuard),
|
||||||
@ -118,12 +120,12 @@ enum InnerGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The guard of a spin lock that disables the local IRQs.
|
/// The guard of a spin lock that disables the local IRQs.
|
||||||
pub struct SpinLockGuard<'a, T> {
|
pub struct SpinLockGuard<'a, T: ?Sized> {
|
||||||
lock: &'a SpinLock<T>,
|
|
||||||
inner_guard: InnerGuard,
|
inner_guard: InnerGuard,
|
||||||
|
lock: &'a SpinLock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Deref for SpinLockGuard<'a, T> {
|
impl<'a, T: ?Sized> Deref for SpinLockGuard<'a, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
@ -131,26 +133,26 @@ impl<'a, T> Deref for SpinLockGuard<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> DerefMut for SpinLockGuard<'a, T> {
|
impl<'a, T: ?Sized> DerefMut for SpinLockGuard<'a, T> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *self.lock.val.get() }
|
unsafe { &mut *self.lock.val.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for SpinLockGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for SpinLockGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.lock.release_lock();
|
self.lock.release_lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: fmt::Debug> fmt::Debug for SpinLockGuard<'a, T> {
|
impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for SpinLockGuard<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&**self, f)
|
fmt::Debug::fmt(&**self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> !Send for SpinLockGuard<'a, T> {}
|
impl<'a, T: ?Sized> !Send for SpinLockGuard<'a, T> {}
|
||||||
|
|
||||||
// Safety. `SpinLockGuard` can be shared between tasks/threads in same CPU.
|
// Safety. `SpinLockGuard` can be shared between tasks/threads in same CPU.
|
||||||
// As `lock()` is only called when there are no race conditions caused by interrupts.
|
// As `lock()` is only called when there are no race conditions caused by interrupts.
|
||||||
unsafe impl<T: Sync> Sync for SpinLockGuard<'_, T> {}
|
unsafe impl<T: ?Sized + Sync> Sync for SpinLockGuard<'_, T> {}
|
||||||
|
@ -12,7 +12,7 @@ use super::{common::IfaceCommon, internal::IfaceInternal, Iface};
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub struct IfaceVirtio {
|
pub struct IfaceVirtio {
|
||||||
driver: Arc<SpinLock<Box<dyn AnyNetworkDevice>>>,
|
driver: Arc<SpinLock<dyn AnyNetworkDevice>>,
|
||||||
common: IfaceCommon,
|
common: IfaceCommon,
|
||||||
dhcp_handle: SocketHandle,
|
dhcp_handle: SocketHandle,
|
||||||
weak_self: Weak<Self>,
|
weak_self: Weak<Self>,
|
||||||
@ -32,7 +32,7 @@ impl IfaceVirtio {
|
|||||||
));
|
));
|
||||||
config
|
config
|
||||||
};
|
};
|
||||||
let mut interface = smoltcp::iface::Interface::new(config, &mut **virtio_net.lock());
|
let mut interface = smoltcp::iface::Interface::new(config, &mut *virtio_net.lock());
|
||||||
interface.update_ip_addrs(|ip_addrs| {
|
interface.update_ip_addrs(|ip_addrs| {
|
||||||
debug_assert!(ip_addrs.is_empty());
|
debug_assert!(ip_addrs.is_empty());
|
||||||
ip_addrs.push(ip_addr).unwrap();
|
ip_addrs.push(ip_addr).unwrap();
|
||||||
@ -115,7 +115,7 @@ impl Iface for IfaceVirtio {
|
|||||||
|
|
||||||
fn poll(&self) {
|
fn poll(&self) {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.lock_irq_disabled();
|
||||||
self.common.poll(&mut **driver);
|
self.common.poll(&mut *driver);
|
||||||
self.process_dhcp();
|
self.process_dhcp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ pub mod driver;
|
|||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec::Vec};
|
use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
|
||||||
use core::{any::Any, fmt::Debug};
|
use core::{any::Any, fmt::Debug};
|
||||||
|
|
||||||
use aster_frame::sync::SpinLock;
|
use aster_frame::sync::SpinLock;
|
||||||
@ -50,7 +50,7 @@ pub trait AnyNetworkDevice: Send + Sync + Any + Debug {
|
|||||||
|
|
||||||
pub trait NetDeviceIrqHandler = Fn() + Send + Sync + 'static;
|
pub trait NetDeviceIrqHandler = Fn() + Send + Sync + 'static;
|
||||||
|
|
||||||
pub fn register_device(name: String, device: Arc<SpinLock<Box<dyn AnyNetworkDevice>>>) {
|
pub fn register_device(name: String, device: Arc<SpinLock<dyn AnyNetworkDevice>>) {
|
||||||
COMPONENT
|
COMPONENT
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -59,7 +59,7 @@ pub fn register_device(name: String, device: Arc<SpinLock<Box<dyn AnyNetworkDevi
|
|||||||
.insert(name, (Arc::new(SpinLock::new(Vec::new())), device));
|
.insert(name, (Arc::new(SpinLock::new(Vec::new())), device));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device(str: &str) -> Option<Arc<SpinLock<Box<dyn AnyNetworkDevice>>>> {
|
pub fn get_device(str: &str) -> Option<Arc<SpinLock<dyn AnyNetworkDevice>>> {
|
||||||
let lock = COMPONENT.get().unwrap().network_device_table.lock();
|
let lock = COMPONENT.get().unwrap().network_device_table.lock();
|
||||||
let (_, device) = lock.get(str)?;
|
let (_, device) = lock.get(str)?;
|
||||||
Some(device.clone())
|
Some(device.clone())
|
||||||
@ -106,7 +106,7 @@ fn init() -> Result<(), ComponentInitError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NetDeviceIrqHandlerListRef = Arc<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>>>;
|
type NetDeviceIrqHandlerListRef = Arc<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>>>;
|
||||||
type NetworkDeviceRef = Arc<SpinLock<Box<dyn AnyNetworkDevice>>>;
|
type NetworkDeviceRef = Arc<SpinLock<dyn AnyNetworkDevice>>;
|
||||||
|
|
||||||
struct Component {
|
struct Component {
|
||||||
/// Device list, the key is device name, value is (callbacks, device);
|
/// Device list, the key is device name, value is (callbacks, device);
|
||||||
|
@ -102,7 +102,7 @@ impl NetworkDevice {
|
|||||||
|
|
||||||
aster_network::register_device(
|
aster_network::register_device(
|
||||||
super::DEVICE_NAME.to_string(),
|
super::DEVICE_NAME.to_string(),
|
||||||
Arc::new(SpinLock::new(Box::new(device))),
|
Arc::new(SpinLock::new(device)),
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user