use intrrupt Mutex instead of spin::Mutex

This commit is contained in:
DeathWish5 2022-02-22 22:39:12 +08:00
parent 4aedfd4005
commit e153f5713e
67 changed files with 569 additions and 51 deletions

View File

@ -15,6 +15,7 @@ virtio = ["virtio-drivers"]
[dependencies]
log = "0.4"
spin = "0.9"
lock = { path = "../lock" }
cfg-if = "1.0"
bitflags = "1.3"
lazy_static = "1.4"

View File

@ -1,6 +1,7 @@
use alloc::{boxed::Box, sync::Arc};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::prelude::{CapabilityType, InputEvent, InputEventType};
use crate::scheme::{impl_event_scheme, InputScheme};

View File

@ -1,5 +1,6 @@
use riscv::register::sie;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::prelude::IrqHandler;
use crate::scheme::{IrqScheme, Scheme};

View File

@ -1,6 +1,7 @@
use core::ops::Range;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::io::{Io, Mmio};
use crate::prelude::IrqHandler;

View File

@ -3,7 +3,8 @@ use core::{fmt, ptr::NonNull};
use acpi::platform::interrupt::InterruptModel;
use acpi::{AcpiHandler, AcpiTables, PhysicalMapping};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use x2apic::ioapic::{IoApic as IoApicInner, IrqFlags, IrqMode};
use super::{IrqPolarity, IrqTriggerMode, Phys2VirtFn};

View File

@ -4,7 +4,8 @@ mod lapic;
use core::ops::Range;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use self::consts::{X86_INT_BASE, X86_INT_LOCAL_APIC_BASE};
use self::ioapic::{IoApic, IoApicList};

View File

@ -1,7 +1,8 @@
use std::collections::VecDeque;
use async_std::{io, io::prelude::*, task};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::scheme::{impl_event_scheme, Scheme, UartScheme};
use crate::utils::EventListener;

View File

@ -5,7 +5,8 @@ use crate::net::get_sockets;
use alloc::sync::Arc;
use alloc::string::String;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::scheme::{NetScheme, Scheme};
use crate::{DeviceError, DeviceResult};

View File

@ -63,7 +63,8 @@ pub use loopback::LoopbackInterface;
use alloc::sync::Arc;
use alloc::vec;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use smoltcp::socket::SocketSet;

View File

@ -3,7 +3,8 @@ use alloc::string::String;
use alloc::sync::Arc;
use alloc::vec;
use alloc::vec::Vec;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use smoltcp::iface::*;
use smoltcp::phy::{self, Device, DeviceCapabilities, Medium};

View File

@ -1,6 +1,7 @@
use alloc::{boxed::Box, collections::VecDeque, string::String, sync::Arc};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::scheme::{impl_event_scheme, Scheme, UartScheme};
use crate::utils::EventListener;

View File

@ -2,7 +2,8 @@ use core::convert::TryInto;
use core::ops::{BitAnd, BitOr, Not};
use bitflags::bitflags;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::io::{Io, Mmio, ReadOnly};
use crate::scheme::{impl_event_scheme, Scheme, UartScheme};

View File

@ -1,6 +1,7 @@
use alloc::{boxed::Box, vec::Vec};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
pub type EventHandler<T = ()> = Box<dyn Fn(&T) + Send + Sync>;

View File

@ -1,4 +1,5 @@
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use virtio_drivers::{VirtIOBlk as InnerDriver, VirtIOHeader};
use crate::scheme::{BlockScheme, Scheme};

View File

@ -1,6 +1,7 @@
use core::fmt::{Result, Write};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use virtio_drivers::{VirtIOConsole as InnerDriver, VirtIOHeader};
use crate::prelude::DeviceResult;

View File

@ -1,4 +1,5 @@
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use virtio_drivers::{VirtIOGpu as InnerDriver, VirtIOHeader};
use crate::prelude::{ColorFormat, DisplayInfo, FrameBuffer};

View File

@ -1,6 +1,7 @@
use core::convert::TryFrom;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use virtio_drivers::{InputConfigSelect, VirtIOHeader, VirtIOInput as InnerDriver};
use crate::prelude::{CapabilityType, InputCapability, InputEvent, InputEventType};

