feat(ida): IDA内部改为使用XArray实现 (#934)

目前可以记录哪些ID已经分配,支持了ID释放的功能.

Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
LoGin
2024-09-25 11:20:52 +08:00
committed by GitHub
parent 9ad34ef277
commit 013ffb708f
20 changed files with 273 additions and 83 deletions

View File

@ -0,0 +1,11 @@
# ID分配
:::{note}
本文作者:龙进 <longjin@DragonOS.org>
2024年9月25日
:::
内核提供了一个名为`IdAllocator`的ID分配器位于`kernel/crates/ida`中。
它能够分配、释放ID。默认它会自增分配假如ID大于设定的最大值它会从最小值开始寻找空闲ID。如果没有空闲的ID则会分配失败。

View File

@ -10,4 +10,5 @@
lib_ui/scm lib_ui/scm
lib_ui/textui lib_ui/textui
unified-init unified-init
id-allocation

View File

@ -39,7 +39,7 @@ elf = { version = "=0.7.2", default-features = false }
fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" } fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" }
# 一个no_std的hashmap、hashset # 一个no_std的hashmap、hashset
hashbrown = "=0.13.2" hashbrown = "=0.13.2"
ida = { path = "src/libs/ida" } ida = { path = "crates/ida" }
intertrait = { path = "crates/intertrait" } intertrait = { path = "crates/intertrait" }
kdepends = { path = "crates/kdepends" } kdepends = { path = "crates/kdepends" }
klog_types = { path = "crates/klog_types" } klog_types = { path = "crates/klog_types" }
@ -57,7 +57,6 @@ wait_queue_macros = { path = "crates/wait_queue_macros" }
paste = "=1.0.14" paste = "=1.0.14"
slabmalloc = { path = "crates/rust-slabmalloc" } slabmalloc = { path = "crates/rust-slabmalloc" }
log = "0.4.21" log = "0.4.21"
xarray = "0.1.0"
lru = "0.12.3" lru = "0.12.3"
# target为x86_64时使用下面的依赖 # target为x86_64时使用下面的依赖

View File

@ -3,7 +3,7 @@ name = "ida"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
authors = ["longjin <longjin@dragonos.org>"] authors = ["longjin <longjin@dragonos.org>"]
description = "一个基于XArray的ID分配器"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
kdepends = { path = "../kdepends" }

View File

@ -0,0 +1,3 @@
# IDA
一个基于XArray的ID分配器

View File

