mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 16:16:16 +04:00
Fixed stack overflow caused by large struct initialization on stack
This commit is contained in:
parent
f807c951d6
commit
54504eb317
@ -62,7 +62,7 @@ isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers", f
|
|||||||
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "dfa70e14" }
|
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "dfa70e14" }
|
||||||
lazy_static = { version = "1.4", features = ["spin_no_std"] }
|
lazy_static = { version = "1.4", features = ["spin_no_std"] }
|
||||||
smoltcp = { git = "https://github.com/rcore-os/smoltcp", rev = "5bd87c7c", default-features = false, features = ["alloc", "log", "ethernet", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] }
|
smoltcp = { git = "https://github.com/rcore-os/smoltcp", rev = "5bd87c7c", default-features = false, features = ["alloc", "log", "ethernet", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] }
|
||||||
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator" }
|
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev="03bd990" }
|
||||||
rcore-console = { git = "https://github.com/rcore-os/rcore-console", rev = "b7bacf9", default-features = false }
|
rcore-console = { git = "https://github.com/rcore-os/rcore-console", rev = "b7bacf9", default-features = false }
|
||||||
rcore-memory = { path = "../crate/memory" }
|
rcore-memory = { path = "../crate/memory" }
|
||||||
rcore-thread = { git = "https://github.com/rcore-os/rcore-thread", rev = "d727949b" }
|
rcore-thread = { git = "https://github.com/rcore-os/rcore-thread", rev = "d727949b" }
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
#![feature(optin_builtin_traits)]
|
#![feature(optin_builtin_traits)]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
#![feature(global_asm)]
|
#![feature(global_asm)]
|
||||||
|
#![feature(negative_impls)]
|
||||||
#![feature(alloc_prelude)]
|
#![feature(alloc_prelude)]
|
||||||
|
#![feature(const_fn)]
|
||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
#![deny(stable_features)]
|
#![deny(stable_features)]
|
||||||
#![deny(unused_unsafe)]
|
#![deny(unused_unsafe)]
|
||||||
|
@ -48,10 +48,7 @@ pub type FrameAlloc = bitmap_allocator::BitAlloc1M;
|
|||||||
#[cfg(feature = "board_k210")]
|
#[cfg(feature = "board_k210")]
|
||||||
pub type FrameAlloc = bitmap_allocator::BitAlloc4K;
|
pub type FrameAlloc = bitmap_allocator::BitAlloc4K;
|
||||||
|
|
||||||
lazy_static! {
|
pub static FRAME_ALLOCATOR: SpinNoIrqLock<FrameAlloc> = SpinNoIrqLock::new(FrameAlloc::DEFAULT);
|
||||||
pub static ref FRAME_ALLOCATOR: SpinNoIrqLock<FrameAlloc> =
|
|
||||||
SpinNoIrqLock::new(FrameAlloc::default());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert physical address to virtual address
|
/// Convert physical address to virtual address
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -32,7 +32,8 @@ use crate::processor;
|
|||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering, AtomicU8};
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
pub type SpinLock<T> = Mutex<T, Spin>;
|
pub type SpinLock<T> = Mutex<T, Spin>;
|
||||||
pub type SpinNoIrqLock<T> = Mutex<T, SpinNoIrq>;
|
pub type SpinNoIrqLock<T> = Mutex<T, SpinNoIrq>;
|
||||||
@ -40,7 +41,8 @@ pub type SleepLock<T> = Mutex<T, Condvar>;
|
|||||||
|
|
||||||
pub struct Mutex<T: ?Sized, S: MutexSupport> {
|
pub struct Mutex<T: ?Sized, S: MutexSupport> {
|
||||||
lock: AtomicBool,
|
lock: AtomicBool,
|
||||||
support: S,
|
support: MaybeUninit<S>,
|
||||||
|
support_initialization: AtomicU8, // 0 = uninitialized, 1 = initializing, 2 = initialized
|
||||||
user: UnsafeCell<(usize, usize)>, // (cid, tid)
|
user: UnsafeCell<(usize, usize)>, // (cid, tid)
|
||||||
data: UnsafeCell<T>,
|
data: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
@ -75,11 +77,12 @@ impl<T, S: MutexSupport> Mutex<T, S> {
|
|||||||
/// drop(lock);
|
/// drop(lock);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new(user_data: T) -> Mutex<T, S> {
|
pub const fn new(user_data: T) -> Mutex<T, S> {
|
||||||
Mutex {
|
Mutex {
|
||||||
lock: AtomicBool::new(false),
|
lock: AtomicBool::new(false),
|
||||||
data: UnsafeCell::new(user_data),
|
data: UnsafeCell::new(user_data),
|
||||||
support: S::new(),
|
support: MaybeUninit::uninit(),
|
||||||
|
support_initialization: AtomicU8::new(0),
|
||||||
user: UnsafeCell::new((0, 0)),
|
user: UnsafeCell::new((0, 0)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +102,7 @@ impl<T: ?Sized, S: MutexSupport> Mutex<T, S> {
|
|||||||
let mut try_count = 0;
|
let mut try_count = 0;
|
||||||
// Wait until the lock looks unlocked before retrying
|
// Wait until the lock looks unlocked before retrying
|
||||||
while self.lock.load(Ordering::Relaxed) {
|
while self.lock.load(Ordering::Relaxed) {
|
||||||
self.support.cpu_relax();
|
unsafe { &*self.support.as_ptr() }.cpu_relax();
|
||||||
try_count += 1;
|
try_count += 1;
|
||||||
if try_count == 0x100000 {
|
if try_count == 0x100000 {
|
||||||
let (cid, tid) = unsafe { *self.user.get() };
|
let (cid, tid) = unsafe { *self.user.get() };
|
||||||
@ -132,6 +135,9 @@ impl<T: ?Sized, S: MutexSupport> Mutex<T, S> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn lock(&self) -> MutexGuard<T, S> {
|
pub fn lock(&self) -> MutexGuard<T, S> {
|
||||||
let support_guard = S::before_lock();
|
let support_guard = S::before_lock();
|
||||||
|
|
||||||
|
self.ensure_support();
|
||||||
|
|
||||||
self.obtain_lock();
|
self.obtain_lock();
|
||||||
MutexGuard {
|
MutexGuard {
|
||||||
mutex: self,
|
mutex: self,
|
||||||
@ -139,6 +145,24 @@ impl<T: ?Sized, S: MutexSupport> Mutex<T, S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ensure_support(&self) {
|
||||||
|
let initialization = self.support_initialization.load(Ordering::Relaxed);
|
||||||
|
if(initialization == 2) { return };
|
||||||
|
if(
|
||||||
|
initialization == 1
|
||||||
|
|| self.support_initialization.compare_and_swap(0, 1, Ordering::Acquire) != 0
|
||||||
|
) {
|
||||||
|
// Wait for another thread to initialize
|
||||||
|
while self.support_initialization.load(Ordering::Acquire) == 1 {
|
||||||
|
core::sync::atomic::spin_loop_hint();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// My turn to initialize
|
||||||
|
(unsafe { core::ptr::write(self.support.as_ptr() as *mut _, S::new()) });
|
||||||
|
self.support_initialization.store(2, Ordering::Release);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Force unlock the spinlock.
|
/// Force unlock the spinlock.
|
||||||
///
|
///
|
||||||
/// This is *extremely* unsafe if the lock is not held by the current
|
/// This is *extremely* unsafe if the lock is not held by the current
|
||||||
@ -201,7 +225,7 @@ impl<'a, T: ?Sized, S: MutexSupport> Drop for MutexGuard<'a, T, S> {
|
|||||||
/// The dropping of the MutexGuard will release the lock it was created from.
|
/// The dropping of the MutexGuard will release the lock it was created from.
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.mutex.lock.store(false, Ordering::Release);
|
self.mutex.lock.store(false, Ordering::Release);
|
||||||
self.mutex.support.after_unlock();
|
unsafe { &*self.mutex.support.as_ptr() }.after_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user