mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 20:16:42 +00:00
Refactor the API of spinlocks
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
0160a85ccd
commit
c44447d54b
@ -62,7 +62,7 @@ impl PtyMaster {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn slave_push_char(&self, ch: u8) {
|
pub(super) fn slave_push_char(&self, ch: u8) {
|
||||||
let mut input = self.input.lock_irq_disabled();
|
let mut input = self.input.disable_irq().lock();
|
||||||
input.push_overwrite(ch);
|
input.push_overwrite(ch);
|
||||||
self.update_state(&input);
|
self.update_state(&input);
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ impl FileIo for PtyMaster {
|
|||||||
|
|
||||||
let mut poller = Poller::new();
|
let mut poller = Poller::new();
|
||||||
loop {
|
loop {
|
||||||
let mut input = self.input.lock_irq_disabled();
|
let mut input = self.input.disable_irq().lock();
|
||||||
|
|
||||||
if input.is_empty() {
|
if input.is_empty() {
|
||||||
let events = self.pollee.poll(IoEvents::IN, Some(&mut poller));
|
let events = self.pollee.poll(IoEvents::IN, Some(&mut poller));
|
||||||
|
@ -36,7 +36,7 @@ impl TtyDriver {
|
|||||||
|
|
||||||
/// Return the tty device in driver's internal table.
|
/// Return the tty device in driver's internal table.
|
||||||
pub fn lookup(&self, index: usize) -> Result<Arc<Tty>> {
|
pub fn lookup(&self, index: usize) -> Result<Arc<Tty>> {
|
||||||
let ttys = self.ttys.lock_irq_disabled();
|
let ttys = self.ttys.disable_irq().lock();
|
||||||
// Return the tty device corresponding to idx
|
// Return the tty device corresponding to idx
|
||||||
if index >= ttys.len() {
|
if index >= ttys.len() {
|
||||||
return_errno_with_message!(Errno::ENODEV, "lookup failed. No tty device");
|
return_errno_with_message!(Errno::ENODEV, "lookup failed. No tty device");
|
||||||
@ -49,12 +49,12 @@ impl TtyDriver {
|
|||||||
/// Install a new tty into the driver's internal tables.
|
/// Install a new tty into the driver's internal tables.
|
||||||
pub fn install(self: &Arc<Self>, tty: Arc<Tty>) {
|
pub fn install(self: &Arc<Self>, tty: Arc<Tty>) {
|
||||||
tty.set_driver(Arc::downgrade(self));
|
tty.set_driver(Arc::downgrade(self));
|
||||||
self.ttys.lock_irq_disabled().push(tty);
|
self.ttys.disable_irq().lock().push(tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// remove a new tty into the driver's internal tables.
|
/// remove a new tty into the driver's internal tables.
|
||||||
pub fn remove(&self, index: usize) -> Result<()> {
|
pub fn remove(&self, index: usize) -> Result<()> {
|
||||||
let mut ttys = self.ttys.lock_irq_disabled();
|
let mut ttys = self.ttys.disable_irq().lock();
|
||||||
if index >= ttys.len() {
|
if index >= ttys.len() {
|
||||||
return_errno_with_message!(Errno::ENODEV, "lookup failed. No tty device");
|
return_errno_with_message!(Errno::ENODEV, "lookup failed. No tty device");
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ impl TtyDriver {
|
|||||||
|
|
||||||
pub fn push_char(&self, ch: u8) {
|
pub fn push_char(&self, ch: u8) {
|
||||||
// FIXME: should the char send to all ttys?
|
// FIXME: should the char send to all ttys?
|
||||||
for tty in &*self.ttys.lock_irq_disabled() {
|
for tty in &*self.ttys.disable_irq().lock() {
|
||||||
tty.push_char(ch);
|
tty.push_char(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ impl LineDiscipline {
|
|||||||
|
|
||||||
/// Push char to line discipline.
|
/// Push char to line discipline.
|
||||||
pub fn push_char<F2: FnMut(&str)>(&self, ch: u8, echo_callback: F2) {
|
pub fn push_char<F2: FnMut(&str)>(&self, ch: u8, echo_callback: F2) {
|
||||||
let termios = self.termios.lock_irq_disabled();
|
let termios = self.termios.disable_irq().lock();
|
||||||
|
|
||||||
let ch = if termios.contains_icrnl() && ch == b'\r' {
|
let ch = if termios.contains_icrnl() && ch == b'\r' {
|
||||||
b'\n'
|
b'\n'
|
||||||
@ -127,7 +127,7 @@ impl LineDiscipline {
|
|||||||
|
|
||||||
// Raw mode
|
// Raw mode
|
||||||
if !termios.is_canonical_mode() {
|
if !termios.is_canonical_mode() {
|
||||||
self.read_buffer.lock_irq_disabled().push_overwrite(ch);
|
self.read_buffer.disable_irq().lock().push_overwrite(ch);
|
||||||
self.update_readable_state();
|
self.update_readable_state();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -136,12 +136,12 @@ impl LineDiscipline {
|
|||||||
|
|
||||||
if ch == *termios.get_special_char(CC_C_CHAR::VKILL) {
|
if ch == *termios.get_special_char(CC_C_CHAR::VKILL) {
|
||||||
// Erase current line
|
// Erase current line
|
||||||
self.current_line.lock_irq_disabled().drain();
|
self.current_line.disable_irq().lock().drain();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ch == *termios.get_special_char(CC_C_CHAR::VERASE) {
|
if ch == *termios.get_special_char(CC_C_CHAR::VERASE) {
|
||||||
// Type backspace
|
// Type backspace
|
||||||
let mut current_line = self.current_line.lock_irq_disabled();
|
let mut current_line = self.current_line.disable_irq().lock();
|
||||||
if !current_line.is_empty() {
|
if !current_line.is_empty() {
|
||||||
current_line.backspace();
|
current_line.backspace();
|
||||||
}
|
}
|
||||||
@ -149,17 +149,17 @@ impl LineDiscipline {
|
|||||||
|
|
||||||
if is_line_terminator(ch, &termios) {
|
if is_line_terminator(ch, &termios) {
|
||||||
// If a new line is met, all bytes in current_line will be moved to read_buffer
|
// If a new line is met, all bytes in current_line will be moved to read_buffer
|
||||||
let mut current_line = self.current_line.lock_irq_disabled();
|
let mut current_line = self.current_line.disable_irq().lock();
|
||||||
current_line.push_char(ch);
|
current_line.push_char(ch);
|
||||||
let current_line_chars = current_line.drain();
|
let current_line_chars = current_line.drain();
|
||||||
for char in current_line_chars {
|
for char in current_line_chars {
|
||||||
self.read_buffer.lock_irq_disabled().push_overwrite(char);
|
self.read_buffer.disable_irq().lock().push_overwrite(char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_printable_char(ch) {
|
if is_printable_char(ch) {
|
||||||
// Printable character
|
// Printable character
|
||||||
self.current_line.lock_irq_disabled().push_char(ch);
|
self.current_line.disable_irq().lock().push_char(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_readable_state();
|
self.update_readable_state();
|
||||||
@ -178,7 +178,7 @@ impl LineDiscipline {
|
|||||||
|
|
||||||
if in_interrupt_context() {
|
if in_interrupt_context() {
|
||||||
// `kernel_signal()` may cause sleep, so only construct parameters here.
|
// `kernel_signal()` may cause sleep, so only construct parameters here.
|
||||||
self.work_item_para.lock_irq_disabled().kernel_signal = Some(signal);
|
self.work_item_para.disable_irq().lock().kernel_signal = Some(signal);
|
||||||
} else {
|
} else {
|
||||||
(self.send_signal)(signal);
|
(self.send_signal)(signal);
|
||||||
}
|
}
|
||||||
@ -187,14 +187,14 @@ impl LineDiscipline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_readable_state(&self) {
|
pub fn update_readable_state(&self) {
|
||||||
let buffer = self.read_buffer.lock_irq_disabled();
|
let buffer = self.read_buffer.disable_irq().lock();
|
||||||
|
|
||||||
if in_interrupt_context() {
|
if in_interrupt_context() {
|
||||||
// Add/Del events may sleep, so only construct parameters here.
|
// Add/Del events may sleep, so only construct parameters here.
|
||||||
if !buffer.is_empty() {
|
if !buffer.is_empty() {
|
||||||
self.work_item_para.lock_irq_disabled().pollee_type = Some(PolleeType::Add);
|
self.work_item_para.disable_irq().lock().pollee_type = Some(PolleeType::Add);
|
||||||
} else {
|
} else {
|
||||||
self.work_item_para.lock_irq_disabled().pollee_type = Some(PolleeType::Del);
|
self.work_item_para.disable_irq().lock().pollee_type = Some(PolleeType::Del);
|
||||||
}
|
}
|
||||||
submit_work_item(self.work_item.clone(), WorkPriority::High);
|
submit_work_item(self.work_item.clone(), WorkPriority::High);
|
||||||
return;
|
return;
|
||||||
@ -209,10 +209,16 @@ impl LineDiscipline {
|
|||||||
|
|
||||||
/// include all operations that may cause sleep, and processes by a work queue.
|
/// include all operations that may cause sleep, and processes by a work queue.
|
||||||
fn update_readable_state_after(&self) {
|
fn update_readable_state_after(&self) {
|
||||||
if let Some(signal) = self.work_item_para.lock_irq_disabled().kernel_signal.take() {
|
if let Some(signal) = self
|
||||||
|
.work_item_para
|
||||||
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
|
.kernel_signal
|
||||||
|
.take()
|
||||||
|
{
|
||||||
(self.send_signal)(signal);
|
(self.send_signal)(signal);
|
||||||
};
|
};
|
||||||
if let Some(pollee_type) = self.work_item_para.lock_irq_disabled().pollee_type.take() {
|
if let Some(pollee_type) = self.work_item_para.disable_irq().lock().pollee_type.take() {
|
||||||
match pollee_type {
|
match pollee_type {
|
||||||
PolleeType::Add => {
|
PolleeType::Add => {
|
||||||
self.pollee.add_events(IoEvents::IN);
|
self.pollee.add_events(IoEvents::IN);
|
||||||
@ -262,13 +268,13 @@ impl LineDiscipline {
|
|||||||
/// read all bytes buffered to dst, return the actual read length.
|
/// read all bytes buffered to dst, return the actual read length.
|
||||||
fn try_read(&self, dst: &mut [u8]) -> Result<usize> {
|
fn try_read(&self, dst: &mut [u8]) -> Result<usize> {
|
||||||
let (vmin, vtime) = {
|
let (vmin, vtime) = {
|
||||||
let termios = self.termios.lock_irq_disabled();
|
let termios = self.termios.disable_irq().lock();
|
||||||
let vmin = *termios.get_special_char(CC_C_CHAR::VMIN);
|
let vmin = *termios.get_special_char(CC_C_CHAR::VMIN);
|
||||||
let vtime = *termios.get_special_char(CC_C_CHAR::VTIME);
|
let vtime = *termios.get_special_char(CC_C_CHAR::VTIME);
|
||||||
(vmin, vtime)
|
(vmin, vtime)
|
||||||
};
|
};
|
||||||
let read_len = {
|
let read_len = {
|
||||||
let len = self.read_buffer.lock_irq_disabled().len();
|
let len = self.read_buffer.disable_irq().lock().len();
|
||||||
let max_read_len = len.min(dst.len());
|
let max_read_len = len.min(dst.len());
|
||||||
if vmin == 0 && vtime == 0 {
|
if vmin == 0 && vtime == 0 {
|
||||||
// poll read
|
// poll read
|
||||||
@ -295,7 +301,7 @@ impl LineDiscipline {
|
|||||||
/// returns immediately with the lesser of the number of bytes available or the number of bytes requested.
|
/// returns immediately with the lesser of the number of bytes available or the number of bytes requested.
|
||||||
/// If no bytes are available, completes immediately, returning 0.
|
/// If no bytes are available, completes immediately, returning 0.
|
||||||
fn poll_read(&self, dst: &mut [u8]) -> usize {
|
fn poll_read(&self, dst: &mut [u8]) -> usize {
|
||||||
let mut buffer = self.read_buffer.lock_irq_disabled();
|
let mut buffer = self.read_buffer.disable_irq().lock();
|
||||||
let len = buffer.len();
|
let len = buffer.len();
|
||||||
let max_read_len = len.min(dst.len());
|
let max_read_len = len.min(dst.len());
|
||||||
if max_read_len == 0 {
|
if max_read_len == 0 {
|
||||||
@ -304,7 +310,7 @@ impl LineDiscipline {
|
|||||||
let mut read_len = 0;
|
let mut read_len = 0;
|
||||||
for dst_i in dst.iter_mut().take(max_read_len) {
|
for dst_i in dst.iter_mut().take(max_read_len) {
|
||||||
if let Some(next_char) = buffer.pop() {
|
if let Some(next_char) = buffer.pop() {
|
||||||
let termios = self.termios.lock_irq_disabled();
|
let termios = self.termios.disable_irq().lock();
|
||||||
if termios.is_canonical_mode() {
|
if termios.is_canonical_mode() {
|
||||||
// canonical mode, read until meet new line
|
// canonical mode, read until meet new line
|
||||||
if is_line_terminator(next_char, &termios) {
|
if is_line_terminator(next_char, &termios) {
|
||||||
@ -353,15 +359,15 @@ impl LineDiscipline {
|
|||||||
|
|
||||||
/// whether there is buffered data
|
/// whether there is buffered data
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.read_buffer.lock_irq_disabled().len() == 0
|
self.read_buffer.disable_irq().lock().len() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn termios(&self) -> KernelTermios {
|
pub fn termios(&self) -> KernelTermios {
|
||||||
*self.termios.lock_irq_disabled()
|
*self.termios.disable_irq().lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_termios(&self, termios: KernelTermios) {
|
pub fn set_termios(&self, termios: KernelTermios) {
|
||||||
*self.termios.lock_irq_disabled() = termios;
|
*self.termios.disable_irq().lock() = termios;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drain_input(&self) {
|
pub fn drain_input(&self) {
|
||||||
|
@ -60,7 +60,7 @@ impl Tty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_driver(&self, driver: Weak<TtyDriver>) {
|
pub fn set_driver(&self, driver: Weak<TtyDriver>) {
|
||||||
*self.driver.lock_irq_disabled() = driver;
|
*self.driver.disable_irq().lock() = driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_char(&self, ch: u8) {
|
pub fn push_char(&self, ch: u8) {
|
||||||
|
@ -233,8 +233,8 @@ mod test {
|
|||||||
// FIXME: `ThreadOptions::new` currently accepts `Fn`, forcing us to use `SpinLock` to gain
|
// FIXME: `ThreadOptions::new` currently accepts `Fn`, forcing us to use `SpinLock` to gain
|
||||||
// internal mutability. We should avoid this `SpinLock` by making `ThreadOptions::new`
|
// internal mutability. We should avoid this `SpinLock` by making `ThreadOptions::new`
|
||||||
// accept `FnOnce`.
|
// accept `FnOnce`.
|
||||||
let writer_with_lock = SpinLock::new(Some(writer));
|
let writer_with_lock: SpinLock<_> = SpinLock::new(Some(writer));
|
||||||
let reader_with_lock = SpinLock::new(Some(reader));
|
let reader_with_lock: SpinLock<_> = SpinLock::new(Some(reader));
|
||||||
|
|
||||||
let signal_writer = Arc::new(AtomicBool::new(false));
|
let signal_writer = Arc::new(AtomicBool::new(false));
|
||||||
let signal_reader = signal_writer.clone();
|
let signal_reader = signal_writer.clone();
|
||||||
|
@ -4,7 +4,7 @@ use alloc::collections::btree_map::Entry;
|
|||||||
use core::sync::atomic::{AtomicU64, Ordering};
|
use core::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
use keyable_arc::KeyableArc;
|
use keyable_arc::KeyableArc;
|
||||||
use ostd::sync::WaitQueue;
|
use ostd::sync::{LocalIrqDisabled, WaitQueue};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::{SocketHandle, SocketSet},
|
iface::{SocketHandle, SocketSet},
|
||||||
phy::Device,
|
phy::Device,
|
||||||
@ -49,23 +49,25 @@ impl IfaceCommon {
|
|||||||
/// Acquires the lock to the interface.
|
/// Acquires the lock to the interface.
|
||||||
///
|
///
|
||||||
/// *Lock ordering:* [`Self::sockets`] first, [`Self::interface`] second.
|
/// *Lock ordering:* [`Self::sockets`] first, [`Self::interface`] second.
|
||||||
pub(super) fn interface(&self) -> SpinLockGuard<smoltcp::iface::Interface> {
|
pub(super) fn interface(&self) -> SpinLockGuard<smoltcp::iface::Interface, LocalIrqDisabled> {
|
||||||
self.interface.lock_irq_disabled()
|
self.interface.disable_irq().lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acuqires the lock to the sockets.
|
/// Acuqires the lock to the sockets.
|
||||||
///
|
///
|
||||||
/// *Lock ordering:* [`Self::sockets`] first, [`Self::interface`] second.
|
/// *Lock ordering:* [`Self::sockets`] first, [`Self::interface`] second.
|
||||||
pub(super) fn sockets(&self) -> SpinLockGuard<smoltcp::iface::SocketSet<'static>> {
|
pub(super) fn sockets(
|
||||||
self.sockets.lock_irq_disabled()
|
&self,
|
||||||
|
) -> SpinLockGuard<smoltcp::iface::SocketSet<'static>, LocalIrqDisabled> {
|
||||||
|
self.sockets.disable_irq().lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn ipv4_addr(&self) -> Option<Ipv4Address> {
|
pub(super) fn ipv4_addr(&self) -> Option<Ipv4Address> {
|
||||||
self.interface.lock_irq_disabled().ipv4_addr()
|
self.interface.disable_irq().lock().ipv4_addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn netmask(&self) -> Option<Ipv4Address> {
|
pub(super) fn netmask(&self) -> Option<Ipv4Address> {
|
||||||
let interface = self.interface.lock_irq_disabled();
|
let interface = self.interface.disable_irq().lock();
|
||||||
let ip_addrs = interface.ip_addrs();
|
let ip_addrs = interface.ip_addrs();
|
||||||
ip_addrs.first().map(|cidr| match cidr {
|
ip_addrs.first().map(|cidr| match cidr {
|
||||||
IpCidr::Ipv4(ipv4_cidr) => ipv4_cidr.netmask(),
|
IpCidr::Ipv4(ipv4_cidr) => ipv4_cidr.netmask(),
|
||||||
@ -132,12 +134,12 @@ impl IfaceCommon {
|
|||||||
|
|
||||||
let (handle, socket_family, observer) = match socket.into_raw() {
|
let (handle, socket_family, observer) = match socket.into_raw() {
|
||||||
(AnyRawSocket::Tcp(tcp_socket), observer) => (
|
(AnyRawSocket::Tcp(tcp_socket), observer) => (
|
||||||
self.sockets.lock_irq_disabled().add(tcp_socket),
|
self.sockets.disable_irq().lock().add(tcp_socket),
|
||||||
SocketFamily::Tcp,
|
SocketFamily::Tcp,
|
||||||
observer,
|
observer,
|
||||||
),
|
),
|
||||||
(AnyRawSocket::Udp(udp_socket), observer) => (
|
(AnyRawSocket::Udp(udp_socket), observer) => (
|
||||||
self.sockets.lock_irq_disabled().add(udp_socket),
|
self.sockets.disable_irq().lock().add(udp_socket),
|
||||||
SocketFamily::Udp,
|
SocketFamily::Udp,
|
||||||
observer,
|
observer,
|
||||||
),
|
),
|
||||||
@ -150,12 +152,12 @@ impl IfaceCommon {
|
|||||||
|
|
||||||
/// Remove a socket from the interface
|
/// Remove a socket from the interface
|
||||||
pub(super) fn remove_socket(&self, handle: SocketHandle) {
|
pub(super) fn remove_socket(&self, handle: SocketHandle) {
|
||||||
self.sockets.lock_irq_disabled().remove(handle);
|
self.sockets.disable_irq().lock().remove(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn poll<D: Device + ?Sized>(&self, device: &mut D) {
|
pub(super) fn poll<D: Device + ?Sized>(&self, device: &mut D) {
|
||||||
let mut sockets = self.sockets.lock_irq_disabled();
|
let mut sockets = self.sockets.disable_irq().lock();
|
||||||
let mut interface = self.interface.lock_irq_disabled();
|
let mut interface = self.interface.disable_irq().lock();
|
||||||
|
|
||||||
let timestamp = get_network_timestamp();
|
let timestamp = get_network_timestamp();
|
||||||
let (has_events, poll_at) = {
|
let (has_events, poll_at) = {
|
||||||
@ -199,7 +201,8 @@ impl IfaceCommon {
|
|||||||
|
|
||||||
let closed_sockets = self
|
let closed_sockets = self
|
||||||
.closing_sockets
|
.closing_sockets
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.extract_if(|closing_socket| closing_socket.is_closed())
|
.extract_if(|closing_socket| closing_socket.is_closed())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
drop(closed_sockets);
|
drop(closed_sockets);
|
||||||
@ -244,7 +247,7 @@ impl IfaceCommon {
|
|||||||
.remove(&keyable_socket);
|
.remove(&keyable_socket);
|
||||||
assert!(removed);
|
assert!(removed);
|
||||||
|
|
||||||
let mut closing_sockets = self.closing_sockets.lock_irq_disabled();
|
let mut closing_sockets = self.closing_sockets.disable_irq().lock();
|
||||||
|
|
||||||
// Check `is_closed` after holding the lock to avoid race conditions.
|
// Check `is_closed` after holding the lock to avoid race conditions.
|
||||||
if keyable_socket.is_closed() {
|
if keyable_socket.is_closed() {
|
||||||
|
@ -17,6 +17,7 @@ pub use any_socket::{
|
|||||||
AnyBoundSocket, AnyUnboundSocket, RawTcpSocket, RawUdpSocket, RECV_BUF_LEN, SEND_BUF_LEN,
|
AnyBoundSocket, AnyUnboundSocket, RawTcpSocket, RawUdpSocket, RECV_BUF_LEN, SEND_BUF_LEN,
|
||||||
};
|
};
|
||||||
pub use loopback::IfaceLoopback;
|
pub use loopback::IfaceLoopback;
|
||||||
|
use ostd::sync::LocalIrqDisabled;
|
||||||
pub use smoltcp::wire::EthernetAddress;
|
pub use smoltcp::wire::EthernetAddress;
|
||||||
pub use util::{spawn_background_poll_thread, BindPortConfig};
|
pub use util::{spawn_background_poll_thread, BindPortConfig};
|
||||||
pub use virtio::IfaceVirtio;
|
pub use virtio::IfaceVirtio;
|
||||||
@ -77,11 +78,11 @@ mod internal {
|
|||||||
pub trait IfaceInternal {
|
pub trait IfaceInternal {
|
||||||
fn common(&self) -> &IfaceCommon;
|
fn common(&self) -> &IfaceCommon;
|
||||||
/// The inner socket set
|
/// The inner socket set
|
||||||
fn sockets(&self) -> SpinLockGuard<SocketSet<'static>> {
|
fn sockets(&self) -> SpinLockGuard<SocketSet<'static>, LocalIrqDisabled> {
|
||||||
self.common().sockets()
|
self.common().sockets()
|
||||||
}
|
}
|
||||||
/// The inner iface.
|
/// The inner iface.
|
||||||
fn iface_inner(&self) -> SpinLockGuard<smoltcp::iface::Interface> {
|
fn iface_inner(&self) -> SpinLockGuard<smoltcp::iface::Interface, LocalIrqDisabled> {
|
||||||
self.common().interface()
|
self.common().interface()
|
||||||
}
|
}
|
||||||
/// The time we should do another poll.
|
/// The time we should do another poll.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use aster_network::AnyNetworkDevice;
|
use aster_network::AnyNetworkDevice;
|
||||||
use aster_virtio::device::network::DEVICE_NAME;
|
use aster_virtio::device::network::DEVICE_NAME;
|
||||||
|
use ostd::sync::PreemptDisabled;
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::{Config, SocketHandle, SocketSet},
|
iface::{Config, SocketHandle, SocketSet},
|
||||||
socket::dhcpv4,
|
socket::dhcpv4,
|
||||||
@ -12,7 +13,7 @@ use super::{common::IfaceCommon, internal::IfaceInternal, Iface};
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub struct IfaceVirtio {
|
pub struct IfaceVirtio {
|
||||||
driver: Arc<SpinLock<dyn AnyNetworkDevice>>,
|
driver: Arc<SpinLock<dyn AnyNetworkDevice, PreemptDisabled>>,
|
||||||
common: IfaceCommon,
|
common: IfaceCommon,
|
||||||
dhcp_handle: SocketHandle,
|
dhcp_handle: SocketHandle,
|
||||||
weak_self: Weak<Self>,
|
weak_self: Weak<Self>,
|
||||||
@ -113,7 +114,7 @@ impl Iface for IfaceVirtio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self) {
|
fn poll(&self) {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
self.common.poll(&mut *driver);
|
self.common.poll(&mut *driver);
|
||||||
self.process_dhcp();
|
self.process_dhcp();
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,13 @@ impl VsockSpace {
|
|||||||
/// Check whether the event is for this socket space
|
/// Check whether the event is for this socket space
|
||||||
fn is_event_for_socket(&self, event: &VsockEvent) -> bool {
|
fn is_event_for_socket(&self, event: &VsockEvent) -> bool {
|
||||||
self.connecting_sockets
|
self.connecting_sockets
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.contains_key(&event.destination.into())
|
.contains_key(&event.destination.into())
|
||||||
|| self
|
|| self
|
||||||
.listen_sockets
|
.listen_sockets
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.contains_key(&event.destination.into())
|
.contains_key(&event.destination.into())
|
||||||
|| self
|
|| self
|
||||||
.connected_sockets
|
.connected_sockets
|
||||||
@ -60,7 +62,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Alloc an unused port range
|
/// Alloc an unused port range
|
||||||
pub fn alloc_ephemeral_port(&self) -> Result<u32> {
|
pub fn alloc_ephemeral_port(&self) -> Result<u32> {
|
||||||
let mut used_ports = self.used_ports.lock_irq_disabled();
|
let mut used_ports = self.used_ports.disable_irq().lock();
|
||||||
// FIXME: the maximal port number is not defined by spec
|
// FIXME: the maximal port number is not defined by spec
|
||||||
for port in 1024..u32::MAX {
|
for port in 1024..u32::MAX {
|
||||||
if !used_ports.contains(&port) {
|
if !used_ports.contains(&port) {
|
||||||
@ -73,13 +75,13 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Bind a port
|
/// Bind a port
|
||||||
pub fn bind_port(&self, port: u32) -> bool {
|
pub fn bind_port(&self, port: u32) -> bool {
|
||||||
let mut used_ports = self.used_ports.lock_irq_disabled();
|
let mut used_ports = self.used_ports.disable_irq().lock();
|
||||||
used_ports.insert(port)
|
used_ports.insert(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recycle a port
|
/// Recycle a port
|
||||||
pub fn recycle_port(&self, port: &u32) -> bool {
|
pub fn recycle_port(&self, port: &u32) -> bool {
|
||||||
let mut used_ports = self.used_ports.lock_irq_disabled();
|
let mut used_ports = self.used_ports.disable_irq().lock();
|
||||||
used_ports.remove(port)
|
used_ports.remove(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,13 +107,13 @@ impl VsockSpace {
|
|||||||
addr: VsockSocketAddr,
|
addr: VsockSocketAddr,
|
||||||
connecting: Arc<Connecting>,
|
connecting: Arc<Connecting>,
|
||||||
) -> Option<Arc<Connecting>> {
|
) -> Option<Arc<Connecting>> {
|
||||||
let mut connecting_sockets = self.connecting_sockets.lock_irq_disabled();
|
let mut connecting_sockets = self.connecting_sockets.disable_irq().lock();
|
||||||
connecting_sockets.insert(addr, connecting)
|
connecting_sockets.insert(addr, connecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove a connecting socket
|
/// Remove a connecting socket
|
||||||
pub fn remove_connecting_socket(&self, addr: &VsockSocketAddr) -> Option<Arc<Connecting>> {
|
pub fn remove_connecting_socket(&self, addr: &VsockSocketAddr) -> Option<Arc<Connecting>> {
|
||||||
let mut connecting_sockets = self.connecting_sockets.lock_irq_disabled();
|
let mut connecting_sockets = self.connecting_sockets.disable_irq().lock();
|
||||||
connecting_sockets.remove(addr)
|
connecting_sockets.remove(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,13 +123,13 @@ impl VsockSpace {
|
|||||||
addr: VsockSocketAddr,
|
addr: VsockSocketAddr,
|
||||||
listen: Arc<Listen>,
|
listen: Arc<Listen>,
|
||||||
) -> Option<Arc<Listen>> {
|
) -> Option<Arc<Listen>> {
|
||||||
let mut listen_sockets = self.listen_sockets.lock_irq_disabled();
|
let mut listen_sockets = self.listen_sockets.disable_irq().lock();
|
||||||
listen_sockets.insert(addr, listen)
|
listen_sockets.insert(addr, listen)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove a listening socket
|
/// Remove a listening socket
|
||||||
pub fn remove_listen_socket(&self, addr: &VsockSocketAddr) -> Option<Arc<Listen>> {
|
pub fn remove_listen_socket(&self, addr: &VsockSocketAddr) -> Option<Arc<Listen>> {
|
||||||
let mut listen_sockets = self.listen_sockets.lock_irq_disabled();
|
let mut listen_sockets = self.listen_sockets.disable_irq().lock();
|
||||||
listen_sockets.remove(addr)
|
listen_sockets.remove(addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,13 +137,13 @@ impl VsockSpace {
|
|||||||
impl VsockSpace {
|
impl VsockSpace {
|
||||||
/// Get the CID of the guest
|
/// Get the CID of the guest
|
||||||
pub fn guest_cid(&self) -> u32 {
|
pub fn guest_cid(&self) -> u32 {
|
||||||
let driver = self.driver.lock_irq_disabled();
|
let driver = self.driver.disable_irq().lock();
|
||||||
driver.guest_cid() as u32
|
driver.guest_cid() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a request packet for initializing a new connection.
|
/// Send a request packet for initializing a new connection.
|
||||||
pub fn request(&self, info: &ConnectionInfo) -> Result<()> {
|
pub fn request(&self, info: &ConnectionInfo) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
driver
|
driver
|
||||||
.request(info)
|
.request(info)
|
||||||
.map_err(|_| Error::with_message(Errno::EIO, "cannot send connect packet"))
|
.map_err(|_| Error::with_message(Errno::EIO, "cannot send connect packet"))
|
||||||
@ -149,7 +151,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Send a response packet for accepting a new connection.
|
/// Send a response packet for accepting a new connection.
|
||||||
pub fn response(&self, info: &ConnectionInfo) -> Result<()> {
|
pub fn response(&self, info: &ConnectionInfo) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
driver
|
driver
|
||||||
.response(info)
|
.response(info)
|
||||||
.map_err(|_| Error::with_message(Errno::EIO, "cannot send response packet"))
|
.map_err(|_| Error::with_message(Errno::EIO, "cannot send response packet"))
|
||||||
@ -157,7 +159,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Send a shutdown packet to close a connection
|
/// Send a shutdown packet to close a connection
|
||||||
pub fn shutdown(&self, info: &ConnectionInfo) -> Result<()> {
|
pub fn shutdown(&self, info: &ConnectionInfo) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
driver
|
driver
|
||||||
.shutdown(info)
|
.shutdown(info)
|
||||||
.map_err(|_| Error::with_message(Errno::EIO, "cannot send shutdown packet"))
|
.map_err(|_| Error::with_message(Errno::EIO, "cannot send shutdown packet"))
|
||||||
@ -165,7 +167,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Send a reset packet to reset a connection
|
/// Send a reset packet to reset a connection
|
||||||
pub fn reset(&self, info: &ConnectionInfo) -> Result<()> {
|
pub fn reset(&self, info: &ConnectionInfo) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
driver
|
driver
|
||||||
.reset(info)
|
.reset(info)
|
||||||
.map_err(|_| Error::with_message(Errno::EIO, "cannot send reset packet"))
|
.map_err(|_| Error::with_message(Errno::EIO, "cannot send reset packet"))
|
||||||
@ -173,7 +175,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Send a credit request packet
|
/// Send a credit request packet
|
||||||
pub fn request_credit(&self, info: &ConnectionInfo) -> Result<()> {
|
pub fn request_credit(&self, info: &ConnectionInfo) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
driver
|
driver
|
||||||
.credit_request(info)
|
.credit_request(info)
|
||||||
.map_err(|_| Error::with_message(Errno::EIO, "cannot send credit request packet"))
|
.map_err(|_| Error::with_message(Errno::EIO, "cannot send credit request packet"))
|
||||||
@ -181,7 +183,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Send a credit update packet
|
/// Send a credit update packet
|
||||||
pub fn update_credit(&self, info: &ConnectionInfo) -> Result<()> {
|
pub fn update_credit(&self, info: &ConnectionInfo) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
driver
|
driver
|
||||||
.credit_update(info)
|
.credit_update(info)
|
||||||
.map_err(|_| Error::with_message(Errno::EIO, "cannot send credit update packet"))
|
.map_err(|_| Error::with_message(Errno::EIO, "cannot send credit update packet"))
|
||||||
@ -189,7 +191,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Send a data packet
|
/// Send a data packet
|
||||||
pub fn send(&self, buffer: &[u8], info: &mut ConnectionInfo) -> Result<()> {
|
pub fn send(&self, buffer: &[u8], info: &mut ConnectionInfo) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
driver
|
driver
|
||||||
.send(buffer, info)
|
.send(buffer, info)
|
||||||
.map_err(|_| Error::with_message(Errno::EIO, "cannot send data packet"))
|
.map_err(|_| Error::with_message(Errno::EIO, "cannot send data packet"))
|
||||||
@ -197,7 +199,7 @@ impl VsockSpace {
|
|||||||
|
|
||||||
/// Poll for each event from the driver
|
/// Poll for each event from the driver
|
||||||
pub fn poll(&self) -> Result<()> {
|
pub fn poll(&self) -> Result<()> {
|
||||||
let mut driver = self.driver.lock_irq_disabled();
|
let mut driver = self.driver.disable_irq().lock();
|
||||||
|
|
||||||
while let Some(event) = self.poll_single(&mut driver)? {
|
while let Some(event) = self.poll_single(&mut driver)? {
|
||||||
if !self.is_event_for_socket(&event) {
|
if !self.is_event_for_socket(&event) {
|
||||||
@ -219,7 +221,7 @@ impl VsockSpace {
|
|||||||
match event.event_type {
|
match event.event_type {
|
||||||
VsockEventType::ConnectionRequest => {
|
VsockEventType::ConnectionRequest => {
|
||||||
// Preparation for listen socket `accept`
|
// Preparation for listen socket `accept`
|
||||||
let listen_sockets = self.listen_sockets.lock_irq_disabled();
|
let listen_sockets = self.listen_sockets.disable_irq().lock();
|
||||||
let Some(listen) = listen_sockets.get(&event.destination.into()) else {
|
let Some(listen) = listen_sockets.get(&event.destination.into()) else {
|
||||||
return_errno_with_message!(
|
return_errno_with_message!(
|
||||||
Errno::EINVAL,
|
Errno::EINVAL,
|
||||||
@ -233,7 +235,7 @@ impl VsockSpace {
|
|||||||
listen.update_io_events();
|
listen.update_io_events();
|
||||||
}
|
}
|
||||||
VsockEventType::ConnectionResponse => {
|
VsockEventType::ConnectionResponse => {
|
||||||
let connecting_sockets = self.connecting_sockets.lock_irq_disabled();
|
let connecting_sockets = self.connecting_sockets.disable_irq().lock();
|
||||||
let Some(connecting) = connecting_sockets.get(&event.destination.into()) else {
|
let Some(connecting) = connecting_sockets.get(&event.destination.into()) else {
|
||||||
return_errno_with_message!(
|
return_errno_with_message!(
|
||||||
Errno::EINVAL,
|
Errno::EINVAL,
|
||||||
|
@ -51,7 +51,7 @@ impl Connected {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize> {
|
pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize> {
|
||||||
let mut connection = self.connection.lock_irq_disabled();
|
let mut connection = self.connection.disable_irq().lock();
|
||||||
let bytes_read = connection.buffer.len().min(buf.len());
|
let bytes_read = connection.buffer.len().min(buf.len());
|
||||||
connection.buffer.pop_slice(&mut buf[..bytes_read]);
|
connection.buffer.pop_slice(&mut buf[..bytes_read]);
|
||||||
connection.info.done_forwarding(bytes_read);
|
connection.info.done_forwarding(bytes_read);
|
||||||
@ -69,7 +69,7 @@ impl Connected {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(&self, packet: &[u8], flags: SendRecvFlags) -> Result<usize> {
|
pub fn send(&self, packet: &[u8], flags: SendRecvFlags) -> Result<usize> {
|
||||||
let mut connection = self.connection.lock_irq_disabled();
|
let mut connection = self.connection.disable_irq().lock();
|
||||||
debug_assert!(flags.is_all_supported());
|
debug_assert!(flags.is_all_supported());
|
||||||
let buf_len = packet.len();
|
let buf_len = packet.len();
|
||||||
VSOCK_GLOBAL
|
VSOCK_GLOBAL
|
||||||
@ -81,21 +81,21 @@ impl Connected {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn should_close(&self) -> bool {
|
pub fn should_close(&self) -> bool {
|
||||||
let connection = self.connection.lock_irq_disabled();
|
let connection = self.connection.disable_irq().lock();
|
||||||
// If buffer is now empty and the peer requested shutdown, finish shutting down the
|
// If buffer is now empty and the peer requested shutdown, finish shutting down the
|
||||||
// connection.
|
// connection.
|
||||||
connection.is_peer_requested_shutdown() && connection.buffer.is_empty()
|
connection.is_peer_requested_shutdown() && connection.buffer.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_closed(&self) -> bool {
|
pub fn is_closed(&self) -> bool {
|
||||||
let connection = self.connection.lock_irq_disabled();
|
let connection = self.connection.disable_irq().lock();
|
||||||
connection.is_local_shutdown()
|
connection.is_local_shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shutdown(&self, _cmd: SockShutdownCmd) -> Result<()> {
|
pub fn shutdown(&self, _cmd: SockShutdownCmd) -> Result<()> {
|
||||||
// TODO: deal with cmd
|
// TODO: deal with cmd
|
||||||
if self.should_close() {
|
if self.should_close() {
|
||||||
let mut connection = self.connection.lock_irq_disabled();
|
let mut connection = self.connection.disable_irq().lock();
|
||||||
if connection.is_local_shutdown() {
|
if connection.is_local_shutdown() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -106,23 +106,24 @@ impl Connected {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn update_info(&self, event: &VsockEvent) {
|
pub fn update_info(&self, event: &VsockEvent) {
|
||||||
let mut connection = self.connection.lock_irq_disabled();
|
let mut connection = self.connection.disable_irq().lock();
|
||||||
connection.update_for_event(event)
|
connection.update_for_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_info(&self) -> ConnectionInfo {
|
pub fn get_info(&self) -> ConnectionInfo {
|
||||||
let connection = self.connection.lock_irq_disabled();
|
let connection = self.connection.disable_irq().lock();
|
||||||
connection.info.clone()
|
connection.info.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_connection_buffer(&self, bytes: &[u8]) -> bool {
|
pub fn add_connection_buffer(&self, bytes: &[u8]) -> bool {
|
||||||
let mut connection = self.connection.lock_irq_disabled();
|
let mut connection = self.connection.disable_irq().lock();
|
||||||
connection.add(bytes)
|
connection.add(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_peer_requested_shutdown(&self) {
|
pub fn set_peer_requested_shutdown(&self) {
|
||||||
self.connection
|
self.connection
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.set_peer_requested_shutdown()
|
.set_peer_requested_shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ impl Connected {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_io_events(&self) {
|
pub fn update_io_events(&self) {
|
||||||
let connection = self.connection.lock_irq_disabled();
|
let connection = self.connection.disable_irq().lock();
|
||||||
// receive
|
// receive
|
||||||
if !connection.buffer.is_empty() {
|
if !connection.buffer.is_empty() {
|
||||||
self.pollee.add_events(IoEvents::IN);
|
self.pollee.add_events(IoEvents::IN);
|
||||||
|
@ -38,11 +38,11 @@ impl Connecting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn info(&self) -> ConnectionInfo {
|
pub fn info(&self) -> ConnectionInfo {
|
||||||
self.info.lock_irq_disabled().clone()
|
self.info.disable_irq().lock().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_info(&self, event: &VsockEvent) {
|
pub fn update_info(&self, event: &VsockEvent) {
|
||||||
self.info.lock_irq_disabled().update_for_event(event)
|
self.info.disable_irq().lock().update_for_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
|
pub fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
|
||||||
|
@ -29,7 +29,7 @@ impl Listen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_incoming(&self, connect: Arc<Connected>) -> Result<()> {
|
pub fn push_incoming(&self, connect: Arc<Connected>) -> Result<()> {
|
||||||
let mut incoming_connections = self.incoming_connection.lock_irq_disabled();
|
let mut incoming_connections = self.incoming_connection.disable_irq().lock();
|
||||||
if incoming_connections.len() >= self.backlog {
|
if incoming_connections.len() >= self.backlog {
|
||||||
return_errno_with_message!(Errno::ECONNREFUSED, "queue in listenging socket is full")
|
return_errno_with_message!(Errno::ECONNREFUSED, "queue in listenging socket is full")
|
||||||
}
|
}
|
||||||
@ -41,7 +41,8 @@ impl Listen {
|
|||||||
pub fn try_accept(&self) -> Result<Arc<Connected>> {
|
pub fn try_accept(&self) -> Result<Arc<Connected>> {
|
||||||
let connection = self
|
let connection = self
|
||||||
.incoming_connection
|
.incoming_connection
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.pop_front()
|
.pop_front()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::with_message(Errno::EAGAIN, "no pending connection is available")
|
Error::with_message(Errno::EAGAIN, "no pending connection is available")
|
||||||
@ -55,7 +56,7 @@ impl Listen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_io_events(&self) {
|
pub fn update_io_events(&self) {
|
||||||
let incomming_connection = self.incoming_connection.lock_irq_disabled();
|
let incomming_connection = self.incoming_connection.disable_irq().lock();
|
||||||
if !incomming_connection.is_empty() {
|
if !incomming_connection.is_empty() {
|
||||||
self.pollee.add_events(IoEvents::IN);
|
self.pollee.add_events(IoEvents::IN);
|
||||||
} else {
|
} else {
|
||||||
|
@ -56,7 +56,7 @@ impl<T: Sync + Send + PreemptSchedInfo> Scheduler<T> for PreemptScheduler<T> {
|
|||||||
cpu_id
|
cpu_id
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut rq = self.rq[target_cpu as usize].lock_irq_disabled();
|
let mut rq = self.rq[target_cpu as usize].disable_irq().lock();
|
||||||
if still_in_rq && let Err(_) = runnable.cpu().set_if_is_none(target_cpu) {
|
if still_in_rq && let Err(_) = runnable.cpu().set_if_is_none(target_cpu) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -71,13 +71,13 @@ impl<T: Sync + Send + PreemptSchedInfo> Scheduler<T> for PreemptScheduler<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<T>)) {
|
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<T>)) {
|
||||||
let local_rq: &PreemptRunQueue<T> = &self.rq[this_cpu() as usize].lock_irq_disabled();
|
let local_rq: &PreemptRunQueue<T> = &self.rq[this_cpu() as usize].disable_irq().lock();
|
||||||
f(local_rq);
|
f(local_rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_mut_rq_with(&self, f: &mut dyn FnMut(&mut dyn LocalRunQueue<T>)) {
|
fn local_mut_rq_with(&self, f: &mut dyn FnMut(&mut dyn LocalRunQueue<T>)) {
|
||||||
let local_rq: &mut PreemptRunQueue<T> =
|
let local_rq: &mut PreemptRunQueue<T> =
|
||||||
&mut self.rq[this_cpu() as usize].lock_irq_disabled();
|
&mut self.rq[this_cpu() as usize].disable_irq().lock();
|
||||||
f(local_rq);
|
f(local_rq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,8 @@ impl WorkQueue {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
self.inner
|
self.inner
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.pending_work_items
|
.pending_work_items
|
||||||
.push(work_item);
|
.push(work_item);
|
||||||
if let Some(worker_pool) = self.worker_pool.upgrade() {
|
if let Some(worker_pool) = self.worker_pool.upgrade() {
|
||||||
@ -150,7 +151,7 @@ impl WorkQueue {
|
|||||||
/// Request a pending work item. The `request_cpu` indicates the CPU where
|
/// Request a pending work item. The `request_cpu` indicates the CPU where
|
||||||
/// the calling worker is located.
|
/// the calling worker is located.
|
||||||
fn dequeue(&self, request_cpu: u32) -> Option<Arc<WorkItem>> {
|
fn dequeue(&self, request_cpu: u32) -> Option<Arc<WorkItem>> {
|
||||||
let mut inner = self.inner.lock_irq_disabled();
|
let mut inner = self.inner.disable_irq().lock();
|
||||||
let index = inner
|
let index = inner
|
||||||
.pending_work_items
|
.pending_work_items
|
||||||
.iter()
|
.iter()
|
||||||
@ -161,7 +162,8 @@ impl WorkQueue {
|
|||||||
|
|
||||||
fn has_pending_work_items(&self, request_cpu: u32) -> bool {
|
fn has_pending_work_items(&self, request_cpu: u32) -> bool {
|
||||||
self.inner
|
self.inner
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.pending_work_items
|
.pending_work_items
|
||||||
.iter()
|
.iter()
|
||||||
.any(|item| item.is_valid_cpu(request_cpu))
|
.any(|item| item.is_valid_cpu(request_cpu))
|
||||||
|
@ -87,10 +87,10 @@ impl Worker {
|
|||||||
if self.is_destroying() {
|
if self.is_destroying() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self.inner.lock_irq_disabled().worker_status = WorkerStatus::Idle;
|
self.inner.disable_irq().lock().worker_status = WorkerStatus::Idle;
|
||||||
worker_pool.idle_current_worker(self.bound_cpu, self.clone());
|
worker_pool.idle_current_worker(self.bound_cpu, self.clone());
|
||||||
if !self.is_destroying() {
|
if !self.is_destroying() {
|
||||||
self.inner.lock_irq_disabled().worker_status = WorkerStatus::Running;
|
self.inner.disable_irq().lock().worker_status = WorkerStatus::Running;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,22 +102,22 @@ impl Worker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn is_idle(&self) -> bool {
|
pub(super) fn is_idle(&self) -> bool {
|
||||||
self.inner.lock_irq_disabled().worker_status == WorkerStatus::Idle
|
self.inner.disable_irq().lock().worker_status == WorkerStatus::Idle
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn is_destroying(&self) -> bool {
|
pub(super) fn is_destroying(&self) -> bool {
|
||||||
self.inner.lock_irq_disabled().worker_status == WorkerStatus::Destroying
|
self.inner.disable_irq().lock().worker_status == WorkerStatus::Destroying
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn destroy(&self) {
|
pub(super) fn destroy(&self) {
|
||||||
self.inner.lock_irq_disabled().worker_status = WorkerStatus::Destroying;
|
self.inner.disable_irq().lock().worker_status = WorkerStatus::Destroying;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit(&self) {
|
fn exit(&self) {
|
||||||
self.inner.lock_irq_disabled().worker_status = WorkerStatus::Exited;
|
self.inner.disable_irq().lock().worker_status = WorkerStatus::Exited;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn is_exit(&self) -> bool {
|
pub(super) fn is_exit(&self) -> bool {
|
||||||
self.inner.lock_irq_disabled().worker_status == WorkerStatus::Exited
|
self.inner.disable_irq().lock().worker_status == WorkerStatus::Exited
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,12 +76,12 @@ impl LocalWorkerPool {
|
|||||||
|
|
||||||
fn add_worker(&self) {
|
fn add_worker(&self) {
|
||||||
let worker = Worker::new(self.parent.clone(), self.cpu_id);
|
let worker = Worker::new(self.parent.clone(), self.cpu_id);
|
||||||
self.workers.lock_irq_disabled().push_back(worker.clone());
|
self.workers.disable_irq().lock().push_back(worker.clone());
|
||||||
worker.bound_thread().run();
|
worker.bound_thread().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_worker(&self) {
|
fn remove_worker(&self) {
|
||||||
let mut workers = self.workers.lock_irq_disabled();
|
let mut workers = self.workers.disable_irq().lock();
|
||||||
for (index, worker) in workers.iter().enumerate() {
|
for (index, worker) in workers.iter().enumerate() {
|
||||||
if worker.is_idle() {
|
if worker.is_idle() {
|
||||||
worker.destroy();
|
worker.destroy();
|
||||||
@ -116,7 +116,7 @@ impl LocalWorkerPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_all_workers(&self) {
|
fn destroy_all_workers(&self) {
|
||||||
for worker in self.workers.lock_irq_disabled().iter() {
|
for worker in self.workers.disable_irq().lock().iter() {
|
||||||
worker.destroy();
|
worker.destroy();
|
||||||
}
|
}
|
||||||
self.idle_wait_queue.wake_all();
|
self.idle_wait_queue.wake_all();
|
||||||
@ -149,12 +149,13 @@ impl WorkerPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_work_queue(&self, work_queue: Arc<WorkQueue>) {
|
pub fn assign_work_queue(&self, work_queue: Arc<WorkQueue>) {
|
||||||
self.work_queues.lock_irq_disabled().push(work_queue);
|
self.work_queues.disable_irq().lock().push(work_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_pending_work_items(&self, request_cpu: u32) -> bool {
|
pub fn has_pending_work_items(&self, request_cpu: u32) -> bool {
|
||||||
self.work_queues
|
self.work_queues
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|work_queue| work_queue.has_pending_work_items(request_cpu))
|
.any(|work_queue| work_queue.has_pending_work_items(request_cpu))
|
||||||
}
|
}
|
||||||
@ -164,7 +165,7 @@ impl WorkerPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_workers(&self, cpu_id: u32) -> u16 {
|
pub fn num_workers(&self, cpu_id: u32) -> u16 {
|
||||||
self.local_pool(cpu_id).workers.lock_irq_disabled().len() as u16
|
self.local_pool(cpu_id).workers.disable_irq().lock().len() as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cpu_set(&self) -> &CpuSet {
|
pub fn cpu_set(&self) -> &CpuSet {
|
||||||
@ -172,7 +173,7 @@ impl WorkerPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn fetch_pending_work_item(&self, request_cpu: u32) -> Option<Arc<WorkItem>> {
|
pub(super) fn fetch_pending_work_item(&self, request_cpu: u32) -> Option<Arc<WorkItem>> {
|
||||||
for work_queue in self.work_queues.lock_irq_disabled().iter() {
|
for work_queue in self.work_queues.disable_irq().lock().iter() {
|
||||||
let item = work_queue.dequeue(request_cpu);
|
let item = work_queue.dequeue(request_cpu);
|
||||||
if item.is_some() {
|
if item.is_some() {
|
||||||
return item;
|
return item;
|
||||||
|
@ -30,13 +30,13 @@ impl CpuClock {
|
|||||||
|
|
||||||
/// Adds `interval` to the original recorded time to update the `CpuClock`.
|
/// Adds `interval` to the original recorded time to update the `CpuClock`.
|
||||||
pub fn add_time(&self, interval: Duration) {
|
pub fn add_time(&self, interval: Duration) {
|
||||||
*self.time.lock_irq_disabled() += interval;
|
*self.time.disable_irq().lock() += interval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clock for CpuClock {
|
impl Clock for CpuClock {
|
||||||
fn read_time(&self) -> Duration {
|
fn read_time(&self) -> Duration {
|
||||||
*self.time.lock_irq_disabled()
|
*self.time.disable_irq().lock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ impl Clock for MonotonicClock {
|
|||||||
|
|
||||||
impl Clock for RealTimeCoarseClock {
|
impl Clock for RealTimeCoarseClock {
|
||||||
fn read_time(&self) -> Duration {
|
fn read_time(&self) -> Duration {
|
||||||
*Self::current_ref().get().unwrap().lock_irq_disabled()
|
*Self::current_ref().get().unwrap().disable_irq().lock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ fn init_jiffies_clock_manager() {
|
|||||||
fn update_coarse_clock() {
|
fn update_coarse_clock() {
|
||||||
let real_time = RealTimeClock::get().read_time();
|
let real_time = RealTimeClock::get().read_time();
|
||||||
let current = RealTimeCoarseClock::current_ref().get().unwrap();
|
let current = RealTimeCoarseClock::current_ref().get().unwrap();
|
||||||
*current.lock_irq_disabled() = real_time;
|
*current.disable_irq().lock() = real_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_coarse_clock() {
|
fn init_coarse_clock() {
|
||||||
|
@ -57,12 +57,12 @@ impl Timer {
|
|||||||
/// Set the interval time for this timer.
|
/// Set the interval time for this timer.
|
||||||
/// The timer will be reset with the interval time upon expiration.
|
/// The timer will be reset with the interval time upon expiration.
|
||||||
pub fn set_interval(&self, interval: Duration) {
|
pub fn set_interval(&self, interval: Duration) {
|
||||||
*self.interval.lock_irq_disabled() = interval;
|
*self.interval.disable_irq().lock() = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel the current timer's set timeout callback.
|
/// Cancel the current timer's set timeout callback.
|
||||||
pub fn cancel(&self) {
|
pub fn cancel(&self) {
|
||||||
let timer_callback = self.timer_callback.lock_irq_disabled();
|
let timer_callback = self.timer_callback.disable_irq().lock();
|
||||||
if let Some(timer_callback) = timer_callback.upgrade() {
|
if let Some(timer_callback) = timer_callback.upgrade() {
|
||||||
timer_callback.cancel();
|
timer_callback.cancel();
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ impl Timer {
|
|||||||
Box::new(move || interval_timer_callback(&timer_weak)),
|
Box::new(move || interval_timer_callback(&timer_weak)),
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut timer_callback = self.timer_callback.lock_irq_disabled();
|
let mut timer_callback = self.timer_callback.disable_irq().lock();
|
||||||
if let Some(timer_callback) = timer_callback.upgrade() {
|
if let Some(timer_callback) = timer_callback.upgrade() {
|
||||||
timer_callback.cancel();
|
timer_callback.cancel();
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ impl Timer {
|
|||||||
|
|
||||||
/// Return the current expired time of this timer.
|
/// Return the current expired time of this timer.
|
||||||
pub fn expired_time(&self) -> Duration {
|
pub fn expired_time(&self) -> Duration {
|
||||||
let timer_callback = self.timer_callback.lock_irq_disabled().upgrade();
|
let timer_callback = self.timer_callback.disable_irq().lock().upgrade();
|
||||||
timer_callback.map_or(Duration::ZERO, |timer_callback| timer_callback.expired_time)
|
timer_callback.map_or(Duration::ZERO, |timer_callback| timer_callback.expired_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ impl Timer {
|
|||||||
|
|
||||||
/// Returns the interval time of the current timer.
|
/// Returns the interval time of the current timer.
|
||||||
pub fn interval(&self) -> Duration {
|
pub fn interval(&self) -> Duration {
|
||||||
*self.interval.lock_irq_disabled()
|
*self.interval.disable_irq().lock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ fn interval_timer_callback(timer: &Weak<Timer>) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
(timer.registered_callback)();
|
(timer.registered_callback)();
|
||||||
let interval = timer.interval.lock_irq_disabled();
|
let interval = timer.interval.disable_irq().lock();
|
||||||
if *interval != Duration::ZERO {
|
if *interval != Duration::ZERO {
|
||||||
timer.set_timeout(Timeout::After(*interval));
|
timer.set_timeout(Timeout::After(*interval));
|
||||||
}
|
}
|
||||||
@ -161,7 +161,8 @@ impl TimerManager {
|
|||||||
|
|
||||||
fn insert(&self, timer_callback: Arc<TimerCallback>) {
|
fn insert(&self, timer_callback: Arc<TimerCallback>) {
|
||||||
self.timer_callbacks
|
self.timer_callbacks
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.push(timer_callback);
|
.push(timer_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +170,7 @@ impl TimerManager {
|
|||||||
/// call the corresponding callback functions.
|
/// call the corresponding callback functions.
|
||||||
pub fn process_expired_timers(&self) {
|
pub fn process_expired_timers(&self) {
|
||||||
let callbacks = {
|
let callbacks = {
|
||||||
let mut timeout_list = self.timer_callbacks.lock_irq_disabled();
|
let mut timeout_list = self.timer_callbacks.disable_irq().lock();
|
||||||
if timeout_list.len() == 0 {
|
if timeout_list.len() == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,8 @@ pub fn register_device(name: String, device: Arc<dyn AnyConsoleDevice>) {
|
|||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.console_device_table
|
.console_device_table
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.insert(name, device);
|
.insert(name, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +41,8 @@ pub fn all_devices() -> Vec<(String, Arc<dyn AnyConsoleDevice>)> {
|
|||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.console_device_table
|
.console_device_table
|
||||||
.lock_irq_disabled();
|
.disable_irq()
|
||||||
|
.lock();
|
||||||
console_devs
|
console_devs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, device)| (name.clone(), device.clone()))
|
.map(|(name, device)| (name.clone(), device.clone()))
|
||||||
|
@ -204,7 +204,8 @@ pub fn _print(args: fmt::Arguments) {
|
|||||||
WRITER
|
WRITER
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.write_fmt(args)
|
.write_fmt(args)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,8 @@ impl HasDaddr for TxBuffer {
|
|||||||
impl Drop for TxBuffer {
|
impl Drop for TxBuffer {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.pool
|
self.pool
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.push_back(self.dma_stream.clone());
|
.push_back(self.dma_stream.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +146,7 @@ fn get_tx_stream_from_pool(
|
|||||||
nbytes: usize,
|
nbytes: usize,
|
||||||
tx_buffer_pool: &'static SpinLock<LinkedList<DmaStream>>,
|
tx_buffer_pool: &'static SpinLock<LinkedList<DmaStream>>,
|
||||||
) -> Option<DmaStream> {
|
) -> Option<DmaStream> {
|
||||||
let mut pool = tx_buffer_pool.lock_irq_disabled();
|
let mut pool = tx_buffer_pool.disable_irq().lock();
|
||||||
let mut cursor = pool.cursor_front_mut();
|
let mut cursor = pool.cursor_front_mut();
|
||||||
while let Some(current) = cursor.current() {
|
while let Some(current) = cursor.current() {
|
||||||
if current.nbytes() >= nbytes {
|
if current.nbytes() >= nbytes {
|
||||||
|
@ -97,7 +97,7 @@ impl DmaPool {
|
|||||||
pub fn alloc_segment(self: &Arc<Self>) -> Result<DmaSegment, ostd::Error> {
|
pub fn alloc_segment(self: &Arc<Self>) -> Result<DmaSegment, ostd::Error> {
|
||||||
// Lock order: pool.avail_pages -> pool.all_pages
|
// Lock order: pool.avail_pages -> pool.all_pages
|
||||||
// pool.avail_pages -> page.allocated_segments
|
// pool.avail_pages -> page.allocated_segments
|
||||||
let mut avail_pages = self.avail_pages.lock_irq_disabled();
|
let mut avail_pages = self.avail_pages.disable_irq().lock();
|
||||||
if avail_pages.is_empty() {
|
if avail_pages.is_empty() {
|
||||||
/// Allocate a new page
|
/// Allocate a new page
|
||||||
let new_page = {
|
let new_page = {
|
||||||
@ -109,7 +109,7 @@ impl DmaPool {
|
|||||||
pool,
|
pool,
|
||||||
)?)
|
)?)
|
||||||
};
|
};
|
||||||
let mut all_pages = self.all_pages.lock_irq_disabled();
|
let mut all_pages = self.all_pages.disable_irq().lock();
|
||||||
avail_pages.push_back(new_page.clone());
|
avail_pages.push_back(new_page.clone());
|
||||||
all_pages.push_back(new_page);
|
all_pages.push_back(new_page);
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ impl DmaPool {
|
|||||||
|
|
||||||
/// Returns the number of pages in pool
|
/// Returns the number of pages in pool
|
||||||
fn num_pages(&self) -> usize {
|
fn num_pages(&self) -> usize {
|
||||||
self.all_pages.lock_irq_disabled().len()
|
self.all_pages.disable_irq().lock().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return segment size in pool
|
/// Return segment size in pool
|
||||||
@ -166,7 +166,7 @@ impl DmaPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_segment(self: &Arc<Self>) -> Option<DmaSegment> {
|
fn alloc_segment(self: &Arc<Self>) -> Option<DmaSegment> {
|
||||||
let mut segments = self.allocated_segments.lock_irq_disabled();
|
let mut segments = self.allocated_segments.disable_irq().lock();
|
||||||
let free_segment_index = get_next_free_index(&segments, self.nr_blocks_per_page())?;
|
let free_segment_index = get_next_free_index(&segments, self.nr_blocks_per_page())?;
|
||||||
segments.set(free_segment_index, true);
|
segments.set(free_segment_index, true);
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ impl DmaPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_full(&self) -> bool {
|
fn is_full(&self) -> bool {
|
||||||
let segments = self.allocated_segments.lock_irq_disabled();
|
let segments = self.allocated_segments.disable_irq().lock();
|
||||||
get_next_free_index(&segments, self.nr_blocks_per_page()).is_none()
|
get_next_free_index(&segments, self.nr_blocks_per_page()).is_none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,10 +257,10 @@ impl Drop for DmaSegment {
|
|||||||
|
|
||||||
// Keep the same lock order as `pool.alloc_segment`
|
// Keep the same lock order as `pool.alloc_segment`
|
||||||
// Lock order: pool.avail_pages -> pool.all_pages -> page.allocated_segments
|
// Lock order: pool.avail_pages -> pool.all_pages -> page.allocated_segments
|
||||||
let mut avail_pages = pool.avail_pages.lock_irq_disabled();
|
let mut avail_pages = pool.avail_pages.disable_irq().lock();
|
||||||
let mut all_pages = pool.all_pages.lock_irq_disabled();
|
let mut all_pages = pool.all_pages.disable_irq().lock();
|
||||||
|
|
||||||
let mut allocated_segments = page.allocated_segments.lock_irq_disabled();
|
let mut allocated_segments = page.allocated_segments.disable_irq().lock();
|
||||||
|
|
||||||
let nr_blocks_per_page = PAGE_SIZE / self.size;
|
let nr_blocks_per_page = PAGE_SIZE / self.size;
|
||||||
let became_avail = get_next_free_index(&allocated_segments, nr_blocks_per_page).is_none();
|
let became_avail = get_next_free_index(&allocated_segments, nr_blocks_per_page).is_none();
|
||||||
|
@ -18,7 +18,10 @@ use core::{any::Any, fmt::Debug};
|
|||||||
pub use buffer::{RxBuffer, TxBuffer, RX_BUFFER_POOL, TX_BUFFER_POOL};
|
pub use buffer::{RxBuffer, TxBuffer, RX_BUFFER_POOL, TX_BUFFER_POOL};
|
||||||
use component::{init_component, ComponentInitError};
|
use component::{init_component, ComponentInitError};
|
||||||
pub use dma_pool::DmaSegment;
|
pub use dma_pool::DmaSegment;
|
||||||
use ostd::{sync::SpinLock, Pod};
|
use ostd::{
|
||||||
|
sync::{PreemptDisabled, SpinLock},
|
||||||
|
Pod,
|
||||||
|
};
|
||||||
use smoltcp::phy;
|
use smoltcp::phy;
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
@ -52,21 +55,23 @@ pub trait AnyNetworkDevice: Send + Sync + Any + Debug {
|
|||||||
|
|
||||||
pub trait NetDeviceIrqHandler = Fn() + Send + Sync + 'static;
|
pub trait NetDeviceIrqHandler = Fn() + Send + Sync + 'static;
|
||||||
|
|
||||||
pub fn register_device(name: String, device: Arc<SpinLock<dyn AnyNetworkDevice>>) {
|
pub fn register_device(name: String, device: Arc<SpinLock<dyn AnyNetworkDevice, PreemptDisabled>>) {
|
||||||
COMPONENT
|
COMPONENT
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.network_device_table
|
.network_device_table
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.insert(name, (Arc::new(SpinLock::new(Vec::new())), device));
|
.insert(name, (Arc::new(SpinLock::new(Vec::new())), device));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device(str: &str) -> Option<Arc<SpinLock<dyn AnyNetworkDevice>>> {
|
pub fn get_device(str: &str) -> Option<Arc<SpinLock<dyn AnyNetworkDevice, PreemptDisabled>>> {
|
||||||
let table = COMPONENT
|
let table = COMPONENT
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.network_device_table
|
.network_device_table
|
||||||
.lock_irq_disabled();
|
.disable_irq()
|
||||||
|
.lock();
|
||||||
let (_, device) = table.get(str)?;
|
let (_, device) = table.get(str)?;
|
||||||
Some(device.clone())
|
Some(device.clone())
|
||||||
}
|
}
|
||||||
@ -80,11 +85,12 @@ pub fn register_recv_callback(name: &str, callback: impl NetDeviceIrqHandler) {
|
|||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.network_device_table
|
.network_device_table
|
||||||
.lock_irq_disabled();
|
.disable_irq()
|
||||||
|
.lock();
|
||||||
let Some((callbacks, _)) = device_table.get(name) else {
|
let Some((callbacks, _)) = device_table.get(name) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
callbacks.lock_irq_disabled().push(Arc::new(callback));
|
callbacks.disable_irq().lock().push(Arc::new(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_recv_irq(name: &str) {
|
pub fn handle_recv_irq(name: &str) {
|
||||||
@ -92,11 +98,12 @@ pub fn handle_recv_irq(name: &str) {
|
|||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.network_device_table
|
.network_device_table
|
||||||
.lock_irq_disabled();
|
.disable_irq()
|
||||||
|
.lock();
|
||||||
let Some((callbacks, _)) = device_table.get(name) else {
|
let Some((callbacks, _)) = device_table.get(name) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let callbacks = callbacks.lock_irq_disabled();
|
let callbacks = callbacks.disable_irq().lock();
|
||||||
for callback in callbacks.iter() {
|
for callback in callbacks.iter() {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
@ -107,7 +114,8 @@ pub fn all_devices() -> Vec<(String, NetworkDeviceRef)> {
|
|||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.network_device_table
|
.network_device_table
|
||||||
.lock_irq_disabled();
|
.disable_irq()
|
||||||
|
.lock();
|
||||||
network_devs
|
network_devs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, (_, device))| (name.clone(), device.clone()))
|
.map(|(name, (_, device))| (name.clone(), device.clone()))
|
||||||
@ -115,8 +123,9 @@ pub fn all_devices() -> Vec<(String, NetworkDeviceRef)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static COMPONENT: Once<Component> = Once::new();
|
static COMPONENT: Once<Component> = Once::new();
|
||||||
pub(crate) static NETWORK_IRQ_HANDLERS: Once<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>>> =
|
pub(crate) static NETWORK_IRQ_HANDLERS: Once<
|
||||||
Once::new();
|
SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>, PreemptDisabled>,
|
||||||
|
> = Once::new();
|
||||||
|
|
||||||
#[init_component]
|
#[init_component]
|
||||||
fn init() -> Result<(), ComponentInitError> {
|
fn init() -> Result<(), ComponentInitError> {
|
||||||
@ -127,13 +136,13 @@ fn init() -> Result<(), ComponentInitError> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetDeviceIrqHandlerListRef = Arc<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>>>;
|
type NetDeviceIrqHandlerListRef = Arc<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>, PreemptDisabled>>;
|
||||||
type NetworkDeviceRef = Arc<SpinLock<dyn AnyNetworkDevice>>;
|
type NetworkDeviceRef = Arc<SpinLock<dyn AnyNetworkDevice, PreemptDisabled>>;
|
||||||
|
|
||||||
struct Component {
|
struct Component {
|
||||||
/// Device list, the key is device name, value is (callbacks, device);
|
/// Device list, the key is device name, value is (callbacks, device);
|
||||||
network_device_table:
|
network_device_table:
|
||||||
SpinLock<BTreeMap<String, (NetDeviceIrqHandlerListRef, NetworkDeviceRef)>>,
|
SpinLock<BTreeMap<String, (NetDeviceIrqHandlerListRef, NetworkDeviceRef)>, PreemptDisabled>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component {
|
impl Component {
|
||||||
|
@ -174,7 +174,7 @@ impl DeviceInner {
|
|||||||
info!("Virtio block device handle irq");
|
info!("Virtio block device handle irq");
|
||||||
// When we enter the IRQs handling function,
|
// When we enter the IRQs handling function,
|
||||||
// IRQs have already been disabled,
|
// IRQs have already been disabled,
|
||||||
// so there is no need to call `lock_irq_disabled`.
|
// so there is no need to call `disable_irq`.
|
||||||
loop {
|
loop {
|
||||||
// Pops the complete request
|
// Pops the complete request
|
||||||
let complete_request = {
|
let complete_request = {
|
||||||
@ -221,7 +221,7 @@ impl DeviceInner {
|
|||||||
// TODO: Most logic is the same as read and write, there should be a refactor.
|
// TODO: Most logic is the same as read and write, there should be a refactor.
|
||||||
// TODO: Should return an Err instead of panic if the device fails.
|
// TODO: Should return an Err instead of panic if the device fails.
|
||||||
fn request_device_id(&self) -> String {
|
fn request_device_id(&self) -> String {
|
||||||
let id = self.id_allocator.lock_irq_disabled().alloc().unwrap();
|
let id = self.id_allocator.disable_irq().lock().alloc().unwrap();
|
||||||
let req_slice = {
|
let req_slice = {
|
||||||
let req_slice = DmaStreamSlice::new(&self.block_requests, id * REQ_SIZE, REQ_SIZE);
|
let req_slice = DmaStreamSlice::new(&self.block_requests, id * REQ_SIZE, REQ_SIZE);
|
||||||
let req = BlockReq {
|
let req = BlockReq {
|
||||||
@ -250,7 +250,7 @@ impl DeviceInner {
|
|||||||
let device_id_slice = DmaStreamSlice::new(&device_id_stream, 0, MAX_ID_LENGTH);
|
let device_id_slice = DmaStreamSlice::new(&device_id_stream, 0, MAX_ID_LENGTH);
|
||||||
let outputs = vec![&device_id_slice, &resp_slice];
|
let outputs = vec![&device_id_slice, &resp_slice];
|
||||||
|
|
||||||
let mut queue = self.queue.lock_irq_disabled();
|
let mut queue = self.queue.disable_irq().lock();
|
||||||
let token = queue
|
let token = queue
|
||||||
.add_dma_buf(&[&req_slice], outputs.as_slice())
|
.add_dma_buf(&[&req_slice], outputs.as_slice())
|
||||||
.expect("add queue failed");
|
.expect("add queue failed");
|
||||||
@ -263,7 +263,7 @@ impl DeviceInner {
|
|||||||
queue.pop_used_with_token(token).expect("pop used failed");
|
queue.pop_used_with_token(token).expect("pop used failed");
|
||||||
|
|
||||||
resp_slice.sync().unwrap();
|
resp_slice.sync().unwrap();
|
||||||
self.id_allocator.lock_irq_disabled().free(id);
|
self.id_allocator.disable_irq().lock().free(id);
|
||||||
let resp: BlockResp = resp_slice.read_val(0).unwrap();
|
let resp: BlockResp = resp_slice.read_val(0).unwrap();
|
||||||
match RespStatus::try_from(resp.status).unwrap() {
|
match RespStatus::try_from(resp.status).unwrap() {
|
||||||
RespStatus::Ok => {}
|
RespStatus::Ok => {}
|
||||||
@ -288,7 +288,7 @@ impl DeviceInner {
|
|||||||
fn read(&self, bio_request: BioRequest) {
|
fn read(&self, bio_request: BioRequest) {
|
||||||
let dma_streams = Self::dma_stream_map(&bio_request);
|
let dma_streams = Self::dma_stream_map(&bio_request);
|
||||||
|
|
||||||
let id = self.id_allocator.lock_irq_disabled().alloc().unwrap();
|
let id = self.id_allocator.disable_irq().lock().alloc().unwrap();
|
||||||
let req_slice = {
|
let req_slice = {
|
||||||
let req_slice = DmaStreamSlice::new(&self.block_requests, id * REQ_SIZE, REQ_SIZE);
|
let req_slice = DmaStreamSlice::new(&self.block_requests, id * REQ_SIZE, REQ_SIZE);
|
||||||
let req = BlockReq {
|
let req = BlockReq {
|
||||||
@ -325,7 +325,7 @@ impl DeviceInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut queue = self.queue.lock_irq_disabled();
|
let mut queue = self.queue.disable_irq().lock();
|
||||||
if num_used_descs > queue.available_desc() {
|
if num_used_descs > queue.available_desc() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -339,7 +339,8 @@ impl DeviceInner {
|
|||||||
// Records the submitted request
|
// Records the submitted request
|
||||||
let submitted_request = SubmittedRequest::new(id as u16, bio_request, dma_streams);
|
let submitted_request = SubmittedRequest::new(id as u16, bio_request, dma_streams);
|
||||||
self.submitted_requests
|
self.submitted_requests
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.insert(token, submitted_request);
|
.insert(token, submitted_request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -349,7 +350,7 @@ impl DeviceInner {
|
|||||||
fn write(&self, bio_request: BioRequest) {
|
fn write(&self, bio_request: BioRequest) {
|
||||||
let dma_streams = Self::dma_stream_map(&bio_request);
|
let dma_streams = Self::dma_stream_map(&bio_request);
|
||||||
|
|
||||||
let id = self.id_allocator.lock_irq_disabled().alloc().unwrap();
|
let id = self.id_allocator.disable_irq().lock().alloc().unwrap();
|
||||||
let req_slice = {
|
let req_slice = {
|
||||||
let req_slice = DmaStreamSlice::new(&self.block_requests, id * REQ_SIZE, REQ_SIZE);
|
let req_slice = DmaStreamSlice::new(&self.block_requests, id * REQ_SIZE, REQ_SIZE);
|
||||||
let req = BlockReq {
|
let req = BlockReq {
|
||||||
@ -385,7 +386,7 @@ impl DeviceInner {
|
|||||||
panic!("The request size surpasses the queue size");
|
panic!("The request size surpasses the queue size");
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
let mut queue = self.queue.lock_irq_disabled();
|
let mut queue = self.queue.disable_irq().lock();
|
||||||
if num_used_descs > queue.available_desc() {
|
if num_used_descs > queue.available_desc() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -399,7 +400,8 @@ impl DeviceInner {
|
|||||||
// Records the submitted request
|
// Records the submitted request
|
||||||
let submitted_request = SubmittedRequest::new(id as u16, bio_request, dma_streams);
|
let submitted_request = SubmittedRequest::new(id as u16, bio_request, dma_streams);
|
||||||
self.submitted_requests
|
self.submitted_requests
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.insert(token, submitted_request);
|
.insert(token, submitted_request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ pub struct ConsoleDevice {
|
|||||||
|
|
||||||
impl AnyConsoleDevice for ConsoleDevice {
|
impl AnyConsoleDevice for ConsoleDevice {
|
||||||
fn send(&self, value: &[u8]) {
|
fn send(&self, value: &[u8]) {
|
||||||
let mut transmit_queue = self.transmit_queue.lock_irq_disabled();
|
let mut transmit_queue = self.transmit_queue.disable_irq().lock();
|
||||||
let mut reader = VmReader::from(value);
|
let mut reader = VmReader::from(value);
|
||||||
|
|
||||||
while reader.remain() > 0 {
|
while reader.remain() > 0 {
|
||||||
@ -106,10 +106,10 @@ impl ConsoleDevice {
|
|||||||
callbacks: RwLock::new(Vec::new()),
|
callbacks: RwLock::new(Vec::new()),
|
||||||
});
|
});
|
||||||
|
|
||||||
device.activate_receive_buffer(&mut device.receive_queue.lock_irq_disabled());
|
device.activate_receive_buffer(&mut device.receive_queue.disable_irq().lock());
|
||||||
|
|
||||||
// Register irq callbacks
|
// Register irq callbacks
|
||||||
let mut transport = device.transport.lock_irq_disabled();
|
let mut transport = device.transport.disable_irq().lock();
|
||||||
let handle_console_input = {
|
let handle_console_input = {
|
||||||
let device = device.clone();
|
let device = device.clone();
|
||||||
move |_: &TrapFrame| device.handle_recv_irq()
|
move |_: &TrapFrame| device.handle_recv_irq()
|
||||||
@ -129,7 +129,7 @@ impl ConsoleDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_recv_irq(&self) {
|
fn handle_recv_irq(&self) {
|
||||||
let mut receive_queue = self.receive_queue.lock_irq_disabled();
|
let mut receive_queue = self.receive_queue.disable_irq().lock();
|
||||||
|
|
||||||
let Ok((_, len)) = receive_queue.pop_used() else {
|
let Ok((_, len)) = receive_queue.pop_used() else {
|
||||||
return;
|
return;
|
||||||
|
@ -122,7 +122,7 @@ impl InputDevice {
|
|||||||
let input_prop = InputProp::from_bits(prop[0]).unwrap();
|
let input_prop = InputProp::from_bits(prop[0]).unwrap();
|
||||||
debug!("input device prop:{:?}", input_prop);
|
debug!("input device prop:{:?}", input_prop);
|
||||||
|
|
||||||
let mut transport = device.transport.lock_irq_disabled();
|
let mut transport = device.transport.disable_irq().lock();
|
||||||
fn config_space_change(_: &TrapFrame) {
|
fn config_space_change(_: &TrapFrame) {
|
||||||
debug!("input device config space change");
|
debug!("input device config space change");
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ impl InputDevice {
|
|||||||
|
|
||||||
/// Pop the pending event.
|
/// Pop the pending event.
|
||||||
fn pop_pending_events(&self, handle_event: &impl Fn(&EventBuf) -> bool) {
|
fn pop_pending_events(&self, handle_event: &impl Fn(&EventBuf) -> bool) {
|
||||||
let mut event_queue = self.event_queue.lock_irq_disabled();
|
let mut event_queue = self.event_queue.disable_irq().lock();
|
||||||
|
|
||||||
// one interrupt may contain several input events, so it should loop
|
// one interrupt may contain several input events, so it should loop
|
||||||
while let Ok((token, _)) = event_queue.pop_used() {
|
while let Ok((token, _)) = event_queue.pop_used() {
|
||||||
|
@ -21,18 +21,19 @@ pub fn register_device(name: String, device: Arc<SpinLock<SocketDevice>>) {
|
|||||||
VSOCK_DEVICE_TABLE
|
VSOCK_DEVICE_TABLE
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.insert(name, (Arc::new(SpinLock::new(Vec::new())), device));
|
.insert(name, (Arc::new(SpinLock::new(Vec::new())), device));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device(str: &str) -> Option<Arc<SpinLock<SocketDevice>>> {
|
pub fn get_device(str: &str) -> Option<Arc<SpinLock<SocketDevice>>> {
|
||||||
let lock = VSOCK_DEVICE_TABLE.get().unwrap().lock_irq_disabled();
|
let lock = VSOCK_DEVICE_TABLE.get().unwrap().disable_irq().lock();
|
||||||
let (_, device) = lock.get(str)?;
|
let (_, device) = lock.get(str)?;
|
||||||
Some(device.clone())
|
Some(device.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_devices() -> Vec<(String, Arc<SpinLock<SocketDevice>>)> {
|
pub fn all_devices() -> Vec<(String, Arc<SpinLock<SocketDevice>>)> {
|
||||||
let vsock_devs = VSOCK_DEVICE_TABLE.get().unwrap().lock_irq_disabled();
|
let vsock_devs = VSOCK_DEVICE_TABLE.get().unwrap().disable_irq().lock();
|
||||||
vsock_devs
|
vsock_devs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, (_, device))| (name.clone(), device.clone()))
|
.map(|(name, (_, device))| (name.clone(), device.clone()))
|
||||||
@ -40,19 +41,19 @@ pub fn all_devices() -> Vec<(String, Arc<SpinLock<SocketDevice>>)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_recv_callback(name: &str, callback: impl VsockDeviceIrqHandler) {
|
pub fn register_recv_callback(name: &str, callback: impl VsockDeviceIrqHandler) {
|
||||||
let lock = VSOCK_DEVICE_TABLE.get().unwrap().lock_irq_disabled();
|
let lock = VSOCK_DEVICE_TABLE.get().unwrap().disable_irq().lock();
|
||||||
let Some((callbacks, _)) = lock.get(name) else {
|
let Some((callbacks, _)) = lock.get(name) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
callbacks.lock_irq_disabled().push(Arc::new(callback));
|
callbacks.disable_irq().lock().push(Arc::new(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_recv_irq(name: &str) {
|
pub fn handle_recv_irq(name: &str) {
|
||||||
let lock = VSOCK_DEVICE_TABLE.get().unwrap().lock_irq_disabled();
|
let lock = VSOCK_DEVICE_TABLE.get().unwrap().disable_irq().lock();
|
||||||
let Some((callbacks, _)) = lock.get(name) else {
|
let Some((callbacks, _)) = lock.get(name) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let lock = callbacks.lock_irq_disabled();
|
let lock = callbacks.disable_irq().lock();
|
||||||
for callback in lock.iter() {
|
for callback in lock.iter() {
|
||||||
callback.call(())
|
callback.call(())
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use id_alloc::IdAlloc;
|
|||||||
use spin::Once;
|
use spin::Once;
|
||||||
use trapframe::TrapFrame;
|
use trapframe::TrapFrame;
|
||||||
|
|
||||||
use crate::sync::{Mutex, SpinLock, SpinLockGuard};
|
use crate::sync::{Mutex, PreemptDisabled, SpinLock, SpinLockGuard};
|
||||||
|
|
||||||
/// The global allocator for software defined IRQ lines.
|
/// The global allocator for software defined IRQ lines.
|
||||||
pub(crate) static IRQ_ALLOCATOR: Once<SpinLock<IdAlloc>> = Once::new();
|
pub(crate) static IRQ_ALLOCATOR: Once<SpinLock<IdAlloc>> = Once::new();
|
||||||
@ -101,7 +101,9 @@ impl IrqLine {
|
|||||||
self.irq_num
|
self.irq_num
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn callback_list(&self) -> SpinLockGuard<alloc::vec::Vec<CallbackElement>> {
|
pub fn callback_list(
|
||||||
|
&self,
|
||||||
|
) -> SpinLockGuard<alloc::vec::Vec<CallbackElement>, PreemptDisabled> {
|
||||||
self.callback_list.lock()
|
self.callback_list.lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,10 @@ pub type InputCallback = dyn Fn(u8) + Send + Sync + 'static;
|
|||||||
|
|
||||||
/// Registers a callback function to be called when there is console input.
|
/// Registers a callback function to be called when there is console input.
|
||||||
pub fn register_console_input_callback(f: &'static InputCallback) {
|
pub fn register_console_input_callback(f: &'static InputCallback) {
|
||||||
SERIAL_INPUT_CALLBACKS.lock_irq_disabled().push(Arc::new(f));
|
SERIAL_INPUT_CALLBACKS
|
||||||
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
|
.push(Arc::new(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Stdout;
|
struct Stdout;
|
||||||
@ -77,7 +80,8 @@ where
|
|||||||
CONSOLE_IRQ_CALLBACK
|
CONSOLE_IRQ_CALLBACK
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.on_active(callback);
|
.on_active(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ impl log::Log for Logger {
|
|||||||
// Use a global lock to prevent interleaving of log messages.
|
// Use a global lock to prevent interleaving of log messages.
|
||||||
use crate::sync::SpinLock;
|
use crate::sync::SpinLock;
|
||||||
static RECORD_LOCK: SpinLock<()> = SpinLock::new(());
|
static RECORD_LOCK: SpinLock<()> = SpinLock::new(());
|
||||||
let _lock = RECORD_LOCK.lock_irq_disabled();
|
let _lock = RECORD_LOCK.disable_irq().lock();
|
||||||
|
|
||||||
early_println!("{} {}: {}", timestamp, level, record_str);
|
early_println!("{} {}: {}", timestamp, level, record_str);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ pub fn init() {
|
|||||||
/// Checks whether the physical addresses has dma mapping.
|
/// Checks whether the physical addresses has dma mapping.
|
||||||
/// Fail if they have been mapped, otherwise insert them.
|
/// Fail if they have been mapped, otherwise insert them.
|
||||||
fn check_and_insert_dma_mapping(start_paddr: Paddr, num_pages: usize) -> bool {
|
fn check_and_insert_dma_mapping(start_paddr: Paddr, num_pages: usize) -> bool {
|
||||||
let mut mapping_set = DMA_MAPPING_SET.get().unwrap().lock_irq_disabled();
|
let mut mapping_set = DMA_MAPPING_SET.get().unwrap().disable_irq().lock();
|
||||||
// Ensure that the addresses used later will not overflow
|
// Ensure that the addresses used later will not overflow
|
||||||
start_paddr.checked_add(num_pages * PAGE_SIZE).unwrap();
|
start_paddr.checked_add(num_pages * PAGE_SIZE).unwrap();
|
||||||
for i in 0..num_pages {
|
for i in 0..num_pages {
|
||||||
@ -81,7 +81,7 @@ fn check_and_insert_dma_mapping(start_paddr: Paddr, num_pages: usize) -> bool {
|
|||||||
|
|
||||||
/// Removes a physical address from the dma mapping set.
|
/// Removes a physical address from the dma mapping set.
|
||||||
fn remove_dma_mapping(start_paddr: Paddr, num_pages: usize) {
|
fn remove_dma_mapping(start_paddr: Paddr, num_pages: usize) {
|
||||||
let mut mapping_set = DMA_MAPPING_SET.get().unwrap().lock_irq_disabled();
|
let mut mapping_set = DMA_MAPPING_SET.get().unwrap().disable_irq().lock();
|
||||||
// Ensure that the addresses used later will not overflow
|
// Ensure that the addresses used later will not overflow
|
||||||
start_paddr.checked_add(num_pages * PAGE_SIZE).unwrap();
|
start_paddr.checked_add(num_pages * PAGE_SIZE).unwrap();
|
||||||
for i in 0..num_pages {
|
for i in 0..num_pages {
|
||||||
|
@ -53,13 +53,14 @@ impl<const ORDER: usize> LockedHeapWithRescue<ORDER> {
|
|||||||
|
|
||||||
/// SAFETY: The range [start, start + size) must be a valid memory region.
|
/// SAFETY: The range [start, start + size) must be a valid memory region.
|
||||||
pub unsafe fn init(&self, start: *const u8, size: usize) {
|
pub unsafe fn init(&self, start: *const u8, size: usize) {
|
||||||
self.heap.lock_irq_disabled().init(start as usize, size);
|
self.heap.disable_irq().lock().init(start as usize, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SAFETY: The range [start, start + size) must be a valid memory region.
|
/// SAFETY: The range [start, start + size) must be a valid memory region.
|
||||||
unsafe fn add_to_heap(&self, start: usize, size: usize) {
|
unsafe fn add_to_heap(&self, start: usize, size: usize) {
|
||||||
self.heap
|
self.heap
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.add_to_heap(start, start + size)
|
.add_to_heap(start, start + size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,7 +89,8 @@ unsafe impl<const ORDER: usize> GlobalAlloc for LockedHeapWithRescue<ORDER> {
|
|||||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||||
debug_assert!(ptr as usize != 0);
|
debug_assert!(ptr as usize != 0);
|
||||||
self.heap
|
self.heap
|
||||||
.lock_irq_disabled()
|
.disable_irq()
|
||||||
|
.lock()
|
||||||
.dealloc(NonNull::new_unchecked(ptr), layout)
|
.dealloc(NonNull::new_unchecked(ptr), layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,6 @@ pub use self::{
|
|||||||
ArcRwMutexReadGuard, ArcRwMutexUpgradeableGuard, ArcRwMutexWriteGuard, RwMutex,
|
ArcRwMutexReadGuard, ArcRwMutexUpgradeableGuard, ArcRwMutexWriteGuard, RwMutex,
|
||||||
RwMutexReadGuard, RwMutexUpgradeableGuard, RwMutexWriteGuard,
|
RwMutexReadGuard, RwMutexUpgradeableGuard, RwMutexWriteGuard,
|
||||||
},
|
},
|
||||||
spin::{ArcSpinLockGuard, SpinLock, SpinLockGuard},
|
spin::{ArcSpinLockGuard, LocalIrqDisabled, PreemptDisabled, SpinLock, SpinLockGuard},
|
||||||
wait::{WaitQueue, Waiter, Waker},
|
wait::{WaitQueue, Waiter, Waker},
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,7 @@ impl RcuMonitor {
|
|||||||
// on the current CPU. If GP is complete, take the callbacks of the current
|
// on the current CPU. If GP is complete, take the callbacks of the current
|
||||||
// GP.
|
// GP.
|
||||||
let callbacks = {
|
let callbacks = {
|
||||||
let mut state = self.state.lock_irq_disabled();
|
let mut state = self.state.disable_irq().lock();
|
||||||
if state.current_gp.is_complete() {
|
if state.current_gp.is_complete() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ impl RcuMonitor {
|
|||||||
where
|
where
|
||||||
F: FnOnce() -> () + Send + 'static,
|
F: FnOnce() -> () + Send + 'static,
|
||||||
{
|
{
|
||||||
let mut state = self.state.lock_irq_disabled();
|
let mut state = self.state.disable_irq().lock();
|
||||||
|
|
||||||
state.next_callbacks.push_back(Box::new(f));
|
state.next_callbacks.push_back(Box::new(f));
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ use alloc::sync::Arc;
|
|||||||
use core::{
|
use core::{
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
fmt,
|
fmt,
|
||||||
|
marker::PhantomData,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
};
|
};
|
||||||
@ -16,65 +17,104 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// A spin lock.
|
/// A spin lock.
|
||||||
pub struct SpinLock<T: ?Sized> {
|
///
|
||||||
|
/// # Guard behavior
|
||||||
|
///
|
||||||
|
/// The type `G' specifies the guard behavior of the spin lock. While holding the lock,
|
||||||
|
/// - if `G` is [`PreemptDisabled`], preemption is disabled;
|
||||||
|
/// - if `G` is [`LocalIrqDisabled`], local IRQs are disabled.
|
||||||
|
///
|
||||||
|
/// The guard behavior can be temporarily upgraded from [`PreemptDisabled`] to
|
||||||
|
/// [`LocalIrqDisabled`] using the [`disable_irq`] method.
|
||||||
|
///
|
||||||
|
/// [`disable_irq`]: Self::disable_irq
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct SpinLock<T: ?Sized, G = PreemptDisabled> {
|
||||||
|
phantom: PhantomData<G>,
|
||||||
|
/// Only the last field of a struct may have a dynamically sized type.
|
||||||
|
/// That's why SpinLockInner is put in the last field.
|
||||||
|
inner: SpinLockInner<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpinLockInner<T: ?Sized> {
|
||||||
lock: AtomicBool,
|
lock: AtomicBool,
|
||||||
val: UnsafeCell<T>,
|
val: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SpinLock<T> {
|
/// A guardian that denotes the guard behavior for holding the spin lock.
|
||||||
|
pub trait Guardian {
|
||||||
|
/// The guard type.
|
||||||
|
type Guard;
|
||||||
|
|
||||||
|
/// Creates a new guard.
|
||||||
|
fn guard() -> Self::Guard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A guardian that disables preemption while holding the spin lock.
|
||||||
|
pub struct PreemptDisabled;
|
||||||
|
|
||||||
|
impl Guardian for PreemptDisabled {
|
||||||
|
type Guard = DisablePreemptGuard;
|
||||||
|
|
||||||
|
fn guard() -> Self::Guard {
|
||||||
|
disable_preempt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A guardian that disables IRQs while holding the spin lock.
|
||||||
|
///
|
||||||
|
/// This guardian would incur a certain time overhead over
|
||||||
|
/// [`PreemptDisabled']. So prefer avoiding using this guardian when
|
||||||
|
/// IRQ handlers are allowed to get executed while holding the
|
||||||
|
/// lock. For example, if a lock is never used in the interrupt
|
||||||
|
/// context, then it is ok not to use this guardian in the process context.
|
||||||
|
pub struct LocalIrqDisabled;
|
||||||
|
|
||||||
|
impl Guardian for LocalIrqDisabled {
|
||||||
|
type Guard = DisabledLocalIrqGuard;
|
||||||
|
|
||||||
|
fn guard() -> Self::Guard {
|
||||||
|
disable_local()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, G: Guardian> SpinLock<T, G> {
|
||||||
/// Creates a new spin lock.
|
/// Creates a new spin lock.
|
||||||
pub const fn new(val: T) -> Self {
|
pub const fn new(val: T) -> Self {
|
||||||
Self {
|
let lock_inner = SpinLockInner {
|
||||||
lock: AtomicBool::new(false),
|
lock: AtomicBool::new(false),
|
||||||
val: UnsafeCell::new(val),
|
val: UnsafeCell::new(val),
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
phantom: PhantomData,
|
||||||
|
inner: lock_inner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> SpinLock<T> {
|
impl<T: ?Sized> SpinLock<T, PreemptDisabled> {
|
||||||
/// Acquires the spin lock with disabling the local IRQs. This is the most secure
|
/// Converts the guard behavior from disabling preemption to disabling IRQs.
|
||||||
/// locking way.
|
pub fn disable_irq(&self) -> &SpinLock<T, LocalIrqDisabled> {
|
||||||
///
|
let ptr = self as *const SpinLock<T, PreemptDisabled>;
|
||||||
/// This method runs in a busy loop until the lock can be acquired.
|
let ptr = ptr as *const SpinLock<T, LocalIrqDisabled>;
|
||||||
/// After acquiring the spin lock, all interrupts are disabled.
|
// SAFETY:
|
||||||
pub fn lock_irq_disabled(&self) -> SpinLockGuard<T> {
|
// 1. The types `SpinLock<T, PreemptDisabled>`, `SpinLockInner<T>` and `SpinLock<T,
|
||||||
let guard = disable_local();
|
// IrqDisabled>` have the same memory layout guaranteed by `#[repr(transparent)]`.
|
||||||
|
// 2. The specified memory location can be borrowed as an immutable reference for the
|
||||||
|
// specified lifetime.
|
||||||
|
unsafe { &*ptr }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized, G: Guardian> SpinLock<T, G> {
|
||||||
|
/// Acquires the spin lock.
|
||||||
|
pub fn lock(&self) -> SpinLockGuard<T, G> {
|
||||||
|
// Notice the guard must be created before acquiring the lock.
|
||||||
|
let inner_guard = G::guard();
|
||||||
self.acquire_lock();
|
self.acquire_lock();
|
||||||
SpinLockGuard_ {
|
SpinLockGuard_ {
|
||||||
lock: self,
|
lock: self,
|
||||||
inner_guard: InnerGuard::IrqGuard(guard),
|
guard: inner_guard,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tries acquiring the spin lock immedidately with disabling the local IRQs.
|
|
||||||
pub fn try_lock_irq_disabled(&self) -> Option<SpinLockGuard<T>> {
|
|
||||||
let irq_guard = disable_local();
|
|
||||||
if self.try_acquire_lock() {
|
|
||||||
let lock_guard = SpinLockGuard_ {
|
|
||||||
lock: self,
|
|
||||||
inner_guard: InnerGuard::IrqGuard(irq_guard),
|
|
||||||
};
|
|
||||||
return Some(lock_guard);
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Acquires the spin lock without disabling local IRQs.
|
|
||||||
///
|
|
||||||
/// This method is twice as fast as the [`lock_irq_disabled`] method.
|
|
||||||
/// So prefer using this method over the [`lock_irq_disabled`] method
|
|
||||||
/// when IRQ handlers are allowed to get executed while
|
|
||||||
/// holding this lock. For example, if a lock is never used
|
|
||||||
/// in the interrupt context, then it is ok to use this method
|
|
||||||
/// in the process context.
|
|
||||||
///
|
|
||||||
/// [`lock_irq_disabled`]: Self::lock_irq_disabled
|
|
||||||
pub fn lock(&self) -> SpinLockGuard<T> {
|
|
||||||
let guard = disable_preempt();
|
|
||||||
self.acquire_lock();
|
|
||||||
SpinLockGuard_ {
|
|
||||||
lock: self,
|
|
||||||
inner_guard: InnerGuard::PreemptGuard(guard),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,22 +124,22 @@ impl<T: ?Sized> SpinLock<T> {
|
|||||||
/// for compile-time checked lifetimes of the lock guard.
|
/// for compile-time checked lifetimes of the lock guard.
|
||||||
///
|
///
|
||||||
/// [`lock`]: Self::lock
|
/// [`lock`]: Self::lock
|
||||||
pub fn lock_arc(self: &Arc<Self>) -> ArcSpinLockGuard<T> {
|
pub fn lock_arc(self: &Arc<Self>) -> ArcSpinLockGuard<T, G> {
|
||||||
let guard = disable_preempt();
|
let inner_guard = G::guard();
|
||||||
self.acquire_lock();
|
self.acquire_lock();
|
||||||
SpinLockGuard_ {
|
SpinLockGuard_ {
|
||||||
lock: self.clone(),
|
lock: self.clone(),
|
||||||
inner_guard: InnerGuard::PreemptGuard(guard),
|
guard: inner_guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries acquiring the spin lock immedidately without disabling the local IRQs.
|
/// Tries acquiring the spin lock immedidately.
|
||||||
pub fn try_lock(&self) -> Option<SpinLockGuard<T>> {
|
pub fn try_lock(&self) -> Option<SpinLockGuard<T, G>> {
|
||||||
let guard = disable_preempt();
|
let inner_guard = G::guard();
|
||||||
if self.try_acquire_lock() {
|
if self.try_acquire_lock() {
|
||||||
let lock_guard = SpinLockGuard_ {
|
let lock_guard = SpinLockGuard_ {
|
||||||
lock: self,
|
lock: self,
|
||||||
inner_guard: InnerGuard::PreemptGuard(guard),
|
guard: inner_guard,
|
||||||
};
|
};
|
||||||
return Some(lock_guard);
|
return Some(lock_guard);
|
||||||
}
|
}
|
||||||
@ -114,72 +154,75 @@ impl<T: ?Sized> SpinLock<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_acquire_lock(&self) -> bool {
|
fn try_acquire_lock(&self) -> bool {
|
||||||
self.lock
|
self.inner
|
||||||
|
.lock
|
||||||
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
|
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release_lock(&self) {
|
fn release_lock(&self) {
|
||||||
self.lock.store(false, Ordering::Release);
|
self.inner.lock.store(false, Ordering::Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + fmt::Debug> fmt::Debug for SpinLock<T> {
|
impl<T: ?Sized + fmt::Debug, G> fmt::Debug for SpinLock<T, G> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.val, f)
|
fmt::Debug::fmt(&self.inner.val, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: Only a single lock holder is permitted to access the inner data of Spinlock.
|
// SAFETY: Only a single lock holder is permitted to access the inner data of Spinlock.
|
||||||
unsafe impl<T: ?Sized + Send> Send for SpinLock<T> {}
|
unsafe impl<T: ?Sized + Send, G> Send for SpinLock<T, G> {}
|
||||||
unsafe impl<T: ?Sized + Send> Sync for SpinLock<T> {}
|
unsafe impl<T: ?Sized + Send, G> Sync for SpinLock<T, G> {}
|
||||||
|
|
||||||
enum InnerGuard {
|
|
||||||
IrqGuard(DisabledLocalIrqGuard),
|
|
||||||
PreemptGuard(DisablePreemptGuard),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A guard that provides exclusive access to the data protected by a [`SpinLock`].
|
/// A guard that provides exclusive access to the data protected by a [`SpinLock`].
|
||||||
pub type SpinLockGuard<'a, T> = SpinLockGuard_<T, &'a SpinLock<T>>;
|
pub type SpinLockGuard<'a, T, G> = SpinLockGuard_<T, &'a SpinLock<T, G>, G>;
|
||||||
/// A guard that provides exclusive access to the data protected by a `Arc<SpinLock>`.
|
/// A guard that provides exclusive access to the data protected by a `Arc<SpinLock>`.
|
||||||
pub type ArcSpinLockGuard<T> = SpinLockGuard_<T, Arc<SpinLock<T>>>;
|
pub type ArcSpinLockGuard<T, G> = SpinLockGuard_<T, Arc<SpinLock<T, G>>, G>;
|
||||||
|
|
||||||
/// The guard of a spin lock that disables the local IRQs.
|
/// The guard of a spin lock.
|
||||||
#[clippy::has_significant_drop]
|
#[clippy::has_significant_drop]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct SpinLockGuard_<T: ?Sized, R: Deref<Target = SpinLock<T>>> {
|
pub struct SpinLockGuard_<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> {
|
||||||
inner_guard: InnerGuard,
|
guard: G::Guard,
|
||||||
lock: R,
|
lock: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T>>> Deref for SpinLockGuard_<T, R> {
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> Deref for SpinLockGuard_<T, R, G> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
unsafe { &*self.lock.val.get() }
|
unsafe { &*self.lock.inner.val.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T>>> DerefMut for SpinLockGuard_<T, R> {
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> DerefMut
|
||||||
|
for SpinLockGuard_<T, R, G>
|
||||||
|
{
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *self.lock.val.get() }
|
unsafe { &mut *self.lock.inner.val.get() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T>>> Drop for SpinLockGuard_<T, R> {
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> Drop for SpinLockGuard_<T, R, G> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.lock.release_lock();
|
self.lock.release_lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized + fmt::Debug, R: Deref<Target = SpinLock<T>>> fmt::Debug for SpinLockGuard_<T, R> {
|
impl<T: ?Sized + fmt::Debug, R: Deref<Target = SpinLock<T, G>>, G: Guardian> fmt::Debug
|
||||||
|
for SpinLockGuard_<T, R, G>
|
||||||
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&**self, f)
|
fmt::Debug::fmt(&**self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, R: Deref<Target = SpinLock<T>>> !Send for SpinLockGuard_<T, R> {}
|
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: Guardian> !Send for SpinLockGuard_<T, R, G> {}
|
||||||
|
|
||||||
// SAFETY: `SpinLockGuard_` can be shared between tasks/threads in same CPU.
|
// SAFETY: `SpinLockGuard_` can be shared between tasks/threads in same CPU.
|
||||||
// As `lock()` is only called when there are no race conditions caused by interrupts.
|
// As `lock()` is only called when there are no race conditions caused by interrupts.
|
||||||
unsafe impl<T: ?Sized + Sync, R: Deref<Target = SpinLock<T>> + Sync> Sync for SpinLockGuard_<T, R> {}
|
unsafe impl<T: ?Sized + Sync, R: Deref<Target = SpinLock<T, G>> + Sync, G: Guardian> Sync
|
||||||
|
for SpinLockGuard_<T, R, G>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -123,7 +123,7 @@ impl WaitQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut wakers = self.wakers.lock_irq_disabled();
|
let mut wakers = self.wakers.disable_irq().lock();
|
||||||
let Some(waker) = wakers.pop_front() else {
|
let Some(waker) = wakers.pop_front() else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@ -147,7 +147,7 @@ impl WaitQueue {
|
|||||||
let mut num_woken = 0;
|
let mut num_woken = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut wakers = self.wakers.lock_irq_disabled();
|
let mut wakers = self.wakers.disable_irq().lock();
|
||||||
let Some(waker) = wakers.pop_front() else {
|
let Some(waker) = wakers.pop_front() else {
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@ -171,7 +171,7 @@ impl WaitQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn enqueue(&self, waker: Arc<Waker>) {
|
fn enqueue(&self, waker: Arc<Waker>) {
|
||||||
let mut wakers = self.wakers.lock_irq_disabled();
|
let mut wakers = self.wakers.disable_irq().lock();
|
||||||
wakers.push_back(waker);
|
wakers.push_back(waker);
|
||||||
self.num_wakers.fetch_add(1, Ordering::Acquire);
|
self.num_wakers.fetch_add(1, Ordering::Acquire);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ impl<T: FifoSchedInfo + Send + Sync> Scheduler<T> for FifoScheduler<T> {
|
|||||||
cpu_id
|
cpu_id
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut rq = self.rq[target_cpu as usize].lock_irq_disabled();
|
let mut rq = self.rq[target_cpu as usize].disable_irq().lock();
|
||||||
if still_in_rq && let Err(_) = runnable.cpu().set_if_is_none(target_cpu) {
|
if still_in_rq && let Err(_) = runnable.cpu().set_if_is_none(target_cpu) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -61,12 +61,12 @@ impl<T: FifoSchedInfo + Send + Sync> Scheduler<T> for FifoScheduler<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<T>)) {
|
fn local_rq_with(&self, f: &mut dyn FnMut(&dyn LocalRunQueue<T>)) {
|
||||||
let local_rq: &FifoRunQueue<T> = &self.rq[this_cpu() as usize].lock_irq_disabled();
|
let local_rq: &FifoRunQueue<T> = &self.rq[this_cpu() as usize].disable_irq().lock();
|
||||||
f(local_rq);
|
f(local_rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_mut_rq_with(&self, f: &mut dyn FnMut(&mut dyn LocalRunQueue<T>)) {
|
fn local_mut_rq_with(&self, f: &mut dyn FnMut(&mut dyn LocalRunQueue<T>)) {
|
||||||
let local_rq: &mut FifoRunQueue<T> = &mut self.rq[this_cpu() as usize].lock_irq_disabled();
|
let local_rq: &mut FifoRunQueue<T> = &mut self.rq[this_cpu() as usize].disable_irq().lock();
|
||||||
f(local_rq);
|
f(local_rq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user