View File

@ -16,6 +16,7 @@ graphic = ["zcore-drivers/graphic"]
[dependencies]
log = "0.4"
spin = "0.9"
lock = { path = "../lock" }
cfg-if = "1.0"
bitflags = "1.3"
trapframe = "0.8.0"

View File

@ -6,6 +6,14 @@ pub(super) static CPU_FREQ_MHZ: InitOnce<u16> = InitOnce::new_with_default(10);
hal_fn_impl! {
impl mod crate::hal_fn::cpu {
fn cpu_id() -> u8 {
let mut cpu_id: i64;
unsafe {
asm!("mv {0}, tp", out(reg) cpu_id);
}
(cpu_id & 0xff) as u8
}
fn cpu_frequency() -> u16 {
*CPU_FREQ_MHZ
}

View File

@ -17,5 +17,17 @@ hal_fn_impl! {
trace!("Handle irq cause: {}", cause);
crate::drivers::all_irq().first_unwrap().handle_irq(cause)
}
fn intr_on() {
unsafe { sstatus::set_sie() };
}
fn intr_off() {
unsafe { sstatus::clear_sie() };
}
fn intr_get() -> bool {
sstatus::read().sie()
}
}
}

View File

@ -4,7 +4,8 @@ use core::fmt::{Debug, Formatter, Result};
use core::slice;
use riscv::{asm, register::satp};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::utils::page_table::{GenericPTE, PageTableImpl, PageTableLevel3};
use crate::{mem::phys_to_virt, MMUFlags, PhysAddr, VirtAddr, KCONFIG};

View File

