forked from rcore-os/zCore
use intrrupt Mutex instead of spin::Mutex
This commit is contained in:
parent
4aedfd4005
commit
e153f5713e
|
@ -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"
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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)?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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::{
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"] }
|
|
@ -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_();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#![no_std]
|
||||||
|
#![feature(asm)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
pub mod interrupt;
|
||||||
|
// pub mod mutex;
|
||||||
|
pub mod spinlock;
|
||||||
|
|
|
@ -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();
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
|
@ -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" }
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
///
|
///
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
Loading…
Reference in New Issue