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] [dependencies]
log = "0.4" log = "0.4"
spin = "0.9" spin = "0.9"
lock = { path = "../lock" }
cfg-if = "1.0" cfg-if = "1.0"
bitflags = "1.3" bitflags = "1.3"
lazy_static = "1.4" lazy_static = "1.4"

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,8 @@ mod lapic;
use core::ops::Range; 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::consts::{X86_INT_BASE, X86_INT_LOCAL_APIC_BASE};
use self::ioapic::{IoApic, IoApicList}; use self::ioapic::{IoApic, IoApicList};

View File

@ -1,7 +1,8 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use async_std::{io, io::prelude::*, task}; 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::scheme::{impl_event_scheme, Scheme, UartScheme};
use crate::utils::EventListener; use crate::utils::EventListener;

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
use alloc::{boxed::Box, collections::VecDeque, string::String, sync::Arc}; 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::scheme::{impl_event_scheme, Scheme, UartScheme};
use crate::utils::EventListener; use crate::utils::EventListener;

View File

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

View File

@ -1,6 +1,7 @@
use alloc::{boxed::Box, vec::Vec}; 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>; 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 virtio_drivers::{VirtIOBlk as InnerDriver, VirtIOHeader};
use crate::scheme::{BlockScheme, Scheme}; use crate::scheme::{BlockScheme, Scheme};

View File

@ -1,6 +1,7 @@
use core::fmt::{Result, Write}; use core::fmt::{Result, Write};
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
use virtio_drivers::{VirtIOConsole as InnerDriver, VirtIOHeader}; use virtio_drivers::{VirtIOConsole as InnerDriver, VirtIOHeader};
use crate::prelude::DeviceResult; 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 virtio_drivers::{VirtIOGpu as InnerDriver, VirtIOHeader};
use crate::prelude::{ColorFormat, DisplayInfo, FrameBuffer}; use crate::prelude::{ColorFormat, DisplayInfo, FrameBuffer};

View File

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

View File