@ -5,11 +5,11 @@ use core::ops::Range;
use crate::drivers::all_irq;
use crate::drivers::prelude::{IrqHandler, IrqPolarity, IrqTriggerMode};
use crate::HalResult;
use x86_64::instructions::interrupts;
hal_fn_impl! {
impl mod crate::hal_fn::interrupt {
fn wait_for_interrupt() {
use x86_64::instructions::interrupts;
interrupts::enable_and_hlt();
interrupts::disable();
}
@ -18,6 +18,18 @@ hal_fn_impl! {
all_irq().first_unwrap().is_valid_irq(gsi)
}
fn intr_on() {
interrupts::enable();
}
fn intr_off() {
interrupts::disable();
}
fn intr_get() -> bool {
interrupts::are_enabled()
}
fn mask_irq(gsi: usize) -> HalResult {
Ok(all_irq().first_unwrap().mask(gsi)?)
}

View File

@ -11,7 +11,8 @@ use alloc::vec::Vec;
use alloc::sync::Arc;
use alloc::string::String;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::drivers::add_device;
use crate::drivers::all_net;

View File

@ -4,7 +4,8 @@ use alloc::boxed::Box;
use core::time::Duration;
use naive_timer::Timer;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
#[allow(dead_code)]
pub(super) const TICKS_PER_SEC: u64 = 100;

View File

@ -2,7 +2,8 @@
use crate::drivers;
use core::fmt::{Arguments, Result, Write};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
struct SerialWriter;

View File

@ -91,6 +91,15 @@ hal_fn_def! {
/// Is a valid IRQ number.
pub fn is_valid_irq(vector: usize) -> bool;
/// Enable the interrupts
pub fn intr_on();
/// Disable the interrupts
pub fn intr_off();
/// Test weather interrupt is enabled
pub fn intr_get() -> bool;
/// Disable IRQ.
pub fn mask_irq(vector: usize) -> HalResult;

View File

@ -47,3 +47,25 @@ pub use kernel_handler::KernelHandler;
#[cfg(any(feature = "smp", doc))]
#[doc(cfg(feature = "smp"))]
pub use imp::boot::{primary_init, primary_init_early, secondary_init};
mod interrupt_ffi {
#[no_mangle]
extern "C" fn intr_on() {
super::interrupt::intr_on();
}
#[no_mangle]
extern "C" fn intr_off() {
super::interrupt::intr_off();
}
#[no_mangle]
extern "C" fn intr_get() -> bool {
super::interrupt::intr_get()
}
#[no_mangle]
extern "C" fn cpu_id() -> u8 {
super::cpu::cpu_id()
}
}

View File

@ -4,7 +4,8 @@ use alloc::vec::Vec;
use core::ops::Range;
use bitmap_allocator::BitAlloc;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use super::mock_mem::MockMemory;
use crate::{PhysAddr, VirtAddr, PAGE_SIZE};

View File

@ -11,7 +11,8 @@ use alloc::vec::Vec;
use alloc::sync::Arc;
use alloc::string::String;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use crate::drivers::add_device;
use crate::drivers::all_net;

View File

@ -6,6 +6,9 @@ use core::{fmt::Debug, marker::PhantomData, slice};
use crate::common::vm::*;
use crate::{mem::PhysFrame, MMUFlags, PhysAddr, VirtAddr};
// use spin::Mutex;
use lock::spinlock::Mutex;
pub trait PageTableLevel: Sync + Send {
const LEVEL: usize;
}
@ -150,7 +153,7 @@ impl<L: PageTableLevel, PTE: GenericPTE> PageTableImpl<L, PTE> {
}
fn dump(&self, limit: usize, print_fn: impl Fn(core::fmt::Arguments)) {
static LOCK: spin::Mutex<()> = spin::Mutex::new(());
static LOCK: Mutex<()> = Mutex::new(());
let _lock = LOCK.lock();
print_fn(format_args!("Root: {:x?}\n", self.table_phys()));

View File

@ -11,6 +11,7 @@ description = "Linux kernel objects"
async-trait = "0.1"
log = "0.4"
spin = "0.9"
lock = { path = "../lock" }
xmas-elf = "0.7"
bitflags = "1.3"
hashbrown = "0.9"

View File

@ -2,7 +2,8 @@ use alloc::{boxed::Box, collections::VecDeque, sync::Arc};
use core::task::{Context, Poll};
use core::{any::Any, future::Future, mem::size_of, pin::Pin};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use kernel_hal::drivers::prelude::{InputEvent, InputEventType};
use kernel_hal::drivers::scheme::InputScheme;

View File

@ -2,7 +2,8 @@ use alloc::{boxed::Box, collections::VecDeque, sync::Arc, vec::Vec};
use core::task::{Context, Poll};
use core::{any::Any, future::Future, pin::Pin};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use kernel_hal::drivers::prelude::input::{Mouse, MouseFlags, MouseState};
use kernel_hal::drivers::scheme::{EventScheme, InputScheme};

View File

@ -5,7 +5,8 @@ use core::any::Any;
use rcore_fs::vfs::*;
use rcore_fs_devfs::DevFS;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
/// random INode data struct
pub struct RandomINodeData {

View File

@ -10,7 +10,8 @@ use core::{
task::{Context, Poll},
};
use rcore_fs::vfs::*;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
#[derive(Clone, PartialEq)]
#[allow(dead_code)]

View File

@ -13,7 +13,8 @@ use core::task::{Context, Poll};
use kernel_hal::console::{self, ConsoleWinSize};
use lazy_static::lazy_static;
use rcore_fs::vfs::*;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
lazy_static! {
/// STDIN global reference

View File

@ -6,7 +6,8 @@ use crate::time::*;
use alloc::{collections::BTreeMap, sync::Arc, sync::Weak, vec::Vec};
use core::ops::Index;
use lazy_static::*;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use spin::RwLock;
/// semid data structure

View File

@ -4,7 +4,8 @@ use crate::error::LxError;
use crate::time::TimeSpec;
use alloc::{collections::BTreeMap, sync::Arc, sync::Weak};
use lazy_static::lazy_static;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use spin::RwLock;
use zircon_object::vm::*;

View File

@ -13,7 +13,8 @@ pub use tcp::*;
pub mod udp;
pub use udp::*;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
/// missing documentation
// pub mod raw;
// pub use raw::*;

View File

@ -15,7 +15,8 @@ use crate::net::SysResult;
use crate::net::TCP_RECVBUF;
use crate::net::TCP_SENDBUF;
use alloc::sync::Arc;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
// alloc
use alloc::boxed::Box;

View File

@ -23,7 +23,8 @@ use crate::net::SysResult;
use crate::net::UDP_METADATA_BUF;
use crate::net::UDP_RECVBUF;
use crate::net::UDP_SENDBUF;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
// alloc
use alloc::boxed::Box;

View File

@ -12,7 +12,8 @@ use crate::net::Socket;
use hashbrown::HashMap;
use rcore_fs::vfs::{FileSystem, INode};
use smoltcp::socket::SocketHandle;
use spin::{Mutex, MutexGuard};
// use spin::{Mutex, MutexGuard};
use lock::spinlock::{Mutex, MutexGuard};
use kernel_hal::VirtAddr;
use zircon_object::{

View File

@ -9,7 +9,8 @@ use core::{
pin::Pin,
task::{Context, Poll},
};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
bitflags! {
#[derive(Default)]

View File

@ -11,7 +11,8 @@ use core::future::Future;
use core::ops::Deref;
use core::pin::Pin;
use core::task::{Context, Poll};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
/// A counting, blocking, semaphore.
pub struct Semaphore {

View File

@ -5,7 +5,8 @@ use crate::signal::{SignalStack, Sigset};
use alloc::sync::Arc;
use kernel_hal::user::{Out, UserOutPtr, UserPtr};
use kernel_hal::VirtAddr;
use spin::{Mutex, MutexGuard};
// use spin::{Mutex, MutexGuard};
use lock::spinlock::{Mutex, MutexGuard};
use zircon_object::task::{CurrentThread, Process, Thread};
use zircon_object::ZxResult;

View File

@ -10,6 +10,7 @@ description = "Linux syscalls implementation"
[dependencies]
log = "0.4"
spin = "0.9"
lock = { path = "../lock" }
bitflags = "1.3"
numeric-enum-macro = "0.2"
zircon-object = { path = "../zircon-object" }

View File

@ -6,7 +6,8 @@ use linux_object::net::Socket;
use linux_object::net::TcpSocketState;
use linux_object::net::UdpSocketState;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
impl Syscall<'_> {
/// net socket

9
lock/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "lock"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
lazy_static = { version = "1.4", features = ["spin_no_std"] }

86
lock/src/interrupt.rs Normal file
View File

@ -0,0 +1,86 @@
use core::cell::{RefCell, RefMut};
use lazy_static::*;
extern "C" {
pub fn intr_on();
pub fn intr_off();
pub fn intr_get() -> bool;
pub fn cpu_id() -> u8;
}
pub fn intr_on_() {
unsafe { intr_on(); }
}
pub fn intr_off_() {
unsafe { intr_off(); }
}
pub fn intr_get_() -> bool {
unsafe { intr_get() }
}
pub fn cpu_id_() -> u8 {
unsafe { cpu_id() }
}
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct Cpu {
pub noff: i32, // Depth of push_off() nesting.
pub interrupt_enable: bool, // Were interrupts enabled before push_off()?
}
impl Cpu {
const fn new() -> Self {
Self {
noff: 0,
interrupt_enable: false,
}
}
}
pub struct SafeRefCell<T>(RefCell<T>);
// #Safety: Only the corresponding cpu will access it.
unsafe impl<Cpu> Sync for SafeRefCell<Cpu> {}
impl<T> SafeRefCell<T> {
const fn new(t: T) -> Self {
Self(RefCell::new(t))
}
}
const DEFAULT_CPU: SafeRefCell<Cpu> = SafeRefCell::new(Cpu::new());
lazy_static! {
pub static ref CPUS: [SafeRefCell<Cpu>; 16] = [DEFAULT_CPU; 16];
}
pub fn mycpu() -> RefMut<'static, Cpu> {
return CPUS[cpu_id_() as usize].0.borrow_mut();
}
// push_off/pop_off are like intr_off_()/intr_on_() except that they are matched:
// it takes two pop_off()s to undo two push_off()s. Also, if interrupts
// are initially off, then push_off, pop_off leaves them off.
pub(crate) fn push_off() {
let old = intr_get_();
intr_off_();
let mut cpu = mycpu();
if cpu.noff == 0 {
cpu.interrupt_enable = old;
}
cpu.noff += 1;
}
pub(crate) fn pop_off() {
let mut cpu = mycpu();
if intr_get_() || cpu.noff < 1 {
panic!("pop_off");
}
cpu.noff -= 1;
if cpu.noff == 0 && cpu.interrupt_enable {
intr_on_();
}
}

9
lock/src/lib.rs Normal file
View File

@ -0,0 +1,9 @@
#![no_std]
#![feature(asm)]
extern crate alloc;
pub mod interrupt;
// pub mod mutex;
pub mod spinlock;

129
lock/src/mutex.rs Normal file
View File

@ -0,0 +1,129 @@
// use alloc::collections::linked_list::LinkedList;
// use core::cell::UnsafeCell;
// use core::future::Future;
// use core::ops::{Deref, DerefMut};
// use core::pin::Pin;
// use core::sync::atomic::{AtomicBool, Ordering};
// use core::task::{Context, Poll, Waker};
// use crate::spinlock::SpinLock;
// /// A mutual exclusion and asynchronous primitive which could work
// /// in bare metal environments.
// ///
// /// This mutex block coroutine waiting for the lock to become available.
// /// The mutex can also be statically initialized or created via a new
// /// constructor. Each mutex has a type parameter which represents the
// /// data that it is protecting. The data can only be accessed through
// /// the RAII guards returned from lock and try_lock, which guarantees
// /// that the data is only ever accessed when the mutex is locked.
// pub struct AMutex<T: ?Sized> {
// state: AtomicBool,
// wakers: SpinLock<LinkedList<Waker>>,
// data: UnsafeCell<T>,
// }
// /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
// /// dropped (falls out of scope), the lock will be unlocked.
// ///
// /// The data protected by the mutex can be accessed through this guard via its
// /// [`Deref`] and [`DerefMut`] implementations.
// ///
// /// This structure is created by the [`lock`] and [`try_lock`] methods on
// /// [`AMutex`].
// ///
// /// [`lock`]: AMutex::lock
// /// [`try_lock`]: AMutex::try_lock
// #[must_use = "if unused the AMutex will immediately unlock"]
// pub struct AMutexGuard<'a, T: ?Sized> {
// mutex: &'a AMutex<T>,
// }
// /// A future which resolves when the target mutex has been successfully
// /// acquired.
// pub struct AMutexLockFuture<'a, T: ?Sized> {
// mutex: &'a AMutex<T>,
// }
// unsafe impl<T: ?Sized + Send> Send for AMutex<T> {}
// unsafe impl<T: ?Sized + Send> Sync for AMutex<T> {}
// unsafe impl<T: ?Sized + Send> Send for AMutexGuard<'_, T> {}
// unsafe impl<T: ?Sized + Sync> Sync for AMutexGuard<'_, T> {}
// unsafe impl<T: ?Sized + Send> Send for AMutexLockFuture<'_, T> {}
// impl<T> AMutex<T> {
// /// Creates a new mutex in an unlocked state ready for use.
// pub fn new(t: T) -> Self {
// AMutex {
// state: AtomicBool::new(false),
// wakers: SpinLock::new(LinkedList::new()),
// data: UnsafeCell::new(t),
// }
// }
// }
// impl<T: ?Sized> AMutex<T> {
// pub fn lock(&self) -> AMutexLockFuture<'_, T> {
// return AMutexLockFuture { mutex: self };
// }
// /// Attempts to acquire this lock immedidately.
// pub fn try_lock(&self) -> Option<AMutexGuard<'_, T>> {
// if !self.state.fetch_or(true, Ordering::Acquire) {
// Some(AMutexGuard { mutex: self })
// } else {
// None
// }
// }
// pub fn unlock(&self) {
// self.state.store(false, Ordering::Release);
// let waker = self.wakers.lock().pop_front();
// if waker.is_some() {
// waker.unwrap().wake();
// }
// }
// pub fn register(&self, waker: Waker) {
// self.wakers.lock().push_back(waker);
// }
// }
// impl<'a, T: ?Sized> Future for AMutexLockFuture<'a, T> {
// type Output = AMutexGuard<'a, T>;
// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// if let Some(lock) = self.mutex.try_lock() {
// return Poll::Ready(lock);
// }
// let waker = cx.waker().clone();
// self.mutex.register(waker);
// if let Some(lock) = self.mutex.try_lock() {
// return Poll::Ready(lock);
// }
// Poll::Pending
// }
// }
// impl<T: ?Sized> Deref for AMutexGuard<'_, T> {
// type Target = T;
// #[inline]
// fn deref(&self) -> &T {
// unsafe { &*self.mutex.data.get() }
// }
// }
// impl<T: ?Sized> DerefMut for AMutexGuard<'_, T> {
// #[inline]
// fn deref_mut(&mut self) -> &mut T {
// unsafe { &mut *self.mutex.data.get() }
// }
// }
// impl<T: ?Sized> Drop for AMutexGuard<'_, T> {
// #[inline]
// fn drop(&mut self) {
// self.mutex.unlock();
// }
// }

164
lock/src/spinlock.rs Normal file
View File

@ -0,0 +1,164 @@
use core::{
cell::UnsafeCell,
fmt,
ops::{Deref, DerefMut},
sync::atomic::{AtomicBool, Ordering},
default::Default,
};
use crate::interrupt::{cpu_id_, pop_off, push_off};
pub struct Mutex<T: ?Sized> {
pub(crate) locked: AtomicBool,
cpuid: u8,
data: UnsafeCell<T>,
}
/// An RAII implementation of a “scoped lock” of a mutex.
/// When this structure is dropped (falls out of scope),
/// the lock will be unlocked.
///
pub struct MutexGuard<'a, T: ?Sized + 'a> {
spinlock: &'a Mutex<T>,
data: &'a mut T,
}
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
impl<T> Mutex<T> {
#[inline(always)]
pub const fn new(data: T) -> Self {
Mutex {
locked: AtomicBool::new(false),
data: UnsafeCell::new(data),
cpuid: 0,
}
}
#[inline(always)]
pub fn into_inner(self) -> T {
// We know statically that there are no outstanding references to
// `self` so there's no need to lock.
let Mutex { data, .. } = self;
data.into_inner()
}
#[inline(always)]
pub fn as_mut_ptr(&self) -> *mut T {
self.data.get()
}
}
impl<T: ?Sized> Mutex<T> {
#[inline(always)]
pub fn lock(&self) -> MutexGuard<T> {
push_off();
if self.holding() {
panic!("a spinlock can only be locked once by a CPU");
}
while self
.locked
.compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed)
.is_err()
{
// Wait until the lock looks unlocked before retrying
while self.is_locked() {
core::hint::spin_loop();
}
}
MutexGuard {
spinlock: self,
data: unsafe { &mut *self.data.get() },
}
}
#[inline(always)]
pub fn try_lock(&self) -> Option<MutexGuard<T>> {
push_off();
if self.holding() {
panic!("a spinlock can only be locked once by a CPU");
}
if self
.locked
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
.is_ok()
{
Some(MutexGuard {
spinlock: self,
data: unsafe { &mut *self.data.get() },
})
} else {
pop_off();
None
}
}
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
// We know statically that there are no other references to `self`, so
// there's no need to lock the inner mutex.
unsafe { &mut *self.data.get() }
}
#[inline(always)]
pub fn is_locked(&self) -> bool {
self.locked.load(Ordering::Relaxed)
}
/// Check whether this cpu is holding the lock.
/// Interrupts must be off.
#[inline(always)]
pub fn holding(&self) -> bool {
return self.is_locked() && self.cpuid == cpu_id_();
}
}
impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.data
}
}
impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.data
}
}
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
/// The dropping of the MutexGuard will release the lock it was created from.
fn drop(&mut self) {
if !self.spinlock.holding() {
panic!("current cpu doesn't hold the lock{}", self.spinlock);
}
self.spinlock.locked.store(false, Ordering::Release);
pop_off();
}
}
impl<T: ?Sized> fmt::Display for Mutex<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Spinlock{{locked={}, cpuid={}}}",
self.locked.load(Ordering::Relaxed),
self.cpuid,
)
}
}
impl<T: ?Sized + Default> Default for Mutex<T> {
fn default() -> Self {
Mutex::new(T::default())
}
}