@ -0,0 +1,210 @@
#![no_std]
#![feature(core_intrinsics)]
#![allow(internal_features)]
#![allow(clippy::needless_return)]
#[cfg(test)]
#[macro_use]
extern crate std;
use core::cmp::min;
use core::intrinsics::unlikely;
use core::marker::PhantomData;
use core::ops::Deref;
struct EmptyIdaItemRef<'a> {
_marker: PhantomData<&'a EmptyIdaItem>,
}
impl<'a> Deref for EmptyIdaItemRef<'a> {
type Target = EmptyIdaItem;
fn deref(&self) -> &Self::Target {
&EmptyIdaItem
}
}
struct EmptyIdaItem;
unsafe impl kdepends::xarray::ItemEntry for EmptyIdaItem {
type Ref<'a> = EmptyIdaItemRef<'a> where Self: 'a;
fn into_raw(self) -> *const () {
core::ptr::null()
}
unsafe fn from_raw(_raw: *const ()) -> Self {
EmptyIdaItem
}
unsafe fn raw_as_ref<'a>(_raw: *const ()) -> Self::Ref<'a> {
EmptyIdaItemRef {
_marker: PhantomData,
}
}
}
/// id分配器
pub struct IdAllocator {
current_id: usize,
min_id: usize,
max_id: usize,
used: usize,
xarray: kdepends::xarray::XArray<EmptyIdaItem>,
}
impl IdAllocator {
/// 创建一个新的id分配器
pub const fn new(initial_id: usize, max_id: usize) -> Option<Self> {
if initial_id >= max_id {
return None;
}
Some(Self {
current_id: initial_id,
min_id: initial_id,
max_id,
used: 0,
xarray: kdepends::xarray::XArray::new(),
})
}
/// 可用的id数量
#[inline]
pub fn available(&self) -> usize {
self.max_id - self.min_id - self.used
}
/// 分配一个新的id
///
/// ## 返回
///
/// 如果分配成功返回Some(id)否则返回None
pub fn alloc(&mut self) -> Option<usize> {
if unlikely(self.available() == 0) {
return None;
}
if let Some(try1) = self.do_find_first_free_index(self.current_id, self.max_id) {
self.current_id = try1;
self.xarray.store(try1 as u64, EmptyIdaItem);
self.used += 1;
return Some(try1);
}
// 从头开始找
if let Some(try2) =
self.do_find_first_free_index(self.min_id, min(self.current_id, self.max_id))
{
self.current_id = try2;
self.xarray.store(try2 as u64, EmptyIdaItem);
self.used += 1;
return Some(try2);
}
return None;
}
/// 检查id是否存在
///
/// ## 参数
///
/// - `id`要检查的id
///
/// ## 返回
///
/// 如果id存在返回true否则返回false
pub fn exists(&self, id: usize) -> bool {
if id < self.min_id || id >= self.max_id {
return false;
}
self.xarray.load(id as u64).is_some()
}
fn do_find_first_free_index(&self, start_id: usize, end: usize) -> Option<usize> {
(start_id..end).find(|&i| !self.exists(i))
}
/// 释放一个id
///
/// ## 参数
///
/// - `id`要释放的id
pub fn free(&mut self, id: usize) {
if id < self.min_id || id >= self.max_id {
return;
}
if self.xarray.remove(id as u64).is_some() {
self.used -= 1;
}
}
/// 返回已经使用的id数量
pub fn used(&self) -> usize {
self.used
}
}
impl core::fmt::Debug for IdAllocator {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("IdAllocator")
.field("current_id", &self.current_id)
.field("min_id", &self.min_id)
.field("max_id", &self.max_id)
.field("used", &self.used)
.field("xarray", &"xarray<()>")
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_fail() {
assert_eq!(IdAllocator::new(10, 10).is_none(), true);
assert_eq!(IdAllocator::new(11, 10).is_none(), true);
}
#[test]
fn test_new_success() {
assert_eq!(IdAllocator::new(9, 10).is_some(), true);
assert_eq!(IdAllocator::new(0, 10).is_some(), true);
}
#[test]
fn test_id_allocator() {
let mut ida = IdAllocator::new(0, 10).unwrap();
assert_eq!(ida.alloc(), Some(0));
assert_eq!(ida.alloc(), Some(1));
assert_eq!(ida.alloc(), Some(2));
assert_eq!(ida.alloc(), Some(3));
assert_eq!(ida.alloc(), Some(4));
assert_eq!(ida.alloc(), Some(5));
assert_eq!(ida.alloc(), Some(6));
assert_eq!(ida.alloc(), Some(7));
assert_eq!(ida.alloc(), Some(8));
assert_eq!(ida.alloc(), Some(9));
assert_eq!(ida.alloc(), None);
for i in 0..10 {
assert_eq!(ida.exists(i), true);
}
ida.free(5);
for i in 0..10 {
if i == 5 {
assert_eq!(ida.exists(i), false);
} else {
assert_eq!(ida.exists(i), true);
}
}
assert_eq!(ida.used(), 9);
assert_eq!(ida.alloc(), Some(5));
assert_eq!(ida.alloc(), None);
assert_eq!(ida.used(), 10);
for i in 0..10 {
ida.free(i);
}
assert_eq!(ida.used(), 0);
}
}

View File

@ -7,9 +7,10 @@ description = "需要导出的依赖项(为保持内核依赖版本与调试
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
ringbuffer = "0.15.0"
memoffset = "0.9.0"
crc = { path = "../crc" } crc = { path = "../crc" }
memoffset = "0.9.0"
ringbuffer = "0.15.0"
xarray = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/xarray", rev = "de93b57c34", features = ["slab-friendly"] }
# 一个无锁MPSC队列 # 一个无锁MPSC队列
[dependencies.thingbuf] [dependencies.thingbuf]

View File