@ -16,6 +16,7 @@ graphic = ["zcore-drivers/graphic"]
[dependencies] [dependencies]
log = "0.4" log = "0.4"
spin = "0.9" spin = "0.9"
lock = { path = "../lock" }
cfg-if = "1.0" cfg-if = "1.0"
bitflags = "1.3" bitflags = "1.3"
trapframe = "0.8.0" 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! { hal_fn_impl! {
impl mod crate::hal_fn::cpu { 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 { fn cpu_frequency() -> u16 {
*CPU_FREQ_MHZ *CPU_FREQ_MHZ
} }

View File

@ -17,5 +17,17 @@ hal_fn_impl! {
trace!("Handle irq cause: {}", cause); trace!("Handle irq cause: {}", cause);
crate::drivers::all_irq().first_unwrap().handle_irq(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 core::slice;
use riscv::{asm, register::satp}; 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::utils::page_table::{GenericPTE, PageTableImpl, PageTableLevel3};
use crate::{mem::phys_to_virt, MMUFlags, PhysAddr, VirtAddr, KCONFIG}; 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::all_irq;
use crate::drivers::prelude::{IrqHandler, IrqPolarity, IrqTriggerMode}; use crate::drivers::prelude::{IrqHandler, IrqPolarity, IrqTriggerMode};
use crate::HalResult; use crate::HalResult;
use x86_64::instructions::interrupts;
hal_fn_impl! { hal_fn_impl! {
impl mod crate::hal_fn::interrupt { impl mod crate::hal_fn::interrupt {
fn wait_for_interrupt() { fn wait_for_interrupt() {
use x86_64::instructions::interrupts;
interrupts::enable_and_hlt(); interrupts::enable_and_hlt();
interrupts::disable(); interrupts::disable();
} }
@ -18,6 +18,18 @@ hal_fn_impl! {
all_irq().first_unwrap().is_valid_irq(gsi) 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 { fn mask_irq(gsi: usize) -> HalResult {
Ok(all_irq().first_unwrap().mask(gsi)?) Ok(all_irq().first_unwrap().mask(gsi)?)
} }

View File

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

View File

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

View File

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

View File

@ -91,6 +91,15 @@ hal_fn_def! {
/// Is a valid IRQ number. /// Is a valid IRQ number.
pub fn is_valid_irq(vector: usize) -> bool; 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. /// Disable IRQ.
pub fn mask_irq(vector: usize) -> HalResult; pub fn mask_irq(vector: usize) -> HalResult;

View File

@ -47,3 +47,25 @@ pub use kernel_handler::KernelHandler;
#[cfg(any(feature = "smp", doc))] #[cfg(any(feature = "smp", doc))]
#[doc(cfg(feature = "smp"))] #[doc(cfg(feature = "smp"))]
pub use imp::boot::{primary_init, primary_init_early, secondary_init}; 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 core::ops::Range;
use bitmap_allocator::BitAlloc; use bitmap_allocator::BitAlloc;
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
use super::mock_mem::MockMemory; use super::mock_mem::MockMemory;
use crate::{PhysAddr, VirtAddr, PAGE_SIZE}; use crate::{PhysAddr, VirtAddr, PAGE_SIZE};

View File

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

View File

@ -6,6 +6,9 @@ use core::{fmt::Debug, marker::PhantomData, slice};
use crate::common::vm::*; use crate::common::vm::*;
use crate::{mem::PhysFrame, MMUFlags, PhysAddr, VirtAddr}; use crate::{mem::PhysFrame, MMUFlags, PhysAddr, VirtAddr};
// use spin::Mutex;
use lock::spinlock::Mutex;
pub trait PageTableLevel: Sync + Send { pub trait PageTableLevel: Sync + Send {
const LEVEL: usize; 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)) { 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(); let _lock = LOCK.lock();
print_fn(format_args!("Root: {:x?}\n", self.table_phys())); print_fn(format_args!("Root: {:x?}\n", self.table_phys()));

View File

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

View File

@ -2,7 +2,8 @@ use alloc::{boxed::Box, collections::VecDeque, sync::Arc};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use core::{any::Any, future::Future, mem::size_of, pin::Pin}; 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::prelude::{InputEvent, InputEventType};
use kernel_hal::drivers::scheme::InputScheme; 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::task::{Context, Poll};
use core::{any::Any, future::Future, pin::Pin}; 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::prelude::input::{Mouse, MouseFlags, MouseState};
use kernel_hal::drivers::scheme::{EventScheme, InputScheme}; use kernel_hal::drivers::scheme::{EventScheme, InputScheme};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,8 @@ use crate::signal::{SignalStack, Sigset};
use alloc::sync::Arc; use alloc::sync::Arc;
use kernel_hal::user::{Out, UserOutPtr, UserPtr}; use kernel_hal::user::{Out, UserOutPtr, UserPtr};
use kernel_hal::VirtAddr; 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::task::{CurrentThread, Process, Thread};
use zircon_object::ZxResult; use zircon_object::ZxResult;

View File

@ -10,6 +10,7 @@ description = "Linux syscalls implementation"
[dependencies] [dependencies]
log = "0.4" log = "0.4"
spin = "0.9" spin = "0.9"
lock = { path = "../lock" }
bitflags = "1.3" bitflags = "1.3"
numeric-enum-macro = "0.2" numeric-enum-macro = "0.2"
zircon-object = { path = "../zircon-object" } 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::TcpSocketState;
use linux_object::net::UdpSocketState; use linux_object::net::UdpSocketState;
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
impl Syscall<'_> { impl Syscall<'_> {
/// net socket /// 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] [dependencies]
log = "0.4" log = "0.4"
spin = "0.9" spin = "0.9"
lock = { path = "../lock" }
cfg-if = "1.0" cfg-if = "1.0"
lazy_static = { version = "1.4", features = ["spin_no_std" ] } lazy_static = { version = "1.4", features = ["spin_no_std" ] }
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" } 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 bitmap_allocator::BitAlloc;
use kernel_hal::PhysAddr; use kernel_hal::PhysAddr;
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
use super::platform::consts::*; use super::platform::consts::*;

View File

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

View File

@ -1,5 +1,6 @@
use alloc::{boxed::Box, sync::Arc}; use alloc::{boxed::Box, sync::Arc};
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
use super::InterruptTrait; use super::InterruptTrait;
use crate::dev::pci::{constants::PCIE_IRQRET_MASK, IPciNode}; 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 core::marker::{Send, Sync};
use lazy_static::*; use lazy_static::*;
use region_alloc::RegionAllocator; use region_alloc::RegionAllocator;
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
/// PCIE Bus Driver. /// PCIE Bus Driver.
pub struct PCIeBusDriver { pub struct PCIeBusDriver {

View File

@ -16,7 +16,8 @@ use alloc::{boxed::Box, vec::Vec};
use kernel_hal::interrupt; use kernel_hal::interrupt;
use numeric_enum_macro::numeric_enum; use numeric_enum_macro::numeric_enum;
use region_alloc::RegionAllocator; use region_alloc::RegionAllocator;
use spin::{Mutex, MutexGuard}; // use spin::{Mutex, MutexGuard};
use lock::spinlock::{Mutex, MutexGuard};
numeric_enum! { numeric_enum! {
#[repr(u8)] #[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! { cfg_if::cfg_if! {
if #[cfg(all(target_arch = "x86_64", target_os = "none"))] { if #[cfg(all(target_arch = "x86_64", target_os = "none"))] {
use kernel_hal::x86_64::{pio_read, pio_write}; 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(()); static PIO_LOCK: Mutex<()> = Mutex::new(());
const PCI_CONFIG_ADDR: u16 = 0xcf8; const PCI_CONFIG_ADDR: u16 = 0xcf8;

View File

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

View File

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

View File

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

View File

@ -3,7 +3,8 @@ use crate::object::*;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::sync::Arc; use alloc::sync::Arc;
use core::time::Duration; 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 /// 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 futures::channel::oneshot;
use kernel_hal::context::{TrapReason, UserContext}; use kernel_hal::context::{TrapReason, UserContext};
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
use super::{Job, Task, Thread}; use super::{Job, Task, Thread};
use crate::ipc::{Channel, MessagePacket}; 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 futures::channel::oneshot::{self, Receiver, Sender};
use hashbrown::HashMap; use hashbrown::HashMap;
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
use super::exception::{ExceptionChannelType, Exceptionate}; use super::exception::{ExceptionChannelType, Exceptionate};
use super::job_policy::{JobPolicy, PolicyAction, PolicyCondition}; 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 bitflags::bitflags;
use futures::{channel::oneshot::*, future::FutureExt, pin_mut, select_biased}; use futures::{channel::oneshot::*, future::FutureExt, pin_mut, select_biased};
use kernel_hal::context::UserContext; use kernel_hal::context::UserContext;
use spin::Mutex; // use spin::Mutex;
use lock::spinlock::Mutex;
use self::thread_state::ContextAccessState; use self::thread_state::ContextAccessState;
use super::{exception::*, Process, Task}; use super::{exception::*, Process, Task};

View File

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