View File

@ -30,6 +30,7 @@ board-d1 = ["link-user-img"]
[dependencies]
log = "0.4"
spin = "0.9"
lock = { path = "../lock" }
cfg-if = "1.0"
lazy_static = { version = "1.4", features = ["spin_no_std" ] }
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" }

View File

@ -4,7 +4,8 @@ use core::ops::Range;
use bitmap_allocator::BitAlloc;
use kernel_hal::PhysAddr;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use super::platform::consts::*;

View File

@ -15,6 +15,7 @@ elf = ["xmas-elf"]
[dependencies]
bitflags = "1.3"
spin = "0.9"
lock = { path = "../lock" }
log = "0.4"
hashbrown = "0.9"
downcast-rs = { version = "1.2", default-features = false }

View File

@ -1,5 +1,6 @@
use alloc::{boxed::Box, sync::Arc};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use super::InterruptTrait;
use crate::dev::pci::{constants::PCIE_IRQRET_MASK, IPciNode};

View File

@ -17,7 +17,8 @@ use core::cmp::min;
use core::marker::{Send, Sync};
use lazy_static::*;
use region_alloc::RegionAllocator;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
/// PCIE Bus Driver.
pub struct PCIeBusDriver {

View File

@ -16,7 +16,8 @@ use alloc::{boxed::Box, vec::Vec};
use kernel_hal::interrupt;
use numeric_enum_macro::numeric_enum;
use region_alloc::RegionAllocator;
use spin::{Mutex, MutexGuard};
// use spin::{Mutex, MutexGuard};
use lock::spinlock::{Mutex, MutexGuard};
numeric_enum! {
#[repr(u8)]

View File

@ -13,7 +13,8 @@ pub fn pci_bdf_raw_addr(bus: u8, dev: u8, func: u8, offset: u8) -> u32 {
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
use kernel_hal::x86_64::{pio_read, pio_write};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
static PIO_LOCK: Mutex<()> = Mutex::new(());
const PCI_CONFIG_ADDR: u16 = 0xcf8;

View File

@ -55,7 +55,7 @@
//! ```
//! use zircon_object::object::*;
//! use std::sync::Arc;
//! use spin::Mutex;
//! use lock::spinlock::Mutex;
//!
//! pub struct SampleObject {
//! base: KObjectBase,

View File

@ -6,7 +6,8 @@ use core::future::Future;
use core::pin::Pin;
use core::sync::atomic::*;
use core::task::{Context, Poll, Waker};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
/// A primitive for creating userspace synchronization tools.
///

View File

@ -4,7 +4,8 @@ use crate::object::*;
use alloc::collections::{BTreeSet, VecDeque};
use alloc::sync::Arc;
use bitflags::bitflags;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
#[path = "port_packet.rs"]
mod port_packet;

View File

@ -3,7 +3,8 @@ use crate::object::*;
use alloc::boxed::Box;
use alloc::sync::Arc;
use core::time::Duration;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
/// An object that may be signaled at some point in the future
///

View File

@ -3,7 +3,8 @@ use core::mem::size_of;
use futures::channel::oneshot;
use kernel_hal::context::{TrapReason, UserContext};
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use super::{Job, Task, Thread};
use crate::ipc::{Channel, MessagePacket};

View File

@ -3,7 +3,8 @@ use core::{any::Any, sync::atomic::AtomicI32};
use futures::channel::oneshot::{self, Receiver, Sender};
use hashbrown::HashMap;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use super::exception::{ExceptionChannelType, Exceptionate};
use super::job_policy::{JobPolicy, PolicyAction, PolicyCondition};

View File

@ -10,7 +10,8 @@ use core::{any::Any, future::Future, pin::Pin};
use bitflags::bitflags;
use futures::{channel::oneshot::*, future::FutureExt, pin_mut, select_biased};
use kernel_hal::context::UserContext;
use spin::Mutex;
// use spin::Mutex;
use lock::spinlock::Mutex;
use self::thread_state::ContextAccessState;
use super::{exception::*, Process, Task};

View File

@ -14,6 +14,7 @@ deny-page-fault = []
[dependencies]
log = "0.4"
spin = "0.9"
lock = { path = "../lock" }
bitflags = "1.3"
numeric-enum-macro = "0.2"
zircon-object = { path = "../zircon-object" }