@ -7,3 +7,4 @@ pub extern crate memoffset;
pub extern crate ringbuffer; pub extern crate ringbuffer;
pub extern crate crc; pub extern crate crc;
pub extern crate xarray;

View File

@ -4,7 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use klog_types::{AllocatorLog, AllocatorLogType, LogSource, MMLogChannel}; use klog_types::{AllocatorLog, AllocatorLogType, LogSource, MMLogChannel};
use crate::{arch::CurrentTimeArch, process::Pid, time::TimeArch}; use crate::{arch::CurrentTimeArch, libs::spinlock::SpinLock, process::Pid, time::TimeArch};
/// 全局的内存分配器日志通道 /// 全局的内存分配器日志通道
/// ///
@ -16,7 +16,8 @@ static __MM_ALLOCATOR_LOG_CHANNEL: MMLogChannel<{ MMDebugLogManager::MAX_ALLOC_L
/// 全局的内存分配器日志id分配器 /// 全局的内存分配器日志id分配器
/// ///
/// id从1开始, 因为0是无效的id /// id从1开始, 因为0是无效的id
static __MM_DEBUG_LOG_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX); static __MM_DEBUG_LOG_IDA: SpinLock<ida::IdAllocator> =
SpinLock::new(ida::IdAllocator::new(1, usize::MAX).unwrap());
/// 记录内存分配器的日志 /// 记录内存分配器的日志
/// ///
@ -50,7 +51,7 @@ impl MMDebugLogManager {
/// - `pid`日志来源的pid /// - `pid`日志来源的pid
#[allow(dead_code)] #[allow(dead_code)]
pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) { pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) {
let id = __MM_DEBUG_LOG_IDA.alloc().unwrap(); let id = __MM_DEBUG_LOG_IDA.lock_irqsave().alloc().unwrap();
let log = AllocatorLog::new( let log = AllocatorLog::new(
id as u64, id as u64,
log_type, log_type,

View File

@ -27,7 +27,8 @@ use system_error::SystemError;
use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable}; use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable};
/// 平台设备id分配器 /// 平台设备id分配器
static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(0, i32::MAX as usize); static PLATFORM_DEVID_IDA: SpinLock<IdAllocator> =
SpinLock::new(IdAllocator::new(0, i32::MAX as usize).unwrap());
#[inline(always)] #[inline(always)]
pub fn platform_device_manager() -> &'static PlatformDeviceManager { pub fn platform_device_manager() -> &'static PlatformDeviceManager {
@ -93,7 +94,10 @@ impl PlatformDeviceManager {
pdev.set_name(pdev.pdev_name().to_string()); pdev.set_name(pdev.pdev_name().to_string());
} }
PLATFORM_DEVID_AUTO => { PLATFORM_DEVID_AUTO => {
let id = PLATFORM_DEVID_IDA.alloc().ok_or(SystemError::EOVERFLOW)?; let id = PLATFORM_DEVID_IDA
.lock()
.alloc()
.ok_or(SystemError::EOVERFLOW)?;
pdev.set_pdev_id(id as i32); pdev.set_pdev_id(id as i32);
pdev.set_pdev_id_auto(true); pdev.set_pdev_id_auto(true);
pdev.set_name(format!("{}.{}.auto", pdev.pdev_name(), pdev.pdev_id().0)); pdev.set_name(format!("{}.{}.auto", pdev.pdev_name(), pdev.pdev_id().0));
@ -112,7 +116,7 @@ impl PlatformDeviceManager {
// failed // failed
let pdevid = pdev.pdev_id(); let pdevid = pdev.pdev_id();
if pdevid.1 { if pdevid.1 {
PLATFORM_DEVID_IDA.free(pdevid.0 as usize); PLATFORM_DEVID_IDA.lock().free(pdevid.0 as usize);
pdev.set_pdev_id(PLATFORM_DEVID_AUTO); pdev.set_pdev_id(PLATFORM_DEVID_AUTO);
} }

View File

@ -34,7 +34,8 @@ use super::{
GeneralRtcPriority, RtcClassOps, RtcDevice, GeneralRtcPriority, RtcClassOps, RtcDevice,
}; };
static RTC_GENERAL_DEVICE_IDA: IdAllocator = IdAllocator::new(0, usize::MAX); static RTC_GENERAL_DEVICE_IDA: SpinLock<IdAllocator> =
SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap());
pub(super) const RTC_HCTOSYS_DEVICE: &str = "rtc0"; pub(super) const RTC_HCTOSYS_DEVICE: &str = "rtc0";
@ -63,7 +64,7 @@ impl RtcGeneralDevice {
/// ///
/// 注意,由于还需要进行其他的初始化操作,因此这个函数并不是公开的构造函数。 /// 注意,由于还需要进行其他的初始化操作,因此这个函数并不是公开的构造函数。
fn new(priority: GeneralRtcPriority) -> Arc<Self> { fn new(priority: GeneralRtcPriority) -> Arc<Self> {
let id = RTC_GENERAL_DEVICE_IDA.alloc().unwrap(); let id = RTC_GENERAL_DEVICE_IDA.lock().alloc().unwrap();
let name = format!("rtc{}", id); let name = format!("rtc{}", id);
Arc::new(Self { Arc::new(Self {
name, name,
@ -106,7 +107,7 @@ impl RtcGeneralDevice {
impl Drop for RtcGeneralDevice { impl Drop for RtcGeneralDevice {
fn drop(&mut self) { fn drop(&mut self) {
RTC_GENERAL_DEVICE_IDA.free(self.id); RTC_GENERAL_DEVICE_IDA.lock().free(self.id);
} }
} }

View File

@ -30,6 +30,7 @@ use crate::{
vfs::syscall::ModeType, vfs::syscall::ModeType,
}, },
init::initcall::INITCALL_CORE, init::initcall::INITCALL_CORE,
libs::spinlock::SpinLock,
}; };
use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_DEV_ANY_ID}; use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_DEV_ANY_ID};
@ -255,7 +256,7 @@ pub struct VirtIODeviceIndexManager {
// ID分配器 // ID分配器
/// ///
/// ID分配器用于分配唯一的索引给VirtIO设备。 /// ID分配器用于分配唯一的索引给VirtIO设备。
ida: IdAllocator, ida: SpinLock<IdAllocator>,
} }
// VirtIO设备索引管理器的新建实例 // VirtIO设备索引管理器的新建实例
@ -265,7 +266,7 @@ impl VirtIODeviceIndexManager {
/// 创建一个新的VirtIO设备索引管理器实例初始时分配器从0开始直到最大usize值。 /// 创建一个新的VirtIO设备索引管理器实例初始时分配器从0开始直到最大usize值。
const fn new() -> Self { const fn new() -> Self {
Self { Self {
ida: IdAllocator::new(0, usize::MAX), ida: SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap()),
} }
} }
@ -273,7 +274,7 @@ impl VirtIODeviceIndexManager {
/// ///
/// 分配一个唯一的索引给VirtIO设备。 /// 分配一个唯一的索引给VirtIO设备。
pub fn alloc(&self) -> VirtIODeviceIndex { pub fn alloc(&self) -> VirtIODeviceIndex {
VirtIODeviceIndex(self.ida.alloc().unwrap()) VirtIODeviceIndex(self.ida.lock().alloc().unwrap())
} }
// 释放一个VirtIO设备索引 // 释放一个VirtIO设备索引
@ -281,7 +282,7 @@ impl VirtIODeviceIndexManager {
/// 释放之前分配的VirtIO设备索引使其可以被重新使用。 /// 释放之前分配的VirtIO设备索引使其可以被重新使用。
#[allow(dead_code)] #[allow(dead_code)]
pub fn free(&self, index: VirtIODeviceIndex) { pub fn free(&self, index: VirtIODeviceIndex) {
self.ida.free(index.0); self.ida.lock().free(index.0);
} }
} }

View File

@ -41,7 +41,7 @@ const PTY_NR_LIMIT: usize = 4096;
pub struct DevPtsFs { pub struct DevPtsFs {
/// 根节点 /// 根节点
root_inode: Arc<LockedDevPtsFSInode>, root_inode: Arc<LockedDevPtsFSInode>,
pts_ida: IdAllocator, pts_ida: SpinLock<IdAllocator>,
pts_count: AtomicU32, pts_count: AtomicU32,
} }
@ -50,7 +50,7 @@ impl DevPtsFs {
let root_inode = Arc::new(LockedDevPtsFSInode::new()); let root_inode = Arc::new(LockedDevPtsFSInode::new());
let ret = Arc::new(Self { let ret = Arc::new(Self {
root_inode, root_inode,
pts_ida: IdAllocator::new(1, NR_UNIX98_PTY_MAX as usize), pts_ida: SpinLock::new(IdAllocator::new(1, NR_UNIX98_PTY_MAX as usize).unwrap()),
pts_count: AtomicU32::new(0), pts_count: AtomicU32::new(0),
}); });
@ -60,7 +60,7 @@ impl DevPtsFs {
} }
pub fn alloc_index(&self) -> Result<usize, SystemError> { pub fn alloc_index(&self) -> Result<usize, SystemError> {
self.pts_ida.alloc().ok_or(SystemError::ENOSPC) self.pts_ida.lock().alloc().ok_or(SystemError::ENOSPC)
} }
} }

View File

@ -15,7 +15,8 @@ use core::any::Any;
use ida::IdAllocator; use ida::IdAllocator;
use system_error::SystemError; use system_error::SystemError;
static EVENTFD_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, u32::MAX as usize); static EVENTFD_ID_ALLOCATOR: SpinLock<IdAllocator> =
SpinLock::new(IdAllocator::new(0, u32::MAX as usize).unwrap());
bitflags! { bitflags! {
pub struct EventFdFlags: u32{ pub struct EventFdFlags: u32{
@ -251,7 +252,10 @@ impl Syscall {
/// See: https://man7.org/linux/man-pages/man2/eventfd2.2.html /// See: https://man7.org/linux/man-pages/man2/eventfd2.2.html
pub fn sys_eventfd(init_val: u32, flags: u32) -> Result<usize, SystemError> { pub fn sys_eventfd(init_val: u32, flags: u32) -> Result<usize, SystemError> {
let flags = EventFdFlags::from_bits(flags).ok_or(SystemError::EINVAL)?; let flags = EventFdFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
let id = EVENTFD_ID_ALLOCATOR.alloc().ok_or(SystemError::ENOMEM)? as u32; let id = EVENTFD_ID_ALLOCATOR
.lock()
.alloc()
.ok_or(SystemError::ENOMEM)? as u32;
let eventfd = EventFd::new(init_val as u64, flags, id); let eventfd = EventFd::new(init_val as u64, flags, id);
let inode = Arc::new(EventFdInode::new(eventfd)); let inode = Arc::new(EventFdInode::new(eventfd));
let filemode = if flags.contains(EventFdFlags::EFD_CLOEXEC) { let filemode = if flags.contains(EventFdFlags::EFD_CLOEXEC) {

View File

@ -5,9 +5,9 @@ use alloc::{
sync::{Arc, Weak}, sync::{Arc, Weak},
vec::Vec, vec::Vec,
}; };
use kdepends::xarray::XArray;
use log::error; use log::error;
use system_error::SystemError; use system_error::SystemError;
use xarray::XArray;
use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData};
use crate::filesystem::eventfd::EventFdInode; use crate::filesystem::eventfd::EventFdInode;

View File

@ -125,7 +125,7 @@ pub struct ShmManager {
impl ShmManager { impl ShmManager {
pub fn new() -> Self { pub fn new() -> Self {
ShmManager { ShmManager {
id_allocator: IdAllocator::new(0, usize::MAX - 1), id_allocator: IdAllocator::new(0, usize::MAX - 1).unwrap(),
id2shm: HashMap::new(), id2shm: HashMap::new(),
key2id: HashMap::new(), key2id: HashMap::new(),
} }

View File

@ -6,6 +6,7 @@
#![feature(concat_idents)] #![feature(concat_idents)]
#![feature(const_for)] #![feature(const_for)]
#![feature(const_mut_refs)] #![feature(const_mut_refs)]
#![feature(const_option)]
#![feature(const_trait_impl)] #![feature(const_trait_impl)]
#![feature(const_refs_to_cell)] #![feature(const_refs_to_cell)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]

View File

@ -1,52 +0,0 @@
#![no_std]
#![feature(core_intrinsics)]
#![allow(internal_features)]
#![allow(clippy::needless_return)]
use core::intrinsics::unlikely;
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
/// id分配器
///
/// TODO: 当前只是为了简单实现功能将来这里应使用类似linux的ida的方式去实现
#[derive(Debug)]
pub struct IdAllocator {
current_id: AtomicUsize,
max_id: usize,
dead: AtomicBool,
}
impl IdAllocator {
/// 创建一个新的id分配器
pub const fn new(initial_id: usize, max_id: usize) -> Self {
Self {
current_id: AtomicUsize::new(initial_id),
max_id,
dead: AtomicBool::new(false),
}
}
/// 分配一个新的id
///
/// ## 返回
///
/// 如果分配成功返回Some(id)否则返回None
pub fn alloc(&self) -> Option<usize> {
if unlikely(self.dead.load(Ordering::SeqCst)) {
return None;
}
let ret = self.current_id.fetch_add(1, Ordering::SeqCst);
// 如果id溢出panic
if ret == self.max_id {
self.dead.store(true, Ordering::SeqCst);
return None;
}
return Some(ret);
}
pub fn free(&self, _id: usize) {
// todo: free
}
}

View File

@ -54,7 +54,8 @@ use super::{
pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536; pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536;
/// LockedVMA的id分配器 /// LockedVMA的id分配器
static LOCKEDVMA_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, usize::MAX); static LOCKEDVMA_ID_ALLOCATOR: SpinLock<IdAllocator> =
SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap());
#[derive(Debug)] #[derive(Debug)]
pub struct AddressSpace { pub struct AddressSpace {
@ -1097,7 +1098,7 @@ impl Eq for LockedVMA {}
impl LockedVMA { impl LockedVMA {
pub fn new(vma: VMA) -> Arc<Self> { pub fn new(vma: VMA) -> Arc<Self> {
let r = Arc::new(Self { let r = Arc::new(Self {
id: LOCKEDVMA_ID_ALLOCATOR.alloc().unwrap(), id: LOCKEDVMA_ID_ALLOCATOR.lock().alloc().unwrap(),
vma: SpinLock::new(vma), vma: SpinLock::new(vma),
}); });
r.vma.lock_irqsave().self_ref = Arc::downgrade(&r); r.vma.lock_irqsave().self_ref = Arc::downgrade(&r);
@ -1316,7 +1317,7 @@ impl LockedVMA {
impl Drop for LockedVMA { impl Drop for LockedVMA {
fn drop(&mut self) { fn drop(&mut self) {
LOCKEDVMA_ID_ALLOCATOR.free(self.id); LOCKEDVMA_ID_ALLOCATOR.lock().free(self.id);
} }
} }

View File

@ -1,6 +1,8 @@
use ida::IdAllocator; use ida::IdAllocator;
use smoltcp::iface::SocketHandle; use smoltcp::iface::SocketHandle;
use crate::libs::spinlock::SpinLock;
int_like!(KernelHandle, usize); int_like!(KernelHandle, usize);
/// # socket的句柄管理组件 /// # socket的句柄管理组件
@ -12,7 +14,8 @@ pub enum GlobalSocketHandle {
Kernel(KernelHandle), Kernel(KernelHandle),
} }
static KERNEL_HANDLE_IDA: IdAllocator = IdAllocator::new(0, usize::MAX); static KERNEL_HANDLE_IDA: SpinLock<IdAllocator> =
SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap());
impl GlobalSocketHandle { impl GlobalSocketHandle {
pub fn new_smoltcp_handle(handle: SocketHandle) -> Self { pub fn new_smoltcp_handle(handle: SocketHandle) -> Self {
@ -20,7 +23,7 @@ impl GlobalSocketHandle {
} }
pub fn new_kernel_handle() -> Self { pub fn new_kernel_handle() -> Self {
return Self::Kernel(KernelHandle::new(KERNEL_HANDLE_IDA.alloc().unwrap())); return Self::Kernel(KernelHandle::new(KERNEL_HANDLE_IDA.lock().alloc().unwrap()));
} }
pub fn smoltcp_handle(&self) -> Option<SocketHandle> { pub fn smoltcp_handle(&self) -> Option<SocketHandle> {