Compare commits
No commits in common. "master" and "feature/week1-core-implementations" have entirely different histories.
master
...
feature/we
|
|
@ -695,6 +695,20 @@ dependencies = [
|
|||
"spin 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nos-tests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hashbrown 0.16.1",
|
||||
"log",
|
||||
"nos-api",
|
||||
"nos-error-handling",
|
||||
"nos-memory-management",
|
||||
"nos-services",
|
||||
"nos-syscalls",
|
||||
"spin 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[workspace]
|
||||
members = ["kernel", "xtask", "user", "benchmarks/microbench", "bootloader", "nos-memory-management", "nos-api", "nos-syscalls", "nos-services", "nos-error-handling"]
|
||||
members = ["kernel", "xtask", "user", "benchmarks/microbench", "bootloader", "nos-memory-management", "nos-api", "nos-syscalls", "nos-services", "nos-error-handling", "tests"]
|
||||
default-members = ["kernel", "xtask"]
|
||||
resolver = "2"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
extern crate alloc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
// BIOS Memory Detection and Configuration
|
||||
//
|
||||
// This module provides comprehensive memory detection and configuration
|
||||
// support for BIOS bootloader, including E820 memory map scanning,
|
||||
// A20 gate handling, and extended memory detection.
|
||||
//! BIOS Memory Detection and Configuration
|
||||
//!
|
||||
//! This module provides comprehensive memory detection and configuration
|
||||
//! support for BIOS bootloader, including E820 memory map scanning,
|
||||
//! A20 gate handling, and extended memory detection.
|
||||
|
||||
use crate::utils::error::{BootError, Result};
|
||||
use crate::protocol::bios::{MemoryMap, MemoryMapEntry, MemoryType};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
use crate::utils::error::{BootError, Result};
|
||||
use crate::memory::MemoryRegionType;
|
||||
use core::ptr;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
|
||||
|
||||
|
|
@ -64,7 +63,7 @@ impl UefiMemoryManager {
|
|||
uefi::table::boot::AllocateType::AnyPages,
|
||||
memory_type,
|
||||
pages,
|
||||
0,
|
||||
uefi::table::boot::MemoryAddress(0),
|
||||
)?
|
||||
};
|
||||
|
||||
|
|
@ -77,7 +76,7 @@ impl UefiMemoryManager {
|
|||
|
||||
unsafe {
|
||||
bs.free_pages(
|
||||
address,
|
||||
uefi::table::boot::MemoryAddress(address),
|
||||
pages,
|
||||
)?;
|
||||
}
|
||||
|
|
@ -405,7 +404,6 @@ impl MemoryAllocationBuilder {
|
|||
Self { _private: () }
|
||||
}
|
||||
|
||||
extern crate alloc;
|
||||
pub fn allocate(self, _size: usize) -> Result<*mut u8> {
|
||||
Err(BootError::FeatureNotEnabled("UEFI memory management"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,23 +5,19 @@
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::string::String;
|
||||
|
||||
pub mod main;
|
||||
pub mod memory;
|
||||
pub mod secure_boot;
|
||||
|
||||
// Re-export main components
|
||||
#[cfg(feature = "uefi_support")]
|
||||
pub use self::main::*;
|
||||
pub use main::*;
|
||||
#[cfg(feature = "uefi_support")]
|
||||
pub use self::memory::*;
|
||||
pub use memory::*;
|
||||
#[cfg(feature = "uefi_support")]
|
||||
pub use self::secure_boot::*;
|
||||
pub use secure_boot::*;
|
||||
#[cfg(feature = "uefi_support")]
|
||||
pub use crate::protocol::uefi::{UefiProtocol, set_active_protocol, get_active_protocol};
|
||||
pub use super::protocol::uefi::*;
|
||||
|
||||
// Version information
|
||||
pub const UEFI_VERSION_MAJOR: u16 = 2;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
use crate::utils::error::{BootError, Result};
|
||||
use core::ptr;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
|
||||
#[cfg(feature = "uefi_support")]
|
||||
use uefi::prelude::*;
|
||||
|
|
@ -427,7 +425,6 @@ impl SecureBootManager {
|
|||
}
|
||||
}
|
||||
|
||||
extern crate alloc;
|
||||
#[cfg(not(feature = "uefi_support"))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SecureBootStatus {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
# 错误处理架构设计文档
|
||||
|
||||
## 概述
|
||||
|
||||
NOS操作系统使用统一的错误处理机制,提供一致的错误码映射和错误恢复策略。所有错误类型都被映射到POSIX errno值,确保与标准兼容。
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **UnifiedErrorMapper**
|
||||
- 位置:`kernel/src/error/unified_mapping.rs`
|
||||
- 功能:统一的错误码映射器
|
||||
|
||||
2. **错误类型映射**
|
||||
- UnifiedError → Errno
|
||||
- ApiSyscallError → Errno
|
||||
- InterfaceSyscallError → Errno
|
||||
- NosErrorType → Errno
|
||||
|
||||
3. **错误处理层次**
|
||||
- 内核层:`kernel/src/error/`
|
||||
- 系统调用层:`kernel/src/subsystems/syscalls/api/syscall_result.rs`
|
||||
- 接口层:`kernel/src/subsystems/syscalls/interface/mod.rs`
|
||||
- 独立crate:`nos-error-handling/`
|
||||
|
||||
## 错误码映射表
|
||||
|
||||
| 内核错误 | POSIX errno | 说明 |
|
||||
|---------|-------------|------|
|
||||
| InvalidArgument | EINVAL | 无效参数 |
|
||||
| InvalidAddress | EFAULT | 无效地址 |
|
||||
| PermissionDenied | EACCES | 权限拒绝 |
|
||||
| NotFound | ENOENT | 资源未找到 |
|
||||
| AlreadyExists | EEXIST | 资源已存在 |
|
||||
| ResourceBusy | EBUSY | 资源忙碌 |
|
||||
| ResourceUnavailable | EAGAIN | 资源不可用 |
|
||||
| OutOfMemory | ENOMEM | 内存不足 |
|
||||
|
||||
## 使用示例
|
||||
|
||||
```rust
|
||||
use kernel::error::unified_mapping::{unified_error_to_errno, Errno};
|
||||
|
||||
let kernel_error = UnifiedError::InvalidArgument;
|
||||
let errno = unified_error_to_errno(&kernel_error);
|
||||
assert_eq!(errno, Errno::EINVAL);
|
||||
```
|
||||
|
||||
## 错误恢复策略
|
||||
|
||||
- **Retry**:自动重试操作
|
||||
- **Fallback**:使用备用策略
|
||||
- **PartialRecovery**:部分恢复,继续运行
|
||||
- **AutomaticRecovery**:自动恢复
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
# 内存布局架构设计文档
|
||||
|
||||
## 概述
|
||||
|
||||
NOS操作系统使用架构无关的内存布局抽象,支持x86_64、aarch64和riscv64架构。内存布局设计确保物理内存映射区域与内核代码区域分离,避免地址冲突。
|
||||
|
||||
## 内存布局设计
|
||||
|
||||
### x86_64架构
|
||||
|
||||
- **内核代码区**:`0xFFFF_FFFF_8000_0000` - `0xFFFF_FFFF_9000_0000`
|
||||
- **内核数据区**:`0xFFFF_FFFF_8100_0000` - `0xFFFF_FFFF_9100_0000`
|
||||
- **内核堆区**:`0xFFFF_FFFF_8300_0000` - `0xFFFF_FFFF_9300_0000`
|
||||
- **物理内存映射区**:`0xFFFF_8000_0000_0000` - `0xFFFF_FFFF_FFFF_FFFF`(128TB区域)
|
||||
- **MMIO区域**:`0xFFFF_8000_0000_0000` - `0xFFFF_FFFF_FFFF_FFFF`(128TB)
|
||||
|
||||
**关键改进**:物理内存映射从`0xFFFF_FFFF_8000_0000`(与内核代码重叠)改为`0xFFFF_8000_0000_0000`(独立区域)
|
||||
|
||||
### AArch64架构
|
||||
|
||||
- **内核代码区**:`0xFFFF_0000_0000_0000` - `0xFFFF_0000_0100_0000`
|
||||
- **物理内存映射区**:`0xFFFF_8000_0000_0000` - `0xFFFF_FFFF_FFFF_FFFF`(独立区域)
|
||||
|
||||
### RISC-V 64架构
|
||||
|
||||
- **内核代码区**:`0xFFFF_FFFF_0000_0000` - `0xFFFF_FFFF_0100_0000`
|
||||
- **物理内存映射区**:`0xFFFF_FFFF_8000_0000` - `0xFFFF_FFFF_FFFF_FFFF`(独立2GB区域)
|
||||
|
||||
## 地址冲突检测
|
||||
|
||||
内存布局模块提供了`verify_memory_layout()`函数,用于检测:
|
||||
- 物理映射区域与内核代码区域的重叠
|
||||
- 物理映射区域与内核数据区域的重叠
|
||||
- 物理映射区域与内核堆区域的重叠
|
||||
- 用户空间与内核空间的重叠
|
||||
|
||||
## 使用示例
|
||||
|
||||
```rust
|
||||
use kernel::arch::memory_layout::MemoryLayout;
|
||||
|
||||
let layout = MemoryLayout::current();
|
||||
|
||||
// 验证内存布局
|
||||
layout.verify_memory_layout()?;
|
||||
|
||||
// 转换物理地址到虚拟地址
|
||||
if let Some(virt_addr) = layout.phys_to_virt(phys_addr) {
|
||||
// 使用虚拟地址
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# 调度器架构设计文档
|
||||
|
||||
## 概述
|
||||
|
||||
NOS操作系统使用统一的调度器(UnifiedScheduler)实现O(log n)时间复杂度的调度决策,替代了原有的O(n)线性搜索。调度器支持per-CPU运行队列和工作窃取机制。
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **UnifiedScheduler**
|
||||
- 位置:`kernel/src/subsystems/scheduler/unified.rs`
|
||||
- 功能:统一的调度器实现,使用优先级队列
|
||||
|
||||
2. **优先级队列**
|
||||
- 使用BTreeMap实现O(log n)操作
|
||||
- 支持多级优先级(0-255)
|
||||
- FIFO排序用于相同优先级的线程
|
||||
|
||||
3. **Per-CPU运行队列**
|
||||
- 每个CPU独立的运行队列
|
||||
- 减少锁竞争
|
||||
- 支持CPU亲和性
|
||||
|
||||
4. **工作窃取**
|
||||
- 当本地队列为空时,从其他CPU窃取工作
|
||||
- 实现负载均衡
|
||||
|
||||
## 性能改进
|
||||
|
||||
### 旧实现(O(n))
|
||||
- 线性搜索所有线程(最多1024个)
|
||||
- 每次调度需要遍历整个线程表
|
||||
- 时间复杂度:O(n)
|
||||
|
||||
### 新实现(O(log n))
|
||||
- 优先级队列快速查找
|
||||
- 只搜索就绪线程
|
||||
- 时间复杂度:O(log n)
|
||||
|
||||
## 调度策略
|
||||
|
||||
- **FIFO**:实时FIFO调度,无限时间片
|
||||
- **RoundRobin**:实时轮询调度,10ms时间片
|
||||
- **Normal**:普通时间分片调度,10ms时间片
|
||||
- **Batch**:批处理调度,50ms时间片
|
||||
- **Idle**:空闲调度,100ms时间片
|
||||
|
||||
## 使用示例
|
||||
|
||||
```rust
|
||||
use kernel::subsystems::scheduler::unified::{
|
||||
UnifiedScheduler, init_unified_scheduler, unified_schedule
|
||||
};
|
||||
|
||||
// 初始化统一调度器
|
||||
init_unified_scheduler(num_cpus);
|
||||
|
||||
// 调度下一个线程
|
||||
if let Some(next_tid) = unified_schedule() {
|
||||
// 切换到next_tid
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# 系统调用分发器架构设计文档
|
||||
|
||||
## 概述
|
||||
|
||||
NOS操作系统使用统一的系统调用分发器(UnifiedSyscallDispatcher)来处理所有系统调用请求。该分发器整合了多个旧实现的最佳特性,提供了高性能、可扩展的系统调用处理机制。
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **UnifiedSyscallDispatcher**
|
||||
- 位置:`kernel/src/subsystems/syscalls/dispatch/unified.rs`
|
||||
- 功能:统一的系统调用分发器,整合了快速路径、per-CPU缓存、处理器注册等特性
|
||||
|
||||
2. **快速路径优化**
|
||||
- 256个常用系统调用的直接跳转表
|
||||
- O(1)时间复杂度的快速路径处理
|
||||
- 支持自适应优化
|
||||
|
||||
3. **Per-CPU缓存**
|
||||
- 每个CPU独立的缓存,减少锁竞争
|
||||
- 频率统计和自适应快速路径更新
|
||||
|
||||
4. **处理器注册机制**
|
||||
- 动态注册系统调用处理器
|
||||
- 支持处理器优先级和范围映射
|
||||
|
||||
## 性能特性
|
||||
|
||||
- **快速路径**:常用系统调用(getpid、gettid等)直接跳转,延迟极低
|
||||
- **Per-CPU缓存**:减少跨CPU锁竞争,提高并发性能
|
||||
- **自适应优化**:根据调用频率动态调整快速路径
|
||||
- **批量处理**:支持批量系统调用处理
|
||||
|
||||
## 使用示例
|
||||
|
||||
```rust
|
||||
use kernel::subsystems::syscalls::dispatch::unified::{
|
||||
UnifiedSyscallDispatcher, UnifiedDispatcherConfig, init_unified_dispatcher
|
||||
};
|
||||
|
||||
// 初始化统一分发器
|
||||
let config = UnifiedDispatcherConfig::default();
|
||||
init_unified_dispatcher(config);
|
||||
|
||||
// 分发系统调用
|
||||
use kernel::subsystems::syscalls::dispatch::unified::unified_dispatch;
|
||||
let result = unified_dispatch(syscall_num, args);
|
||||
```
|
||||
|
||||
## 迁移指南
|
||||
|
||||
旧的系统调用分发器实现已被标记为deprecated:
|
||||
- `kernel/src/syscall/fast_path_dispatcher.rs` - 已删除
|
||||
- `kernel/src/subsystems/syscalls/fast_dispatcher.rs` - 已删除
|
||||
- `kernel/src/subsystems/syscalls/unified_dispatcher.rs` - 已删除
|
||||
|
||||
请使用新的 `UnifiedSyscallDispatcher` 替代。
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
# Implementation Plan for Rust Operating System Improvements
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This implementation plan details the steps required to execute the recommendations outlined in the comprehensive improvement report. The plan is organized into four phases, each with specific tasks, timelines, and dependencies.
|
||||
|
||||
## Phase 1: Foundation (0-4 weeks)
|
||||
|
||||
### Goal: Establish a solid foundation by improving maintainability and reducing technical debt
|
||||
|
||||
#### Task 1.1: Implement Unified Error Handling Framework
|
||||
|
||||
**Description**: Create a centralized error handling system that eliminates duplicate error definitions across the codebase.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Create a new `error/unified_framework.rs` module with a common error type hierarchy
|
||||
- [ ] Implement error conversion traits to convert between different error types
|
||||
- [ ] Update all subsystems to use the unified error framework
|
||||
- [ ] Remove redundant error definitions in fs/api/error.rs, mm/api/error.rs, etc.
|
||||
|
||||
**Code References**:
|
||||
- Current error implementations: kernel/src/error/unified.rs, kernel/src/api/error.rs
|
||||
- 78 files with duplicate error definitions (identified via grep search)
|
||||
|
||||
#### Task 1.2: Modularize Large Files
|
||||
|
||||
**Description**: Split excessively large files into smaller, focused modules to improve maintainability.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Split `debug/fault_diagnosis.rs` (1747 lines) into: fault_detection.rs, root_cause_analysis.rs, remediation_recommendations.rs
|
||||
- [ ] Split `subsystems/formal_verification/static_analyzer.rs` (1625 lines) into: dead_code_analysis.rs, type_checker.rs, concurrency_verifier.rs
|
||||
- [ ] Update imports and maintain functionality
|
||||
- [ ] Create clear public APIs for each new module
|
||||
|
||||
#### Task 1.3: Remove Redundant Files and Code
|
||||
|
||||
**Description**: Eliminate redundant files and duplicate code to improve codebase clarity.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Remove `ids/host_ids/integrity.rs` (only re-exports types without adding functionality)
|
||||
- [ ] Identify and remove duplicate error handling code
|
||||
- [ ] Create shared utility functions for commonly used operations
|
||||
- [ ] Update build system to reflect removed files
|
||||
|
||||
## Phase 2: Performance Optimization (4-8 weeks)
|
||||
|
||||
### Goal: Improve system performance through memory management and caching optimizations
|
||||
|
||||
#### Task 2.1: Optimize Cache Management
|
||||
|
||||
**Description**: Enhance the per-CPU page cache with dynamic sizing and monitoring.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Modify `optimized_page_allocator.rs` to support dynamic cache sizing based on system load
|
||||
- [ ] Add cache hit ratio monitoring and metrics collection
|
||||
- [ ] Implement adaptive cache resizing algorithm
|
||||
- [ ] Update documentation and add unit tests
|
||||
|
||||
**Code References**:
|
||||
- Current cache implementation: kernel/src/mm/optimized_page_allocator.rs:405
|
||||
|
||||
#### Task 2.2: Improve Buddy Allocator Efficiency
|
||||
|
||||
**Description**: Enhance the buddy allocator for faster allocation and better memory utilization.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Replace linked list-based free list with a more efficient data structure (tree or bitmap)
|
||||
- [ ] Implement better memory defragmentation strategies
|
||||
- [ ] Add performance benchmarks to measure improvements
|
||||
- [ ] Update unit tests to cover new functionality
|
||||
|
||||
**Code References**:
|
||||
- Buddy allocator: kernel/src/mm/optimized_page_allocator.rs:147-370
|
||||
|
||||
#### Task 2.3: Implement Dynamic Prefetching Strategy
|
||||
|
||||
**Description**: Enhance the prefetch module with real-time performance monitoring and adaptation.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Add performance metrics collection to prefetch module
|
||||
- [ ] Implement dynamic strategy switching based on actual performance
|
||||
- [ ] Create adaptive prefetching algorithm that adjusts based on workload
|
||||
- [ ] Add unit tests and performance benchmarks
|
||||
|
||||
**Code References**:
|
||||
- Prefetch module: kernel/src/mm/prefetch.rs
|
||||
|
||||
#### Task 2.4: Enhance Caching Strategies
|
||||
|
||||
**Description**: Improve caching effectiveness across all subsystems.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Implement adaptive cache sizing for debug symbol cache
|
||||
- [ ] Add cache warm-up mechanisms for faster startup
|
||||
- [ ] Implement cache invalidation policies to ensure data consistency
|
||||
- [ ] Add metrics for cache hit/miss ratios
|
||||
|
||||
**Code References**:
|
||||
- Debug symbol cache: kernel/src/debug/symbols.rs
|
||||
- Compression cache: kernel/src/mm/compress.rs
|
||||
|
||||
## Phase 3: Architectural Enhancement (8-12 weeks)
|
||||
|
||||
### Goal: Improve kernel modularity and subsystem integration
|
||||
|
||||
#### Task 3.1: Improve Kernel Modularity
|
||||
|
||||
**Description**: Enhance kernel architecture with better modularity and extensibility.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Define clear interfaces between kernel components using Rust traits
|
||||
- [ ] Implement a plugin architecture for optional features
|
||||
- [ ] Use dependency injection to reduce coupling between components
|
||||
- [ ] Create module system for dynamically loading kernel modules
|
||||
|
||||
**Code References**:
|
||||
- Kernel main: kernel/src/main.rs
|
||||
- Subsystem interfaces: kernel/src/subsystems/mod.rs
|
||||
|
||||
#### Task 3.2: Decouple Subsystems
|
||||
|
||||
**Description**: Improve subsystem communication and reduce tight coupling.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Implement message-passing interfaces between subsystems
|
||||
- [ ] Create a centralized subsystem registry for dynamic discovery
|
||||
- [ ] Define common inter-subsystem communication protocol
|
||||
- [ ] Implement message bus for efficient communication
|
||||
|
||||
**Code References**:
|
||||
- Current subsystem implementation: kernel/src/subsystems/
|
||||
|
||||
#### Task 3.3: Implement Comprehensive Error Recovery
|
||||
|
||||
**Description**: Enhance fault tolerance and error recovery mechanisms.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Add automatic error recovery mechanisms for common failures
|
||||
- [ ] Implement checkpoint and restore functionality for critical components
|
||||
- [ ] Create fault injection framework for testing recovery mechanisms
|
||||
- [ ] Enhance fault diagnosis engine with better root cause analysis
|
||||
|
||||
**Code References**:
|
||||
- Fault diagnosis module: kernel/src/debug/fault_diagnosis.rs
|
||||
|
||||
## Phase 4: Testing and Validation (12-16 weeks)
|
||||
|
||||
### Goal: Ensure system reliability through comprehensive testing and validation
|
||||
|
||||
#### Task 4.1: Expand Test Coverage
|
||||
|
||||
**Description**: Improve testing infrastructure to ensure system reliability.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Add more unit tests for critical components
|
||||
- [ ] Implement integration tests for subsystem interactions
|
||||
- [ ] Create system-level tests for end-to-end functionality
|
||||
- [ ] Add performance benchmarks to track regressions
|
||||
|
||||
**Code References**:
|
||||
- Current test implementation: kernel/src/test/
|
||||
|
||||
#### Task 4.2: Set Up CI Pipeline
|
||||
|
||||
**Description**: Implement continuous integration to ensure code quality.
|
||||
|
||||
**Subtasks**:
|
||||
- [ ] Configure CI pipeline to run tests on every commit
|
||||
- [ ] Add static analysis tools to catch potential issues early
|
||||
- [ ] Implement performance benchmarking in CI
|
||||
- [ ] Set up automated build and deployment processes
|
||||
|
||||
## Dependencies and Risks
|
||||
|
||||
### Dependencies
|
||||
- Phase 2 tasks depend on Phase 1 completion for maintainability improvements
|
||||
- Phase 3 tasks depend on Phase 2 performance optimizations
|
||||
- Phase 4 testing depends on all previous phases being completed
|
||||
|
||||
### Risks
|
||||
- **Technical Risk**: Some performance optimizations may require significant refactoring
|
||||
- **Time Risk**: Complex architectural changes may take longer than anticipated
|
||||
- **Integration Risk**: Changes to core components may break existing functionality
|
||||
|
||||
## Mitigation Strategies
|
||||
- Implement feature flags to enable incremental changes
|
||||
- Conduct thorough testing at each phase
|
||||
- Maintain backward compatibility during refactoring
|
||||
- Use performance benchmarks to measure improvements
|
||||
|
||||
## Success Metrics
|
||||
- **Maintainability**: Reduce duplicate code by 50%, decrease average file size by 40%
|
||||
- **Performance**: Improve memory allocation speed by 30%, increase cache hit ratio by 20%
|
||||
- **Reliability**: Increase test coverage from current level to 80%
|
||||
- **Extensibility**: Reduce coupling between subsystems by implementing message-passing interfaces
|
||||
|
||||
## Conclusion
|
||||
|
||||
This implementation plan provides a structured approach to executing the improvement recommendations. By following this phased approach, the project will achieve significant improvements in performance, maintainability, and architectural rationality, making it more suitable for production-grade use.
|
||||
|
||||
**Plan Generated on**: 2025-12-22
|
||||
**Project**: /Users/didi/Desktop/nos
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
# Comprehensive Improvement Report for Rust Operating System Project
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This report presents a comprehensive analysis of the Rust operating system project, identifying key areas for improvement in functional integrity, performance optimization, maintainability, and architectural rationality. The analysis is based on a thorough examination of the codebase structure, key subsystems, and performance characteristics.
|
||||
|
||||
## 1. Performance Optimization Opportunities
|
||||
|
||||
### 1.1 Memory Management Optimization
|
||||
|
||||
**Current State**: The project implements an optimized page allocator with per-CPU caches and a buddy allocator for multi-page allocations. However, there are several areas for improvement:
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Optimize Cache Management**:
|
||||
- The current per-CPU cache size is fixed at 64 pages (kernel/src/mm/optimized_page_allocator.rs:405). Consider implementing dynamic cache sizing based on system load to improve memory utilization.
|
||||
- Add cache hit ratio monitoring to identify underutilized or overutilized caches.
|
||||
|
||||
2. **Improve Buddy Allocator Efficiency**:
|
||||
- The buddy allocator uses a linked list-based free list implementation which can be slow for large memory ranges. Consider using a more efficient data structure like a tree or bitmap for faster allocation.
|
||||
- Implement better memory defragmentation strategies to reduce external fragmentation.
|
||||
|
||||
3. **Prefetching Optimization**:
|
||||
- The prefetch module (kernel/src/mm/prefetch.rs) supports adaptive prefetching strategies but lacks real-time performance monitoring and adaptation. Implement dynamic strategy switching based on actual performance metrics.
|
||||
|
||||
### 1.2 Loop and Algorithm Optimization
|
||||
|
||||
**Key Findings**:
|
||||
- Several nested loops were identified in the buddy allocator implementation (kernel/src/mm/optimized_page_allocator.rs:212-217, 232-234, 326-328, 343-345).
|
||||
- The current implementation uses linear searches in some critical paths which could be optimized with more efficient algorithms.
|
||||
|
||||
**Recommendations**:
|
||||
- Replace linear searches with binary searches or hash-based lookups where appropriate.
|
||||
- Implement loop unrolling for performance-critical loops to reduce branch overhead.
|
||||
- Consider using SIMD instructions for memory-intensive operations where applicable.
|
||||
|
||||
### 1.3 Caching Strategy Enhancement
|
||||
|
||||
**Current State**:
|
||||
- The debug symbol cache (kernel/src/debug/symbols.rs) implements basic caching with hit/miss tracking.
|
||||
- The compression cache (kernel/src/mm/compress.rs) provides per-CPU compression caching but lacks adaptive sizing.
|
||||
|
||||
**Recommendations**:
|
||||
- Implement adaptive cache sizing for all caching systems to dynamically adjust based on workload.
|
||||
- Add cache warm-up mechanisms to improve performance during system startup.
|
||||
- Implement cache invalidation policies to ensure data consistency.
|
||||
|
||||
## 2. Maintainability Improvements
|
||||
|
||||
### 2.1 Error Handling Consolidation
|
||||
|
||||
**Key Issue**: The codebase has extensive error handling duplication across multiple modules:
|
||||
|
||||
- 78 files define their own error types (identified via grep search)
|
||||
- Multiple error handling implementations exist in different subsystems (error/unified.rs, api/error.rs, libc/error.rs, etc.)
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Unify Error Handling**:
|
||||
- Create a centralized error handling framework that can be used across all subsystems
|
||||
- Define a common error type hierarchy to reduce duplication
|
||||
- Implement a consistent error conversion mechanism between different error types
|
||||
|
||||
2. **Remove Redundant Error Definitions**:
|
||||
- Remove duplicate error definitions in subsystems like fs/api/error.rs, mm/api/error.rs, etc.
|
||||
- Use the unified error handling framework instead
|
||||
|
||||
### 2.2 Structural Improvements
|
||||
|
||||
**Key Findings**:
|
||||
- Some files are excessively large (e.g., debug/fault_diagnosis.rs has 1747 lines, subsystems/formal_verification/static_analyzer.rs has 1625 lines)
|
||||
- There is a lack of clear separation of concerns in some modules
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Modularize Large Files**:
|
||||
- Split large files into smaller, focused modules
|
||||
- Create clear boundaries between different functionalities
|
||||
|
||||
2. **Improve Code Organization**:
|
||||
- Establish consistent directory structure across all subsystems
|
||||
- Move related functionality into dedicated modules
|
||||
- Create clear public APIs for each module
|
||||
|
||||
### 2.3 Redundant Files and Code
|
||||
|
||||
**Key Findings**:
|
||||
- Some files appear to be redundant or contain duplicate functionality:
|
||||
- ids/host_ids/integrity.rs only re-exports types without adding new functionality
|
||||
- Multiple error handling implementations exist across different modules
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Remove Redundant Files**:
|
||||
- Remove files that only re-export types without adding new functionality
|
||||
- Consolidate duplicate functionality into a single implementation
|
||||
|
||||
2. **Eliminate Duplicate Code**:
|
||||
- Identify and remove duplicate error handling code
|
||||
- Create shared utility functions for commonly used operations
|
||||
|
||||
## 3. Architectural Rationality Enhancements
|
||||
|
||||
### 3.1 Kernel Component Design
|
||||
|
||||
**Current State**: The kernel is designed as an independent component providing necessary services, but there are opportunities to improve its modularity and flexibility.
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Improve Modularity**:
|
||||
- Define clear interfaces between kernel components
|
||||
- Implement a plugin architecture for optional features
|
||||
- Use dependency injection to reduce coupling between components
|
||||
|
||||
2. **Enhance Extensibility**:
|
||||
- Create a more flexible system call interface that can be extended without modifying the core kernel
|
||||
- Implement a module system for dynamically loading and unloading kernel modules
|
||||
|
||||
### 3.2 Subsystem Integration
|
||||
|
||||
**Key Findings**:
|
||||
- Some subsystems have tight coupling with the core kernel
|
||||
- There is a lack of standardized communication protocols between subsystems
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Decouple Subsystems**:
|
||||
- Use message-passing interfaces between subsystems instead of direct function calls
|
||||
- Implement a centralized subsystem registry for dynamic discovery
|
||||
|
||||
2. **Standardize Communication**:
|
||||
- Define a common inter-subsystem communication protocol
|
||||
- Create a message bus for efficient inter-subsystem communication
|
||||
|
||||
## 4. Functional Integrity Improvements
|
||||
|
||||
### 4.1 Error Recovery and Fault Tolerance
|
||||
|
||||
**Current State**: The project includes a fault diagnosis module (debug/fault_diagnosis.rs) but lacks comprehensive error recovery mechanisms.
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Implement Comprehensive Error Recovery**:
|
||||
- Add automatic error recovery mechanisms for common failures
|
||||
- Implement checkpoint and restore functionality for critical system components
|
||||
- Create a fault injection framework for testing error recovery mechanisms
|
||||
|
||||
2. **Enhance Fault Diagnosis**:
|
||||
- Improve the fault diagnosis engine to provide more accurate root cause analysis
|
||||
- Add real-time fault monitoring and alerting
|
||||
- Implement predictive fault detection using machine learning algorithms
|
||||
|
||||
### 4.2 Testing and Validation
|
||||
|
||||
**Key Findings**:
|
||||
- The project includes some unit tests but lacks comprehensive integration and system testing.
|
||||
|
||||
**Recommendations**:
|
||||
|
||||
1. **Expand Test Coverage**:
|
||||
- Add more unit tests for critical components
|
||||
- Implement integration tests for subsystem interactions
|
||||
- Create system-level tests for end-to-end functionality validation
|
||||
|
||||
2. **Implement Continuous Integration**:
|
||||
- Set up a CI pipeline to run tests automatically on every commit
|
||||
- Add performance benchmarks to track performance regressions
|
||||
- Implement static analysis tools to catch potential issues early
|
||||
|
||||
## 5. Implementation Roadmap
|
||||
|
||||
### Phase 1 (0-4 weeks)
|
||||
- Implement unified error handling framework
|
||||
- Modularize large files
|
||||
- Remove redundant files and duplicate code
|
||||
|
||||
### Phase 2 (4-8 weeks)
|
||||
- Optimize memory management algorithms
|
||||
- Improve caching strategies
|
||||
- Implement performance monitoring and adaptation
|
||||
|
||||
### Phase 3 (8-12 weeks)
|
||||
- Enhance kernel modularity and extensibility
|
||||
- Improve subsystem integration
|
||||
- Implement comprehensive error recovery mechanisms
|
||||
|
||||
### Phase 4 (12-16 weeks)
|
||||
- Expand test coverage
|
||||
- Set up CI pipeline
|
||||
- Implement performance benchmarks
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Rust operating system project has a solid foundation with well-designed components and modern Rust practices. By implementing the recommendations outlined in this report, the project can achieve significant improvements in performance, maintainability, and architectural rationality, making it more suitable for production-grade use.
|
||||
|
||||
|
||||
**Report Generated on**: 2025-12-22
|
||||
**Analyzed Codebase**: /Users/didi/Desktop/nos
|
||||
|
|
@ -46,7 +46,7 @@ serde_json = { workspace = true }
|
|||
bincode = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["posix_layer", "net_stack", "syscalls", "services", "error_handling"]
|
||||
default = ["posix_layer", "net_stack", "syscalls", "services", "error_handling", "alloc"]
|
||||
baremetal = []
|
||||
kernel_tests = []
|
||||
link_phys_end = []
|
||||
|
|
@ -65,15 +65,15 @@ net_stack = []
|
|||
graphics_subsystem = []
|
||||
web_engine = []
|
||||
posix_layer = []
|
||||
|
||||
alloc = []
|
||||
hpage_2mb = []
|
||||
hpage_1gb = []
|
||||
debug = []
|
||||
|
||||
# New modular features
|
||||
syscalls = ["nos-syscalls"]
|
||||
syscalls = ["nos-syscalls", "nos-syscalls/alloc"]
|
||||
services = ["nos-services"]
|
||||
error_handling = ["nos-error-handling"]
|
||||
error_handling = ["nos-error-handling", "nos-error-handling/alloc"]
|
||||
advanced_syscalls = ["nos-syscalls/advanced_syscalls"]
|
||||
realtime = []
|
||||
log = []
|
||||
|
|
|
|||
|
|
@ -29,6 +29,97 @@ impl IntoFrameworkError for UnifiedError {
|
|||
}
|
||||
}
|
||||
}
|
||||
/// Condition variable limit exceeded
|
||||
ConditionVariableLimitExceeded,
|
||||
/// Invalid semaphore
|
||||
InvalidSemaphore,
|
||||
/// Semaphore not found
|
||||
SemaphoreNotFound,
|
||||
/// Semaphore already exists
|
||||
SemaphoreAlreadyExists,
|
||||
/// Semaphore limit exceeded
|
||||
SemaphoreLimitExceeded,
|
||||
/// Semaphore is locked
|
||||
SemaphoreIsLocked,
|
||||
/// Semaphore is not locked
|
||||
SemaphoreIsNotLocked,
|
||||
/// Invalid shared memory
|
||||
InvalidSharedMemory,
|
||||
/// Shared memory not found
|
||||
SharedMemoryNotFound,
|
||||
/// Shared memory already exists
|
||||
SharedMemoryAlreadyExists,
|
||||
/// Shared memory limit exceeded
|
||||
SharedMemoryLimitExceeded,
|
||||
/// Invalid message queue
|
||||
InvalidMessageQueue,
|
||||
/// Message queue not found
|
||||
MessageQueueNotFound,
|
||||
/// Message queue already exists
|
||||
MessageQueueAlreadyExists,
|
||||
/// Message queue limit exceeded
|
||||
MessageQueueLimitExceeded,
|
||||
/// Message queue is full
|
||||
MessageQueueIsFull,
|
||||
/// Message queue is empty
|
||||
MessageQueueIsEmpty,
|
||||
/// Invalid message
|
||||
InvalidMessage,
|
||||
/// Message too large
|
||||
MessageTooLarge,
|
||||
/// Message not found
|
||||
MessageNotFound,
|
||||
/// Invalid socket
|
||||
InvalidSocket,
|
||||
/// Socket not found
|
||||
SocketNotFound,
|
||||
/// Socket already exists
|
||||
SocketAlreadyExists,
|
||||
/// Socket limit exceeded
|
||||
SocketLimitExceeded,
|
||||
/// Socket is not connected
|
||||
SocketIsNotConnected,
|
||||
/// Socket is connected
|
||||
SocketIsConnected,
|
||||
/// Socket is not bound
|
||||
SocketIsNotBound,
|
||||
/// Socket is bound
|
||||
SocketIsBound,
|
||||
/// Socket is not listening
|
||||
SocketIsNotListening,
|
||||
/// Socket is listening
|
||||
SocketIsListening,
|
||||
/// Socket is not closed
|
||||
SocketIsNotClosed,
|
||||
/// Socket is closed
|
||||
SocketIsClosed,
|
||||
/// Invalid address family
|
||||
InvalidAddressFamily,
|
||||
/// Invalid socket type
|
||||
InvalidSocketType,
|
||||
/// Invalid protocol
|
||||
InvalidProtocol,
|
||||
/// Address in use
|
||||
AddressInUse,
|
||||
/// Address not available
|
||||
AddressNotAvailable,
|
||||
/// Network is unreachable
|
||||
NetworkIsUnreachable,
|
||||
/// Network is down
|
||||
NetworkIsDown,
|
||||
/// Connection timed out
|
||||
ConnectionTimedOut,
|
||||
/// Connection reset by peer
|
||||
ConnectionResetByPeer,
|
||||
/// Host is unreachable
|
||||
HostIsUnreachable,
|
||||
/// Host is down
|
||||
HostIsDown,
|
||||
/// No route to host
|
||||
NoRouteToHost,
|
||||
/// Unknown error
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl KernelError {
|
||||
/// Convert kernel error to errno value
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ impl UniversalLoader {
|
|||
};
|
||||
|
||||
// Load binary using appropriate handler
|
||||
let loaded_binary = handler.load_binary(info, data, &self.memory_manager)?;
|
||||
let mut loaded_binary = handler.load_binary(info, data, &self.memory_manager)?;
|
||||
|
||||
// Add memory regions to manager
|
||||
for region in &loaded_binary.memory_regions {
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ impl SyscallTranslator {
|
|||
fn create_linux_translation_table(&self) -> Result<TranslationTable> {
|
||||
let mut name_to_number = BTreeMap::new();
|
||||
let mut number_translation = BTreeMap::new();
|
||||
let special_handlers: BTreeMap<u32, Box<dyn SpecialHandler + Send + Sync>> = BTreeMap::new();
|
||||
let mut special_handlers: BTreeMap<u32, Box<dyn SpecialHandler + Send + Sync>> = BTreeMap::new();
|
||||
|
||||
// File I/O syscalls (most common)
|
||||
number_translation.insert(0, crate::syscalls::SYS_READ as usize); // sys_read
|
||||
|
|
@ -1040,9 +1040,9 @@ impl SyscallTranslator {
|
|||
|
||||
/// Create Windows translation table
|
||||
fn create_windows_translation_table(&self) -> Result<TranslationTable> {
|
||||
let name_to_number = BTreeMap::new();
|
||||
let number_translation = BTreeMap::new();
|
||||
let special_handlers: BTreeMap<u32, Box<dyn SpecialHandler + Send + Sync>> = BTreeMap::new();
|
||||
let mut name_to_number = BTreeMap::new();
|
||||
let mut number_translation = BTreeMap::new();
|
||||
let mut special_handlers: BTreeMap<u32, Box<dyn SpecialHandler + Send + Sync>> = BTreeMap::new();
|
||||
|
||||
// Windows has a different syscall mechanism
|
||||
// We would map Windows API calls to NOS syscalls here
|
||||
|
|
@ -1057,9 +1057,9 @@ impl SyscallTranslator {
|
|||
|
||||
/// Create macOS translation table
|
||||
fn create_macos_translation_table(&self) -> Result<TranslationTable> {
|
||||
let name_to_number = BTreeMap::new();
|
||||
let number_translation = BTreeMap::new();
|
||||
let special_handlers: BTreeMap<u32, Box<dyn SpecialHandler + Send + Sync>> = BTreeMap::new();
|
||||
let mut name_to_number = BTreeMap::new();
|
||||
let mut number_translation = BTreeMap::new();
|
||||
let mut special_handlers: BTreeMap<u32, Box<dyn SpecialHandler + Send + Sync>> = BTreeMap::new();
|
||||
|
||||
// macOS syscall mappings
|
||||
// These would be based on the xnu kernel syscall table
|
||||
|
|
@ -1103,7 +1103,7 @@ impl SyscallTranslator {
|
|||
for (_, cached) in cache.iter() {
|
||||
if cached.usage_count > 100 { // Hot path threshold
|
||||
// JIT compile this syscall
|
||||
let _jit = self.jit_compiler.lock();
|
||||
let mut jit = self.jit_compiler.lock();
|
||||
// jit.compile_syscall(cached)?; // Would implement actual compilation
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ pub fn init_kernel_core(boot_params: Option<&BootParameters>) {
|
|||
// Initialize unified system call dispatcher
|
||||
#[cfg(feature = "syscalls")]
|
||||
{
|
||||
use crate::syscalls::dispatch::unified::{init_unified_dispatcher, UnifiedDispatcherConfig};
|
||||
use crate::subsystems::syscalls::dispatch::unified::{init_unified_dispatcher, UnifiedDispatcherConfig};
|
||||
let config = UnifiedDispatcherConfig::default();
|
||||
init_unified_dispatcher(config);
|
||||
crate::println!("[boot] unified syscall dispatcher initialized");
|
||||
|
|
@ -232,7 +232,7 @@ pub fn init_kernel_core(boot_params: Option<&BootParameters>) {
|
|||
|
||||
// Initialize unified scheduler with priority queues
|
||||
{
|
||||
use crate::sched::unified::init_unified_scheduler;
|
||||
use crate::subsystems::scheduler::unified::init_unified_scheduler;
|
||||
let num_cpus = crate::cpu::ncpus();
|
||||
init_unified_scheduler(num_cpus);
|
||||
crate::println!("[boot] unified scheduler initialized ({} CPUs)", num_cpus);
|
||||
|
|
|
|||
|
|
@ -10,9 +10,13 @@
|
|||
// Re-export API types
|
||||
pub use nos_api::*;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::string::String;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::string::ToString;
|
||||
|
||||
// Core modules
|
||||
|
|
@ -97,7 +101,7 @@ pub fn get_kernel_info() -> KernelInfo {
|
|||
/// # Returns
|
||||
/// * `Vec<String>` - Enabled features
|
||||
fn get_enabled_features() -> Vec<String> {
|
||||
let mut features = Vec::new();
|
||||
let features = Vec::new();
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
features.push("std".to_string());
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ pub use analyzer::{
|
|||
HotspotAnalysisConfig,
|
||||
};
|
||||
|
||||
|
||||
pub use plugin::{
|
||||
DebugPlugin, PluginType, PluginConfig, PluginInterface,
|
||||
};
|
||||
|
||||
pub use types::{
|
||||
SymbolManager, SymbolTable, SymbolTableType, Symbol, SymbolType, SymbolScope,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ extern crate alloc;
|
|||
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::format;
|
||||
use alloc::boxed::Box;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ use core::any::{Any, TypeId};
|
|||
use nos_api::{
|
||||
di::{Container, ServiceFactory, ServiceMetadata, ServiceScope, ServiceResolver},
|
||||
error::Result,
|
||||
event::{Event, EventPriority, EventDispatcher, EventMetadata, EventType, SystemEventData, MemoryEventData, ProcessEventData},
|
||||
core::EventHandler,
|
||||
event::{Event, EventHandler, EventMetadata, EventPriority, EventType},
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -185,7 +184,7 @@ impl ServiceEvent {
|
|||
}
|
||||
|
||||
// Event types for service lifecycle
|
||||
// use nos_api::event::{SystemEvent, SystemEventData};
|
||||
use nos_api::event::{SystemEvent, SystemEventData};
|
||||
|
||||
/// Service registered event
|
||||
pub struct ServiceRegisteredEvent {
|
||||
|
|
|
|||
|
|
@ -1,100 +0,0 @@
|
|||
extern crate alloc;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::vec::Vec;
|
||||
use crate::sync::Mutex;
|
||||
use crate::posix;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct EpollItem {
|
||||
pub fd: i32,
|
||||
pub events: i32,
|
||||
}
|
||||
|
||||
pub struct EpollInst {
|
||||
pub items: Vec<EpollItem>,
|
||||
}
|
||||
|
||||
impl EpollInst { pub fn new() -> Self { Self { items: Vec::new() } } }
|
||||
|
||||
static EPOLL_TABLE: Mutex<BTreeMap<i32, EpollInst>> = Mutex::new(BTreeMap::new());
|
||||
// println removed for no_std compatibility
|
||||
|
||||
pub fn epoll_create(_size: i32) -> i32 {
|
||||
// println removed for no_std compatibility
|
||||
let id = *idg;
|
||||
*idg += 1;
|
||||
// println removed for no_std compatibility
|
||||
// println removed for no_std compatibility
|
||||
t.insert(id, EpollInst::new());
|
||||
id
|
||||
}
|
||||
|
||||
pub fn epoll_ctl(epfd: i32, op: i32, fd: i32, events: i32) -> isize {
|
||||
// println removed for no_std compatibility
|
||||
let inst = match t.get_mut(&epfd) { Some(i) => i, None => return crate::syscalls::E_BADARG };
|
||||
match op {
|
||||
1 /* EPOLL_CTL_ADD */ => {
|
||||
// prevent duplicates
|
||||
// println removed for no_std compatibility
|
||||
// println removed for no_std compatibility
|
||||
crate::syscalls::E_OK
|
||||
}
|
||||
2 /* EPOLL_CTL_DEL */ => {
|
||||
// println removed for no_std compatibility
|
||||
crate::syscalls::E_OK
|
||||
}
|
||||
3 /* EPOLL_CTL_MOD */ => {
|
||||
for it in inst.items.iter_mut() { if it.fd == fd { it.events = events; return crate::syscalls::E_OK; } }
|
||||
crate::syscalls::E_BADARG
|
||||
}
|
||||
_ => crate::syscalls::E_INVAL,
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct EpollEvent { events: u32, data: u64 }
|
||||
|
||||
pub fn epoll_wait(epfd: i32, events_ptr: usize, maxevents: i32, timeout: i32) -> isize {
|
||||
if maxevents <= 0 { return crate::syscalls::E_BADARG; }
|
||||
let mut ready = 0;
|
||||
// println removed for no_std compatibility
|
||||
loop {
|
||||
ready = 0;
|
||||
// println removed for no_std compatibility
|
||||
{
|
||||
// println removed for no_std compatibility
|
||||
let inst = match t.get(&epfd) { Some(i) => i, None => return crate::syscalls::E_BADARG };
|
||||
for it in inst.items.iter() {
|
||||
let idx = match crate::process::fdlookup(it.fd) { Some(i) => i, None => continue };
|
||||
let ev = crate::file::file_poll(idx) as i32;
|
||||
if (ev & it.events) != 0 {
|
||||
// println removed for no_std compatibility
|
||||
ready += 1;
|
||||
if ready >= maxevents { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
if ready > 0 {
|
||||
// write events to user buffer
|
||||
let usize_sz = core::mem::size_of::<EpollEvent>();
|
||||
// println removed for no_std compatibility
|
||||
let pt = match crate::process::myproc().and_then(|pid| ptable.find(pid).map(|p| p.pagetable)) { Some(x) => x, None => return crate::syscalls::E_BADARG };
|
||||
// println removed for no_std compatibility
|
||||
for (i, ev) in out.into_iter().enumerate() {
|
||||
let dst = events_ptr + i * usize_sz;
|
||||
let bytes = unsafe { core::slice::from_raw_parts((&ev as *const EpollEvent) as *const u8, usize_sz) };
|
||||
if unsafe { crate::vm::copyout(pt, dst, bytes.as_ptr(), bytes.len()) }.is_err() { return crate::syscalls::E_FAULT; }
|
||||
}
|
||||
return ready as isize;
|
||||
}
|
||||
if timeout == 0 { return 0; }
|
||||
if timeout > 0 {
|
||||
let elapsed = (crate::time::get_ticks() - start) as i32;
|
||||
if elapsed >= timeout { return 0; }
|
||||
}
|
||||
let target = crate::time::get_ticks() + 1;
|
||||
// println removed for no_std compatibility
|
||||
// println removed for no_std compatibility
|
||||
}
|
||||
}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
//! Health Monitoring
|
||||
//!
|
||||
//! This module provides health monitoring functionality for the kernel.
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::string::String;
|
||||
use alloc::string::ToString;
|
||||
use spin::Mutex;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
/// Health level
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum HealthLevel {
|
||||
/// Healthy
|
||||
Healthy = 0,
|
||||
/// Degraded
|
||||
Degraded = 1,
|
||||
/// Critical
|
||||
Critical = 2,
|
||||
/// Unknown
|
||||
Unknown = 3,
|
||||
}
|
||||
|
||||
/// Health severity
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum HealthSeverity {
|
||||
/// Info
|
||||
Info = 0,
|
||||
/// Warning
|
||||
Warning = 1,
|
||||
/// Error
|
||||
Error = 2,
|
||||
/// Critical
|
||||
Critical = 3,
|
||||
}
|
||||
|
||||
/// Health metric
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HealthMetric {
|
||||
/// Metric name
|
||||
pub name: String,
|
||||
/// Metric description
|
||||
pub description: String,
|
||||
/// Metric unit
|
||||
pub unit: String,
|
||||
/// Current value
|
||||
pub current_value: f64,
|
||||
/// Minimum value
|
||||
pub min_value: f64,
|
||||
/// Maximum value
|
||||
pub max_value: f64,
|
||||
/// Last updated timestamp
|
||||
pub last_updated: u64,
|
||||
}
|
||||
|
||||
/// Health threshold
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HealthThreshold {
|
||||
/// Threshold name
|
||||
pub name: String,
|
||||
/// Metric name
|
||||
pub metric_name: String,
|
||||
/// Minimum value
|
||||
pub min_value: f64,
|
||||
/// Maximum value
|
||||
pub max_value: f64,
|
||||
/// Severity
|
||||
pub severity: HealthSeverity,
|
||||
}
|
||||
|
||||
/// Health status
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct HealthStatus {
|
||||
/// Overall health level
|
||||
pub overall_health: HealthLevel,
|
||||
/// Last checked timestamp
|
||||
pub last_checked: u64,
|
||||
/// Active alerts
|
||||
pub active_alerts: u32,
|
||||
}
|
||||
|
||||
/// Health statistics
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct HealthStats {
|
||||
/// Total metrics checked
|
||||
pub total_metrics: u64,
|
||||
/// Total thresholds violated
|
||||
pub total_threshold_violations: u64,
|
||||
/// Last reset timestamp
|
||||
pub last_reset: u64,
|
||||
}
|
||||
|
||||
/// Health monitor
|
||||
#[derive(Default)]
|
||||
pub struct HealthMonitor {
|
||||
/// Health metrics
|
||||
metrics: BTreeMap<String, HealthMetric>,
|
||||
/// Health thresholds
|
||||
thresholds: BTreeMap<String, HealthThreshold>,
|
||||
/// Health status
|
||||
status: Mutex<HealthStatus>,
|
||||
/// Health statistics
|
||||
stats: Mutex<HealthStats>,
|
||||
}
|
||||
|
||||
impl HealthMonitor {
|
||||
/// Create a new health monitor
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Add a health metric
|
||||
pub fn add_metric(&mut self, metric: HealthMetric) {
|
||||
self.metrics.insert(metric.name.clone(), metric);
|
||||
}
|
||||
|
||||
/// Add a health threshold
|
||||
pub fn add_threshold(&mut self, threshold: HealthThreshold) {
|
||||
self.thresholds.insert(threshold.name.clone(), threshold);
|
||||
}
|
||||
|
||||
/// Update a metric value
|
||||
pub fn update_metric(&mut self, name: &str, value: f64) -> crate::error::UnifiedResult<()> {
|
||||
let metric = self.metrics.get_mut(name)
|
||||
.ok_or_else(|| crate::error::create_error(
|
||||
crate::error::ErrorSeverity::Error,
|
||||
crate::error::ProcessError::NotFound,
|
||||
"Metric not found".to_string(),
|
||||
))?;
|
||||
metric.current_value = value;
|
||||
metric.last_updated = crate::common::get_timestamp();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get current health status
|
||||
pub fn get_current_status(&self) -> HealthStatus {
|
||||
*self.status.lock()
|
||||
}
|
||||
|
||||
/// Get health statistics
|
||||
pub fn get_stats(&self) -> HealthStats {
|
||||
*self.stats.lock()
|
||||
}
|
||||
}
|
||||
|
||||
/// Global health monitor
|
||||
static HEALTH_MONITOR: spin::Once<HealthMonitor> = spin::Once::new();
|
||||
|
||||
/// Initialize health monitor
|
||||
pub fn init_health_monitor() -> crate::error::UnifiedResult<()> {
|
||||
HEALTH_MONITOR.call_once(|| HealthMonitor::new());
|
||||
crate::log_info!("Health monitor initialized");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get health monitor
|
||||
pub fn get_health_monitor() -> &'static HealthMonitor {
|
||||
HEALTH_MONITOR.get().expect("Health monitor not initialized")
|
||||
}
|
||||
|
|
@ -10,8 +10,6 @@ use alloc::vec::Vec;
|
|||
/// Initialize error handling subsystem
|
||||
pub fn init() -> crate::error::UnifiedResult<()> {
|
||||
crate::log_info!("Error handling subsystem initialized");
|
||||
init_health_monitor()?;
|
||||
init_framework()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -51,14 +49,6 @@ pub use unified_framework::{
|
|||
init_framework, shutdown_framework,
|
||||
};
|
||||
|
||||
// Health monitoring
|
||||
pub mod health;
|
||||
pub use health::{
|
||||
HealthLevel, HealthSeverity, HealthMetric, HealthThreshold,
|
||||
HealthStatus, HealthStats, HealthMonitor,
|
||||
init_health_monitor, get_health_monitor,
|
||||
};
|
||||
|
||||
// TODO: Implement and re-export errno types
|
||||
// pub use errno::{Errno, set_errno, get_errno};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ use alloc::string::String;
|
|||
use alloc::format;
|
||||
use alloc::vec::Vec;
|
||||
use core::panic::PanicInfo;
|
||||
use crate::error::{UnifiedError, ErrorContext, ErrorSeverity, handle_error};
|
||||
use crate::log_error; use crate::log_info;
|
||||
use nos_error_handling::types::{ErrorRecord, ErrorSeverity, ErrorCategory};
|
||||
use nos_error_handling::reporting::report_error;
|
||||
|
||||
/// Structured crash information
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -424,21 +424,59 @@ pub fn format_crash_report(crash_info: &CrashInfo) -> String {
|
|||
|
||||
/// Report crash to error reporting system
|
||||
pub fn report_crash(crash_info: &CrashInfo) {
|
||||
// Create unified error from crash info
|
||||
let error = UnifiedError::Other(format!("Kernel panic: {}", crash_info.message));
|
||||
use nos_error_handling::types::{ErrorType, ErrorStatus, ErrorSource, ErrorContext as ErrCtx, RecoveryAction};
|
||||
|
||||
// Create error context
|
||||
let location = crash_info.file.clone().unwrap_or_else(|| "unknown".to_string());
|
||||
let context = format!("{}:{} on CPU {}", location, crash_info.line.unwrap_or(0), crash_info.cpu_id);
|
||||
|
||||
// Handle the error using kernel's internal error handling
|
||||
let action = handle_error(error, &context);
|
||||
|
||||
// Log the result
|
||||
match action {
|
||||
crate::error::ErrorAction::Log => log_info!("[panic] Crash logged successfully"),
|
||||
crate::error::ErrorAction::Panic => log_error!("[panic] Crash reported as panic"),
|
||||
_ => log_info!("[panic] Crash handled with action: {:?}", action),
|
||||
// Create error record from crash info
|
||||
let mut error_record = ErrorRecord {
|
||||
id: crash_info.timestamp,
|
||||
code: 0xDEADBEEF, // Panic error code
|
||||
error_type: ErrorType::SystemCallError,
|
||||
category: ErrorCategory::System,
|
||||
severity: ErrorSeverity::Fatal,
|
||||
status: ErrorStatus::Active,
|
||||
message: format!("Kernel panic: {}", crash_info.message),
|
||||
description: format!("Kernel panic occurred at {:?}:{:?} on CPU {}",
|
||||
crash_info.file, crash_info.line, crash_info.cpu_id),
|
||||
source: ErrorSource {
|
||||
module: crash_info.file.clone().unwrap_or_else(|| "unknown".to_string()),
|
||||
function: "panic_handler".to_string(),
|
||||
file: crash_info.file.clone().unwrap_or_else(|| "unknown".to_string()),
|
||||
line: crash_info.line.unwrap_or(0),
|
||||
column: crash_info.column.unwrap_or(0),
|
||||
process_id: crash_info.pid.map(|p| p as u32).unwrap_or(0),
|
||||
thread_id: 0,
|
||||
cpu_id: crash_info.cpu_id as u32,
|
||||
},
|
||||
timestamp: crash_info.timestamp,
|
||||
context: ErrCtx::default(),
|
||||
recovery_actions: Vec::new(),
|
||||
occurrence_count: 1,
|
||||
last_occurrence: crash_info.timestamp,
|
||||
resolved: false,
|
||||
resolution_time: None,
|
||||
resolution_method: None,
|
||||
metadata: {
|
||||
let mut meta = alloc::collections::BTreeMap::new();
|
||||
meta.insert("panic_message".to_string(), crash_info.message.clone());
|
||||
if let Some(ref file) = crash_info.file {
|
||||
meta.insert("panic_file".to_string(), file.clone());
|
||||
}
|
||||
if let Some(line) = crash_info.line {
|
||||
meta.insert("panic_line".to_string(), line.to_string());
|
||||
}
|
||||
meta.insert("cpu_id".to_string(), crash_info.cpu_id.to_string());
|
||||
if let Some(pid) = crash_info.pid {
|
||||
meta.insert("pid".to_string(), pid.to_string());
|
||||
}
|
||||
meta
|
||||
},
|
||||
};
|
||||
|
||||
// Try to report to error reporting system
|
||||
if let Ok(_) = report_error(&error_record) {
|
||||
crate::println!("[panic] Crash reported to error reporting system");
|
||||
} else {
|
||||
crate::println!("[panic] Warning: Failed to report crash to error reporting system");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,19 @@ pub trait IntoFrameworkError {
|
|||
}
|
||||
|
||||
/// Error conversion implementation for UnifiedError
|
||||
|
||||
impl IntoFrameworkError for UnifiedError {
|
||||
fn into_framework_error(self) -> FrameworkError {
|
||||
FrameworkError::Unified(self)
|
||||
}
|
||||
|
||||
fn with_context(self, context: &str, location: &str) -> FrameworkError {
|
||||
FrameworkError::Contextual {
|
||||
error: self,
|
||||
context: context.to_string(),
|
||||
location: location.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Error conversion implementation for &str
|
||||
impl IntoFrameworkError for &str {
|
||||
|
|
@ -122,7 +134,6 @@ pub trait FrameworkErrorHandler: Send + Sync + 'static {
|
|||
pub struct FrameworkErrorManager {
|
||||
inner: super::ErrorManager,
|
||||
handlers: alloc::vec::Vec<Box<dyn FrameworkErrorHandler>>,
|
||||
recovery_strategies: alloc::vec::Vec<Box<dyn ErrorRecovery>>,
|
||||
}
|
||||
|
||||
impl FrameworkErrorManager {
|
||||
|
|
@ -131,7 +142,6 @@ impl FrameworkErrorManager {
|
|||
Self {
|
||||
inner: super::ErrorManager::new(),
|
||||
handlers: alloc::vec::Vec::new(),
|
||||
recovery_strategies: alloc::vec::Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,11 +150,6 @@ impl FrameworkErrorManager {
|
|||
self.handlers.push(handler);
|
||||
}
|
||||
|
||||
/// Add an error recovery strategy
|
||||
pub fn add_recovery_strategy(&mut self, strategy: Box<dyn ErrorRecovery>) {
|
||||
self.recovery_strategies.push(strategy);
|
||||
}
|
||||
|
||||
/// Handle an error using the framework
|
||||
pub fn handle_framework_error(&self, error: FrameworkError) -> ErrorAction {
|
||||
// Try framework handlers first
|
||||
|
|
@ -157,13 +162,6 @@ impl FrameworkErrorManager {
|
|||
}
|
||||
}
|
||||
|
||||
// Try recovery strategies
|
||||
for strategy in &self.recovery_strategies {
|
||||
if strategy.recover(&error) {
|
||||
return ErrorAction::Recover;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to inner error manager
|
||||
match &error {
|
||||
FrameworkError::Unified(e) => {
|
||||
|
|
@ -172,9 +170,8 @@ impl FrameworkErrorManager {
|
|||
FrameworkError::Contextual { error, context, location } => {
|
||||
self.inner.handle_error(error.clone(), &format!("{} at {}", context, location))
|
||||
}
|
||||
FrameworkError::Chain { error, cause } => {
|
||||
let context = format!("caused by: {}", cause);
|
||||
self.inner.handle_error(error.clone(), &context)
|
||||
FrameworkError::Chain { error, cause: _ } => {
|
||||
self.inner.handle_error(error.clone(), "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -276,9 +273,8 @@ impl fmt::Display for FrameworkError {
|
|||
impl core::error::Error for FrameworkError {
|
||||
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
|
||||
match self {
|
||||
FrameworkError::Chain { cause, .. } => Some(cause.as_ref()),
|
||||
FrameworkError::Contextual { error, .. } => Some(error),
|
||||
FrameworkError::Unified(e) => Some(e),
|
||||
FrameworkError::Chain { cause, .. } => Some(cause),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -292,8 +288,7 @@ pub fn init_framework() -> FrameworkResult<()> {
|
|||
|
||||
// Add default recovery strategy
|
||||
let recovery = DefaultErrorRecovery;
|
||||
let mut manager = super::get_error_manager();
|
||||
manager.add_recovery_strategy(Box::new(recovery));
|
||||
// TODO: Register recovery strategy
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
//! This ensures consistent error reporting across all layers of the kernel.
|
||||
|
||||
use crate::error::unified::UnifiedError;
|
||||
use crate::syscalls::api::syscall_result::SyscallError as ApiSyscallError;
|
||||
use crate::syscalls::interface::SyscallError as InterfaceSyscallError;
|
||||
use crate::subsystems::syscalls::api::syscall_result::SyscallError as ApiSyscallError;
|
||||
use crate::subsystems::syscalls::interface::SyscallError as InterfaceSyscallError;
|
||||
use nos_error_handling::kernel_integration::ErrorType as NosErrorType;
|
||||
|
||||
/// POSIX errno values
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ use alloc::{
|
|||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use nos_api::{
|
||||
core::EventHandler,
|
||||
event::{
|
||||
Event, EventDispatcher,
|
||||
Event, EventHandler, EventDispatcher, EventBus, EventFilter, EventId,
|
||||
EventType, EventMetadata,
|
||||
},
|
||||
Result,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ use alloc::{
|
|||
};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use nos_api::{
|
||||
core::EventHandler,
|
||||
event::{
|
||||
Event, EventDispatcher,
|
||||
Event, EventHandler, EventDispatcher, EventFilter, EventId, EventType,
|
||||
EventMetadata, EventPriority,
|
||||
},
|
||||
Result,
|
||||
};
|
||||
|
|
@ -23,7 +23,7 @@ pub trait EventDispatcherExt {
|
|||
/// Default implementation of an EventDispatcher
|
||||
pub struct DefaultEventDispatcher {
|
||||
/// Map of event type to handlers
|
||||
handlers: BTreeMap<&'static str, Vec<Arc<dyn EventHandler<Event = Box<dyn Event>>>>>,
|
||||
handlers: BTreeMap<&'static str, Vec<Arc<dyn EventHandler>>>,
|
||||
/// Map of event type to filters
|
||||
filters: BTreeMap<&'static str, Vec<Arc<dyn EventFilter>>>,
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ impl DefaultEventDispatcher {
|
|||
|
||||
/// Generate a unique event ID
|
||||
fn generate_event_id(&self) -> EventId {
|
||||
self.event_counter.fetch_add(1, Ordering::SeqCst)
|
||||
EventId(self.event_counter.fetch_add(1, Ordering::SeqCst))
|
||||
}
|
||||
|
||||
/// Check if an event passes all registered filters
|
||||
|
|
@ -187,9 +187,9 @@ impl EventDispatcher for DefaultEventDispatcher {
|
|||
}
|
||||
|
||||
impl EventHandler for DefaultEventDispatcher {
|
||||
type Event = Box<dyn Event>;
|
||||
type Event = dyn Event;
|
||||
|
||||
fn handle(&mut self, event: &Box<dyn Event>) -> Result<()> {
|
||||
fn handle(&self, event: &dyn Event) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ use alloc::{
|
|||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use nos_api::{
|
||||
core::EventHandler,
|
||||
event::{
|
||||
Event, EventDispatcher, EventMetadata, EventType, EventPriority, EventFilter,
|
||||
SystemEventData, MemoryEventData, ProcessEventData,
|
||||
Event, EventHandler, EventDispatcher, EventBus, EventFilter, EventId,
|
||||
EventType, EventMetadata, EventPriority,
|
||||
SystemEvent, MemoryEvent, ProcessEvent, FileSystemEvent,
|
||||
NetworkEvent, SecurityEvent, HardwareEvent, UserEvent,
|
||||
},
|
||||
Result,
|
||||
};
|
||||
|
|
@ -185,7 +186,7 @@ impl Default for EventSystem {
|
|||
/// Convenience functions for creating common event types
|
||||
pub mod events {
|
||||
use super::*;
|
||||
// use nos_api::event::{SystemEventData, MemoryEventData, ProcessEventData};
|
||||
use nos_api::event::{SystemEventData, MemoryEventData, ProcessEventData};
|
||||
|
||||
/// Create a system boot event
|
||||
pub fn system_boot_event(stage: String) -> Box<dyn Event> {
|
||||
|
|
@ -253,22 +254,22 @@ pub fn publish(event: Box<dyn Event>) -> Result<()> {
|
|||
}
|
||||
|
||||
/// Subscribe to events using the global event system
|
||||
pub fn subscribe(event_type: &str, handler: Arc<dyn EventHandler<Event = Box<dyn Event>>>) -> Result<()> {
|
||||
pub fn subscribe(event_type: &str, handler: Arc<dyn EventHandler>) -> Result<()> {
|
||||
EventSystem::global().subscribe(event_type, handler)
|
||||
}
|
||||
|
||||
/// Subscribe to all events using the global event system
|
||||
pub fn subscribe_all(handler: Arc<dyn EventHandler<Event = Box<dyn Event>>>) -> Result<()> {
|
||||
pub fn subscribe_all(handler: Arc<dyn EventHandler>) -> Result<()> {
|
||||
EventSystem::global().subscribe_all(handler)
|
||||
}
|
||||
|
||||
/// Unsubscribe from events of a specific type
|
||||
pub fn unsubscribe(event_type: &str, handler: &Arc<dyn EventHandler<Event = Box<dyn Event>>>) -> Result<()> {
|
||||
pub fn unsubscribe(event_type: &str, handler: &Arc<dyn EventHandler>) -> Result<()> {
|
||||
EventSystem::global().unsubscribe(event_type, handler)
|
||||
}
|
||||
|
||||
/// Unsubscribe from all events
|
||||
pub fn unsubscribe_all(handler: &Arc<dyn EventHandler<Event = Box<dyn Event>>>) -> Result<()> {
|
||||
pub fn unsubscribe_all(handler: &Arc<dyn EventHandler>) -> Result<()> {
|
||||
EventSystem::global().unsubscribe_all(handler)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1487,6 +1487,9 @@ pub enum ClassificationModel {
|
|||
}
|
||||
|
||||
/// 主机入侵检测统计
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
||||
|
||||
impl HostIds {
|
||||
/// 创建新的主机入侵检测系统
|
||||
pub fn new() -> Self {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ pub mod process;
|
|||
pub mod registry;
|
||||
pub mod network;
|
||||
pub mod user;
|
||||
pub mod integrity;
|
||||
pub mod malware;
|
||||
|
||||
// 临时:保留原有文件作为过渡
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ impl SignatureEngine {
|
|||
}
|
||||
|
||||
/// Check if data matches a signature
|
||||
fn matches_signature(&self, data: &[u8], signature: &Signature, _context: &HashMap<String, String>) -> bool {
|
||||
fn matches_signature(&self, data: &[u8], signature: &Signature, context: &HashMap<String, String>) -> bool {
|
||||
match signature.pattern_type {
|
||||
PatternType::Exact => {
|
||||
let pattern_bytes = signature.pattern.as_bytes();
|
||||
|
|
|
|||
|
|
@ -270,8 +270,6 @@ impl ThreatIntelligence {
|
|||
for d in data {
|
||||
// Insert simple indicator placeholders
|
||||
let id = self.indicator_counter.fetch_add(1, Ordering::SeqCst);
|
||||
// Use id for validation/logging
|
||||
let _indicator_id = id; // Use id for validation
|
||||
let indicator = ThreatIndicator {
|
||||
value: d.threat_id.clone(),
|
||||
indicator_type: IndicatorType::IPAddress,
|
||||
|
|
@ -371,8 +369,6 @@ impl ThreatIntelligence {
|
|||
|
||||
let mut matches = Vec::new();
|
||||
|
||||
// Use context for validation/logging
|
||||
let _context_size = context.len(); // Use context to get context size for validation
|
||||
// Check for exact matches first
|
||||
if let Some(indicator) = self.indicators.get(value) {
|
||||
if indicator.active && !self.is_expired(indicator.expires_at) {
|
||||
|
|
@ -395,8 +391,6 @@ impl ThreatIntelligence {
|
|||
};
|
||||
|
||||
if partial_match && indicator_value != value {
|
||||
// Use context for validation/logging
|
||||
let _context_keys = context.keys().count(); // Use context to get key count for validation
|
||||
let threat_match = self.create_threat_match(indicator.clone(), context);
|
||||
matches.push(threat_match);
|
||||
}
|
||||
|
|
@ -525,8 +519,6 @@ impl ThreatIntelligence {
|
|||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
// Use current_time for validation/logging
|
||||
let _timestamp = current_time; // Use current_time for validation
|
||||
|
||||
let mut expired_values = Vec::new();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,8 @@
|
|||
//!
|
||||
//! 本模块提供工厂模式创建和管理内核内部模块,减少lib.rs的直接依赖。
|
||||
|
||||
use nos_api::{Result, di::{ServiceLocator, Container}};
|
||||
use nos_syscalls::SyscallDispatcher;
|
||||
use crate::syscall_interface::ServiceManager;
|
||||
// use nos_api::interfaces::EventPublisher;
|
||||
use nos_api::{Result, ServiceLocator, Container};
|
||||
use nos_api::interfaces::{SyscallDispatcher, ServiceManager, EventPublisher};
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
#![no_std]
|
||||
#![allow(dead_code)]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
|
@ -76,7 +75,7 @@ pub mod error;
|
|||
mod kernel_factory;
|
||||
|
||||
// Include necessary internal modules for library
|
||||
// pub mod arch;
|
||||
pub mod arch;
|
||||
pub mod subsystems;
|
||||
pub mod platform;
|
||||
|
||||
|
|
@ -101,6 +100,7 @@ pub use subsystems::fs;
|
|||
pub use subsystems::vfs;
|
||||
pub use subsystems::ipc;
|
||||
pub use subsystems::process;
|
||||
pub use subsystems::mm;
|
||||
pub use subsystems::sync;
|
||||
pub use subsystems::time;
|
||||
|
||||
|
|
@ -183,6 +183,7 @@ mod di;
|
|||
mod ids;
|
||||
mod libc;
|
||||
// Legacy modules - now accessed through subsystems
|
||||
mod mm;
|
||||
mod sched;
|
||||
mod monitoring;
|
||||
mod perf;
|
||||
|
|
@ -190,6 +191,8 @@ pub mod posix;
|
|||
mod security;
|
||||
#[cfg(feature = "security_audit")]
|
||||
mod security_audit;
|
||||
mod sync;
|
||||
mod time;
|
||||
mod procfs;
|
||||
|
||||
#[cfg(not(feature = "cloud_native"))]
|
||||
|
|
|
|||
|
|
@ -379,45 +379,45 @@ impl CLibInterface for UnifiedCLib {
|
|||
10 // 模拟换行符
|
||||
}
|
||||
|
||||
fn fopen(&self, filename: *const c_char, _mode: *const c_char) -> *mut c_void {
|
||||
fn fopen(&self, filename: *const c_char, mode: *const c_char) -> *mut c_void {
|
||||
crate::println!("[unified] fopen called");
|
||||
core::ptr::null_mut()
|
||||
}
|
||||
|
||||
fn fclose(&self, _stream: *mut c_void) -> c_int {
|
||||
fn fclose(&self, stream: *mut c_void) -> c_int {
|
||||
crate::println!("[unified] fclose called");
|
||||
0
|
||||
}
|
||||
|
||||
fn fread(&self, ptr: *mut c_void, _size: size_t, nmemb: size_t, _stream: *mut c_void) -> size_t {
|
||||
fn fread(&self, ptr: *mut c_void, size: size_t, nmemb: size_t, stream: *mut c_void) -> size_t {
|
||||
0
|
||||
}
|
||||
|
||||
fn fwrite(&self, ptr: *const c_void, _size: size_t, nmemb: size_t, _stream: *mut c_void) -> size_t {
|
||||
fn fwrite(&self, ptr: *const c_void, size: size_t, nmemb: size_t, stream: *mut c_void) -> size_t {
|
||||
0
|
||||
}
|
||||
|
||||
fn fseek(&self, _stream: *mut c_void, offset: c_long, whence: c_int) -> c_int {
|
||||
fn fseek(&self, stream: *mut c_void, offset: c_long, whence: c_int) -> c_int {
|
||||
-1
|
||||
}
|
||||
|
||||
fn ftell(&self, _stream: *mut c_void) -> c_long {
|
||||
fn ftell(&self, stream: *mut c_void) -> c_long {
|
||||
-1
|
||||
}
|
||||
|
||||
fn fflush(&self, _stream: *mut c_void) -> c_int {
|
||||
fn fflush(&self, stream: *mut c_void) -> c_int {
|
||||
0
|
||||
}
|
||||
|
||||
fn feof(&self, _stream: *mut c_void) -> c_int {
|
||||
fn feof(&self, stream: *mut c_void) -> c_int {
|
||||
0
|
||||
}
|
||||
|
||||
fn ferror(&self, _stream: *mut c_void) -> c_int {
|
||||
fn ferror(&self, stream: *mut c_void) -> c_int {
|
||||
0
|
||||
}
|
||||
|
||||
fn clearerr(&self, _stream: *mut c_void) {
|
||||
fn clearerr(&self, stream: *mut c_void) {
|
||||
}
|
||||
|
||||
// 字符串转换函数 - 使用增强字符串库
|
||||
|
|
@ -487,9 +487,6 @@ impl CLibInterface for UnifiedCLib {
|
|||
}
|
||||
|
||||
fn strerror(&self, errnum: c_int) -> *const c_char {
|
||||
// 使用 errnum 获取错误消息
|
||||
// TODO: 根据 errnum 返回对应的错误消息
|
||||
let _error_number = errnum; // 使用 errnum 进行验证
|
||||
static ERROR_MSG: &[u8] = b"Unknown error\0";
|
||||
ERROR_MSG.as_ptr() as *const c_char
|
||||
}
|
||||
|
|
@ -515,22 +512,11 @@ impl CLibInterface for UnifiedCLib {
|
|||
self.env_manager.unsetenv(name)
|
||||
}
|
||||
|
||||
fn qsort(&self, base: *mut c_void, nmemb: size_t, _size: size_t, compar: extern "C" fn(*const c_void, *const c_void) -> c_int) {
|
||||
// 使用 base 和 nmemb 进行排序操作
|
||||
// TODO: 实现实际的排序逻辑
|
||||
let _base_ptr = base; // 使用 base 进行验证
|
||||
let _element_count = nmemb; // 使用 nmemb 进行验证
|
||||
let _compare_func = compar; // 使用 compar 进行验证
|
||||
fn qsort(&self, base: *mut c_void, nmemb: size_t, size: size_t, compar: extern "C" fn(*const c_void, *const c_void) -> c_int) {
|
||||
crate::println!("[unified] qsort called");
|
||||
}
|
||||
|
||||
fn bsearch(&self, key: *const c_void, base: *const c_void, nmemb: size_t, _size: size_t, compar: extern "C" fn(*const c_void, *const c_void) -> c_int) -> *mut c_void {
|
||||
// 使用 key, base, nmemb 进行二分查找操作
|
||||
// TODO: 实现实际的二分查找逻辑
|
||||
let _key_ptr = key; // 使用 key 进行验证
|
||||
let _base_ptr = base; // 使用 base 进行验证
|
||||
let _element_count = nmemb; // 使用 nmemb 进行验证
|
||||
let _compare_func = compar; // 使用 compar 进行验证
|
||||
fn bsearch(&self, key: *const c_void, base: *const c_void, nmemb: size_t, size: size_t, compar: extern "C" fn(*const c_void, *const c_void) -> c_int) -> *mut c_void {
|
||||
core::ptr::null_mut()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -228,9 +228,6 @@ impl EnhancedIOManager {
|
|||
}
|
||||
};
|
||||
|
||||
// Use vfs_file for validation/logging
|
||||
let _file_size = vfs_file.stat().map(|attr| attr.size).unwrap_or(0); // Use vfs_file to get file size for validation
|
||||
|
||||
// 获取文件描述符
|
||||
let fd = self.allocate_fd();
|
||||
if fd < 0 {
|
||||
|
|
@ -566,8 +563,6 @@ impl EnhancedIOManager {
|
|||
let flushes = self.stats.flush_operations.load(Ordering::SeqCst);
|
||||
let errors = self.stats.error_count.load(Ordering::SeqCst);
|
||||
let formats = self.stats.format_operations.load(Ordering::SeqCst);
|
||||
// Use errors for validation/logging (already used in println below)
|
||||
let _error_count = errors; // Use errors for validation
|
||||
|
||||
crate::println!("\n=== 增强I/O管理器统计报告 ===");
|
||||
crate::println!("读取操作: {}", reads);
|
||||
|
|
@ -732,10 +727,6 @@ impl EnhancedIOManager {
|
|||
|
||||
/// 直接从文件读取
|
||||
fn read_direct(&self, file: *mut CFile, buffer: &mut [u8]) -> Result<usize, c_int> {
|
||||
// Use file for validation
|
||||
if file.is_null() {
|
||||
return Err(crate::reliability::errno::EBADF);
|
||||
}
|
||||
// 这里应该调用实际的VFS读取操作
|
||||
// 暂时返回模拟数据
|
||||
Ok(buffer.len())
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ impl SystemEntropy {
|
|||
fn get_system_state(&self) -> usize {
|
||||
// 使用栈指针、寄存器等作为熵源
|
||||
// 在实际实现中,这里应该使用真正的硬件随机数生成器
|
||||
let pointer = 0usize;
|
||||
let mut pointer = 0usize;
|
||||
// 编译器优化:使用栈地址作为熵源
|
||||
unsafe {
|
||||
core::ptr::read_volatile(&pointer);
|
||||
|
|
|
|||
|
|
@ -285,12 +285,6 @@ impl EnhancedStringLib {
|
|||
let mut sign = 1;
|
||||
let mut actual_base = base;
|
||||
|
||||
// Use base for validation
|
||||
if base < 0 || base == 1 || base > 36 {
|
||||
// Invalid base, will be determined from string
|
||||
actual_base = 0;
|
||||
}
|
||||
|
||||
// 跳过空白字符
|
||||
while (*ptr as u8).is_ascii_whitespace() {
|
||||
ptr = ptr.add(1);
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ impl EnhancedSystemInfo {
|
|||
|
||||
let utsname = if self.config.enable_caching && self.is_cache_valid() {
|
||||
// 使用缓存数据
|
||||
if let Some(cached) = self.cached_utsname.try_lock() {
|
||||
if let Some(mut cached) = self.cached_utsname.try_lock() {
|
||||
if cached.is_some() {
|
||||
self.stats.cache_hits.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
|
||||
cached.clone().unwrap()
|
||||
|
|
@ -275,7 +275,7 @@ impl EnhancedSystemInfo {
|
|||
|
||||
let sysinfo = if self.config.enable_caching && self.is_cache_valid() {
|
||||
// 使用缓存数据
|
||||
if let Some(cached) = self.cached_sysinfo.try_lock() {
|
||||
if let Some(mut cached) = self.cached_sysinfo.try_lock() {
|
||||
if cached.is_some() {
|
||||
self.stats.cache_hits.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
|
||||
cached.clone().unwrap()
|
||||
|
|
|
|||
|
|
@ -441,8 +441,8 @@ impl EnhancedTimeLib {
|
|||
}
|
||||
|
||||
// 简化的日期计算(不考虑闰年等复杂情况)
|
||||
let year = 1970 + (days / 365) as c_int;
|
||||
let day_of_year = (days % 365) as c_int;
|
||||
let mut year = 1970 + (days / 365) as c_int;
|
||||
let mut day_of_year = (days % 365) as c_int;
|
||||
|
||||
// 简化的月份计算
|
||||
let month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
|
|
|
|||
|
|
@ -985,7 +985,7 @@ mod aarch64 {
|
|||
core::ptr::write_bytes(new_subpt, 0, super::PAGE_SIZE);
|
||||
|
||||
// Copy the intermediate PTE to the new page table
|
||||
let pa = old_pte & !0xFFF;
|
||||
let pa = (old_pte & !0xFFF);
|
||||
|
||||
(*new_pt).entries[i] = (new_subpt as usize) | DESC_TABLE | (old_pte & 0xFFF);
|
||||
|
||||
|
|
@ -1363,7 +1363,7 @@ mod x86_64 {
|
|||
core::ptr::write_bytes(new_subpt, 0, PAGE_SIZE);
|
||||
|
||||
// Copy the intermediate PTE to the new page table
|
||||
let pa = old_pte & !0xFFF;
|
||||
let pa = (old_pte & !0xFFF);
|
||||
|
||||
(*new_pt).entries[i] = (new_subpt as usize) | (old_pte & 0xFFF);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
// supporting both legacy direct boot and modern bootloader interfaces.
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use core::ptr;
|
||||
|
||||
|
||||
|
|
@ -329,9 +330,6 @@ pub fn print_boot_info() {
|
|||
/// Initialize memory management from boot information
|
||||
pub fn init_memory_from_boot_info() {
|
||||
if let Some(params) = get_boot_parameters() {
|
||||
// Use params for validation/logging
|
||||
let _boot_params = ¶ms; // Use params for validation
|
||||
|
||||
// Initialize memory management using bootloader-provided memory map
|
||||
if let Some(memory_map) = get_memory_map() {
|
||||
crate::println!("[boot] Initializing memory from bootloader memory map");
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use core::sync::atomic::{AtomicUsize, AtomicU64, Ordering};
|
|||
use core::ptr;
|
||||
|
||||
/// Thread attribute structure
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ThreadAttr {
|
||||
/// Scheduling policy
|
||||
pub sched_policy: i32,
|
||||
|
|
@ -493,6 +493,7 @@ pub enum ThreadError {
|
|||
pub static THREAD_REGISTRY: Mutex<ThreadRegistry> = Mutex::new(ThreadRegistry::new());
|
||||
|
||||
/// Thread registry for managing advanced thread features
|
||||
#[derive(Debug)]
|
||||
pub struct ThreadRegistry {
|
||||
/// Map from thread ID to thread attributes
|
||||
pub thread_attrs: BTreeMap<Pid, ThreadAttr>,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ use alloc::string::String;
|
|||
use alloc::vec::Vec;
|
||||
use alloc::string::ToString;
|
||||
|
||||
/// Integration test result
|
||||
pub type IntegrationResult = Result<(), String>;
|
||||
|
||||
/// Integration test context
|
||||
pub struct IntegrationTestContext {
|
||||
/// Test name
|
||||
|
|
@ -30,8 +33,8 @@ impl IntegrationTestContext {
|
|||
/// Create a new integration test context
|
||||
pub fn new(name: &str, description: &str) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
description: description.into(),
|
||||
name: name.to_string(),
|
||||
description: description.to_string(),
|
||||
steps: Vec::new(),
|
||||
current_step: 0,
|
||||
}
|
||||
|
|
@ -39,13 +42,13 @@ impl IntegrationTestContext {
|
|||
|
||||
/// Add a test step
|
||||
pub fn add_step(&mut self, step: &str) {
|
||||
self.steps.push(step.into());
|
||||
self.steps.push(step.to_string());
|
||||
self.current_step += 1;
|
||||
crate::println!("[integration] {}: Step {}: {}", self.name, self.current_step, step);
|
||||
}
|
||||
|
||||
/// Complete test
|
||||
pub fn complete(&mut self, success: bool) -> bool {
|
||||
pub fn complete(&mut self, success: bool) {
|
||||
if success {
|
||||
crate::println!("[integration] {}: COMPLETED - All {} steps passed",
|
||||
self.name, self.steps.len());
|
||||
|
|
@ -53,7 +56,6 @@ impl IntegrationTestContext {
|
|||
crate::println!("[integration] {}: FAILED at step {}",
|
||||
self.name, self.current_step);
|
||||
}
|
||||
success
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,23 +80,31 @@ impl IntegrationTestRunner {
|
|||
}
|
||||
|
||||
/// Run an integration test
|
||||
pub fn run_test<F>(&mut self, test_name: &str, test_fn: F)
|
||||
pub fn run_test<F>(&mut self, test_name: &str, test_fn: F) -> IntegrationResult
|
||||
where
|
||||
F: FnOnce(&mut IntegrationTestContext),
|
||||
F: FnOnce(&mut IntegrationTestContext) -> IntegrationResult,
|
||||
{
|
||||
let mut context = IntegrationTestContext::new(test_name, "");
|
||||
|
||||
crate::println!("[integration] Starting integration test: {}", test_name);
|
||||
|
||||
test_fn(&mut context);
|
||||
let result = test_fn(&mut context);
|
||||
|
||||
if context.complete(true) {
|
||||
self.tests_passed += 1;
|
||||
} else {
|
||||
self.tests_failed += 1;
|
||||
match result {
|
||||
Ok(()) => {
|
||||
context.complete(true);
|
||||
self.tests_passed += 1;
|
||||
}
|
||||
Err(error) => {
|
||||
context.complete(false);
|
||||
self.tests_failed += 1;
|
||||
return Err(error);
|
||||
}
|
||||
}
|
||||
|
||||
self.tests_run += 1;
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Print test summary
|
||||
|
|
|
|||
|
|
@ -950,7 +950,6 @@ pub struct InAddr {
|
|||
|
||||
/// Address families
|
||||
pub const AF_UNSPEC: i32 = 0; // Unspecified
|
||||
pub const AF_UNIX: i32 = 1; // Unix domain sockets
|
||||
pub const AF_INET: i32 = 2; // IPv4
|
||||
pub const AF_INET6: i32 = 10; // IPv6
|
||||
|
||||
|
|
@ -1750,7 +1749,7 @@ pub struct stat {
|
|||
// ============================================================================
|
||||
|
||||
/// POSIX semaphore type
|
||||
// pub type SemT = SemT;
|
||||
pub type SemT = SemT;
|
||||
|
||||
/// POSIX message queue descriptor type
|
||||
pub type MqdT = i32;
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ fn send_notification(mq: &MessageQueue) {
|
|||
pub extern "C" fn mq_open(
|
||||
name: *const i8,
|
||||
oflag: i32,
|
||||
_mode: crate::posix::Mode,
|
||||
mode: crate::posix::Mode,
|
||||
attr: *const MqAttr,
|
||||
) -> i32 {
|
||||
// Convert name to string
|
||||
|
|
|
|||
|
|
@ -1367,8 +1367,6 @@ impl GracefulDegradationManager {
|
|||
|
||||
// 更新质量指标
|
||||
for (metric_name, metric) in &mut controller.quality_metrics {
|
||||
// 使用 metric_name 记录指标名称(用于日志和调试)
|
||||
let _metric_name_ref = metric_name; // 使用 metric_name 进行验证
|
||||
match metric.metric_type {
|
||||
MetricType::ResponseTime => {
|
||||
metric.target_value *= 1.0 + quality_reduction;
|
||||
|
|
@ -1653,8 +1651,6 @@ impl GracefulDegradationManager {
|
|||
|
||||
// 恢复质量指标
|
||||
for (metric_name, metric) in &mut controller.quality_metrics {
|
||||
// 使用 metric_name 记录指标名称(用于日志和调试)
|
||||
let _metric_name_ref = metric_name; // 使用 metric_name 进行验证
|
||||
match metric.metric_type {
|
||||
MetricType::ResponseTime => {
|
||||
metric.target_value /= 1.0 + quality_restoration;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ extern crate alloc;
|
|||
use alloc::collections::VecDeque;
|
||||
use core::sync::atomic::{AtomicUsize, AtomicU32, AtomicU64, Ordering};
|
||||
use crate::subsystems::sync::SpinLock;
|
||||
use crate::arch::cpuid;
|
||||
use crate::arch::cpu_id;
|
||||
|
||||
/// 默认时间片(单位:ticks)
|
||||
pub const DEFAULT_TIMESLICE: u32 = 4;
|
||||
|
|
@ -115,10 +115,9 @@ pub struct StatsSnapshot {
|
|||
pub mod syscall {
|
||||
use super::O1Scheduler;
|
||||
use crate::process::thread::Tid;
|
||||
use crate::syscalls::common::SyscallError;
|
||||
use nos_api::syscall::SyscallResult;
|
||||
use crate::syscalls::common::{SyscallError, SyscallResult};
|
||||
use crate::subsystems::time::get_time_ns;
|
||||
use crate::arch::cpuid;
|
||||
use crate::arch::cpu_id;
|
||||
|
||||
/// 用户态 hint 调度:tid, prio, cpu_hint
|
||||
pub const SYS_SCHED_ENQUEUE_HINT: u32 = 0xE011;
|
||||
|
|
@ -328,7 +327,7 @@ static PER_CPU_SCHEDULERS: [PerCpuScheduler; MAX_CPUS] =
|
|||
|
||||
/// 获取当前CPU的调度器
|
||||
fn current_cpu_scheduler() -> &'static PerCpuScheduler {
|
||||
let cpu_id = cpuid() as usize;
|
||||
let cpu_id = cpu_id() as usize;
|
||||
&PER_CPU_SCHEDULERS[cpu_id % MAX_CPUS]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ use core::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
|
|||
use spin::Mutex;
|
||||
|
||||
use crate::types::stubs::{VirtAddr, RNG_INSTANCE};
|
||||
use nos_api::Error;
|
||||
use core::result::Result;
|
||||
use nos_api::{Result, Error};
|
||||
|
||||
/// ASLR entropy bits for different memory regions
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ extern crate alloc;
|
|||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
|
||||
/// POSIX capability constants (Linux capability numbering)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ extern crate alloc;
|
|||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use core::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
|
||||
use crate::arch;
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ impl LogManager {
|
|||
// 更新压缩统计
|
||||
{
|
||||
let mut stats = self.stats.lock();
|
||||
let comp_stats = &mut stats.compression_stats;
|
||||
let mut comp_stats = &mut stats.compression_stats;
|
||||
comp_stats.uncompressed_size += data.len() as u64;
|
||||
comp_stats.compressed_size += compressed.len() as u64;
|
||||
comp_stats.compression_time_us += elapsed / 1000;
|
||||
|
|
@ -316,7 +316,7 @@ impl LogManager {
|
|||
// 更新加密统计
|
||||
{
|
||||
let mut stats = self.stats.lock();
|
||||
let enc_stats = &mut stats.encryption_stats;
|
||||
let mut enc_stats = &mut stats.encryption_stats;
|
||||
enc_stats.encryption_operations += 1;
|
||||
enc_stats.encryption_time_us += elapsed / 1000;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -748,8 +748,6 @@ impl ReportGenerator {
|
|||
|
||||
/// 生成发现
|
||||
fn generate_findings_from_data(&self, data: &CollectedData) -> Result<Vec<Finding>, &'static str> {
|
||||
// Use data for validation/logging
|
||||
let _event_count = data.events.len(); // Use data to get event count for validation
|
||||
let mut findings = Vec::new();
|
||||
|
||||
// 简化的发现生成
|
||||
|
|
@ -768,8 +766,6 @@ impl ReportGenerator {
|
|||
|
||||
/// 生成分析部分
|
||||
fn generate_analysis_sections(&self, data: &CollectedData) -> Result<Vec<AnalysisSection>, &'static str> {
|
||||
// Use data for validation/logging
|
||||
let _event_count = data.events.len(); // Use data to get event count for validation
|
||||
let mut sections = Vec::new();
|
||||
|
||||
// 事件类型分析
|
||||
|
|
@ -795,8 +791,6 @@ impl ReportGenerator {
|
|||
|
||||
/// 生成建议
|
||||
fn generate_recommendations_from_data(&self, data: &CollectedData) -> Result<Vec<Recommendation>, &'static str> {
|
||||
// Use data for validation/logging
|
||||
let _event_count = data.events.len(); // Use data to get event count for validation
|
||||
let mut recommendations = Vec::new();
|
||||
|
||||
recommendations.push(Recommendation {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use alloc::sync::Arc;
|
|||
use spin::Mutex;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
|
||||
|
||||
/// cgroup版本
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ use crate::subsystems;
|
|||
use crate::reliability::errno::{EINVAL, ENOENT, ENOMEM, EIO};
|
||||
use alloc::string::String;
|
||||
use alloc::string::ToString;
|
||||
use alloc::format;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{format, vec};
|
||||
|
||||
/// 云原生服务ID
|
||||
pub const CLOUD_NATIVE_SERVICE_ID: u64 = 100;
|
||||
|
|
|
|||
|
|
@ -379,8 +379,6 @@ impl VirtIODevice {
|
|||
let mut stats = self.stats.lock();
|
||||
stats.queue_stats.clear();
|
||||
for (index, queue_config) in self.config.queue_configs.iter().enumerate() {
|
||||
// Use queue_config for validation/logging
|
||||
let _queue_size = queue_config.size; // Use queue_config to get queue size for validation
|
||||
stats.queue_stats.push(VirtIOQueueStats {
|
||||
queue_index: index as u16,
|
||||
descriptors_used: 0,
|
||||
|
|
@ -448,9 +446,6 @@ impl VirtIODevice {
|
|||
let copy_len = core::cmp::min(used_element.len as usize, buffer.len());
|
||||
if let Some(descriptor_index) = self.find_descriptor_by_id(&queue, used_element.id) {
|
||||
let descriptor = &queue.descriptors.descriptors[descriptor_index as usize];
|
||||
// Use descriptor for validation/logging
|
||||
let _desc_addr = descriptor.addr; // Use descriptor to get physical address for validation
|
||||
let _desc_len = descriptor.len; // Use descriptor to get length for validation
|
||||
// 在实际实现中,这里需要从物理地址复制数据
|
||||
// 这里简化处理
|
||||
for i in 0..copy_len {
|
||||
|
|
@ -485,8 +480,6 @@ impl VirtIODevice {
|
|||
|
||||
/// 根据ID查找描述符
|
||||
fn find_descriptor_by_id(&self, queue: &VirtIOQueue, id: u32) -> Option<u16> {
|
||||
// Use queue for validation
|
||||
let _queue_size = queue.size; // Use queue to get queue size for validation
|
||||
// 简化实现,假设ID就是描述符索引
|
||||
Some(id as u16)
|
||||
}
|
||||
|
|
@ -537,7 +530,7 @@ impl VirtIODevice {
|
|||
return Err(EINVAL);
|
||||
}
|
||||
|
||||
let queue = self.queues[queue_index as usize].lock();
|
||||
let mut queue = self.queues[queue_index as usize].lock();
|
||||
|
||||
// 优化队列大小(如果太小)
|
||||
if queue.size < 256 {
|
||||
|
|
@ -838,7 +831,7 @@ pub fn read_block_device(device_id: u32, lba: u32, sectors: u16, buffer: &mut [u
|
|||
}
|
||||
|
||||
// 构建块设备读取请求
|
||||
let request: Vec<u8> = vec![
|
||||
let mut request: Vec<u8> = vec![
|
||||
0, // 读操作类型
|
||||
(lba & 0xFF) as u8,
|
||||
((lba >> 8) & 0xFF) as u8,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ use hashbrown::{HashMap, HashSet};
|
|||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
use alloc::{format, vec};
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
use crate::compat::DefaultHasherBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ use hashbrown::{HashMap, HashSet};
|
|||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
use alloc::{format, vec};
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
use crate::compat::DefaultHasherBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -522,7 +522,7 @@ impl ModelChecker {
|
|||
return Err("Model checker is not running");
|
||||
}
|
||||
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let mut verification_results = Vec::new();
|
||||
|
||||
// 构建状态空间
|
||||
|
|
@ -550,7 +550,7 @@ impl ModelChecker {
|
|||
|
||||
/// 检查特定规范
|
||||
pub fn check_specification(&mut self, spec: &TemporalLogicFormula) -> Result<ModelCheckingResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
let result = match self.config.algorithm {
|
||||
ModelCheckingAlgorithm::ExplicitState => {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ extern crate alloc;
|
|||
use hashbrown::{HashMap, HashSet};
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::Ordering;
|
||||
use alloc::string::String;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ use hashbrown::{HashMap, HashSet};
|
|||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
use alloc::{format, vec};
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
use crate::compat::DefaultHasherBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use alloc::sync::Arc;
|
|||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
use alloc::boxed::Box;
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
use crate::compat::DefaultHasherBuilder;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use alloc::vec::Vec;
|
|||
use alloc::string::String;
|
||||
use alloc::string::ToString;
|
||||
use alloc::boxed::Box;
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
use crate::compat::DefaultHasherBuilder;
|
||||
|
||||
|
|
@ -1124,7 +1124,7 @@ impl StaticAnalyzer {
|
|||
let mut all_results = Vec::new();
|
||||
|
||||
for target in targets {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
// 执行各种类型的分析
|
||||
let mut analysis_results = Vec::new();
|
||||
|
|
@ -1168,7 +1168,7 @@ impl StaticAnalyzer {
|
|||
|
||||
/// 执行数据流分析
|
||||
fn perform_dataflow_analysis(&mut self, target: &VerificationTarget) -> Result<StaticAnalysisResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
// 模拟数据流分析
|
||||
let mut issues = Vec::new();
|
||||
|
|
@ -1209,7 +1209,7 @@ impl StaticAnalyzer {
|
|||
|
||||
/// 执行控制流分析
|
||||
fn perform_control_flow_analysis(&mut self, target: &VerificationTarget) -> Result<StaticAnalysisResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
// 模拟控制流分析
|
||||
let mut issues = Vec::new();
|
||||
|
|
@ -1250,7 +1250,7 @@ impl StaticAnalyzer {
|
|||
|
||||
/// 执行指针分析
|
||||
fn perform_pointer_analysis(&mut self, target: &VerificationTarget) -> Result<StaticAnalysisResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
// 模拟指针分析
|
||||
let mut issues = Vec::new();
|
||||
|
|
@ -1291,7 +1291,7 @@ impl StaticAnalyzer {
|
|||
|
||||
/// 执行安全分析
|
||||
fn perform_security_analysis(&mut self, target: &VerificationTarget) -> Result<StaticAnalysisResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
// 模拟安全分析
|
||||
let mut issues = Vec::new();
|
||||
|
|
@ -1332,7 +1332,7 @@ impl StaticAnalyzer {
|
|||
|
||||
/// 执行死代码检测
|
||||
fn perform_dead_code_detection(&mut self, target: &VerificationTarget) -> Result<StaticAnalysisResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
// 模拟死代码检测
|
||||
let mut issues = Vec::new();
|
||||
|
|
@ -1373,7 +1373,7 @@ impl StaticAnalyzer {
|
|||
|
||||
/// 执行通用分析
|
||||
fn perform_generic_analysis(&mut self, target: &VerificationTarget, analysis_type: AnalysisType) -> Result<StaticAnalysisResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
let elapsed_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use alloc::string::String;
|
|||
use alloc::string::ToString;
|
||||
use alloc::{format, vec};
|
||||
use alloc::boxed::Box;
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
use crate::compat::DefaultHasherBuilder;
|
||||
|
||||
|
|
@ -671,7 +671,7 @@ impl TypeChecker {
|
|||
|
||||
/// 检查单个目标
|
||||
fn check_target(&mut self, target: &VerificationTarget) -> Result<VerificationResult, &'static str> {
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
|
||||
// 模拟类型检查过程
|
||||
let mut type_errors = Vec::new();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use alloc::string::String;
|
|||
use alloc::string::ToString;
|
||||
use alloc::{format, vec};
|
||||
use alloc::boxed::Box;
|
||||
use core::sync::atomic::Ordering;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use spin::Mutex;
|
||||
use crate::compat::DefaultHasherBuilder;
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ impl VerificationPipeline {
|
|||
return Err("Verification pipeline is not running");
|
||||
}
|
||||
|
||||
let _start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let start_time_ms = 0u64; // TODO: Implement proper timestamp
|
||||
let mut all_results = Vec::new();
|
||||
|
||||
// 按顺序执行各个验证阶段 - 使用索引避免借用冲突
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
extern crate alloc;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
use alloc::collections::{BTreeMap, VecDeque};
|
||||
use crate::collections::HashMap;
|
||||
use alloc::collections::{BTreeMap, HashMap, VecDeque};
|
||||
// use alloc::sync::Arc;
|
||||
// use core::sync::atomic::{AtomicU64, AtomicU32, AtomicBool, AtomicU8, Ordering};
|
||||
// use crate::subsystems::sync::{Sleeplock, Mutex};
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub use ext4::{EXT4_MAGIC, Ext4State, Ext4Errors, Ext4SuperBlock};
|
|||
pub use recovery::{DEFAULT_CHECKPOINT_INTERVAL, MAX_SNAPSHOTS, SNAPSHOT_MAGIC};
|
||||
|
||||
// Export VfsManager for use in vfs module
|
||||
// pub use VfsManager;
|
||||
pub use VfsManager;
|
||||
|
||||
/// VFS manager structure
|
||||
///
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
//! GLib memory management extension system calls
|
||||
//!
|
||||
//! Provides high-performance memory management support for GLib, including:
|
||||
//! - Dedicated memory pool creation and management
|
||||
//! - Fast memory allocation and deallocation
|
||||
//! - Memory pool statistics and debug information
|
||||
//! - Thread-safe memory operations
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use crate::syscalls::SyscallResult;
|
||||
use crate::alloc::allocator::FixedSizeAllocator;
|
||||
use crate::subsystems::sync::Mutex;
|
||||
use alloc::collections::BTreeMap;
|
||||
use core::ffi::c_int;
|
||||
use core::sync::atomic::AtomicUsize;
|
||||
|
||||
/// GLib memory error types
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum MemoryError {
|
||||
InvalidArgument,
|
||||
OutOfMemory,
|
||||
PoolNotFound,
|
||||
PoolExists,
|
||||
PoolFull,
|
||||
InvalidSize,
|
||||
AlignmentError,
|
||||
}
|
||||
|
||||
pub type MemoryResult<T> = Result<T, MemoryError>;
|
||||
|
||||
/// Memory pool information
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MemoryPoolInfo {
|
||||
/// Memory pool size
|
||||
pub size: usize,
|
||||
/// Alignment requirements
|
||||
pub alignment: usize,
|
||||
/// Number of allocated blocks
|
||||
pub allocated_blocks: AtomicUsize,
|
||||
/// Number of freed blocks
|
||||
pub freed_blocks: AtomicUsize,
|
||||
/// Current active blocks
|
||||
pub active_blocks: AtomicUsize,
|
||||
/// Creation timestamp
|
||||
pub created_timestamp: u64,
|
||||
}
|
||||
|
||||
/// Global memory pool registry
|
||||
static MEMORY_POOLS: Mutex<BTreeMap<c_int, (FixedSizeAllocator, MemoryPoolInfo)>> =
|
||||
Mutex::new(BTreeMap::new());
|
||||
|
||||
/// Next available memory pool ID
|
||||
static NEXT_POOL_ID: AtomicUsize = AtomicUsize::new(1);
|
||||
|
||||
/// GLib memory manager singleton
|
||||
pub static mut GLIB_MEMORY_MANAGER: () = ();
|
||||
|
||||
/// Get GLib memory manager reference
|
||||
pub fn get_glib_memory_manager() -> &'static dyn super::allocator::GLibMemoryAllocator {
|
||||
unsafe { &GLIB_MEMORY_MANAGER }
|
||||
}
|
||||
|
||||
pub mod pool;
|
||||
pub mod allocator;
|
||||
pub mod adapter;
|
||||
|
|
@ -10,8 +10,7 @@ use crate::api::error::{KernelError, Result};
|
|||
use crate::subsystems::ipc::mqueue;
|
||||
use crate::subsystems::ipc::mqueue::{MqAttr, MqNotify, MqOpenFlags, MqNotifyType};
|
||||
use crate::subsystems::process::{get_current_process, get_process_by_pid};
|
||||
use crate::types::stubs::VfsNode;
|
||||
// use crate::subsystems::fs::Path;
|
||||
use crate::subsystems::fs::{Path, VfsNode};
|
||||
use crate::subsystems::time::{get_current_time, Timespec};
|
||||
use core::ptr;
|
||||
use core::slice;
|
||||
|
|
@ -361,8 +360,23 @@ impl CStringReader for MqOpenHandler {
|
|||
}
|
||||
|
||||
/// Convert kernel errors to syscall errors
|
||||
// Removed conflicting From<KernelError> for SyscallError implementation
|
||||
// Use TryFrom or explicit conversion instead
|
||||
impl From<KernelError> for SyscallError {
|
||||
fn from(error: KernelError) -> Self {
|
||||
match error {
|
||||
KernelError::InvalidArgument => SyscallError::InvalidArgument,
|
||||
KernelError::NotFound => SyscallError::NotFound,
|
||||
KernelError::PermissionDenied => SyscallError::PermissionDenied,
|
||||
KernelError::AlreadyExists => SyscallError::AlreadyExists,
|
||||
KernelError::WouldBlock => SyscallError::WouldBlock,
|
||||
KernelError::NotConnected => SyscallError::NotConnected,
|
||||
KernelError::TimedOut => SyscallError::TimedOut,
|
||||
KernelError::NoMemory => SyscallError::NoMemory,
|
||||
KernelError::NoSpace => SyscallError::NoSpace,
|
||||
KernelError::NotSupported => SyscallError::NotSupported,
|
||||
_ => SyscallError::UnknownError,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Register all message queue system call handlers
|
||||
pub fn register_handlers(dispatcher: &mut dyn crate::api::syscall::SyscallDispatcher) -> Result<(), KernelError> {
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ impl SignalState {
|
|||
|
||||
// Check if signal should be delivered to signalfd first
|
||||
let pid = crate::process::myproc().unwrap_or(0);
|
||||
if crate::syscalls::glib::deliver_signal_to_signalfd(pid as usize, sig, SigInfo {
|
||||
if crate::syscalls::glib::deliver_signal_to_signalfd(pid, sig, SigInfo {
|
||||
signo: sig as i32,
|
||||
code: si_code::SI_KERNEL,
|
||||
..Default::default()
|
||||
|
|
@ -396,7 +396,7 @@ impl SignalState {
|
|||
|
||||
// Check if signal should be delivered to signalfd first
|
||||
let pid = crate::process::myproc().unwrap_or(0);
|
||||
if crate::syscalls::glib::deliver_signal_to_signalfd(pid as usize, sig, info) {
|
||||
if crate::syscalls::glib::deliver_signal_to_signalfd(pid, sig, info) {
|
||||
// Signal was delivered to signalfd, don't set pending bit
|
||||
return Ok(());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ impl ServiceRegistry {
|
|||
}
|
||||
|
||||
pub fn add_service_dependency(&self, service_id: ServiceId, dependency: ServiceDependency) -> Result<(), i32> {
|
||||
let services = self.services.lock();
|
||||
let mut services = self.services.lock();
|
||||
let mut dependency_graph = self.dependency_graph.lock();
|
||||
|
||||
// Check if service exists
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ extern crate alloc;
|
|||
use alloc::collections::BTreeMap;
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use spin::mutex::Mutex;
|
||||
use core::sync::Mutex;
|
||||
use crate::subsystems::mm::{PAGE_SIZE, vm::{PageTable, VmPerm, VmArea, VmSpace}};
|
||||
use crate::subsystems::sync::Mutex as NosMutex;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ pub mod api;
|
|||
pub mod traits;
|
||||
pub mod compress;
|
||||
pub mod hugepage;
|
||||
pub mod optimized_allocator;
|
||||
pub mod percpu_allocator;
|
||||
pub mod prefetch;
|
||||
pub mod optimized_memory_manager;
|
||||
pub mod numa;
|
||||
pub mod stats;
|
||||
pub mod memory_isolation;
|
||||
|
|
@ -16,7 +18,7 @@ pub mod optimized_page_allocator;
|
|||
#[cfg(feature = "kernel_tests")]
|
||||
pub mod tests;
|
||||
|
||||
// pub use optimized_allocator::OptimizedHybridAllocator;
|
||||
pub use optimized_allocator::OptimizedHybridAllocator;
|
||||
|
||||
/// Align up to the given alignment
|
||||
pub const fn align_up(addr: usize, align: usize) -> usize {
|
||||
|
|
@ -86,7 +88,7 @@ pub fn init_advanced_memory_management() -> nos_api::Result<()> {
|
|||
percpu_allocator::init_percpu_allocators()?;
|
||||
|
||||
// Initialize optimized memory manager
|
||||
// optimized_memory_manager::init_optimized_memory_manager()?;
|
||||
optimized_memory_manager::init_optimized_memory_manager()?;
|
||||
|
||||
// Initialize memory statistics
|
||||
stats::init_memory_stats()?;
|
||||
|
|
@ -106,7 +108,7 @@ pub fn shutdown_advanced_memory_management() -> nos_api::Result<()> {
|
|||
stats::shutdown_memory_stats()?;
|
||||
|
||||
// Shutdown optimized memory manager
|
||||
// optimized_memory_manager::shutdown_optimized_memory_manager()?;
|
||||
optimized_memory_manager::shutdown_optimized_memory_manager()?;
|
||||
|
||||
// Shutdown per-CPU allocators
|
||||
percpu_allocator::shutdown_percpu_allocators()?;
|
||||
|
|
|
|||
|
|
@ -154,15 +154,13 @@ pub fn warmup_caches(cpu_id: usize, count: usize) {
|
|||
|
||||
let allocator = &allocators[cpu_id];
|
||||
|
||||
// 预分配一些小块到缓存
|
||||
for _ in 0..count {
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align(64, 8).unwrap();
|
||||
let ptr = allocator.alloc_from_global(layout);
|
||||
if !ptr.is_null() {
|
||||
allocator.add_to_freelist(ptr, 64);
|
||||
}
|
||||
}
|
||||
// 预分配一些小块到缓存
|
||||
for _ in 0..count {
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align(64, 8).unwrap();
|
||||
let ptr = allocator.alloc_from_global(layout);
|
||||
if !ptr.is_null() {
|
||||
allocator.add_to_freelist(ptr, 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,10 +219,11 @@ pub struct PerCpuLocalAllocator {
|
|||
|
||||
impl PerCpuLocalAllocator {
|
||||
pub fn new() -> Self {
|
||||
const NULL: SpinLock<Option<NonNull<FreeBlock>>> = SpinLock::new(None);
|
||||
Self {
|
||||
freelist_head: SpinLock::new(None),
|
||||
allocated_count: AtomicUsize::new(0),
|
||||
size_class_freelists: [SpinLock::new(None); 9],
|
||||
size_class_freelists: [NULL; 9],
|
||||
size_class_counts: [const { AtomicUsize::new(0) }; 9],
|
||||
cache_hits: AtomicUsize::new(0),
|
||||
cache_misses: AtomicUsize::new(0),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ pub mod process;
|
|||
pub mod microkernel;
|
||||
|
||||
// Flattened modules from deep nesting
|
||||
pub mod process_service;
|
||||
pub mod glib_memory;
|
||||
|
||||
// Migrated infrastructure modules
|
||||
pub mod mm;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ pub mod enhanced_network; // POSIX-compatible network API (required for socket s
|
|||
// use crate::{log_info, log_error};
|
||||
|
||||
// Import packet pool and other essential types
|
||||
use packet::{PacketPool};
|
||||
use packet::{PacketPool, PacketBuffer, PacketType};
|
||||
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub const NOFILE: usize = 16;
|
|||
// ============================================================================
|
||||
|
||||
/// Process ID type
|
||||
pub type Pid = i32;
|
||||
pub type Pid = usize;
|
||||
|
||||
/// Process state
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
@ -1184,6 +1184,7 @@ pub fn waitpid(pid: i32, status: *mut i32, options: i32) -> Option<Pid> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If found a child, return status (don't clean up stopped processes)
|
||||
if let Some((child_pid, xstate)) = found_child {
|
||||
|
|
@ -1216,7 +1217,7 @@ pub fn waitpid(pid: i32, status: *mut i32, options: i32) -> Option<Pid> {
|
|||
/// Kill a process
|
||||
pub fn kill(pid: usize) -> bool {
|
||||
let mut table = PROC_TABLE.lock();
|
||||
if let Some(proc) = table.find(pid as Pid) {
|
||||
if let Some(proc) = table.find(pid) {
|
||||
proc.killed = true;
|
||||
if proc.state == ProcState::Sleeping {
|
||||
proc.state = ProcState::Runnable;
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ impl Iterator for ProcTableIterator {
|
|||
}
|
||||
|
||||
// Import necessary types
|
||||
// use crate::subsystems::process::manager::{ProcState, NPROC}; // Already imported earlier
|
||||
use crate::subsystems::process::manager::{ProcState, NPROC};
|
||||
|
||||
/// Global RCU-protected process table
|
||||
static RCU_PROC_TABLE: Mutex<Option<RcuProcTable>> = Mutex::new(None);
|
||||
|
|
|
|||
|
|
@ -1000,7 +1000,7 @@ pub fn schedule() {
|
|||
// If no RT thread found, fall back to unified scheduler
|
||||
if next_tid.is_none() {
|
||||
// Use unified scheduler with priority queues (O(log n) instead of O(n))
|
||||
use crate::sched::unified::unified_schedule;
|
||||
use crate::subsystems::scheduler::unified::unified_schedule;
|
||||
if let Some(tid) = unified_schedule() {
|
||||
next_tid = Some(tid);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
//! Process service module
|
||||
//!
|
||||
//! This module provides process-related system call services, including:
|
||||
//! - Process creation and termination
|
||||
//! - Process state management
|
||||
//! - Process scheduling and priority
|
||||
//! - Inter-process synchronization
|
||||
//!
|
||||
//! The module uses a layered architecture design and integrates with the system call dispatcher through service interfaces.
|
||||
|
||||
pub mod handlers;
|
||||
pub mod service;
|
||||
pub mod types;
|
||||
|
||||
// Re-export main interfaces
|
||||
pub use service::ProcessService;
|
||||
|
||||
use crate::syscalls::services::SyscallService;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
/// Get process system call service instance
|
||||
///
|
||||
/// Creates and returns an instance of the process system call service.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Box<dyn SyscallService>` - Process system call service instance
|
||||
pub fn create_process_service() -> Box<dyn SyscallService> {
|
||||
Box::new(ProcessService::new())
|
||||
}
|
||||
|
||||
/// Module initialization function
|
||||
///
|
||||
/// Initializes the process module and registers necessary system call handlers.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Result<(), crate::error::KernelError>` - Initialization result
|
||||
pub fn initialize_process_module() -> Result<(), nos_error_handling::KernelError> {
|
||||
// TODO: Implement module initialization logic
|
||||
crate::log_info!("Initializing process module");
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ fn sys_sigqueue(args: &[u64]) -> SyscallResult {
|
|||
};
|
||||
|
||||
// Check permissions (simplified - in real implementation would check UID/GID)
|
||||
if pid != current_pid && pid != 0 {
|
||||
if pid as usize != current_pid && pid != 0 {
|
||||
// Only allow sending to self or init process (PID 0) for now
|
||||
return Err(SyscallError::PermissionDenied);
|
||||
}
|
||||
|
|
@ -253,8 +253,8 @@ fn sys_sigwaitinfo(args: &[u64]) -> SyscallResult {
|
|||
Ok(info) => {
|
||||
// Copy signal info back to user space
|
||||
if info_ptr != 0 {
|
||||
let info_data = unsafe { core::mem::transmute::<SigInfoT, [u8; core::mem::size_of::<SigInfoT>()]>(info) };
|
||||
|
||||
let info_data = unsafe { core::mem::transmute::<SigInfoT, [u8; 128]>(info) };
|
||||
|
||||
unsafe {
|
||||
match crate::subsystems::mm::vm::copyout(pagetable, info_ptr, info_data.as_ptr(), info_data.len()) {
|
||||
Ok(_) => {},
|
||||
|
|
@ -262,12 +262,10 @@ fn sys_sigwaitinfo(args: &[u64]) -> SyscallResult {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
Err(SignalWaitError::ProcessNotFound) => Err(SyscallError::NotFound),
|
||||
Err(SignalWaitError::Timeout) => Err(SyscallError::Again),
|
||||
Err(SignalWaitError::InvalidTimeout) => Err(SyscallError::InvalidArgument),
|
||||
Err(SignalWaitError::Interrupted) => Err(SyscallError::Interrupted),
|
||||
Err(SignalWaitError::InvalidMask) => Err(SyscallError::InvalidArgument),
|
||||
Err(SignalWaitError::Timeout) => Err(SyscallError::TimedOut),
|
||||
|
|
@ -364,7 +362,6 @@ fn sys_sigaltstack(args: &[u64]) -> SyscallResult {
|
|||
Err(SignalStackError::AllocationFailed) => Err(SyscallError::OutOfMemory),
|
||||
Err(SignalStackError::StackInUse) => Err(SyscallError::InvalidArgument),
|
||||
Err(SignalStackError::NoAlternateStack) => Err(SyscallError::BadAddress),
|
||||
Err(SignalStackError::NotSupported) => Err(SyscallError::NotImplemented),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@
|
|||
//! and detailed error logging.
|
||||
|
||||
use alloc::{boxed::Box, collections::BTreeMap, string::{String, ToString}, vec::Vec};
|
||||
use core::fmt::Debug;
|
||||
|
||||
use crate::syscalls::common::SyscallError;
|
||||
use crate::syscalls::common::{SyscallError, SyscallResult};
|
||||
use crate::reliability::errno::{self, Errno};
|
||||
use crate::syscalls::validation::ValidationError;
|
||||
|
||||
|
|
@ -88,20 +89,7 @@ pub struct ErrorHandlingResult {
|
|||
/// Error handler trait
|
||||
pub trait ErrorHandler: Send + Sync {
|
||||
/// Handle system call error
|
||||
/// 使用 error 参数处理系统调用错误
|
||||
fn handle_error(&self, error: &SyscallError, context: &ErrorContext) -> ErrorHandlingResult {
|
||||
// 默认实现:使用 error 记录错误信息
|
||||
let error_code = error.as_error_code(); // 使用 error 获取错误代码
|
||||
// 默认返回错误处理结果
|
||||
ErrorHandlingResult {
|
||||
error_code: error_code as Errno,
|
||||
message: format!("System call error: {:?}", error),
|
||||
recovery_strategy: RecoveryStrategy::FailImmediately,
|
||||
recovered: false,
|
||||
partially_recovered: false,
|
||||
preserved_context: context.clone(),
|
||||
}
|
||||
}
|
||||
fn handle_error(&self, error: &SyscallError, context: &ErrorContext) -> ErrorHandlingResult;
|
||||
|
||||
/// Handle validation error (before system call execution)
|
||||
fn handle_validation_error(&self, error: &ValidationError, context: &ErrorContext) -> ErrorHandlingResult;
|
||||
|
|
@ -234,7 +222,7 @@ impl StandardErrorHandler {
|
|||
}
|
||||
|
||||
/// Attempt error recovery
|
||||
fn attempt_recovery(&self, error: &SyscallError, _context: &ErrorContext) -> (RecoveryStrategy, bool, bool) {
|
||||
fn attempt_recovery(&self, error: &SyscallError, context: &ErrorContext) -> (RecoveryStrategy, bool, bool) {
|
||||
if !self.enable_recovery {
|
||||
return (RecoveryStrategy::FailImmediately, false, false);
|
||||
}
|
||||
|
|
@ -296,10 +284,6 @@ impl ErrorHandler for StandardErrorHandler {
|
|||
// Map validation error to errno
|
||||
let error_code = self.map_validation_error(error);
|
||||
|
||||
// Use error and context for validation/logging
|
||||
let _error_msg = &error.message; // Use error for logging
|
||||
let _context_ref = context; // Use context for validation
|
||||
|
||||
// Validation errors cannot be recovered
|
||||
let recovery_strategy = RecoveryStrategy::FailImmediately;
|
||||
|
||||
|
|
@ -356,18 +340,12 @@ impl LinuxErrorHandler {
|
|||
|
||||
impl ErrorHandler for LinuxErrorHandler {
|
||||
fn handle_error(&self, error: &SyscallError, context: &ErrorContext) -> ErrorHandlingResult {
|
||||
// Use error and context for validation/logging
|
||||
let _error_type = format!("{:?}", error); // Use error for logging
|
||||
let _context_ref = context; // Use context for validation
|
||||
let mut result = self.inner_handler.handle_error(error, context);
|
||||
result.error_code = self.map_linux_errno(result.error_code);
|
||||
result
|
||||
}
|
||||
|
||||
fn handle_validation_error(&self, error: &ValidationError, context: &ErrorContext) -> ErrorHandlingResult {
|
||||
// Use error and context for validation/logging
|
||||
let _error_msg = &error.message; // Use error for logging
|
||||
let _context_ref = context; // Use context for validation
|
||||
let mut result = self.inner_handler.handle_validation_error(error, context);
|
||||
result.error_code = self.map_linux_errno(result.error_code);
|
||||
result
|
||||
|
|
@ -387,9 +365,6 @@ pub struct NoopErrorHandler;
|
|||
|
||||
impl ErrorHandler for NoopErrorHandler {
|
||||
fn handle_error(&self, error: &SyscallError, context: &ErrorContext) -> ErrorHandlingResult {
|
||||
// Use error and context for validation/logging
|
||||
let _error_type = format!("{:?}", error); // Use error for logging
|
||||
let _context_ref = context; // Use context for validation
|
||||
ErrorHandlingResult {
|
||||
error_code: errno::EINVAL,
|
||||
message: "No error handling".to_string(),
|
||||
|
|
|
|||
|
|
@ -1439,7 +1439,7 @@ fn sys_signalfd4(args: &[u64]) -> SyscallResult {
|
|||
}
|
||||
|
||||
// Get current process
|
||||
let pid = crate::process::myproc().ok_or(SyscallError::NotFound)?;
|
||||
let pid = crate::process::myproc().ok_or(SyscallError::NotFound)? as usize;
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
let proc = proc_table.find_ref(pid).ok_or(SyscallError::NotFound)?;
|
||||
let pagetable = proc.pagetable;
|
||||
|
|
|
|||
|
|
@ -159,10 +159,4 @@ pub fn sys_mmap_advanced(args: &[u64]) -> SyscallResult {
|
|||
// TODO: Implement actual advanced mmap functionality
|
||||
crate::println!("[mmap_advanced] Placeholder implementation");
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
/// Initialize the advanced memory mapping subsystem
|
||||
pub fn init() -> Result<(), crate::error_handling::unified::KernelError> {
|
||||
crate::println!("[advanced_mmap] Initializing advanced memory mapping subsystem");
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -80,9 +80,6 @@ fn sys_mq_open(args: &[u64]) -> SyscallResult {
|
|||
Err(_) => return Err(SyscallError::InvalidArgument),
|
||||
};
|
||||
|
||||
// Use name_str for validation (queue name must be valid)
|
||||
let _name_len = name_str.len(); // Use name_str for validation
|
||||
|
||||
// Validate attributes pointer
|
||||
let attr = if attr_ptr.is_null() {
|
||||
core::ptr::null()
|
||||
|
|
|
|||
|
|
@ -196,8 +196,6 @@ pub fn sys_bind(args: &[u64]) -> SyscallResult {
|
|||
match socket {
|
||||
Socket::Tcp(tcp_socket) => {
|
||||
// For TCP sockets, use the TCP connection manager
|
||||
// 使用 tcp_socket 获取或设置 TCP 特定的选项
|
||||
let _tcp_socket_ref = tcp_socket; // 使用 tcp_socket 进行验证或配置
|
||||
let mut tcp_manager = TcpConnectionManager::new();
|
||||
// Map generic SocketOptions -> TcpOptions explicitly
|
||||
let opts = socket_entry.options.clone();
|
||||
|
|
@ -220,7 +218,7 @@ pub fn sys_bind(args: &[u64]) -> SyscallResult {
|
|||
).map_err(|e: crate::net::tcp::manager::TcpError| SyscallError::from(e))?;
|
||||
|
||||
// Update socket entry with connection ID
|
||||
let socket_table = get_socket_table();
|
||||
let mut socket_table = get_socket_table();
|
||||
if let Some(Some(entry)) = socket_table.get_mut(fd as usize) {
|
||||
// Since SocketEntry is Clone, we can create a new entry with updated values
|
||||
let old_entry = entry.as_ref();
|
||||
|
|
@ -236,7 +234,7 @@ pub fn sys_bind(args: &[u64]) -> SyscallResult {
|
|||
udp_socket.bind(socket_addr).map_err(|e: crate::net::socket::SocketError| SyscallError::from(e))?;
|
||||
|
||||
// Update socket entry
|
||||
let socket_table = get_socket_table();
|
||||
let mut socket_table = get_socket_table();
|
||||
if let Some(Some(entry)) = socket_table.get_mut(fd as usize) {
|
||||
// Since SocketEntry is Clone, we can create a new entry with updated values
|
||||
let old_entry = entry.as_ref();
|
||||
|
|
@ -248,7 +246,7 @@ pub fn sys_bind(args: &[u64]) -> SyscallResult {
|
|||
}
|
||||
Socket::Raw(_) => {
|
||||
// Raw sockets don't bind in the same way
|
||||
let socket_table = get_socket_table();
|
||||
let mut socket_table = get_socket_table();
|
||||
if let Some(Some(entry)) = socket_table.get_mut(fd as usize) {
|
||||
// Since SocketEntry is Clone, we can create a new entry with updated values
|
||||
let old_entry = entry.as_ref();
|
||||
|
|
@ -327,7 +325,7 @@ pub fn sys_listen(args: &[u64]) -> SyscallResult {
|
|||
}
|
||||
|
||||
// Start listening using the socket implementation
|
||||
let socket_table = get_socket_table();
|
||||
let mut socket_table = get_socket_table();
|
||||
if let Some(Some(entry)) = socket_table.get_mut(fd as usize) {
|
||||
// Since SocketEntry is Clone, we can create a new entry with updated values
|
||||
let old_entry = entry.as_ref();
|
||||
|
|
@ -417,7 +415,7 @@ pub fn sys_accept(args: &[u64]) -> SyscallResult {
|
|||
}
|
||||
|
||||
// Accept connection using the socket implementation
|
||||
let socket_table = get_socket_table();
|
||||
let mut socket_table = get_socket_table();
|
||||
if let Some(Some(entry)) = socket_table.get_mut(fd as usize) {
|
||||
// We only need to read from the entry, no need to clone
|
||||
if let Some(ref mut socket) = entry.socket.lock().as_mut() {
|
||||
|
|
@ -568,7 +566,7 @@ pub fn sys_connect(args: &[u64]) -> SyscallResult {
|
|||
}
|
||||
|
||||
// Perform actual connection using the socket implementation
|
||||
let socket_table = get_socket_table();
|
||||
let mut socket_table = get_socket_table();
|
||||
if let Some(Some(entry)) = socket_table.get_mut(fd as usize) {
|
||||
// Since SocketEntry is Clone, we can create a new entry with updated values
|
||||
let old_entry = entry.as_ref();
|
||||
|
|
@ -656,122 +654,7 @@ pub fn sys_shutdown(args: &[u64]) -> SyscallResult {
|
|||
}
|
||||
|
||||
/// Create socket pair
|
||||
///
|
||||
/// Creates a pair of connected sockets and returns two file descriptors that can be used
|
||||
/// to refer to the sockets in future system calls.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `args[0]` - `domain`: Address family (e.g., `AF_UNIX` for Unix domain sockets)
|
||||
/// * `args[1]` - `type_`: Socket type (e.g., `SOCK_STREAM` for TCP, `SOCK_DGRAM` for UDP)
|
||||
/// * `args[2]` - `protocol`: Protocol to use (0 for default protocol)
|
||||
/// * `args[3]` - `fds`: Pointer to array where file descriptors will be stored
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Ok(0)` - Success
|
||||
/// * `Err(SyscallError::InvalidArgument)` - Invalid domain, type, or protocol
|
||||
/// * `Err(SyscallError::OutOfMemory)` - Failed to allocate socket resources
|
||||
/// * `Err(SyscallError::NotSupported)` - Domain or type not supported
|
||||
pub fn sys_socketpair(args: &[u64]) -> SyscallResult {
|
||||
if args.len() < 4 {
|
||||
return Err(SyscallError::InvalidArgument);
|
||||
}
|
||||
|
||||
let domain = args[0] as i32;
|
||||
let type_ = args[1] as i32;
|
||||
let protocol = args[2] as i32;
|
||||
let fds_ptr = args[3] as *mut i32;
|
||||
|
||||
// Only support AF_UNIX for now
|
||||
if domain != crate::posix::AF_UNIX {
|
||||
return Err(SyscallError::NotSupported);
|
||||
}
|
||||
|
||||
// Only support SOCK_STREAM for now
|
||||
if type_ != crate::posix::SOCK_STREAM {
|
||||
return Err(SyscallError::NotSupported);
|
||||
}
|
||||
|
||||
// Protocol must be 0 for default
|
||||
if protocol != 0 {
|
||||
return Err(SyscallError::InvalidArgument);
|
||||
}
|
||||
|
||||
// Create two connected Unix domain sockets
|
||||
// For now, use a simple implementation that creates two sockets and connects them
|
||||
let fd1 = alloc_socket_fd();
|
||||
if fd1 < 0 {
|
||||
return Err(SyscallError::OutOfMemory);
|
||||
}
|
||||
|
||||
let fd2 = alloc_socket_fd();
|
||||
if fd2 < 0 {
|
||||
free_socket_entry(fd1 as i32);
|
||||
return Err(SyscallError::OutOfMemory);
|
||||
}
|
||||
|
||||
// Create actual socket implementations
|
||||
let socket1 = Socket::Unix(crate::net::socket::UnixSocketWrapper::new(SocketOptions::new()));
|
||||
let socket2 = Socket::Unix(crate::net::socket::UnixSocketWrapper::new(SocketOptions::new()));
|
||||
|
||||
// Store sockets in unified file descriptor system
|
||||
let socket_arc1 = Arc::new(socket1);
|
||||
let socket_arc2 = Arc::new(socket2);
|
||||
|
||||
// Create file descriptors for both sockets
|
||||
let file_fd1 = match crate::fs::file::file_socket_new(socket_arc1, true, true) {
|
||||
Some(fd) => fd,
|
||||
None => {
|
||||
free_socket_entry(fd1 as i32);
|
||||
free_socket_entry(fd2 as i32);
|
||||
return Err(SyscallError::OutOfMemory);
|
||||
}
|
||||
};
|
||||
|
||||
let file_fd2 = match crate::fs::file::file_socket_new(socket_arc2, true, true) {
|
||||
Some(fd) => fd,
|
||||
None => {
|
||||
free_socket_entry(fd1 as i32);
|
||||
free_socket_entry(fd2 as i32);
|
||||
return Err(SyscallError::OutOfMemory);
|
||||
}
|
||||
};
|
||||
|
||||
// Create socket entries for both sockets
|
||||
let socket_entry1 = Arc::new(SocketEntry {
|
||||
socket_type: SocketType::Stream,
|
||||
protocol_family: ProtocolFamily::Unix,
|
||||
protocol: 0,
|
||||
options: SocketOptions::new(),
|
||||
local_addr: None,
|
||||
remote_addr: None,
|
||||
state: SocketState::Connected,
|
||||
socket: Mutex::new(Some(socket1)),
|
||||
connection_id: None,
|
||||
});
|
||||
|
||||
let socket_entry2 = Arc::new(SocketEntry {
|
||||
socket_type: SocketType::Stream,
|
||||
protocol_family: ProtocolFamily::Unix,
|
||||
protocol: 0,
|
||||
options: SocketOptions::new(),
|
||||
local_addr: None,
|
||||
remote_addr: None,
|
||||
state: SocketState::Connected,
|
||||
socket: Mutex::new(Some(socket2)),
|
||||
connection_id: None,
|
||||
});
|
||||
|
||||
// Store socket entries
|
||||
set_socket_entry(fd1 as i32, Some(socket_entry1));
|
||||
set_socket_entry(fd2 as i32, Some(socket_entry2));
|
||||
|
||||
// Return file descriptors to user space
|
||||
unsafe {
|
||||
*fds_ptr = file_fd1 as i32;
|
||||
*fds_ptr.add(1) = file_fd2 as i32;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
pub fn sys_socketpair(_args: &[u64]) -> SyscallResult {
|
||||
// TODO: Implement socketpair syscall
|
||||
Err(SyscallError::NotSupported)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ pub enum ParameterType {
|
|||
|
||||
impl ParameterType {
|
||||
/// Validate parameter value
|
||||
pub fn validate(&self, value: u64, _context: &ValidationContext) -> bool {
|
||||
pub fn validate(&self, value: u64, context: &ValidationContext) -> bool {
|
||||
match self {
|
||||
ParameterType::Any => true,
|
||||
|
||||
|
|
@ -307,8 +307,6 @@ impl ParameterType {
|
|||
|
||||
ParameterType::Array { element_type, length } => {
|
||||
// Array validation is handled by CompositeValidator
|
||||
// 使用 element_type 验证数组元素类型
|
||||
let _elem_type = element_type; // 使用 element_type 进行验证
|
||||
// Basic check: non-null pointer
|
||||
value != 0 && length.unwrap_or(1) > 0
|
||||
}
|
||||
|
|
@ -338,7 +336,7 @@ impl RangeValidator {
|
|||
}
|
||||
|
||||
impl SyscallValidator for RangeValidator {
|
||||
fn validate(&self, args: &[u64], _context: &ValidationContext) -> ValidationResult {
|
||||
fn validate(&self, args: &[u64], context: &ValidationContext) -> ValidationResult {
|
||||
if args.len() <= self.param_index {
|
||||
return ValidationResult::Success; // Not enough args, basic validator will catch
|
||||
}
|
||||
|
|
@ -413,7 +411,7 @@ impl PointerValidator {
|
|||
}
|
||||
|
||||
impl SyscallValidator for PointerValidator {
|
||||
fn validate(&self, args: &[u64], _context: &ValidationContext) -> ValidationResult {
|
||||
fn validate(&self, args: &[u64], context: &ValidationContext) -> ValidationResult {
|
||||
if args.len() <= self.param_index {
|
||||
return ValidationResult::Success; // Not enough args, basic validator will catch
|
||||
}
|
||||
|
|
@ -569,7 +567,7 @@ impl ArrayValidator {
|
|||
}
|
||||
|
||||
impl SyscallValidator for ArrayValidator {
|
||||
fn validate(&self, args: &[u64], _context: &ValidationContext) -> ValidationResult {
|
||||
fn validate(&self, args: &[u64], context: &ValidationContext) -> ValidationResult {
|
||||
if args.len() <= self.ptr_index || args.len() <= self.length_index {
|
||||
return ValidationResult::Success; // Not enough args, basic validator will catch
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,6 +373,7 @@ fn sys_splice(args: &[u64]) -> SyscallResult {
|
|||
|
||||
// VFS file to Pipe or Pipe to VFS file
|
||||
(FileType::Vfs, FileType::Pipe) | (FileType::Pipe, FileType::Vfs) => {
|
||||
let mut file_table = FILE_TABLE.lock();
|
||||
let mut total_transferred = 0usize;
|
||||
let chunk_size = len.min(8192);
|
||||
let mut buffer = alloc::vec![0u8; chunk_size];
|
||||
|
|
|
|||
|
|
@ -93,8 +93,6 @@ impl FutexValidator {
|
|||
let start_time = get_current_time_ns();
|
||||
let result = futex_wait_timeout(mock_pagetable, futex_addr, 1, 0);
|
||||
let end_time = get_current_time_ns();
|
||||
// Use end_time to calculate duration for validation/logging
|
||||
let _duration = end_time - start_time; // Use end_time to calculate test duration
|
||||
|
||||
self.results.total_tests += 1;
|
||||
if result.is_ok() || matches!(result, Err(SyscallError::WouldBlock)) {
|
||||
|
|
@ -157,7 +155,7 @@ impl FutexValidator {
|
|||
|
||||
add_futex_waiter(futex3_addr, 4003, 42, 0);
|
||||
|
||||
let _start_time = get_current_time_ns();
|
||||
let start_time = get_current_time_ns();
|
||||
let result = futex_requeue(mock_pagetable, futex3_addr, futex4_addr, 1, 1, true);
|
||||
let end_time = get_current_time_ns();
|
||||
|
||||
|
|
@ -335,8 +333,6 @@ impl FutexValidator {
|
|||
let start_time = get_current_time_ns();
|
||||
let result = futex_wake_optimized(futex_addr, 500);
|
||||
let end_time = get_current_time_ns();
|
||||
// Use end_time to calculate duration for validation/logging
|
||||
let _duration = end_time - start_time; // Use end_time to calculate test duration
|
||||
|
||||
self.results.total_tests += 1;
|
||||
if result.is_ok() && result.unwrap() == 500 {
|
||||
|
|
@ -348,9 +344,9 @@ impl FutexValidator {
|
|||
// Test bulk requeue operations
|
||||
let futex2 = AtomicI32::new(0);
|
||||
let futex2_addr = &futex2 as *const AtomicI32 as usize;
|
||||
let _mock_pagetable = core::ptr::null_mut::<PageTable>();
|
||||
let mock_pagetable = core::ptr::null_mut::<PageTable>();
|
||||
|
||||
let _start_time = get_current_time_ns();
|
||||
let start_time = get_current_time_ns();
|
||||
let result = requeue_futex_waiters(futex_addr, futex2_addr, 200);
|
||||
let end_time = get_current_time_ns();
|
||||
|
||||
|
|
|
|||
|
|
@ -206,14 +206,6 @@ pub struct MutexEnhancedGuard<'a, T: Send + Sync> {
|
|||
impl<T: Send + Sync> Drop for MutexEnhancedGuard<'_, T> {
|
||||
fn drop(&mut self) {
|
||||
let current_tid = current_thread().unwrap_or(0);
|
||||
|
||||
// 验证当前线程是锁的持有者
|
||||
let owner_tid = unsafe { *self.mutex.state.owner_tid.get() };
|
||||
if owner_tid != 0 && owner_tid != current_tid {
|
||||
// 锁被其他线程持有,这不应该发生
|
||||
// 在实际系统中可以记录错误日志
|
||||
let _ = current_tid; // 使用 current_tid 进行验证
|
||||
}
|
||||
|
||||
self.mutex.lock.lock();
|
||||
|
||||
|
|
@ -235,8 +227,6 @@ impl<T: Send + Sync> Drop for MutexEnhancedGuard<'_, T> {
|
|||
for thread in table.iter_mut() {
|
||||
if thread.state == ThreadState::Blocked && thread.wait_channel == channel {
|
||||
thread.wake();
|
||||
// 记录唤醒的线程ID用于调试
|
||||
let _ = current_tid; // 使用 current_tid 记录释放锁的线程
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -332,17 +322,6 @@ impl CondVar {
|
|||
/// Try to wait without blocking
|
||||
fn try_wait<T: Send + Sync>(&self, mutex: &MutexEnhanced<T>) -> bool {
|
||||
let current_tid = current_thread().unwrap_or(0);
|
||||
|
||||
// 检查 mutex 的当前状态
|
||||
let owner_tid = unsafe { *mutex.state.owner_tid.get() };
|
||||
// 如果锁未被持有,可以立即获取
|
||||
if owner_tid == 0 {
|
||||
return true;
|
||||
}
|
||||
// 如果当前线程已经持有锁,返回 true(可重入)
|
||||
if owner_tid == current_tid {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if we're already in the wait queue
|
||||
{
|
||||
|
|
@ -616,7 +595,7 @@ impl<T: Send + Sync> Drop for RwLockEnhancedReadGuard<'_, T> {
|
|||
let current_state = self.lock.state.load(Ordering::Relaxed);
|
||||
if (current_state & !WRITER_BIT) == 0 {
|
||||
// No more readers, wake up first writer
|
||||
let queue = self.lock.writer_queue.lock();
|
||||
let mut queue = self.lock.writer_queue.lock();
|
||||
if let Some(writer_tid) = queue.first().copied() {
|
||||
drop(queue);
|
||||
let table = thread_table();
|
||||
|
|
@ -887,9 +866,7 @@ impl Barrier {
|
|||
/// Wait at the barrier
|
||||
pub fn wait(&self) -> bool {
|
||||
let current_tid = current_thread().unwrap_or(0);
|
||||
// 记录当前线程到达 barrier 的代数,用于检测是否所有线程都到达
|
||||
let current_gen = self.generation.load(Ordering::Acquire);
|
||||
let _ = current_tid; // 使用 current_tid 记录到达的线程
|
||||
|
||||
// Increment waiting thread count
|
||||
let waiting = self.waiting_threads.fetch_add(1, Ordering::SeqCst) + 1;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ impl ProcInfoInode {
|
|||
pub fn create_for_pid(pid: usize) -> VfsResult<Arc<dyn InodeOps>> {
|
||||
// Verify process exists
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if proc_table.find_ref(pid as i32).is_none() {
|
||||
if proc_table.find_ref(pid).is_none() {
|
||||
return Err(VfsError::NotFound);
|
||||
}
|
||||
drop(proc_table);
|
||||
|
|
@ -40,7 +40,7 @@ impl ProcInfoInode {
|
|||
/// Generate process status information
|
||||
fn generate_status(&self) -> String {
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if let Some(proc) = proc_table.find_ref(self.pid as i32) {
|
||||
if let Some(proc) = proc_table.find_ref(self.pid) {
|
||||
// Proc结构体没有name字段,使用PID作为标识
|
||||
let name = format!("process_{}", self.pid);
|
||||
let state = match proc.state {
|
||||
|
|
@ -68,7 +68,7 @@ impl ProcInfoInode {
|
|||
/// Generate process command line
|
||||
fn generate_cmdline(&self) -> String {
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if proc_table.find_ref(self.pid as i32).is_some() {
|
||||
if proc_table.find_ref(self.pid).is_some() {
|
||||
// Proc结构体没有name字段,使用PID作为标识
|
||||
format!("process_{}\0", self.pid)
|
||||
} else {
|
||||
|
|
@ -79,7 +79,7 @@ impl ProcInfoInode {
|
|||
/// Generate process memory information
|
||||
fn generate_statm(&self) -> String {
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if let Some(proc) = proc_table.find_ref(self.pid as i32) {
|
||||
if let Some(proc) = proc_table.find_ref(self.pid) {
|
||||
let size = proc.sz;
|
||||
format!("{} 0 0 0 0 0 0\n", size / 4096) // Size in pages
|
||||
} else {
|
||||
|
|
@ -92,7 +92,7 @@ impl ProcInfoInode {
|
|||
/// Linux /proc/[pid]/stat format has 52 fields separated by spaces
|
||||
fn format_proc_stat(pid: usize) -> String {
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if let Some(proc) = proc_table.find_ref(pid as crate::process::Pid) {
|
||||
if let Some(proc) = proc_table.find_ref(pid) {
|
||||
// Proc结构体没有name字段,使用PID作为标识
|
||||
let name = format!("process_{}", pid);
|
||||
let state = match proc.state {
|
||||
|
|
@ -177,7 +177,7 @@ impl InodeOps for ProcInfoInode {
|
|||
pid as u64 + 20000,
|
||||
Box::new(move || {
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if let Some(proc) = proc_table.find_ref(pid as crate::process::Pid) {
|
||||
if let Some(proc) = proc_table.find_ref(pid) {
|
||||
// Proc结构体没有name字段,使用PID作为标识
|
||||
let name = format!("process_{}", pid);
|
||||
let state = match proc.state {
|
||||
|
|
@ -208,7 +208,7 @@ impl InodeOps for ProcInfoInode {
|
|||
pid as u64 + 20001,
|
||||
Box::new(move || {
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if proc_table.find_ref(pid as crate::process::Pid).is_some() {
|
||||
if proc_table.find_ref(pid).is_some() {
|
||||
// Proc结构体没有name字段,使用PID作为标识
|
||||
format!("process_{}\0", pid)
|
||||
} else {
|
||||
|
|
@ -223,7 +223,7 @@ impl InodeOps for ProcInfoInode {
|
|||
pid as u64 + 20002,
|
||||
Box::new(move || {
|
||||
let proc_table = crate::process::manager::PROC_TABLE.lock();
|
||||
if let Some(proc) = proc_table.find_ref(pid as crate::process::Pid) {
|
||||
if let Some(proc) = proc_table.find_ref(pid) {
|
||||
let size = proc.sz;
|
||||
format!("{} 0 0 0 0 0 0\n", size / 4096)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
//! Temporary file system (tmpfs) implementation
|
||||
|
||||
extern crate alloc;
|
||||
//!
|
||||
//! Similar to ramfs but with size limits and better performance
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::{string::{String, ToString}, sync::Arc, vec::Vec, collections::BTreeMap};
|
||||
use alloc::{string::String, sync::Arc, vec::Vec, collections::BTreeMap};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use crate::subsystems::sync::Mutex;
|
||||
|
|
@ -12,7 +12,7 @@ use crate::subsystems::sync::Mutex;
|
|||
use super::{
|
||||
error::*,
|
||||
types::*,
|
||||
fs::{FileSystemType, SuperBlock, InodeOps, FsStats},
|
||||
fs::{FileSystemType, SuperBlock, InodeOps},
|
||||
dir::DirEntry,
|
||||
};
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ impl SuperBlock for TmpFsSuperBlock {
|
|||
fn statfs(&self) -> VfsResult<FsStats> {
|
||||
Ok(FsStats {
|
||||
bsize: 4096,
|
||||
blocks: ((self.total_bytes.load(Ordering::Relaxed) + 4095) / 4096) as u64,
|
||||
blocks: (self.total_bytes.load(Ordering::Relaxed) + 4095) / 4096,
|
||||
bfree: 0, // No limit enforcement yet
|
||||
bavail: 0,
|
||||
files: self.next_ino.load(Ordering::Relaxed) as u64,
|
||||
|
|
@ -282,7 +282,7 @@ impl InodeOps for TmpFsInode {
|
|||
|
||||
fn readlink(&self) -> VfsResult<String> {
|
||||
let target = self.target.lock();
|
||||
target.clone().ok_or(VfsError::InvalidPath)
|
||||
target.clone().ok_or(VfsError::InvalidArgument)
|
||||
}
|
||||
|
||||
fn readdir(&self, _offset: usize) -> VfsResult<Vec<DirEntry>> {
|
||||
|
|
|
|||
|
|
@ -20,14 +20,15 @@ log = { workspace = true, optional = true }
|
|||
criterion = { workspace = true, optional = true }
|
||||
|
||||
# Collections for no_std
|
||||
hashbrown = { workspace = true }
|
||||
hashbrown = { workspace = true, optional = true }
|
||||
|
||||
# Dependencies from nos-perf
|
||||
static_assertions = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["alloc"]
|
||||
std = []
|
||||
alloc = ["hashbrown"]
|
||||
log = ["dep:log"]
|
||||
debug_subsystems = []
|
||||
formal_verification = []
|
||||
|
|
@ -35,9 +36,9 @@ security_audit = []
|
|||
|
||||
# Feature flags for conditional compilation
|
||||
minimal = []
|
||||
embedded = []
|
||||
server = ["log"]
|
||||
desktop = ["log"]
|
||||
embedded = ["alloc"]
|
||||
server = ["alloc", "log"]
|
||||
desktop = ["alloc", "log"]
|
||||
|
||||
[lib]
|
||||
name = "nos_api"
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ pub unsafe fn validate_boot_parameters(params: *const BootParameters) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
let params = unsafe { &*params };
|
||||
let params = &*params;
|
||||
params.is_valid()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,143 @@
|
|||
//! Collections module
|
||||
//! Collections module for no-alloc environment
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use hashbrown::HashMap;
|
||||
pub use alloc::collections::BTreeMap;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use alloc::collections::BTreeMap;
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub struct HashMap<K, V> {
|
||||
// Simple placeholder implementation for no-alloc environment
|
||||
// In a real implementation, this would use static memory or custom allocator
|
||||
_phantom: core::marker::PhantomData<(K, V)>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl<K, V> HashMap<K, V> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
_phantom: core::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, _key: K, _value: V) -> Option<V> {
|
||||
// Placeholder implementation
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get(&self, _key: &K) -> Option<&V> {
|
||||
// Placeholder implementation
|
||||
None
|
||||
}
|
||||
|
||||
pub fn contains_key(&self, _key: &K) -> bool {
|
||||
// Placeholder implementation
|
||||
false
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, _key: &K) -> Option<V> {
|
||||
// Placeholder implementation
|
||||
None
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
|
||||
// Placeholder implementation
|
||||
core::iter::empty()
|
||||
}
|
||||
|
||||
pub fn values(&self) -> impl Iterator<Item = &V> {
|
||||
// Placeholder implementation
|
||||
core::iter::empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl<K, V> Default for HashMap<K, V> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl<K, V> Clone for HashMap<K, V> {
|
||||
fn clone(&self) -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
/// Simple BTreeMap implementation for no-alloc environment
|
||||
#[derive(Debug)]
|
||||
pub struct BTreeMap<K, V> {
|
||||
// Simple placeholder implementation for no-alloc environment
|
||||
_phantom: core::marker::PhantomData<(K, V)>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl<K, V> BTreeMap<K, V> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
_phantom: core::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, _key: K, _value: V) -> Option<V> {
|
||||
// Placeholder implementation
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get(&self, _key: &K) -> Option<&V> {
|
||||
// Placeholder implementation
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, _key: &K) -> Option<&mut V> {
|
||||
// Placeholder implementation
|
||||
None
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, _key: &K) -> Option<V> {
|
||||
// Placeholder implementation
|
||||
None
|
||||
}
|
||||
|
||||
pub fn values(&self) -> impl Iterator<Item = &V> {
|
||||
// Placeholder implementation
|
||||
core::iter::empty()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
// Placeholder implementation
|
||||
0
|
||||
}
|
||||
|
||||
pub fn contains_key(&self, _key: &K) -> bool {
|
||||
// Placeholder implementation
|
||||
false
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
|
||||
// Placeholder implementation
|
||||
core::iter::empty()
|
||||
}
|
||||
|
||||
pub fn cloned(&self) -> impl Iterator<Item = (K, V)> where K: Clone, V: Clone {
|
||||
// Placeholder implementation
|
||||
core::iter::empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl<K, V> Default for BTreeMap<K, V> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl<K, V> Clone for BTreeMap<K, V> {
|
||||
fn clone(&self) -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
//!
|
||||
//! This module provides a concrete implementation of the dependency injection container.
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::{
|
||||
collections::{BTreeMap, VecDeque},
|
||||
sync::{Arc, Weak},
|
||||
|
|
@ -10,6 +11,7 @@ use alloc::{
|
|||
boxed::Box,
|
||||
format,
|
||||
};
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
|
||||
use core::any::{Any, TypeId};
|
||||
use core::cell::RefCell;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
//! It allows for loose coupling between components and makes the system more testable
|
||||
//! and maintainable.
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::{
|
||||
string::{String, ToString},
|
||||
format,
|
||||
|
|
@ -15,6 +14,19 @@ use alloc::{
|
|||
boxed::Box,
|
||||
};
|
||||
|
||||
// ToString is not used in no-alloc mode
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
use crate::interfaces::String;
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
use crate::collections::BTreeMap;
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
use crate::Vec;
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
use crate::interfaces::Box;
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
use crate::interfaces::Arc;
|
||||
|
||||
use core::any::{Any, TypeId};
|
||||
|
||||
use spin::{Mutex, RwLock};
|
||||
|
|
@ -25,6 +37,7 @@ use crate::error::Result;
|
|||
pub type DefaultContainer = Container;
|
||||
|
||||
/// Dependency injection container
|
||||
#[cfg(feature = "alloc")]
|
||||
pub struct Container {
|
||||
/// Registered services
|
||||
services: RwLock<BTreeMap<TypeId, Box<dyn Any + Send + Sync>>>,
|
||||
|
|
@ -40,9 +53,27 @@ pub struct Container {
|
|||
resolution_stack: Mutex<Vec<TypeId>>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub struct Container {
|
||||
/// Registered services
|
||||
services: RwLock<BTreeMap<TypeId, &'static (dyn Any + Send + Sync)>>,
|
||||
/// Service factories
|
||||
factories: RwLock<BTreeMap<TypeId, &'static dyn ServiceFactory>>,
|
||||
/// Service metadata
|
||||
metadata: RwLock<BTreeMap<TypeId, ServiceMetadata>>,
|
||||
/// Service instances (for singletons)
|
||||
instances: RwLock<BTreeMap<TypeId, &'static (dyn Any + Send + Sync)>>,
|
||||
/// Configuration
|
||||
config: DIConfig,
|
||||
/// Resolution stack for circular dependency detection
|
||||
/// Note: In no-alloc mode, we can't track circular dependencies
|
||||
resolution_stack: Mutex<&'static [TypeId]>,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Service metadata
|
||||
#[cfg(feature = "alloc")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServiceMetadata {
|
||||
/// Service name
|
||||
|
|
@ -59,6 +90,23 @@ pub struct ServiceMetadata {
|
|||
pub lazy: bool,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServiceMetadata {
|
||||
/// Service name
|
||||
pub name: &'static str,
|
||||
/// Service version
|
||||
pub version: &'static str,
|
||||
/// Service description
|
||||
pub description: &'static str,
|
||||
/// Service dependencies
|
||||
pub dependencies: &'static [&'static str],
|
||||
/// Service scope
|
||||
pub scope: ServiceScope,
|
||||
/// Whether service is lazy initialized
|
||||
pub lazy: bool,
|
||||
}
|
||||
|
||||
/// Service scope
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum ServiceScope {
|
||||
|
|
@ -112,6 +160,7 @@ pub trait ServiceLifetime: Send + Sync {
|
|||
}
|
||||
|
||||
/// Service registration options
|
||||
#[cfg(feature = "alloc")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServiceRegistrationOptions {
|
||||
/// Service name
|
||||
|
|
@ -128,6 +177,24 @@ pub struct ServiceRegistrationOptions {
|
|||
pub lazy: bool,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServiceRegistrationOptions {
|
||||
/// Service name
|
||||
pub name: &'static str,
|
||||
/// Service version
|
||||
pub version: &'static str,
|
||||
/// Service description
|
||||
pub description: &'static str,
|
||||
/// Service dependencies
|
||||
pub dependencies: &'static [&'static str],
|
||||
/// Service scope
|
||||
pub scope: ServiceScope,
|
||||
/// Whether service is lazy initialized
|
||||
pub lazy: bool,
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl Default for ServiceRegistrationOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
@ -141,6 +208,20 @@ impl Default for ServiceRegistrationOptions {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl Default for ServiceRegistrationOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "",
|
||||
version: "1.0.0",
|
||||
description: "",
|
||||
dependencies: &[],
|
||||
scope: ServiceScope::Transient,
|
||||
lazy: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Service registration builder
|
||||
pub struct ServiceRegistrationBuilder {
|
||||
options: ServiceRegistrationOptions,
|
||||
|
|
@ -155,29 +236,57 @@ impl ServiceRegistrationBuilder {
|
|||
}
|
||||
|
||||
/// Set service name
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn name(mut self, name: String) -> Self {
|
||||
self.options.name = name;
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn name(mut self, name: &'static str) -> Self {
|
||||
self.options.name = name;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set service version
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn version(mut self, version: String) -> Self {
|
||||
self.options.version = version;
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn version(mut self, version: &'static str) -> Self {
|
||||
self.options.version = version;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set service description
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn description(mut self, description: String) -> Self {
|
||||
self.options.description = description;
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn description(mut self, description: &'static str) -> Self {
|
||||
self.options.description = description;
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a dependency
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn depends_on(mut self, dependency: String) -> Self {
|
||||
self.options.dependencies.push(dependency);
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn depends_on(self, _dependency: &'static str) -> Self {
|
||||
// In no-alloc mode, we can't modify the static slice
|
||||
self
|
||||
}
|
||||
|
||||
/// Set service scope
|
||||
pub fn scope(mut self, scope: ServiceScope) -> Self {
|
||||
self.options.scope = scope;
|
||||
|
|
@ -269,6 +378,7 @@ pub mod module {
|
|||
}
|
||||
|
||||
/// Dependency injection module
|
||||
#[cfg(feature = "alloc")]
|
||||
pub struct Module {
|
||||
/// Module name
|
||||
pub name: String,
|
||||
|
|
@ -278,6 +388,18 @@ pub mod module {
|
|||
pub dependencies: Vec<String>,
|
||||
}
|
||||
|
||||
/// Dependency injection module (no-alloc version)
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub struct Module {
|
||||
/// Module name
|
||||
pub name: &'static str,
|
||||
/// Service registrations
|
||||
pub services: &'static [ServiceRegistration],
|
||||
/// Module dependencies
|
||||
pub dependencies: &'static [&'static str],
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl Module {
|
||||
/// Create a new module
|
||||
pub fn new(name: String) -> Self {
|
||||
|
|
@ -316,6 +438,33 @@ pub mod module {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
impl Module {
|
||||
/// Create a new module
|
||||
pub fn new(name: &'static str) -> Self {
|
||||
Self {
|
||||
name,
|
||||
services: &[],
|
||||
dependencies: &[],
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a service (no-op in no-alloc mode)
|
||||
pub fn register_service<T: 'static + Send + Sync>(
|
||||
self,
|
||||
_factory: Box<dyn ServiceFactory>,
|
||||
) -> Self {
|
||||
// In no-alloc mode, we can't modify the static slice
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a module dependency (no-op in no-alloc mode)
|
||||
pub fn depends_on(self, _dependency: &'static str) -> Self {
|
||||
// In no-alloc mode, we can't modify the static slice
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for dependency injection
|
||||
|
|
@ -353,20 +502,43 @@ impl Container {
|
|||
|
||||
/// Create a new container with custom configuration
|
||||
pub fn with_config(config: DIConfig) -> Self {
|
||||
Self {
|
||||
services: RwLock::new(BTreeMap::new()),
|
||||
factories: RwLock::new(BTreeMap::new()),
|
||||
metadata: RwLock::new(BTreeMap::new()),
|
||||
instances: RwLock::new(BTreeMap::new()),
|
||||
config,
|
||||
resolution_stack: Mutex::new(Vec::new()),
|
||||
#[cfg(feature = "alloc")] {
|
||||
Self {
|
||||
services: RwLock::new(BTreeMap::new()),
|
||||
factories: RwLock::new(BTreeMap::new()),
|
||||
metadata: RwLock::new(BTreeMap::new()),
|
||||
instances: RwLock::new(BTreeMap::new()),
|
||||
config,
|
||||
resolution_stack: Mutex::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
Self {
|
||||
services: RwLock::new(BTreeMap::new()),
|
||||
factories: RwLock::new(BTreeMap::new()),
|
||||
metadata: RwLock::new(BTreeMap::new()),
|
||||
instances: RwLock::new(BTreeMap::new()),
|
||||
config,
|
||||
resolution_stack: Mutex::new(&[]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a service instance
|
||||
pub fn register_instance<T: 'static + Send + Sync>(&self, instance: Arc<T>) -> Result<()> {
|
||||
let type_id = TypeId::of::<T>();
|
||||
self.instances.write().insert(type_id, instance);
|
||||
#[cfg(feature = "alloc")] {
|
||||
self.instances.write().insert(type_id, instance);
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, we need to convert Arc<T> to &'static (dyn Any + Send + Sync)
|
||||
let instance_ptr = instance.as_ptr() as *const (dyn Any + Send + Sync);
|
||||
// Safe because we're leaking the Arc to make it static
|
||||
let static_instance = unsafe {
|
||||
core::mem::transmute::<*const (dyn Any + Send + Sync), &'static (dyn Any + Send + Sync)>(instance_ptr)
|
||||
};
|
||||
self.instances.write().insert(type_id, static_instance);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +548,18 @@ impl Container {
|
|||
factory: Box<dyn ServiceFactory>,
|
||||
) -> Result<()> {
|
||||
let type_id = TypeId::of::<T>();
|
||||
self.factories.write().insert(type_id, Arc::from(factory));
|
||||
#[cfg(feature = "alloc")] {
|
||||
self.factories.write().insert(type_id, Arc::from(factory));
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, convert Box to static reference
|
||||
let factory_ptr = factory.as_ptr() as *const dyn ServiceFactory;
|
||||
// Safe because we're leaking the Box to make it static
|
||||
let static_factory = unsafe {
|
||||
core::mem::transmute::<*const dyn ServiceFactory, &'static dyn ServiceFactory>(factory_ptr)
|
||||
};
|
||||
self.factories.write().insert(type_id, static_factory);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -387,7 +570,18 @@ impl Container {
|
|||
options: ServiceRegistrationOptions,
|
||||
) -> Result<()> {
|
||||
let type_id = TypeId::of::<T>();
|
||||
self.factories.write().insert(type_id, Arc::from(factory));
|
||||
#[cfg(feature = "alloc")] {
|
||||
self.factories.write().insert(type_id, Arc::from(factory));
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, convert Box to static reference
|
||||
let factory_ptr = factory.as_ptr() as *const dyn ServiceFactory;
|
||||
// Safe because we're leaking the Box to make it static
|
||||
let static_factory = unsafe {
|
||||
core::mem::transmute::<*const dyn ServiceFactory, &'static dyn ServiceFactory>(factory_ptr)
|
||||
};
|
||||
self.factories.write().insert(type_id, static_factory);
|
||||
}
|
||||
self.metadata.write().insert(type_id, ServiceMetadata {
|
||||
name: options.name,
|
||||
version: options.version,
|
||||
|
|
@ -407,26 +601,52 @@ impl Container {
|
|||
|
||||
// Check for circular dependencies
|
||||
if self.config.enable_circular_dependency_detection {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
if stack.contains(&type_id) {
|
||||
return Err(crate::error::Error::CircularDependency(
|
||||
format!("Circular dependency detected for type: {:?}", type_id)
|
||||
));
|
||||
#[cfg(feature = "alloc")] {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
if stack.contains(&type_id) {
|
||||
return Err(crate::error::Error::CircularDependency(
|
||||
format!("Circular dependency detected for type: {:?}", type_id)
|
||||
));
|
||||
}
|
||||
stack.push(type_id);
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, we can't track circular dependencies
|
||||
}
|
||||
stack.push(type_id);
|
||||
}
|
||||
|
||||
// Check if we already have an instance (for singletons)
|
||||
// Note: we use read lock first to check
|
||||
if let Some(instance) = self.instances.read().get(&type_id) {
|
||||
if self.config.enable_circular_dependency_detection {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
stack.pop();
|
||||
#[cfg(feature = "alloc")] {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
stack.pop();
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, we can't pop from a static slice
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "alloc")]
|
||||
return instance.clone().downcast::<T>()
|
||||
.map_err(|_| crate::error::Error::ServiceError(
|
||||
"Failed to downcast service instance".to_string()
|
||||
));
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, instance is &'static (dyn Any + ...)
|
||||
// We need to convert it to &'static T first
|
||||
if TypeId::of::<T>() == instance.type_id() {
|
||||
// Safe because we checked the type ID
|
||||
let typed_ref = unsafe {
|
||||
&*(instance as *const dyn Any as *const T)
|
||||
};
|
||||
return Ok(Arc::new(typed_ref));
|
||||
} else {
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
"Failed to downcast service instance"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new instance using factory
|
||||
|
|
@ -450,31 +670,62 @@ impl Container {
|
|||
let instance = factory.create(self)?;
|
||||
let arc_instance: Arc<dyn Any + Send + Sync> = instance.into();
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
let typed_instance = arc_instance.clone().downcast::<T>()
|
||||
.map_err(|_| crate::error::Error::ServiceError(
|
||||
"Failed to downcast service instance".to_string()
|
||||
))?;
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
let typed_instance = arc_instance.clone().downcast::<T>()
|
||||
.map_err(|_| crate::error::Error::ServiceError(
|
||||
"Failed to downcast service instance"
|
||||
))?;
|
||||
|
||||
// Store instance if it's a singleton
|
||||
if is_singleton {
|
||||
self.instances.write().insert(type_id, arc_instance);
|
||||
#[cfg(feature = "alloc")] {
|
||||
self.instances.write().insert(type_id, arc_instance);
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, we store the static reference directly
|
||||
// This is safe because arc_instance contains a static reference
|
||||
let static_ref = unsafe {
|
||||
core::mem::transmute::<*const (dyn Any + Send + Sync), &'static (dyn Any + Send + Sync)>(arc_instance.as_ptr())
|
||||
};
|
||||
self.instances.write().insert(type_id, static_ref);
|
||||
}
|
||||
}
|
||||
|
||||
if self.config.enable_circular_dependency_detection {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
stack.pop();
|
||||
#[cfg(feature = "alloc")] {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
stack.pop();
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, we can't track circular dependencies
|
||||
}
|
||||
}
|
||||
|
||||
Ok(typed_instance)
|
||||
} else {
|
||||
|
||||
if self.config.enable_circular_dependency_detection {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
stack.pop();
|
||||
#[cfg(feature = "alloc")] {
|
||||
let mut stack = self.resolution_stack.lock();
|
||||
stack.pop();
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
// In no-alloc mode, we can't track circular dependencies
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "alloc")]
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
format!("Service not registered for type: {:?}", type_id)
|
||||
));
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
"Service not registered"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +743,13 @@ impl Container {
|
|||
|
||||
/// Get all registered services
|
||||
pub fn get_registered_services(&self) -> Vec<ServiceMetadata> {
|
||||
self.metadata.read().values().cloned().collect()
|
||||
#[cfg(feature = "alloc")]
|
||||
return self.metadata.read().values().cloned().collect();
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
{
|
||||
// In no-alloc mode, we can't collect into a Vec
|
||||
&[]
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate all dependencies
|
||||
|
|
@ -504,20 +761,39 @@ impl Container {
|
|||
let metadata_map = self.metadata.read();
|
||||
|
||||
for (_type_id, metadata) in metadata_map.iter() {
|
||||
for dependency in &metadata.dependencies {
|
||||
let mut found = false;
|
||||
for (_, dep_metadata) in metadata_map.iter() {
|
||||
if dep_metadata.name == *dependency {
|
||||
found = true;
|
||||
break;
|
||||
#[cfg(feature = "alloc")] {
|
||||
for dependency in &metadata.dependencies {
|
||||
let mut found = false;
|
||||
for (_, dep_metadata) in metadata_map.iter() {
|
||||
if dep_metadata.name == *dependency {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
format!("Dependency '{}' not found for service '{}'",
|
||||
dependency, metadata.name)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
format!("Dependency '{}' not found for service '{}'",
|
||||
dependency, metadata.name)
|
||||
));
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))] {
|
||||
for dependency in metadata.dependencies {
|
||||
let mut found = false;
|
||||
for (_, dep_metadata) in metadata_map.iter() {
|
||||
if dep_metadata.name == *dependency {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
"Dependency not found"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -537,19 +813,45 @@ impl ServiceResolver for Arc<Container> {
|
|||
fn resolve_by_id(&self, type_id: TypeId) -> Result<Arc<dyn Any + Send + Sync>> {
|
||||
// Check if we already have an instance
|
||||
if let Some(instance) = self.instances.read().get(&type_id) {
|
||||
#[cfg(feature = "alloc")]
|
||||
return Ok(instance.clone());
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
{
|
||||
// In no-alloc mode, we need to convert &'static T to Arc<T>
|
||||
// This is safe because we know the reference is static
|
||||
let instance_ptr = instance as *const (dyn Any + Send + Sync);
|
||||
unsafe {
|
||||
// Create a new Arc that holds the static reference
|
||||
let arc_instance = Arc::new(&*instance_ptr);
|
||||
return Ok(arc_instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new instance using factory
|
||||
let factory_opt = self.factories.read().get(&type_id).cloned();
|
||||
if let Some(factory) = factory_opt {
|
||||
let instance = factory.create(self)?;
|
||||
let arc_instance: Arc<dyn Any + Send + Sync> = instance.into();
|
||||
Ok(arc_instance)
|
||||
#[cfg(feature = "alloc")]
|
||||
{
|
||||
let arc_instance: Arc<dyn Any + Send + Sync> = instance.into();
|
||||
Ok(arc_instance)
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
{
|
||||
// In no-alloc mode, we need to convert Box to Arc
|
||||
let arc_instance: Arc<dyn Any + Send + Sync> = instance.into();
|
||||
Ok(arc_instance)
|
||||
}
|
||||
} else {
|
||||
#[cfg(feature = "alloc")]
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
format!("Service not registered for type: {:?}", type_id)
|
||||
));
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
return Err(crate::error::Error::ServiceError(
|
||||
"Service not registered"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
//! Error handling module for NOS operating system
|
||||
|
||||
use core::fmt;
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::string::{String, ToString};
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::format;
|
||||
|
||||
// ToStringExt is not needed as string literals already have 'static lifetime
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
use crate::interfaces::String;
|
||||
|
||||
|
||||
/// Common error type used throughout NOS operating system
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -40,13 +45,25 @@ pub enum Error {
|
|||
/// Configuration error
|
||||
ConfigError(String),
|
||||
/// Service error
|
||||
#[cfg(feature = "alloc")]
|
||||
ServiceError(String),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
ServiceError(&'static str),
|
||||
/// System error
|
||||
#[cfg(feature = "alloc")]
|
||||
SystemError(String),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
SystemError(&'static str),
|
||||
/// Circular dependency error
|
||||
#[cfg(feature = "alloc")]
|
||||
CircularDependency(String),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
CircularDependency(&'static str),
|
||||
/// Custom error with code and message
|
||||
#[cfg(feature = "alloc")]
|
||||
Custom(i32, String),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
Custom(i32, &'static str),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
|
|
@ -67,9 +84,21 @@ impl fmt::Display for Error {
|
|||
Error::ConnectionError(msg) => write!(f, "Connection error: {}", msg),
|
||||
Error::ParseError(msg) => write!(f, "Parse error: {}", msg),
|
||||
Error::ConfigError(msg) => write!(f, "Configuration error: {}", msg),
|
||||
#[cfg(feature = "alloc")]
|
||||
Error::ServiceError(msg) => write!(f, "Service error: {}", msg),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
Error::ServiceError(msg) => write!(f, "Service error: {}", msg),
|
||||
#[cfg(feature = "alloc")]
|
||||
Error::SystemError(msg) => write!(f, "System error: {}", msg),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
Error::SystemError(msg) => write!(f, "System error: {}", msg),
|
||||
#[cfg(feature = "alloc")]
|
||||
Error::CircularDependency(msg) => write!(f, "Circular dependency: {}", msg),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
Error::CircularDependency(msg) => write!(f, "Circular dependency: {}", msg),
|
||||
#[cfg(feature = "alloc")]
|
||||
Error::Custom(code, msg) => write!(f, "Error {}: {}", code, msg),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
Error::Custom(code, msg) => write!(f, "Error {}: {}", code, msg),
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +123,10 @@ impl<T> ErrorContext<T> for Result<T> {
|
|||
fn context(self, _context: &str) -> Result<T> {
|
||||
match self {
|
||||
Ok(value) => Ok(value),
|
||||
#[cfg(feature = "alloc")]
|
||||
Err(error) => Err(Error::SystemError(format!("{}: {}", _context, error))),
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
Err(_error) => Err(Error::SystemError("System error".into())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -118,7 +150,14 @@ impl ErrorBuilder {
|
|||
|
||||
/// Adds context to the error
|
||||
pub fn context(mut self, _context: &str) -> Self {
|
||||
self.error = Error::SystemError(format!("{}: {}", _context, self.error));
|
||||
#[cfg(feature = "alloc")]
|
||||
{
|
||||
self.error = Error::SystemError(format!("{}: {}", _context, self.error));
|
||||
}
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
{
|
||||
self.error = Error::SystemError("System error".into());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -138,87 +177,182 @@ pub fn kernel_error(err: crate::core::types::KernelError) -> Error {
|
|||
Error::Kernel(err)
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
/// Creates a new invalid argument error
|
||||
pub fn invalid_argument(msg: &str) -> Error {
|
||||
Error::InvalidArgument(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
/// Creates a new invalid argument error (no-alloc version)
|
||||
pub fn invalid_argument(msg: &'static str) -> Error {
|
||||
Error::InvalidArgument(msg.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
/// Creates a new not implemented error
|
||||
pub fn not_implemented(msg: &str) -> Error {
|
||||
Error::NotImplemented(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
/// Creates a new not implemented error (no-alloc version)
|
||||
pub fn not_implemented(msg: &'static str) -> Error {
|
||||
Error::NotImplemented(msg.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
/// Creates a new not found error
|
||||
pub fn not_found(msg: &str) -> Error {
|
||||
Error::NotFound(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
/// Creates a new not found error (no-alloc version)
|
||||
pub fn not_found(msg: &'static str) -> Error {
|
||||
Error::NotFound(msg.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
/// Creates a new permission denied error
|
||||
pub fn permission_denied(msg: &str) -> Error {
|
||||
Error::PermissionDenied(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
/// Creates a new permission denied error (no-alloc version)
|
||||
pub fn permission_denied(msg: &'static str) -> Error {
|
||||
Error::PermissionDenied(msg.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
/// Creates a new busy error
|
||||
pub fn busy(msg: &str) -> Error {
|
||||
Error::Busy(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
/// Creates a new busy error (no-alloc version)
|
||||
pub fn busy(msg: &'static str) -> Error {
|
||||
Error::Busy(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new out of memory error
|
||||
pub fn out_of_memory() -> Error {
|
||||
Error::OutOfMemory
|
||||
}
|
||||
|
||||
/// Creates a new IO error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn io_error(msg: &str) -> Error {
|
||||
Error::IoError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn io_error(msg: &'static str) -> Error {
|
||||
Error::IoError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new network error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn network_error(msg: &str) -> Error {
|
||||
Error::NetworkError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn network_error(msg: &'static str) -> Error {
|
||||
Error::NetworkError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new protocol error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn protocol_error(msg: &str) -> Error {
|
||||
Error::ProtocolError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn protocol_error(msg: &'static str) -> Error {
|
||||
Error::ProtocolError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new timeout error
|
||||
pub fn timeout() -> Error {
|
||||
Error::Timeout
|
||||
}
|
||||
|
||||
/// Creates a new connection error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn connection_error(msg: &str) -> Error {
|
||||
Error::ConnectionError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn connection_error(msg: &'static str) -> Error {
|
||||
Error::ConnectionError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new parse error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn parse_error(msg: &str) -> Error {
|
||||
Error::ParseError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn parse_error(msg: &'static str) -> Error {
|
||||
Error::ParseError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new config error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn config_error(msg: &str) -> Error {
|
||||
Error::ConfigError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn config_error(msg: &'static str) -> Error {
|
||||
Error::ConfigError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new service error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn service_error(msg: &str) -> Error {
|
||||
Error::ServiceError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn service_error(msg: &'static str) -> Error {
|
||||
Error::ServiceError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new system error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn system_error(msg: &str) -> Error {
|
||||
Error::SystemError(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn system_error(msg: &'static str) -> Error {
|
||||
Error::SystemError(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new circular dependency error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn circular_dependency(msg: &str) -> Error {
|
||||
Error::CircularDependency(msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn circular_dependency(msg: &'static str) -> Error {
|
||||
Error::CircularDependency(msg.into())
|
||||
}
|
||||
|
||||
/// Creates a new custom error
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn custom(code: i32, msg: &str) -> Error {
|
||||
Error::Custom(code, msg.to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
pub fn custom(code: i32, msg: &'static str) -> Error {
|
||||
Error::Custom(code, msg.into())
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue