add no-irq rwlock

This commit is contained in:
DeathWish5 2022-03-07 17:41:23 +08:00
parent d6d80b0bf6
commit e9a417963c
77 changed files with 378 additions and 500 deletions

View File

@ -89,7 +89,7 @@ impl<M: IoMapper> DevicetreeDriverBuilder<M> {
match comp {
#[cfg(feature = "virtio")]
c if c.contains("virtio,mmio") => self.parse_virtio(node, props),
c if c.contains("allwinner,sunxi-gmac") => self.parse_ethernet(node, comp, props),
// c if c.contains("allwinner,sunxi-gmac") => self.parse_ethernet(node, comp, props),
c if c.contains("ns16550a") => self.parse_uart(node, comp, props),
c if c.contains("allwinner,sun20i-uart") => self.parse_uart(node, comp, props),
_ => Err(DeviceError::NotSupported),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,6 +26,9 @@ pub(super) fn super_soft() {
#[no_mangle]
pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
let scause = scause::read();
info!("trap happened: {:?}", TrapReason::from(scause));
match TrapReason::from(scause) {
TrapReason::SoftwareBreakpoint => breakpoint(&mut tf.sepc),
TrapReason::PageFault(vaddr, flags) => crate::KHANDLER.handle_page_fault(vaddr, flags),

View File

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

View File

@ -12,7 +12,7 @@ use alloc::sync::Arc;
use alloc::string::String;
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
use crate::drivers::add_device;
use crate::drivers::all_net;

View File

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

View File

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

View File

@ -3,7 +3,8 @@
use alloc::{sync::Arc, vec::Vec};
use core::convert::From;
use spin::{RwLock, RwLockReadGuard};
// use spin::{RwLock, RwLockReadGuard};
use lock::rwlock::{RwLock, RwLockReadGuard};
use zcore_drivers::scheme::{
BlockScheme, DisplayScheme, InputScheme, IrqScheme, NetScheme, Scheme, UartScheme,

View File

@ -5,7 +5,7 @@ use core::ops::Range;
use bitmap_allocator::BitAlloc;
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
use super::mock_mem::MockMemory;
use crate::{PhysAddr, VirtAddr, PAGE_SIZE};

View File

@ -12,7 +12,7 @@ use alloc::sync::Arc;
use alloc::string::String;
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
use crate::drivers::add_device;
use crate::drivers::all_net;

View File

@ -7,7 +7,7 @@ use crate::common::vm::*;
use crate::{mem::PhysFrame, MMUFlags, PhysAddr, VirtAddr};
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
pub trait PageTableLevel: Sync + Send {
const LEVEL: usize;

View File

@ -3,7 +3,7 @@ use core::task::{Context, Poll};
use core::{any::Any, future::Future, mem::size_of, pin::Pin};
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
use kernel_hal::drivers::prelude::{InputEvent, InputEventType};
use kernel_hal::drivers::scheme::InputScheme;

View File

@ -3,7 +3,7 @@ use core::task::{Context, Poll};
use core::{any::Any, future::Future, pin::Pin};
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
use kernel_hal::drivers::prelude::input::{Mouse, MouseFlags, MouseState};
use kernel_hal::drivers::scheme::{EventScheme, InputScheme};

View File

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

View File

@ -1,7 +1,8 @@
//! Implement Device
use rcore_fs::dev::{Device, Result};
use spin::RwLock;
// use spin::RwLock;
use lock::rwlock::RwLock;
/// memory buffer for device
pub struct MemBuf(RwLock<&'static mut [u8]>);

View File

@ -3,7 +3,8 @@
use alloc::{boxed::Box, string::String, sync::Arc};
use async_trait::async_trait;
use spin::RwLock;
// use spin::RwLock;
use lock::rwlock::RwLock;
use rcore_fs::vfs::{FileType, FsError, INode, Metadata, PollStatus};
use zircon_object::object::*;

View File

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

View File

@ -7,7 +7,8 @@ extern crate rcore_fs;
use kernel_hal::drivers::scheme::BlockScheme;
use rcore_fs::dev::{BlockDevice, DevError, Device, Result};
use spin::RwLock;
// use spin::RwLock;
use lock::rwlock::RwLock;
/// A naive LRU cache layer for `BlockDevice`, re-exported from `rcore-fs`.
pub use rcore_fs::dev::block_cache::BlockCache;

View File

@ -14,7 +14,7 @@ use kernel_hal::console::{self, ConsoleWinSize};
use lazy_static::lazy_static;
use rcore_fs::vfs::*;
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
lazy_static! {
/// STDIN global reference

View File

@ -8,6 +8,8 @@ pub use self::shared_mem::*;
use alloc::collections::BTreeMap;
use alloc::sync::Arc;
use bitflags::*;
// use spin::Mutex;
use lock::mutex::Mutex;
/// Semaphore table in a process
#[derive(Default)]
@ -130,7 +132,7 @@ impl Drop for SemProc {
impl ShmProc {
/// Insert the `SharedGuard` and return its ID
pub fn add(&mut self, shared_guard: Arc<spin::Mutex<ShmGuard>>) -> ShmId {
pub fn add(&mut self, shared_guard: Arc<Mutex<ShmGuard>>) -> ShmId {
let id = self.get_free_id();
let shm_identifier = ShmIdentifier {
addr: 0,

View File

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

View File

@ -5,13 +5,13 @@ use crate::time::TimeSpec;
use alloc::{collections::BTreeMap, sync::Arc, sync::Weak};
use lazy_static::lazy_static;
// use spin::Mutex;
use lock::spinlock::Mutex;
use spin::RwLock;
use lock::mutex::Mutex;
// use spin::RwLock;
use lock::rwlock::RwLock;
use zircon_object::vm::*;
lazy_static! {
static ref KEY2SHM: RwLock<BTreeMap<u32, Weak<spin::Mutex<ShmGuard>>>> =
RwLock::new(BTreeMap::new());
static ref KEY2SHM: RwLock<BTreeMap<u32, Weak<Mutex<ShmGuard>>>> = RwLock::new(BTreeMap::new());
}
/// shmid data structure
@ -44,7 +44,7 @@ pub struct ShmIdentifier {
/// Shared memory address
pub addr: usize,
/// Shared memory buffer and data
pub guard: Arc<spin::Mutex<ShmGuard>>,
pub guard: Arc<Mutex<ShmGuard>>,
}
/// shared memory buffer and data
@ -67,7 +67,7 @@ impl ShmIdentifier {
memsize: usize,
flags: usize,
cpid: u32,
) -> Result<Arc<spin::Mutex<ShmGuard>>, LxError> {
) -> Result<Arc<Mutex<ShmGuard>>, LxError> {
let mut key2shm = KEY2SHM.write();
let flag = IpcGetFlag::from_bits_truncate(flags);
@ -81,7 +81,7 @@ impl ShmIdentifier {
return Ok(guard);
}
}
let shared_guard = Arc::new(spin::Mutex::new(ShmGuard {
let shared_guard = Arc::new(Mutex::new(ShmGuard {
shared_guard: VmObject::new_paged(pages(memsize)),
shmid_ds: Mutex::new(ShmidDs {
perm: IpcPerm {

View File

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

View File

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

View File

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

View File

@ -13,7 +13,7 @@ use hashbrown::HashMap;
use rcore_fs::vfs::{FileSystem, INode};
use smoltcp::socket::SocketHandle;
// use spin::{Mutex, MutexGuard};
use lock::spinlock::{Mutex, MutexGuard};
use lock::mutex::{Mutex, MutexGuard};
use kernel_hal::VirtAddr;
use zircon_object::{
@ -485,7 +485,7 @@ impl LinuxProcess {
}
/// Insert the `SharedGuard` and return its ID
pub fn shm_add(&self, shared_guard: Arc<spin::Mutex<ShmGuard>>) -> usize {
pub fn shm_add(&self, shared_guard: Arc<Mutex<ShmGuard>>) -> usize {
self.inner.lock().shm_identifiers.add(shared_guard)
}

View File

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

View File

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

View File

@ -6,7 +6,7 @@ use alloc::sync::Arc;
use kernel_hal::user::{Out, UserOutPtr, UserPtr};
use kernel_hal::VirtAddr;
// use spin::{Mutex, MutexGuard};
use lock::spinlock::{Mutex, MutexGuard};
use lock::mutex::{Mutex, MutexGuard};
use zircon_object::task::{CurrentThread, Process, Thread};
use zircon_object::ZxResult;

View File

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

View File

@ -1,27 +1,33 @@
use core::cell::{RefCell, RefMut};
use lazy_static::*;
extern "C" interrupt_ffi {
pub fn intr_on();
pub fn intr_off();
pub fn intr_get() -> bool;
pub fn cpu_id() -> u8;
mod lock_ffi {
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_on() {
unsafe {
lock_ffi::intr_on();
}
}
pub fn intr_off_() {
unsafe { intr_off(); }
pub fn intr_off() {
unsafe {
lock_ffi::intr_off();
}
}
pub fn intr_get_() -> bool {
unsafe { intr_get() }
pub fn intr_get() -> bool {
unsafe { lock_ffi::intr_get() }
}
pub fn cpu_id_() -> u8 {
unsafe { cpu_id() }
pub fn cpu_id() -> u8 {
unsafe { lock_ffi::cpu_id() }
}
#[derive(Debug, Default, Clone, Copy)]
@ -58,15 +64,15 @@ lazy_static! {
}
pub fn mycpu() -> RefMut<'static, Cpu> {
return CPUS[cpu_id_() as usize].0.borrow_mut();
return CPUS[cpu_id() as usize].0.borrow_mut();
}
// push_off/pop_off are like intr_off_()/intr_on_() except that they are matched:
// 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 old = intr_get();
intr_off();
let mut cpu = mycpu();
if cpu.noff == 0 {
cpu.interrupt_enable = old;
@ -76,11 +82,11 @@ pub(crate) fn push_off() {
pub(crate) fn pop_off() {
let mut cpu = mycpu();
if intr_get_() || cpu.noff < 1 {
if intr_get() || cpu.noff < 1 {
panic!("pop_off");
}
cpu.noff -= 1;
if cpu.noff == 0 && cpu.interrupt_enable {
intr_on_();
intr_on();
}
}

View File

@ -3,7 +3,7 @@
extern crate alloc;
pub mod interrupt;
// pub mod mutex;
pub mod spinlock;
mod interrupt;
pub mod mutex;
pub mod rwlock;

View File

@ -1,16 +1,15 @@
use core::{
cell::UnsafeCell,
default::Default,
fmt,
ops::{Deref, DerefMut},
sync::atomic::{AtomicBool, Ordering},
default::Default,
};
use crate::interrupt::{cpu_id_, pop_off, push_off};
use crate::interrupt::{pop_off, push_off};
pub struct Mutex<T: ?Sized> {
pub(crate) locked: AtomicBool,
cpuid: u8,
data: UnsafeCell<T>,
}
@ -32,7 +31,6 @@ impl<T> Mutex<T> {
Mutex {
locked: AtomicBool::new(false),
data: UnsafeCell::new(data),
cpuid: 0,
}
}
@ -54,10 +52,6 @@ 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)
@ -68,7 +62,6 @@ impl<T: ?Sized> Mutex<T> {
core::hint::spin_loop();
}
}
MutexGuard {
spinlock: self,
data: unsafe { &mut *self.data.get() },
@ -78,9 +71,6 @@ impl<T: ?Sized> Mutex<T> {
#[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)
@ -107,13 +97,6 @@ impl<T: ?Sized> Mutex<T> {
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> {
@ -138,7 +121,7 @@ impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
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() {
if !self.spinlock.is_locked() {
panic!("current cpu doesn't hold the lock{}", self.spinlock);
}
self.spinlock.locked.store(false, Ordering::Release);
@ -146,14 +129,17 @@ impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
}
}
// Not make sence, just to use #[drive(Debug)]
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,
)
write!(f, "Mutex{{locked={}}}", self.locked.load(Ordering::Relaxed),)
}
}
// Not make sence, just to use #[drive(Debug)]
impl<T: ?Sized> fmt::Debug for Mutex<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Mutex{{locked={}}}", self.locked.load(Ordering::Relaxed))
}
}

View File

@ -4,14 +4,15 @@ use core::{
cell::UnsafeCell,
fmt,
hint::spin_loop,
marker::PhantomData,
// marker::PhantomData,
mem,
ops::{Deref, DerefMut},
sync::atomic::{AtomicUsize, Ordering},
};
use crate::interrupt::{pop_off, push_off};
pub struct RwLock<T: ?Sized> {
// phantom: PhantomData<R>,
lock: AtomicUsize,
data: UnsafeCell<T>,
}
@ -52,8 +53,8 @@ pub struct RwLockUpgradableGuard<'a, T: 'a + ?Sized> {
}
// Same unsafe impls as `std::sync::RwLock`
unsafe impl<T: ?Sized + Send, R> Send for RwLock<T> {}
unsafe impl<T: ?Sized + Send + Sync, R> Sync for RwLock<T> {}
unsafe impl<T: ?Sized + Send> Send for RwLock<T> {}
unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
impl<T> RwLock<T> {
/// Creates a new spinlock wrapping the supplied data.
@ -74,13 +75,13 @@ impl<T> RwLock<T> {
#[inline]
pub const fn new(data: T) -> Self {
RwLock {
phantom: PhantomData,
// phantom: PhantomData,
lock: AtomicUsize::new(0),
data: UnsafeCell::new(data),
}
}
/// Consumes this `RwLock`, returning the underlying data.
/// Consumes this `RwLock`eturning the underlying data.
#[inline]
pub fn into_inner(self) -> T {
// We know statically that there are no outstanding references to
@ -189,9 +190,7 @@ impl<T: ?Sized> RwLock<T> {
}
}
}
}
impl<T: ?Sized, R> RwLock<T> {
/// Attempt to acquire this lock with shared read access.
///
/// This function will never block and will return immediately if `read`
@ -216,6 +215,7 @@ impl<T: ?Sized, R> RwLock<T> {
/// ```
#[inline]
pub fn try_read(&self) -> Option<RwLockReadGuard<T>> {
push_off();
let value = self.lock.fetch_add(READER, Ordering::Acquire);
// We check the UPGRADED bit here so that new readers are prevented when an UPGRADED lock is held.
@ -223,6 +223,7 @@ impl<T: ?Sized, R> RwLock<T> {
if value & (WRITER | UPGRADED) != 0 {
// Lock is taken, undo.
self.lock.fetch_sub(READER, Ordering::Release);
pop_off();
None
} else {
Some(RwLockReadGuard {
@ -285,6 +286,7 @@ impl<T: ?Sized, R> RwLock<T> {
#[inline(always)]
fn try_write_internal(&self, strong: bool) -> Option<RwLockWriteGuard<T>> {
push_off();
if compare_exchange(
&self.lock,
0,
@ -296,11 +298,12 @@ impl<T: ?Sized, R> RwLock<T> {
.is_ok()
{
Some(RwLockWriteGuard {
phantom: PhantomData,
// phantom: PhantomData,
inner: self,
data: unsafe { &mut *self.data.get() },
})
} else {
pop_off();
None
}
}
@ -332,15 +335,17 @@ impl<T: ?Sized, R> RwLock<T> {
/// Tries to obtain an upgradeable lock guard.
#[inline]
pub fn try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T>> {
push_off();
if self.lock.fetch_or(UPGRADED, Ordering::Acquire) & (WRITER | UPGRADED) == 0 {
Some(RwLockUpgradableGuard {
phantom: PhantomData,
// phantom: PhantomData,
inner: self,
data: unsafe { &*self.data.get() },
})
} else {
// We can't unflip the UPGRADED bit back just yet as there is another upgradeable or write lock.
// When they unlock, they will clear the bit.
pop_off();
None
}
}
@ -364,7 +369,7 @@ impl<T: ?Sized, R> RwLock<T> {
}
}
impl<T: ?Sized + fmt::Debug, R> fmt::Debug for RwLock<T> {
impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.try_read() {
Some(guard) => write!(f, "RwLock {{ data: ")
@ -375,7 +380,7 @@ impl<T: ?Sized + fmt::Debug, R> fmt::Debug for RwLock<T> {
}
}
impl<T: ?Sized + Default, R> Default for RwLock<T> {
impl<T: ?Sized + Default> Default for RwLock<T> {
fn default() -> Self {
Self::new(Default::default())
}
@ -418,7 +423,7 @@ impl<'rwlock, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'rwlock
}
}
impl<'rwlock, T: ?Sized> RwLockUpgradableGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> RwLockUpgradableGuard<'rwlock, T> {
/// Upgrades an upgradeable lock guard to a writable lock guard.
///
/// ```
@ -428,21 +433,21 @@ impl<'rwlock, T: ?Sized> RwLockUpgradableGuard<'rwlock, T, R> {
/// let writable = upgradeable.upgrade();
/// ```
#[inline]
pub fn upgrade(mut self) -> RwLockWriteGuard<'rwlock, T, R> {
pub fn upgrade(mut self) -> RwLockWriteGuard<'rwlock, T> {
loop {
self = match self.try_upgrade_internal(false) {
Ok(guard) => return guard,
Err(e) => e,
};
R::relax();
spin_loop();
}
}
}
impl<'rwlock, T: ?Sized, R> RwLockUpgradableGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> RwLockUpgradableGuard<'rwlock, T> {
#[inline(always)]
fn try_upgrade_internal(self, strong: bool) -> Result<RwLockWriteGuard<'rwlock, T, R>, Self> {
fn try_upgrade_internal(self, strong: bool) -> Result<RwLockWriteGuard<'rwlock, T>, Self> {
if compare_exchange(
&self.inner.lock,
UPGRADED,
@ -460,7 +465,7 @@ impl<'rwlock, T: ?Sized, R> RwLockUpgradableGuard<'rwlock, T, R> {
// Upgrade successful
Ok(RwLockWriteGuard {
phantom: PhantomData,
// phantom: PhantomData,
inner,
data: unsafe { &mut *inner.data.get() },
})
@ -481,7 +486,7 @@ impl<'rwlock, T: ?Sized, R> RwLockUpgradableGuard<'rwlock, T, R> {
/// };
/// ```
#[inline]
pub fn try_upgrade(self) -> Result<RwLockWriteGuard<'rwlock, T, R>, Self> {
pub fn try_upgrade(self) -> Result<RwLockWriteGuard<'rwlock, T>, Self> {
self.try_upgrade_internal(true)
}
@ -532,19 +537,19 @@ impl<'rwlock, T: ?Sized, R> RwLockUpgradableGuard<'rwlock, T, R> {
}
}
impl<'rwlock, T: ?Sized + fmt::Debug, R> fmt::Debug for RwLockUpgradableGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized + fmt::Debug> fmt::Debug for RwLockUpgradableGuard<'rwlock, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<'rwlock, T: ?Sized + fmt::Display, R> fmt::Display for RwLockUpgradableGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized + fmt::Display> fmt::Display for RwLockUpgradableGuard<'rwlock, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<'rwlock, T: ?Sized, R> RwLockWriteGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
/// Downgrades the writable lock guard to a readable, shared lock guard. Cannot fail and is guaranteed not to spin.
///
/// ```
@ -585,7 +590,7 @@ impl<'rwlock, T: ?Sized, R> RwLockWriteGuard<'rwlock, T, R> {
/// assert_eq!(*readable, 1);
/// ```
#[inline]
pub fn downgrade_to_upgradeable(self) -> RwLockUpgradableGuard<'rwlock, T, R> {
pub fn downgrade_to_upgradeable(self) -> RwLockUpgradableGuard<'rwlock, T> {
debug_assert_eq!(
self.inner.lock.load(Ordering::Acquire) & (WRITER | UPGRADED),
WRITER
@ -600,7 +605,7 @@ impl<'rwlock, T: ?Sized, R> RwLockWriteGuard<'rwlock, T, R> {
mem::forget(self);
RwLockUpgradableGuard {
phantom: PhantomData,
// phantom: PhantomData,
inner,
data: unsafe { &*inner.data.get() },
}
@ -626,13 +631,13 @@ impl<'rwlock, T: ?Sized, R> RwLockWriteGuard<'rwlock, T, R> {
}
}
impl<'rwlock, T: ?Sized + fmt::Debug, R> fmt::Debug for RwLockWriteGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'rwlock, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<'rwlock, T: ?Sized + fmt::Display, R> fmt::Display for RwLockWriteGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'rwlock, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
@ -646,7 +651,7 @@ impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
}
}
impl<'rwlock, T: ?Sized, R> Deref for RwLockUpgradableGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> Deref for RwLockUpgradableGuard<'rwlock, T> {
type Target = T;
fn deref(&self) -> &T {
@ -654,7 +659,7 @@ impl<'rwlock, T: ?Sized, R> Deref for RwLockUpgradableGuard<'rwlock, T, R> {
}
}
impl<'rwlock, T: ?Sized, R> Deref for RwLockWriteGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
type Target = T;
fn deref(&self) -> &T {
@ -662,7 +667,7 @@ impl<'rwlock, T: ?Sized, R> Deref for RwLockWriteGuard<'rwlock, T, R> {
}
}
impl<'rwlock, T: ?Sized, R> DerefMut for RwLockWriteGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
fn deref_mut(&mut self) -> &mut T {
self.data
}
@ -672,20 +677,22 @@ impl<'rwlock, T: ?Sized> Drop for RwLockReadGuard<'rwlock, T> {
fn drop(&mut self) {
debug_assert!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED) > 0);
self.lock.fetch_sub(READER, Ordering::Release);
pop_off();
}
}
impl<'rwlock, T: ?Sized, R> Drop for RwLockUpgradableGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> Drop for RwLockUpgradableGuard<'rwlock, T> {
fn drop(&mut self) {
debug_assert_eq!(
self.inner.lock.load(Ordering::Relaxed) & (WRITER | UPGRADED),
UPGRADED
);
self.inner.lock.fetch_sub(UPGRADED, Ordering::AcqRel);
pop_off();
}
}
impl<'rwlock, T: ?Sized, R> Drop for RwLockWriteGuard<'rwlock, T, R> {
impl<'rwlock, T: ?Sized> Drop for RwLockWriteGuard<'rwlock, T> {
fn drop(&mut self) {
debug_assert_eq!(self.inner.lock.load(Ordering::Relaxed) & WRITER, WRITER);
@ -694,6 +701,7 @@ impl<'rwlock, T: ?Sized, R> Drop for RwLockWriteGuard<'rwlock, T, R> {
self.inner
.lock
.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
pop_off();
}
}
@ -713,365 +721,230 @@ fn compare_exchange(
}
}
#[cfg(feature = "lock_api")]
unsafe impl<R: RelaxStrategy> lock_api_crate::RawRwLock for RwLock<(), R> {
type GuardMarker = lock_api_crate::GuardSend;
// #[cfg(test)]
// mod tests {
// use std::prelude::v1::*;
const INIT: Self = Self::new(());
// use std::sync::atomic::{AtomicUsize, Ordering};
// use std::sync::mpsc::channel;
// use std::sync::Arc;
// use std::thread;
#[inline(always)]
fn lock_exclusive(&self) {
// Prevent guard destructor running
core::mem::forget(self.write());
}
// type RwLock<T> = super::RwLock<T>;
#[inline(always)]
fn try_lock_exclusive(&self) -> bool {
// Prevent guard destructor running
self.try_write().map(|g| core::mem::forget(g)).is_some()
}
// #[derive(Eq, PartialEq, Debug)]
// struct NonCopy(i32);
#[inline(always)]
unsafe fn unlock_exclusive(&self) {
drop(RwLockWriteGuard {
inner: self,
data: &mut (),
phantom: PhantomData,
});
}
// #[test]
// fn smoke() {
// let l = RwLock::new(());
// drop(l.read());
// drop(l.write());
// drop((l.read(), l.read()));
// drop(l.write());
// }
#[inline(always)]
fn lock_shared(&self) {
// Prevent guard destructor running
core::mem::forget(self.read());
}
// // TODO: needs RNG
// //#[test]
// //fn frob() {
// // static R: RwLock = RwLock::new();
// // const N: usize = 10;
// // const M: usize = 1000;
// //
// // let (txx) = channel::<()>();
// // for _ in 0..N {
// // let tx = tx.clone();
// // thread::spawn(move|| {
// // let mut rng = rand::thread_rng();
// // for _ in 0..M {
// // if rng.gen_weighted_bool(N) {
// // drop(R.write());
// // } else {
// // drop(R.read());
// // }
// // }
// // drop(tx);
// // });
// // }
// // drop(tx);
// // let _ = rx.recv();
// // unsafe { R.destroy(); }
// //}
#[inline(always)]
fn try_lock_shared(&self) -> bool {
// Prevent guard destructor running
self.try_read().map(|g| core::mem::forget(g)).is_some()
}
// #[test]
// fn test_rw_arc() {
// let arc = Arc::new(RwLock::new(0));
// let arc2 = arc.clone();
// let (txx) = channel();
#[inline(always)]
unsafe fn unlock_shared(&self) {
drop(RwLockReadGuard {
lock: &self.lock,
data: &(),
});
}
// thread::spawn(move || {
// let mut lock = arc2.write();
// for _ in 0..10 {
// let tmp = *lock;
// *lock = -1;
// thread::yield_now();
// *lock = tmp + 1;
// }
// tx.send(()).unwrap();
// });
#[inline(always)]
fn is_locked(&self) -> bool {
self.lock.load(Ordering::Relaxed) != 0
}
}
// // Readers try to catch the writer in the act
// let mut children = Vec::new();
// for _ in 0..5 {
// let arc3 = arc.clone();
// children.push(thread::spawn(move || {
// let lock = arc3.read();
// assert!(*lock >= 0);
// }));
// }
#[cfg(feature = "lock_api")]
unsafe impl<R: RelaxStrategy> lock_api_crate::RawRwLockUpgrade for RwLock<(), R> {
#[inline(always)]
fn lock_upgradable(&self) {
// Prevent guard destructor running
core::mem::forget(self.upgradeable_read());
}
// // Wait for children to pass their asserts
// for r in children {
// assert!(r.join().is_ok());
// }
#[inline(always)]
fn try_lock_upgradable(&self) -> bool {
// Prevent guard destructor running
self.try_upgradeable_read()
.map(|g| core::mem::forget(g))
.is_some()
}
// // Wait for writer to finish
// rx.recv().unwrap();
// let lock = arc.read();
// assert_eq!(*lock, 10);
// }
#[inline(always)]
unsafe fn unlock_upgradable(&self) {
drop(RwLockUpgradableGuard {
inner: self,
data: &(),
phantom: PhantomData,
});
}
// #[test]
// fn test_rw_access_in_unwind() {
// let arc = Arc::new(RwLock::new(1));
// let arc2 = arc.clone();
// let _ = thread::spawn(move || -> () {
// struct Unwinder {
// i: Arc<RwLock<isize>>,
// }
// impl Drop for Unwinder {
// fn drop(&mut self) {
// let mut lock = self.i.write();
// *lock += 1;
// }
// }
// let _u = Unwinder { i: arc2 };
// panic!();
// })
// .join();
// let lock = arc.read();
// assert_eq!(*lock, 2);
// }
#[inline(always)]
unsafe fn upgrade(&self) {
let tmp_guard = RwLockUpgradableGuard {
inner: self,
data: &(),
phantom: PhantomData,
};
core::mem::forget(tmp_guard.upgrade());
}
// #[test]
// fn test_rwlock_unsized() {
// let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
// {
// let b = &mut *rw.write();
// b[0] = 4;
// b[2] = 5;
// }
// let comp: &[i32] = &[4, 2, 5];
// assert_eq!(&*rw.read(), comp);
// }
#[inline(always)]
unsafe fn try_upgrade(&self) -> bool {
let tmp_guard = RwLockUpgradableGuard {
inner: self,
data: &(),
phantom: PhantomData,
};
tmp_guard
.try_upgrade()
.map(|g| core::mem::forget(g))
.is_ok()
}
}
// #[test]
// fn test_rwlock_try_write() {
// use std::mem::drop;
#[cfg(feature = "lock_api")]
unsafe impl<R: RelaxStrategy> lock_api_crate::RawRwLockDowngrade for RwLock<(), R> {
unsafe fn downgrade(&self) {
let tmp_guard = RwLockWriteGuard {
inner: self,
data: &mut (),
phantom: PhantomData,
};
core::mem::forget(tmp_guard.downgrade());
}
}
// let lock = RwLock::new(0isize);
// let read_guard = lock.read();
#[cfg(feature = "lock_api1")]
unsafe impl lock_api::RawRwLockUpgradeDowngrade for RwLock<()> {
unsafe fn downgrade_upgradable(&self) {
let tmp_guard = RwLockUpgradableGuard {
inner: self,
data: &(),
phantom: PhantomData,
};
core::mem::forget(tmp_guard.downgrade());
}
// let write_result = lock.try_write();
// match write_result {
// None => (),
// Some(_) => assert!(
// false,
// "try_write should not succeed while read_guard is in scope"
// ),
// }
unsafe fn downgrade_to_upgradable(&self) {
let tmp_guard = RwLockWriteGuard {
inner: self,
data: &mut (),
phantom: PhantomData,
};
core::mem::forget(tmp_guard.downgrade_to_upgradeable());
}
}
// drop(read_guard);
// }
#[cfg(test)]
mod tests {
use std::prelude::v1::*;
// #[test]
// fn test_rw_try_read() {
// let m = RwLock::new(0);
// ::std::mem::forget(m.write());
// assert!(m.try_read().is_none());
// }
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::thread;
// #[test]
// fn test_into_inner() {
// let m = RwLock::new(NonCopy(10));
// assert_eq!(m.into_inner(), NonCopy(10));
// }
type RwLock<T> = super::RwLock<T>;
// #[test]
// fn test_into_inner_drop() {
// struct Foo(Arc<AtomicUsize>);
// impl Drop for Foo {
// fn drop(&mut self) {
// self.0.fetch_add(1, Ordering::SeqCst);
// }
// }
// let num_drops = Arc::new(AtomicUsize::new(0));
// let m = RwLock::new(Foo(num_drops.clone()));
// assert_eq!(num_drops.load(Ordering::SeqCst), 0);
// {
// let _inner = m.into_inner();
// assert_eq!(num_drops.load(Ordering::SeqCst), 0);
// }
// assert_eq!(num_drops.load(Ordering::SeqCst), 1);
// }
#[derive(Eq, PartialEq, Debug)]
struct NonCopy(i32);
// #[test]
// fn test_force_read_decrement() {
// let m = RwLock::new(());
// ::std::mem::forget(m.read());
// ::std::mem::forget(m.read());
// ::std::mem::forget(m.read());
// assert!(m.try_write().is_none());
// unsafe {
// m.force_read_decrement();
// m.force_read_decrement();
// }
// assert!(m.try_write().is_none());
// unsafe {
// m.force_read_decrement();
// }
// assert!(m.try_write().is_some());
// }
#[test]
fn smoke() {
let l = RwLock::new(());
drop(l.read());
drop(l.write());
drop((l.read(), l.read()));
drop(l.write());
}
// #[test]
// fn test_force_write_unlock() {
// let m = RwLock::new(());
// ::std::mem::forget(m.write());
// assert!(m.try_read().is_none());
// unsafe {
// m.force_write_unlock();
// }
// assert!(m.try_read().is_some());
// }
// TODO: needs RNG
//#[test]
//fn frob() {
// static R: RwLock = RwLock::new();
// const N: usize = 10;
// const M: usize = 1000;
//
// let (tx, rx) = channel::<()>();
// for _ in 0..N {
// let tx = tx.clone();
// thread::spawn(move|| {
// let mut rng = rand::thread_rng();
// for _ in 0..M {
// if rng.gen_weighted_bool(N) {
// drop(R.write());
// } else {
// drop(R.read());
// }
// }
// drop(tx);
// });
// }
// drop(tx);
// let _ = rx.recv();
// unsafe { R.destroy(); }
//}
// #[test]
// fn test_upgrade_downgrade() {
// let m = RwLock::new(());
// {
// let _r = m.read();
// let upg = m.try_upgradeable_read().unwrap();
// assert!(m.try_read().is_none());
// assert!(m.try_write().is_none());
// assert!(upg.try_upgrade().is_err());
// }
// {
// let w = m.write();
// assert!(m.try_upgradeable_read().is_none());
// let _r = w.downgrade();
// assert!(m.try_upgradeable_read().is_some());
// assert!(m.try_read().is_some());
// assert!(m.try_write().is_none());
// }
// {
// let _u = m.upgradeable_read();
// assert!(m.try_upgradeable_read().is_none());
// }
#[test]
fn test_rw_arc() {
let arc = Arc::new(RwLock::new(0));
let arc2 = arc.clone();
let (tx, rx) = channel();
thread::spawn(move || {
let mut lock = arc2.write();
for _ in 0..10 {
let tmp = *lock;
*lock = -1;
thread::yield_now();
*lock = tmp + 1;
}
tx.send(()).unwrap();
});
// Readers try to catch the writer in the act
let mut children = Vec::new();
for _ in 0..5 {
let arc3 = arc.clone();
children.push(thread::spawn(move || {
let lock = arc3.read();
assert!(*lock >= 0);
}));
}
// Wait for children to pass their asserts
for r in children {
assert!(r.join().is_ok());
}
// Wait for writer to finish
rx.recv().unwrap();
let lock = arc.read();
assert_eq!(*lock, 10);
}
#[test]
fn test_rw_access_in_unwind() {
let arc = Arc::new(RwLock::new(1));
let arc2 = arc.clone();
let _ = thread::spawn(move || -> () {
struct Unwinder {
i: Arc<RwLock<isize>>,
}
impl Drop for Unwinder {
fn drop(&mut self) {
let mut lock = self.i.write();
*lock += 1;
}
}
let _u = Unwinder { i: arc2 };
panic!();
})
.join();
let lock = arc.read();
assert_eq!(*lock, 2);
}
#[test]
fn test_rwlock_unsized() {
let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
{
let b = &mut *rw.write();
b[0] = 4;
b[2] = 5;
}
let comp: &[i32] = &[4, 2, 5];
assert_eq!(&*rw.read(), comp);
}
#[test]
fn test_rwlock_try_write() {
use std::mem::drop;
let lock = RwLock::new(0isize);
let read_guard = lock.read();
let write_result = lock.try_write();
match write_result {
None => (),
Some(_) => assert!(
false,
"try_write should not succeed while read_guard is in scope"
),
}
drop(read_guard);
}
#[test]
fn test_rw_try_read() {
let m = RwLock::new(0);
::std::mem::forget(m.write());
assert!(m.try_read().is_none());
}
#[test]
fn test_into_inner() {
let m = RwLock::new(NonCopy(10));
assert_eq!(m.into_inner(), NonCopy(10));
}
#[test]
fn test_into_inner_drop() {
struct Foo(Arc<AtomicUsize>);
impl Drop for Foo {
fn drop(&mut self) {
self.0.fetch_add(1, Ordering::SeqCst);
}
}
let num_drops = Arc::new(AtomicUsize::new(0));
let m = RwLock::new(Foo(num_drops.clone()));
assert_eq!(num_drops.load(Ordering::SeqCst), 0);
{
let _inner = m.into_inner();
assert_eq!(num_drops.load(Ordering::SeqCst), 0);
}
assert_eq!(num_drops.load(Ordering::SeqCst), 1);
}
#[test]
fn test_force_read_decrement() {
let m = RwLock::new(());
::std::mem::forget(m.read());
::std::mem::forget(m.read());
::std::mem::forget(m.read());
assert!(m.try_write().is_none());
unsafe {
m.force_read_decrement();
m.force_read_decrement();
}
assert!(m.try_write().is_none());
unsafe {
m.force_read_decrement();
}
assert!(m.try_write().is_some());
}
#[test]
fn test_force_write_unlock() {
let m = RwLock::new(());
::std::mem::forget(m.write());
assert!(m.try_read().is_none());
unsafe {
m.force_write_unlock();
}
assert!(m.try_read().is_some());
}
#[test]
fn test_upgrade_downgrade() {
let m = RwLock::new(());
{
let _r = m.read();
let upg = m.try_upgradeable_read().unwrap();
assert!(m.try_read().is_none());
assert!(m.try_write().is_none());
assert!(upg.try_upgrade().is_err());
}
{
let w = m.write();
assert!(m.try_upgradeable_read().is_none());
let _r = w.downgrade();
assert!(m.try_upgradeable_read().is_some());
assert!(m.try_read().is_some());
assert!(m.try_write().is_none());
}
{
let _u = m.upgradeable_read();
assert!(m.try_upgradeable_read().is_none());
}
assert!(m.try_upgradeable_read().unwrap().try_upgrade().is_ok());
}
}
// assert!(m.try_upgradeable_read().unwrap().try_upgrade().is_ok());
// }
// }

View File

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

View File

@ -5,7 +5,7 @@ use {
alloc::{sync::Arc, vec::Vec},
lazy_static::lazy_static,
// spin::Mutex,
lock::spinlock::Mutex,
lock::mutex::Mutex,
};
lazy_static! {

View File

@ -5,7 +5,7 @@ use {
alloc::{sync::Arc, vec::Vec},
dev::Iommu,
// spin::Mutex,
lock::spinlock::Mutex,
lock::mutex::Mutex,
};
/// Bus Transaction Initiator.

View File

@ -1,5 +1,5 @@
use kernel_hal::interrupt;
use {super::*, /*spin::Mutex*/lock::spinlock::Mutex,};
use {super::*, /*spin::Mutex*/ lock::mutex::Mutex};
pub struct EventInterrupt {
vector: usize,

View File

@ -8,7 +8,7 @@ use {
alloc::{boxed::Box, sync::Arc},
bitflags::bitflags,
// spin::Mutex,
lock::spinlock::Mutex,
lock::mutex::Mutex,
};
mod event_interrupt;

View File

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

View File

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

View File

@ -4,7 +4,8 @@ use crate::{ZxError, ZxResult};
use alloc::boxed::Box;
use core::convert::TryFrom;
use kernel_hal::interrupt;
use spin::*;
// use spin::*;
use lock::mutex::Mutex;
/// Enumeration for PCI capabilities.
#[derive(Debug)]

View File

@ -17,7 +17,7 @@ use kernel_hal::interrupt;
use numeric_enum_macro::numeric_enum;
use region_alloc::RegionAllocator;
// use spin::{Mutex, MutexGuard};
use lock::spinlock::{Mutex, MutexGuard};
use lock::mutex::{Mutex, MutexGuard};
numeric_enum! {
#[repr(u8)]

View File

@ -14,7 +14,7 @@ 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 lock::spinlock::Mutex;
use lock::mutex::Mutex;
static PIO_LOCK: Mutex<()> = Mutex::new(());
const PCI_CONFIG_ADDR: u16 = 0xcf8;

View File

@ -8,7 +8,8 @@ use {
alloc::sync::Arc,
core::convert::TryInto,
rvm::{self, Vcpu as VcpuInner},
spin::Mutex,
//spin::Mutex,
lock::mutex::Mutex,
};
/// Virtual CPU within a Guest, which allows for execution within the virtual machine.

View File

@ -8,7 +8,7 @@ use {
futures::channel::oneshot::{self, Sender},
hashbrown::HashMap,
// spin::Mutex,
lock::spinlock::Mutex,
lock::mutex::Mutex,
};
/// Bidirectional interprocess communication

View File

@ -3,7 +3,7 @@ use {
alloc::collections::VecDeque,
alloc::sync::{Arc, Weak},
// spin::Mutex,
lock::spinlock::Mutex,
lock::mutex::Mutex,
};
/// First-In First-Out inter-process queue.

View File

@ -3,7 +3,7 @@ use {
alloc::collections::VecDeque,
alloc::sync::{Arc, Weak},
bitflags::bitflags,
spin::Mutex,
lock::mutex::Mutex, // spin::Mutex,
};
/// Bidirectional streaming IPC transport.

View File

@ -55,7 +55,7 @@
//! ```
//! use zircon_object::object::*;
//! use std::sync::Arc;
//! use lock::spinlock::Mutex;
//! use lock::mutex::Mutex;
//!
//! pub struct SampleObject {
//! base: KObjectBase,
@ -105,7 +105,7 @@ use {
task::{Context, Poll},
},
downcast_rs::{impl_downcast, DowncastSync},
lock::spinlock::Mutex, // spin::Mutex,
lock::mutex::Mutex, // spin::Mutex,
};
pub use {super::*, handle::*, rights::*, signal::*};

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ use {
crate::task::Task,
alloc::sync::{Arc, Weak},
alloc::vec::Vec,
lock::spinlock::Mutex, //spin::Mutex,
lock::mutex::Mutex, //spin::Mutex,
};
/// Control a group of processes

View File

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

View File

@ -11,7 +11,7 @@ use bitflags::bitflags;
use futures::{channel::oneshot::*, future::FutureExt, pin_mut, select_biased};
use kernel_hal::context::UserContext;
// use spin::Mutex;
use lock::spinlock::Mutex;
use lock::mutex::Mutex;
use self::thread_state::ContextAccessState;
use super::{exception::*, Process, Task};

View File

@ -1,5 +1,5 @@
use {
super::*, crate::object::*, alloc::sync::Arc, lock::spinlock::Mutex, /*spin::Mutex*/
super::*, crate::object::*, alloc::sync::Arc, lock::mutex::Mutex, /*spin::Mutex*/
numeric_enum_macro::numeric_enum,
};

View File

@ -6,7 +6,7 @@ use {
kernel_hal::vm::{
GenericPageTable, IgnoreNotMappedErr, Page, PageSize, PageTable, PagingError,
},
spin::Mutex,
lock::mutex::Mutex, //spin::Mutex,
};
bitflags! {

View File

@ -9,7 +9,7 @@ use {
bitflags::bitflags,
core::ops::Deref,
kernel_hal::CachePolicy,
spin::Mutex,
lock::mutex::Mutex, //spin::Mutex,
};
mod paged;

View File

@ -9,7 +9,8 @@ use {
core::sync::atomic::*,
hashbrown::HashMap,
kernel_hal::{mem::PhysFrame, PAGE_SIZE},
spin::{Mutex, MutexGuard},
// spin::{Mutex, MutexGuard},
lock::mutex::{Mutex, MutexGuard},
};
enum VMOType {

View File

@ -1,4 +1,4 @@
use {super::*, alloc::sync::Arc, lock::spinlock::Mutex /*spin::Mutex*/};
use {super::*, alloc::sync::Arc, lock::mutex::Mutex /*spin::Mutex*/};
/// VMO representing a physical range of memory.
pub struct VMObjectPhysical {

View File

@ -1,7 +1,7 @@
use {
super::*,
alloc::{string::String, vec::Vec},
lock::spinlock::Mutex, //spin::Mutex,
lock::mutex::Mutex, //spin::Mutex,
zircon_object::{
ipc::{Channel, MessagePacket},
object::{obj_type, HandleInfo},