mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 12:16:31 +00:00
增加内存分配日志监视器 (#424)
* 完成内存日志监视,并输出日志到文件 * 修复进程退出后,procfs查看进程status文件会崩溃的问题 * 修复signal唤醒进程的判断条件问题
This commit is contained in:
@ -10,13 +10,17 @@ edition = "2021"
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[workspace]
|
||||
members = [ "src/libs/intertrait" ]
|
||||
members = [
|
||||
"crates/*",
|
||||
"src/libs/intertrait"
|
||||
]
|
||||
|
||||
[features]
|
||||
default = ["backtrace"]
|
||||
# 内核栈回溯
|
||||
backtrace = []
|
||||
|
||||
|
||||
# 运行时依赖项
|
||||
[dependencies]
|
||||
x86 = "0.52.0"
|
||||
@ -25,8 +29,6 @@ bit_field = "0.10"
|
||||
bitflags = "1.3.2"
|
||||
bitfield-struct = "0.5.3"
|
||||
virtio-drivers = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/virtio-drivers.git", rev = "f1d1cbb" }
|
||||
# 一个无锁MPSC队列
|
||||
thingbuf = { version = "0.1.3", default-features = false, features = ["alloc"] }
|
||||
smoltcp = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/smoltcp.git", rev = "9027825", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
|
||||
# num-traits 0.2.15
|
||||
num-traits = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/num-traits.git", rev="1597c1c", default-features = false }
|
||||
@ -35,7 +37,6 @@ num-derive = "0.3"
|
||||
# 一个no_std的hashmap、hashset
|
||||
hashbrown = "0.13.2"
|
||||
elf = { version = "0.7.2", default-features = false }
|
||||
memoffset = "0.9.0"
|
||||
atomic_enum = "0.2.0"
|
||||
raw-cpuid = "11.0.1"
|
||||
acpi = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/acpi-rs.git", rev = "fb69243dcf" }
|
||||
@ -43,6 +44,9 @@ intertrait = { path = "src/libs/intertrait" }
|
||||
linkme = "0.2"
|
||||
ida = { path = "src/libs/ida" }
|
||||
mini-backtrace = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/mini-backtrace.git", rev = "ba98506685" }
|
||||
klog_types = { path = "crates/klog_types" }
|
||||
kdepends = { path = "crates/kdepends" }
|
||||
|
||||
|
||||
# 构建时依赖项
|
||||
[build-dependencies]
|
||||
|
@ -90,7 +90,6 @@ impl CFilesBuilder {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
c.define("__x86_64__", None);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn setup_global_include_dir(c: &mut Build) {
|
||||
|
@ -1,22 +1,9 @@
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
|
||||
#![feature(const_for)]
|
||||
#![feature(const_mut_refs)]
|
||||
#![feature(const_trait_impl)]
|
||||
#[cfg(test)]
|
||||
extern crate std;
|
||||
|
||||
pub mod crc64;
|
||||
pub mod tables;
|
||||
|
||||
pub fn add(left: usize, right: usize) -> usize {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
|
18
kernel/crates/kdepends/Cargo.toml
Normal file
18
kernel/crates/kdepends/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "kdepends"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "需要导出的依赖项(为保持内核依赖版本与调试器依赖项版本相同,因此把公共依赖项写在这里)"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
memoffset = "0.9.0"
|
||||
crc = { path = "../crc" }
|
||||
|
||||
# 一个无锁MPSC队列
|
||||
[dependencies.thingbuf]
|
||||
git = "https://git.mirrors.dragonos.org/DragonOS-Community/thingbuf.git"
|
||||
rev = "2dded730c3"
|
||||
default-features = false
|
||||
features = ["alloc", "static"]
|
9
kernel/crates/kdepends/src/lib.rs
Normal file
9
kernel/crates/kdepends/src/lib.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#![no_std]
|
||||
|
||||
#[allow(unused)]
|
||||
#[macro_use]
|
||||
pub extern crate thingbuf;
|
||||
|
||||
pub extern crate memoffset;
|
||||
|
||||
pub extern crate crc;
|
9
kernel/crates/klog_types/Cargo.toml
Normal file
9
kernel/crates/klog_types/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "klog_types"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
kdepends = { path = "../kdepends" }
|
241
kernel/crates/klog_types/src/lib.rs
Normal file
241
kernel/crates/klog_types/src/lib.rs
Normal file
@ -0,0 +1,241 @@
|
||||
#![no_std]
|
||||
#![feature(const_refs_to_cell)]
|
||||
#![feature(const_size_of_val)]
|
||||
|
||||
extern crate alloc;
|
||||
use core::{fmt::Debug, mem::size_of_val};
|
||||
|
||||
use alloc::format;
|
||||
use kdepends::{memoffset::offset_of, thingbuf::StaticThingBuf};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct AllocatorLog {
|
||||
/// 日志的id
|
||||
pub id: u64,
|
||||
/// 日志类型
|
||||
pub type_: AllocatorLogType,
|
||||
/// 日志的时间
|
||||
pub time: u64,
|
||||
|
||||
/// 日志的来源
|
||||
pub source: LogSource,
|
||||
|
||||
/// 日志的来源pid
|
||||
pub pid: Option<usize>,
|
||||
|
||||
pub checksum: u64,
|
||||
}
|
||||
|
||||
impl AllocatorLog {
|
||||
/// 创建一个日志
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `id`:日志的id
|
||||
/// - `type_`:日志类型
|
||||
/// - `source`:日志来源
|
||||
/// - `pid`:日志来源的pid
|
||||
/// - `time`:日志的时间
|
||||
pub fn new(
|
||||
id: u64,
|
||||
type_: AllocatorLogType,
|
||||
source: LogSource,
|
||||
pid: Option<usize>,
|
||||
time: u64,
|
||||
) -> Self {
|
||||
let mut x = Self {
|
||||
id,
|
||||
type_,
|
||||
time,
|
||||
source,
|
||||
pid,
|
||||
checksum: 0,
|
||||
};
|
||||
let checksum = Self::calculate_checksum(&x);
|
||||
x.checksum = checksum;
|
||||
return x;
|
||||
}
|
||||
|
||||
pub const fn zeroed() -> Self {
|
||||
return Self {
|
||||
id: 0,
|
||||
type_: AllocatorLogType::Undefined,
|
||||
time: 0,
|
||||
source: LogSource::Undefined,
|
||||
pid: None,
|
||||
checksum: 0,
|
||||
};
|
||||
}
|
||||
|
||||
/// 计算日志的校验和
|
||||
pub fn calculate_checksum(value: &Self) -> u64 {
|
||||
let buf = unsafe {
|
||||
core::slice::from_raw_parts(
|
||||
value as *const _ as *const u8,
|
||||
core::mem::size_of::<Self>() - core::mem::size_of::<u64>(),
|
||||
)
|
||||
};
|
||||
let checksum = kdepends::crc::crc64::crc64_be(0, buf);
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/// 验证日志的校验和
|
||||
pub fn validate_checksum(&self) -> bool {
|
||||
let checksum = Self::calculate_checksum(self);
|
||||
return checksum == self.checksum;
|
||||
}
|
||||
|
||||
/// 当前日志是否有效
|
||||
pub fn is_valid(&self) -> bool {
|
||||
if self.validate_checksum() == false {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.id == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for AllocatorLog {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
|
||||
return self.id.partial_cmp(&other.id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for AllocatorLog {
|
||||
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
|
||||
return self.id.cmp(&other.id);
|
||||
}
|
||||
}
|
||||
|
||||
/// 内存分配器日志类型
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum AllocatorLogType {
|
||||
Undefined,
|
||||
Alloc(AllocLogItem),
|
||||
AllocZeroed(AllocLogItem),
|
||||
Free(AllocLogItem),
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct AllocLogItem {
|
||||
pub layout: core::alloc::Layout,
|
||||
pub vaddr: Option<usize>,
|
||||
pub paddr: Option<usize>,
|
||||
}
|
||||
|
||||
impl AllocLogItem {
|
||||
pub fn new(layout: core::alloc::Layout, vaddr: Option<usize>, paddr: Option<usize>) -> Self {
|
||||
return Self {
|
||||
layout,
|
||||
vaddr,
|
||||
paddr,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for AllocLogItem {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("AllocLogItem")
|
||||
.field("layout", &self.layout)
|
||||
.field(
|
||||
"vaddr",
|
||||
&format_args!("{:#x}", *self.vaddr.as_ref().unwrap_or(&0)),
|
||||
)
|
||||
.field(
|
||||
"paddr",
|
||||
&format_args!("{:#x}", self.paddr.as_ref().unwrap_or(&0)),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum LogSource {
|
||||
Undefined = 0,
|
||||
Bump = 1,
|
||||
Buddy = 2,
|
||||
Slab = 3,
|
||||
}
|
||||
|
||||
pub struct MMLogCycle;
|
||||
|
||||
impl MMLogCycle {
|
||||
pub const fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl kdepends::thingbuf::Recycle<AllocatorLog> for MMLogCycle {
|
||||
fn new_element(&self) -> AllocatorLog {
|
||||
AllocatorLog::zeroed()
|
||||
}
|
||||
|
||||
fn recycle(&self, element: &mut AllocatorLog) {
|
||||
*element = AllocatorLog::zeroed();
|
||||
}
|
||||
}
|
||||
|
||||
/// 内存分配器日志通道
|
||||
#[repr(C)]
|
||||
pub struct MMLogChannel<const CAP: usize> {
|
||||
pub magic: u32,
|
||||
/// 日志元素的大小
|
||||
pub element_size: u32,
|
||||
/// 日志通道每个槽的大小(字节)
|
||||
pub slot_size: u32,
|
||||
pub capacity: u64,
|
||||
pub slots_offset: u64,
|
||||
pub buf: StaticThingBuf<AllocatorLog, CAP, MMLogCycle>,
|
||||
}
|
||||
|
||||
impl<const CAP: usize> Debug for MMLogChannel<CAP> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("MMLogChannel")
|
||||
.field("magic", &format!("{:#x}", self.magic))
|
||||
.field("element_size", &self.element_size)
|
||||
.field("capacity", &self.capacity)
|
||||
.field("slots_offset", &self.slots_offset)
|
||||
.field(
|
||||
"buf",
|
||||
&format!(
|
||||
"StaticThingBuf<AllocatorLog, {}, MMLogCycle>",
|
||||
self.capacity
|
||||
),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const CAP: usize> MMLogChannel<CAP> {
|
||||
/// 日志通道的魔数
|
||||
pub const MM_LOG_CHANNEL_MAGIC: u32 = 0x4d4c4348;
|
||||
|
||||
/// 创建一个大小为`capacity`日志通道
|
||||
pub const fn new(capacity: usize) -> Self {
|
||||
let buffer = StaticThingBuf::with_recycle(MMLogCycle::new());
|
||||
assert!(buffer.offset_of_slots() != 0);
|
||||
let slot_total_size = size_of_val(&buffer) - buffer.offset_of_slots();
|
||||
let slot_size = slot_total_size / capacity;
|
||||
assert!(slot_size != 0);
|
||||
assert!(slot_size > size_of_val(&AllocatorLog::zeroed()));
|
||||
|
||||
let r = Self {
|
||||
magic: Self::MM_LOG_CHANNEL_MAGIC,
|
||||
element_size: core::mem::size_of::<AllocatorLog>() as u32,
|
||||
capacity: capacity as u64,
|
||||
slot_size: slot_size as u32,
|
||||
slots_offset: (offset_of!(MMLogChannel<CAP>, buf) + buffer.offset_of_slots()) as u64,
|
||||
buf: buffer,
|
||||
};
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ use alloc::{
|
||||
vec::Vec,
|
||||
};
|
||||
|
||||
use memoffset::offset_of;
|
||||
use kdepends::memoffset::offset_of;
|
||||
use x86::{controlregs::Cr4, segmentation::SegmentSelector};
|
||||
|
||||
use crate::{
|
||||
|
@ -4,7 +4,7 @@ use core::{
|
||||
sync::atomic::{compiler_fence, AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
use memoffset::offset_of;
|
||||
use kdepends::memoffset::offset_of;
|
||||
|
||||
use crate::{
|
||||
arch::process::table::TSSManager, exception::InterruptArch,
|
||||
|
78
kernel/src/debug/klog/mm.rs
Normal file
78
kernel/src/debug/klog/mm.rs
Normal file
@ -0,0 +1,78 @@
|
||||
extern crate klog_types;
|
||||
|
||||
use core::intrinsics::unlikely;
|
||||
|
||||
use klog_types::{AllocatorLog, AllocatorLogType, LogSource, MMLogChannel};
|
||||
|
||||
use crate::{
|
||||
arch::CurrentTimeArch,
|
||||
process::{Pid, ProcessManager},
|
||||
time::TimeArch,
|
||||
};
|
||||
|
||||
/// 全局的内存分配器日志通道
|
||||
///
|
||||
/// 标记为`no_mangle`是为了让调试器能够找到这个变量
|
||||
#[no_mangle]
|
||||
static __MM_ALLOCATOR_LOG_CHANNEL: MMLogChannel<{ MMDebugLogManager::MAX_ALLOC_LOG_NUM }> =
|
||||
MMLogChannel::new(MMDebugLogManager::MAX_ALLOC_LOG_NUM);
|
||||
|
||||
/// 全局的内存分配器日志id分配器
|
||||
///
|
||||
/// id从1开始, 因为0是无效的id
|
||||
static __MM_DEBUG_LOG_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX);
|
||||
|
||||
/// 记录内存分配器的日志
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `log_type`:日志类型
|
||||
/// - `source`:日志来源
|
||||
pub fn mm_debug_log(log_type: AllocatorLogType, source: LogSource) {
|
||||
let pid = if unlikely(!ProcessManager::initialized()) {
|
||||
Some(Pid::new(0))
|
||||
} else {
|
||||
Some(ProcessManager::current_pcb().pid())
|
||||
};
|
||||
MMDebugLogManager::log(log_type, source, pid);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct MMDebugLogManager;
|
||||
|
||||
impl MMDebugLogManager {
|
||||
/// 最大的内存分配器日志数量
|
||||
pub const MAX_ALLOC_LOG_NUM: usize = 100000;
|
||||
|
||||
/// 记录内存分配器的日志
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `log_type`:日志类型
|
||||
/// - `source`:日志来源
|
||||
/// - `pid`:日志来源的pid
|
||||
pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) {
|
||||
let id = __MM_DEBUG_LOG_IDA.alloc().unwrap();
|
||||
let log = AllocatorLog::new(
|
||||
id as u64,
|
||||
log_type,
|
||||
source,
|
||||
pid.map(|p| p.data()),
|
||||
CurrentTimeArch::get_cycles() as u64,
|
||||
);
|
||||
|
||||
let mut log = log;
|
||||
loop {
|
||||
let r = __MM_ALLOCATOR_LOG_CHANNEL.buf.push(log);
|
||||
if let Err(r) = r {
|
||||
// 如果日志通道满了,就把最早的日志丢弃
|
||||
if __MM_ALLOCATOR_LOG_CHANNEL.buf.remaining() == 0 {
|
||||
__MM_ALLOCATOR_LOG_CHANNEL.buf.pop();
|
||||
}
|
||||
log = r.into_inner();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
kernel/src/debug/klog/mod.rs
Normal file
1
kernel/src/debug/klog/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod mm;
|
1
kernel/src/debug/mod.rs
Normal file
1
kernel/src/debug/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod klog;
|
@ -26,7 +26,7 @@ use crate::{
|
||||
use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable};
|
||||
|
||||
/// 平台设备id分配器
|
||||
static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(i32::MAX as usize);
|
||||
static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(0, i32::MAX as usize);
|
||||
|
||||
#[inline(always)]
|
||||
pub fn platform_device_manager() -> &'static PlatformDeviceManager {
|
||||
|
@ -2,7 +2,7 @@ use core::intrinsics::unlikely;
|
||||
|
||||
use alloc::string::String;
|
||||
|
||||
use thingbuf::mpsc::{
|
||||
use kdepends::thingbuf::mpsc::{
|
||||
self,
|
||||
errors::{TryRecvError, TrySendError},
|
||||
};
|
||||
|
@ -179,23 +179,24 @@ impl ProcFSInode {
|
||||
);
|
||||
pdata.append(&mut format!("\nvrtime:\t{}", vrtime).as_bytes().to_owned());
|
||||
|
||||
let binding = pcb.basic().user_vm().unwrap();
|
||||
let address_space_guard = binding.read();
|
||||
// todo: 当前进程运行过程中占用内存的峰值
|
||||
let hiwater_vm: u64 = 0;
|
||||
// 进程代码段的大小
|
||||
let text = (address_space_guard.end_code - address_space_guard.start_code) / 1024;
|
||||
// 进程数据段的大小
|
||||
let data = (address_space_guard.end_data - address_space_guard.start_data) / 1024;
|
||||
drop(address_space_guard);
|
||||
if let Some(user_vm) = pcb.basic().user_vm() {
|
||||
let address_space_guard = user_vm.read();
|
||||
// todo: 当前进程运行过程中占用内存的峰值
|
||||
let hiwater_vm: u64 = 0;
|
||||
// 进程代码段的大小
|
||||
let text = (address_space_guard.end_code - address_space_guard.start_code) / 1024;
|
||||
// 进程数据段的大小
|
||||
let data = (address_space_guard.end_data - address_space_guard.start_data) / 1024;
|
||||
drop(address_space_guard);
|
||||
pdata.append(
|
||||
&mut format!("\nVmPeak:\t{} kB", hiwater_vm)
|
||||
.as_bytes()
|
||||
.to_owned(),
|
||||
);
|
||||
pdata.append(&mut format!("\nVmData:\t{} kB", data).as_bytes().to_owned());
|
||||
pdata.append(&mut format!("\nVmExe:\t{} kB", text).as_bytes().to_owned());
|
||||
}
|
||||
|
||||
pdata.append(
|
||||
&mut format!("\nVmPeak:\t{} kB", hiwater_vm)
|
||||
.as_bytes()
|
||||
.to_owned(),
|
||||
);
|
||||
pdata.append(&mut format!("\nVmData:\t{} kB", data).as_bytes().to_owned());
|
||||
pdata.append(&mut format!("\nVmExe:\t{} kB", text).as_bytes().to_owned());
|
||||
pdata.append(
|
||||
&mut format!("\nflags: {:?}\n", pcb.flags().clone())
|
||||
.as_bytes()
|
||||
|
@ -50,10 +50,13 @@ impl Signal {
|
||||
kwarn!("No such process.");
|
||||
return retval;
|
||||
}
|
||||
|
||||
let pcb = pcb.unwrap();
|
||||
// println!("Target pcb = {:?}", pcb.as_ref().unwrap());
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
// 发送信号
|
||||
retval = self.send_signal(info, pcb.unwrap(), PidType::PID);
|
||||
retval = self.send_signal(info, pcb.clone(), PidType::PID);
|
||||
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
return retval;
|
||||
}
|
||||
@ -282,8 +285,33 @@ fn signal_wake_up(pcb: Arc<ProcessControlBlock>, _guard: SpinLockGuard<SignalStr
|
||||
// 如果不是 fatal 的就只唤醒 stop 的进程来响应
|
||||
// kdebug!("signal_wake_up");
|
||||
// 如果目标进程已经在运行,则发起一个ipi,使得它陷入内核
|
||||
let r = ProcessManager::wakeup_stop(&pcb);
|
||||
if r.is_ok() {
|
||||
let state = pcb.sched_info().state();
|
||||
let mut wakeup_ok = true;
|
||||
if state.is_blocked_interruptable() {
|
||||
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
|
||||
wakeup_ok = false;
|
||||
kwarn!(
|
||||
"Current pid: {:?}, signal_wake_up target {:?} error: {:?}",
|
||||
ProcessManager::current_pcb().pid(),
|
||||
pcb.pid(),
|
||||
e
|
||||
);
|
||||
});
|
||||
} else if state.is_stopped() {
|
||||
ProcessManager::wakeup_stop(&pcb).unwrap_or_else(|e| {
|
||||
wakeup_ok = false;
|
||||
kwarn!(
|
||||
"Current pid: {:?}, signal_wake_up target {:?} error: {:?}",
|
||||
ProcessManager::current_pcb().pid(),
|
||||
pcb.pid(),
|
||||
e
|
||||
);
|
||||
});
|
||||
} else {
|
||||
wakeup_ok = false;
|
||||
}
|
||||
|
||||
if wakeup_ok {
|
||||
ProcessManager::kick(&pcb);
|
||||
} else {
|
||||
if fatal {
|
||||
|
@ -39,6 +39,7 @@ mod arch;
|
||||
mod libs;
|
||||
#[macro_use]
|
||||
mod include;
|
||||
mod debug;
|
||||
mod driver; // 如果driver依赖了libs,应该在libs后面导出
|
||||
mod exception;
|
||||
mod filesystem;
|
||||
@ -60,17 +61,17 @@ extern crate bitflags;
|
||||
extern crate elf;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate memoffset;
|
||||
extern crate num;
|
||||
#[macro_use]
|
||||
extern crate num_derive;
|
||||
extern crate smoltcp;
|
||||
extern crate thingbuf;
|
||||
#[macro_use]
|
||||
extern crate intertrait;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
extern crate x86;
|
||||
|
||||
extern crate klog_types;
|
||||
|
||||
use crate::mm::allocator::kernel_allocator::KernelAllocator;
|
||||
|
||||
use crate::process::ProcessManager;
|
||||
|
@ -16,9 +16,9 @@ pub struct IdAllocator {
|
||||
|
||||
impl IdAllocator {
|
||||
/// 创建一个新的id分配器
|
||||
pub const fn new(max_id: usize) -> Self {
|
||||
pub const fn new(initial_id: usize, max_id: usize) -> Self {
|
||||
Self {
|
||||
current_id: AtomicUsize::new(0),
|
||||
current_id: AtomicUsize::new(initial_id),
|
||||
max_id,
|
||||
dead: AtomicBool::new(false),
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
use klog_types::AllocLogItem;
|
||||
|
||||
use crate::{
|
||||
arch::mm::LockedFrameAllocator,
|
||||
debug::klog::mm::mm_debug_log,
|
||||
libs::align::page_align_up,
|
||||
mm::{MMArch, MemoryManagementArch, VirtAddr},
|
||||
};
|
||||
@ -81,15 +84,46 @@ impl LocalAlloc for KernelAllocator {
|
||||
/// 为内核slab分配器实现GlobalAlloc特性
|
||||
unsafe impl GlobalAlloc for KernelAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
return self.local_alloc(layout);
|
||||
let r = self.local_alloc(layout);
|
||||
mm_debug_log(
|
||||
klog_types::AllocatorLogType::Alloc(AllocLogItem::new(
|
||||
layout.clone(),
|
||||
Some(r as usize),
|
||||
None,
|
||||
)),
|
||||
klog_types::LogSource::Buddy,
|
||||
);
|
||||
|
||||
return r;
|
||||
|
||||
// self.local_alloc_zeroed(layout, 0)
|
||||
}
|
||||
|
||||
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
|
||||
self.local_alloc_zeroed(layout)
|
||||
let r = self.local_alloc_zeroed(layout);
|
||||
|
||||
mm_debug_log(
|
||||
klog_types::AllocatorLogType::AllocZeroed(AllocLogItem::new(
|
||||
layout.clone(),
|
||||
Some(r as usize),
|
||||
None,
|
||||
)),
|
||||
klog_types::LogSource::Buddy,
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
mm_debug_log(
|
||||
klog_types::AllocatorLogType::Free(AllocLogItem::new(
|
||||
layout.clone(),
|
||||
Some(ptr as usize),
|
||||
None,
|
||||
)),
|
||||
klog_types::LogSource::Buddy,
|
||||
);
|
||||
|
||||
self.local_dealloc(ptr, layout);
|
||||
}
|
||||
}
|
||||
|
@ -121,6 +121,11 @@ impl ProcessManager {
|
||||
kinfo!("Process Manager initialized.");
|
||||
}
|
||||
|
||||
/// 判断进程管理器是否已经初始化完成
|
||||
pub fn initialized() -> bool {
|
||||
unsafe { __PROCESS_MANAGEMENT_INIT_DONE }
|
||||
}
|
||||
|
||||
/// 获取当前进程的pcb
|
||||
pub fn current_pcb() -> Arc<ProcessControlBlock> {
|
||||
if unlikely(unsafe { !__PROCESS_MANAGEMENT_INIT_DONE }) {
|
||||
@ -461,6 +466,11 @@ impl ProcessState {
|
||||
return matches!(self, ProcessState::Blocked(_));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_blocked_interruptable(&self) -> bool {
|
||||
return matches!(self, ProcessState::Blocked(true));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_exited(&self) -> bool {
|
||||
return matches!(self, ProcessState::Exited(_));
|
||||
|
Reference in New Issue
Block a user