Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion kernel/src/arch_impl/aarch64/syscall_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,15 @@ fn sys_exec_aarch64(
let bin_path = alloc::format!("/bin/{}", program_name);
match load_elf_from_ext2(&bin_path) {
Ok(data) => data,
Err(_) => crate::userspace_test::get_test_binary(&program_name),
Err(errno) => {
// ARM64 doesn't have userspace_test module fallback
log::error!(
"sys_exec_aarch64: Failed to load /bin/{}: {}",
program_name,
errno
);
return (-(errno as i64)) as u64;
}
}
};

Expand Down
17 changes: 17 additions & 0 deletions kernel/src/arch_impl/aarch64/timer_interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ static TIMER_INITIALIZED: core::sync::atomic::AtomicBool =
/// Total timer interrupt count (for frequency verification)
static TIMER_INTERRUPT_COUNT: AtomicU64 = AtomicU64::new(0);

#[cfg(feature = "boot_tests")]
static RESET_QUANTUM_CALL_COUNT: AtomicU64 = AtomicU64::new(0);

/// Interval for printing timer count (every N interrupts for frequency verification)
/// Printing on every interrupt adds overhead; reduce frequency for more accurate measurement
/// At 200 Hz: print interval 200 = print once per second
Expand Down Expand Up @@ -226,9 +229,23 @@ fn poll_keyboard_to_stdin() {

/// Reset the quantum counter (called when switching threads)
pub fn reset_quantum() {
#[cfg(feature = "boot_tests")]
RESET_QUANTUM_CALL_COUNT.fetch_add(1, Ordering::SeqCst);
CURRENT_QUANTUM.store(TIME_QUANTUM, Ordering::Relaxed);
}

/// Get reset_quantum() call count for tests.
#[cfg(feature = "boot_tests")]
pub fn reset_quantum_call_count() -> u64 {
RESET_QUANTUM_CALL_COUNT.load(Ordering::SeqCst)
}

/// Reset reset_quantum() call count for tests.
#[cfg(feature = "boot_tests")]
pub fn reset_quantum_call_count_reset() {
RESET_QUANTUM_CALL_COUNT.store(0, Ordering::SeqCst);
}

/// Check if the timer is initialized
pub fn is_initialized() -> bool {
TIMER_INITIALIZED.load(Ordering::Acquire)
Expand Down
42 changes: 0 additions & 42 deletions kernel/src/ipc/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,31 +89,23 @@ pub enum FdKind {
UdpSocket(Arc<Mutex<crate::socket::udp::UdpSocket>>),
/// TCP socket (unbound, or bound but not connected/listening)
/// The u16 is the bound local port (0 if unbound)
#[cfg(target_arch = "x86_64")]
TcpSocket(u16),
/// TCP listener (bound and listening socket)
/// The u16 is the listening port
#[cfg(target_arch = "x86_64")]
TcpListener(u16),
/// TCP connection (established connection)
/// Contains the connection ID for lookup in the global TCP connection table
#[cfg(target_arch = "x86_64")]
TcpConnection(crate::net::tcp::ConnectionId),
/// Regular file descriptor
#[allow(dead_code)] // Will be constructed when open() is fully implemented
#[cfg(target_arch = "x86_64")]
RegularFile(Arc<Mutex<RegularFile>>),
/// Directory file descriptor (for getdents)
#[cfg(target_arch = "x86_64")]
Directory(Arc<Mutex<DirectoryFile>>),
/// Device file (/dev/null, /dev/zero, /dev/console, /dev/tty)
#[cfg(target_arch = "x86_64")]
Device(crate::fs::devfs::DeviceType),
/// /dev directory (virtual directory for listing devices)
#[cfg(target_arch = "x86_64")]
DevfsDirectory { position: u64 },
/// /dev/pts directory (virtual directory for listing PTY slaves)
#[cfg(target_arch = "x86_64")]
DevptsDirectory { position: u64 },
/// PTY master file descriptor
/// Allow unused - constructed by posix_openpt syscall in Phase 2
Expand All @@ -133,10 +125,8 @@ pub enum FdKind {
/// Fully architecture-independent
UnixListener(alloc::sync::Arc<spin::Mutex<crate::socket::unix::UnixListener>>),
/// FIFO (named pipe) read end - path is stored for cleanup on close
#[cfg(target_arch = "x86_64")]
FifoRead(alloc::string::String, Arc<Mutex<super::pipe::PipeBuffer>>),
/// FIFO (named pipe) write end - path is stored for cleanup on close
#[cfg(target_arch = "x86_64")]
FifoWrite(alloc::string::String, Arc<Mutex<super::pipe::PipeBuffer>>),
}

Expand All @@ -147,21 +137,13 @@ impl core::fmt::Debug for FdKind {
FdKind::PipeRead(_) => write!(f, "PipeRead"),
FdKind::PipeWrite(_) => write!(f, "PipeWrite"),
FdKind::UdpSocket(_) => write!(f, "UdpSocket"),
#[cfg(target_arch = "x86_64")]
FdKind::TcpSocket(port) => write!(f, "TcpSocket(port={})", port),
#[cfg(target_arch = "x86_64")]
FdKind::TcpListener(port) => write!(f, "TcpListener(port={})", port),
#[cfg(target_arch = "x86_64")]
FdKind::TcpConnection(id) => write!(f, "TcpConnection({:?})", id),
#[cfg(target_arch = "x86_64")]
FdKind::RegularFile(_) => write!(f, "RegularFile"),
#[cfg(target_arch = "x86_64")]
FdKind::Directory(_) => write!(f, "Directory"),
#[cfg(target_arch = "x86_64")]
FdKind::Device(dt) => write!(f, "Device({:?})", dt),
#[cfg(target_arch = "x86_64")]
FdKind::DevfsDirectory { position } => write!(f, "DevfsDirectory(pos={})", position),
#[cfg(target_arch = "x86_64")]
FdKind::DevptsDirectory { position } => write!(f, "DevptsDirectory(pos={})", position),
FdKind::PtyMaster(n) => write!(f, "PtyMaster({})", n),
FdKind::PtySlave(n) => write!(f, "PtySlave({})", n),
Expand All @@ -177,9 +159,7 @@ impl core::fmt::Debug for FdKind {
let listener = l.lock();
write!(f, "UnixListener(pending={})", listener.pending_count())
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoRead(path, _) => write!(f, "FifoRead({})", path),
#[cfg(target_arch = "x86_64")]
FdKind::FifoWrite(path, _) => write!(f, "FifoWrite({})", path),
}
}
Expand Down Expand Up @@ -259,23 +239,20 @@ impl Clone for FdTable {
match &fd_entry.kind {
FdKind::PipeRead(buffer) => buffer.lock().add_reader(),
FdKind::PipeWrite(buffer) => buffer.lock().add_writer(),
#[cfg(target_arch = "x86_64")]
FdKind::FifoRead(path, buffer) => {
// Increment both FIFO entry reader count and pipe buffer reader count
if let Some(entry) = super::fifo::FIFO_REGISTRY.get(path) {
entry.lock().readers += 1;
}
buffer.lock().add_reader();
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoWrite(path, buffer) => {
// Increment both FIFO entry writer count and pipe buffer writer count
if let Some(entry) = super::fifo::FIFO_REGISTRY.get(path) {
entry.lock().writers += 1;
}
buffer.lock().add_writer();
}
#[cfg(target_arch = "x86_64")]
FdKind::PtyMaster(pty_num) => {
// Increment PTY master reference count for the clone
if let Some(pair) = crate::tty::pty::get(*pty_num) {
Expand All @@ -284,7 +261,6 @@ impl Clone for FdTable {
pty_num, old_count, old_count + 1);
}
}
#[cfg(target_arch = "x86_64")]
FdKind::TcpConnection(conn_id) => {
// Increment TCP connection reference count for the clone
crate::net::tcp::tcp_add_ref(conn_id);
Expand Down Expand Up @@ -397,12 +373,10 @@ impl FdTable {
match old_entry.kind {
FdKind::PipeRead(buffer) => buffer.lock().close_read(),
FdKind::PipeWrite(buffer) => buffer.lock().close_write(),
#[cfg(target_arch = "x86_64")]
FdKind::FifoRead(ref path, ref buffer) => {
super::fifo::close_fifo_read(path);
buffer.lock().close_read();
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoWrite(ref path, ref buffer) => {
super::fifo::close_fifo_write(path);
buffer.lock().close_write();
Expand All @@ -415,14 +389,12 @@ impl FdTable {
match &fd_entry.kind {
FdKind::PipeRead(buffer) => buffer.lock().add_reader(),
FdKind::PipeWrite(buffer) => buffer.lock().add_writer(),
#[cfg(target_arch = "x86_64")]
FdKind::FifoRead(path, buffer) => {
if let Some(entry) = super::fifo::FIFO_REGISTRY.get(path) {
entry.lock().readers += 1;
}
buffer.lock().add_reader();
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoWrite(path, buffer) => {
if let Some(entry) = super::fifo::FIFO_REGISTRY.get(path) {
entry.lock().writers += 1;
Expand Down Expand Up @@ -462,14 +434,12 @@ impl FdTable {
match &fd_entry.kind {
FdKind::PipeRead(buffer) => buffer.lock().add_reader(),
FdKind::PipeWrite(buffer) => buffer.lock().add_writer(),
#[cfg(target_arch = "x86_64")]
FdKind::FifoRead(path, buffer) => {
if let Some(entry) = super::fifo::FIFO_REGISTRY.get(path) {
entry.lock().readers += 1;
}
buffer.lock().add_reader();
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoWrite(path, buffer) => {
if let Some(entry) = super::fifo::FIFO_REGISTRY.get(path) {
entry.lock().writers += 1;
Expand All @@ -491,12 +461,10 @@ impl FdTable {
match &fd_entry.kind {
FdKind::PipeRead(buffer) => buffer.lock().close_read(),
FdKind::PipeWrite(buffer) => buffer.lock().close_write(),
#[cfg(target_arch = "x86_64")]
FdKind::FifoRead(path, buffer) => {
super::fifo::close_fifo_read(path);
buffer.lock().close_read();
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoWrite(path, buffer) => {
super::fifo::close_fifo_write(path);
buffer.lock().close_write();
Expand Down Expand Up @@ -558,18 +526,15 @@ impl Drop for FdTable {
// Socket cleanup handled by UdpSocket::Drop when Arc refcount reaches 0
log::debug!("FdTable::drop() - releasing UDP socket fd {}", i);
}
#[cfg(target_arch = "x86_64")]
FdKind::TcpSocket(_) => {
// Unbound TCP socket doesn't need cleanup
log::debug!("FdTable::drop() - releasing TCP socket fd {}", i);
}
#[cfg(target_arch = "x86_64")]
FdKind::TcpListener(port) => {
// Remove from listener table
crate::net::tcp::TCP_LISTENERS.lock().remove(&port);
log::debug!("FdTable::drop() - closed TCP listener fd {} on port {}", i, port);
}
#[cfg(target_arch = "x86_64")]
FdKind::TcpConnection(conn_id) => {
// Close the TCP connection
let _ = crate::net::tcp::tcp_close(&conn_id);
Expand All @@ -578,27 +543,22 @@ impl Drop for FdTable {
FdKind::StdIo(_) => {
// StdIo doesn't need cleanup
}
#[cfg(target_arch = "x86_64")]
FdKind::RegularFile(_) => {
// Regular file cleanup handled by Arc refcount
log::debug!("FdTable::drop() - releasing regular file fd {}", i);
}
#[cfg(target_arch = "x86_64")]
FdKind::Directory(_) => {
// Directory cleanup handled by Arc refcount
log::debug!("FdTable::drop() - releasing directory fd {}", i);
}
#[cfg(target_arch = "x86_64")]
FdKind::Device(_) => {
// Device files don't need cleanup
log::debug!("FdTable::drop() - releasing device fd {}", i);
}
#[cfg(target_arch = "x86_64")]
FdKind::DevfsDirectory { .. } => {
// Devfs directory doesn't need cleanup
log::debug!("FdTable::drop() - releasing devfs directory fd {}", i);
}
#[cfg(target_arch = "x86_64")]
FdKind::DevptsDirectory { .. } => {
// Devpts directory doesn't need cleanup
log::debug!("FdTable::drop() - releasing devpts directory fd {}", i);
Expand Down Expand Up @@ -640,14 +600,12 @@ impl Drop for FdTable {
l.wake_waiters();
log::debug!("FdTable::drop() - closed Unix listener fd {}", i);
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoRead(path, buffer) => {
// Decrement FIFO reader count and pipe buffer reader count
super::fifo::close_fifo_read(&path);
buffer.lock().close_read();
log::debug!("FdTable::drop() - closed FIFO read fd {} ({})", i, path);
}
#[cfg(target_arch = "x86_64")]
FdKind::FifoWrite(path, buffer) => {
// Decrement FIFO writer count and pipe buffer writer count
super::fifo::close_fifo_write(&path);
Expand Down
3 changes: 1 addition & 2 deletions kernel/src/ipc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
//! This module provides IPC primitives for Breenix:
//! - File descriptors (fd.rs) - Per-process file descriptor tables
//! - Pipes (pipe.rs) - Unidirectional byte streams
//! - FIFOs (fifo.rs) - Named pipes for filesystem-based IPC (x86_64 only)
//! - FIFOs (fifo.rs) - Named pipes for filesystem-based IPC
//! - Stdin (stdin.rs) - Kernel stdin ring buffer for keyboard input
//! - Poll (poll.rs) - Poll file descriptors for I/O readiness

pub mod fd;
#[cfg(target_arch = "x86_64")]
pub mod fifo;
pub mod pipe;
pub mod poll;
Expand Down
Loading
Loading