Merge branch 'multi_core' into 'master'
Multi core See merge request redox-os/kernel!118
This commit is contained in:
@@ -31,7 +31,7 @@ version = "0.29.0"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
default = ["serial_debug"]
|
||||
default = ["acpi", "multi_core", "serial_debug"]
|
||||
acpi = []
|
||||
doc = []
|
||||
graphical_debug = []
|
||||
|
||||
@@ -53,7 +53,7 @@ impl RSDP {
|
||||
fn slice_to_rsdp(slice: &[u8]) -> Option<&RSDP> {
|
||||
let ptr = slice.as_ptr() as usize;
|
||||
|
||||
if slice.len() >= mem::size_of::<RSDP>() && ptr & (!0x7) == ptr {
|
||||
if slice.len() >= mem::size_of::<RSDP>() && ptr & (!0x3) == ptr {
|
||||
let rsdp = unsafe { &*(slice.as_ptr() as *const RSDP) };
|
||||
// TODO: Validate
|
||||
Some(rsdp)
|
||||
|
||||
@@ -47,6 +47,7 @@ unsafe fn trigger(irq: u8) {
|
||||
}
|
||||
irq_trigger(irq);
|
||||
}
|
||||
|
||||
/// Unmask the IRQ. This is called from the IRQ scheme, which does this when a user process has
|
||||
/// processed the IRQ.
|
||||
pub unsafe fn acknowledge(irq: usize) {
|
||||
@@ -55,6 +56,7 @@ pub unsafe fn acknowledge(irq: usize) {
|
||||
IrqMethod::Apic => ioapic_unmask(irq),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends an end-of-interrupt, so that the interrupt controller can go on to the next one.
|
||||
pub unsafe fn eoi(irq: u8) {
|
||||
match irq_method() {
|
||||
@@ -77,17 +79,25 @@ unsafe fn ioapic_mask(irq: u8) {
|
||||
ioapic::mask(irq);
|
||||
}
|
||||
|
||||
|
||||
unsafe fn pic_eoi(irq: u8) {
|
||||
debug_assert!(irq < 16);
|
||||
|
||||
if irq >= 8 {
|
||||
pic::MASTER.ack();
|
||||
if irq == 15 {
|
||||
//TODO: check spurious
|
||||
return;
|
||||
}
|
||||
pic::SLAVE.ack();
|
||||
} else {
|
||||
if irq == 7 {
|
||||
//TODO: check spurious
|
||||
return;
|
||||
}
|
||||
pic::MASTER.ack();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn lapic_eoi() {
|
||||
local_apic::LOCAL_APIC.eoi()
|
||||
}
|
||||
@@ -101,6 +111,7 @@ unsafe fn pic_unmask(irq: usize) {
|
||||
pic::MASTER.mask_clear(irq as u8);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn ioapic_unmask(irq: usize) {
|
||||
ioapic::unmask(irq as u8);
|
||||
}
|
||||
@@ -156,67 +167,70 @@ interrupt!(com1, {
|
||||
});
|
||||
|
||||
interrupt!(lpt2, {
|
||||
eoi(5);
|
||||
trigger(5);
|
||||
eoi(5);
|
||||
});
|
||||
|
||||
interrupt!(floppy, {
|
||||
eoi(6);
|
||||
trigger(6);
|
||||
eoi(6);
|
||||
});
|
||||
|
||||
interrupt!(lpt1, {
|
||||
eoi(7);
|
||||
trigger(7);
|
||||
eoi(7);
|
||||
});
|
||||
|
||||
interrupt!(rtc, {
|
||||
eoi(8);
|
||||
trigger(8);
|
||||
eoi(8);
|
||||
});
|
||||
|
||||
interrupt!(pci1, {
|
||||
eoi(9);
|
||||
trigger(9);
|
||||
eoi(9);
|
||||
});
|
||||
|
||||
interrupt!(pci2, {
|
||||
eoi(10);
|
||||
trigger(10);
|
||||
eoi(10);
|
||||
});
|
||||
|
||||
interrupt!(pci3, {
|
||||
eoi(11);
|
||||
trigger(11);
|
||||
eoi(11);
|
||||
});
|
||||
|
||||
interrupt!(mouse, {
|
||||
eoi(12);
|
||||
trigger(12);
|
||||
eoi(12);
|
||||
});
|
||||
|
||||
interrupt!(fpu, {
|
||||
eoi(13);
|
||||
trigger(13);
|
||||
eoi(13);
|
||||
});
|
||||
|
||||
interrupt!(ata1, {
|
||||
eoi(14);
|
||||
trigger(14);
|
||||
eoi(14);
|
||||
});
|
||||
|
||||
interrupt!(ata2, {
|
||||
eoi(15);
|
||||
trigger(15);
|
||||
eoi(15);
|
||||
});
|
||||
|
||||
interrupt!(lapic_timer, {
|
||||
println!("Local apic timer interrupt");
|
||||
lapic_eoi();
|
||||
});
|
||||
|
||||
interrupt!(lapic_error, {
|
||||
println!("Local apic internal error: ESR={:#0x}", local_apic::LOCAL_APIC.esr());
|
||||
lapic_eoi();
|
||||
});
|
||||
|
||||
interrupt!(calib_pit, {
|
||||
const PIT_RATE: u64 = 2_250_286;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use spin::Mutex;
|
||||
use crate::arch::{macros::InterruptStack, paging::PAGE_SIZE};
|
||||
use crate::common::unique::Unique;
|
||||
use crate::context::arch;
|
||||
use crate::context::file::FileDescriptor;
|
||||
use crate::context::file::{FileDescriptor, FileDescription};
|
||||
use crate::context::memory::{Grant, Memory, SharedMemory, Tls};
|
||||
use crate::ipi::{ipi, IpiKind, IpiTarget};
|
||||
use crate::scheme::{SchemeNamespace, FileHandle};
|
||||
@@ -91,6 +91,76 @@ impl PartialEq for WaitpidKey {
|
||||
|
||||
impl Eq for WaitpidKey {}
|
||||
|
||||
pub struct ContextSnapshot {
|
||||
// Copy fields
|
||||
pub id: ContextId,
|
||||
pub pgid: ContextId,
|
||||
pub ppid: ContextId,
|
||||
pub ruid: u32,
|
||||
pub rgid: u32,
|
||||
pub rns: SchemeNamespace,
|
||||
pub euid: u32,
|
||||
pub egid: u32,
|
||||
pub ens: SchemeNamespace,
|
||||
pub sigmask: [u64; 2],
|
||||
pub umask: usize,
|
||||
pub status: Status,
|
||||
pub status_reason: &'static str,
|
||||
pub running: bool,
|
||||
pub cpu_id: Option<usize>,
|
||||
pub ticks: u64,
|
||||
pub syscall: Option<(usize, usize, usize, usize, usize, usize)>,
|
||||
// Clone fields
|
||||
//TODO: is there a faster way than allocation?
|
||||
pub name: Box<[u8]>,
|
||||
pub files: Vec<Option<FileDescription>>,
|
||||
// pub cwd: Box<[u8]>,
|
||||
}
|
||||
|
||||
impl ContextSnapshot {
|
||||
//TODO: Should this accept &mut Context to ensure name/files will not change?
|
||||
pub fn new(context: &Context) -> Self {
|
||||
let name = context.name.lock().clone();
|
||||
let mut files = Vec::new();
|
||||
for descriptor_opt in context.files.lock().iter() {
|
||||
let description = if let Some(descriptor) = descriptor_opt {
|
||||
let description = descriptor.description.read();
|
||||
Some(FileDescription {
|
||||
namespace: description.namespace,
|
||||
scheme: description.scheme,
|
||||
number: description.number,
|
||||
flags: description.flags,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
files.push(description);
|
||||
}
|
||||
|
||||
Self {
|
||||
id: context.id,
|
||||
pgid: context.pgid,
|
||||
ppid: context.ppid,
|
||||
ruid: context.ruid,
|
||||
rgid: context.rgid,
|
||||
rns: context.rns,
|
||||
euid: context.euid,
|
||||
egid: context.egid,
|
||||
ens: context.ens,
|
||||
sigmask: context.sigmask,
|
||||
umask: context.umask,
|
||||
status: context.status,
|
||||
status_reason: context.status_reason,
|
||||
running: context.running,
|
||||
cpu_id: context.cpu_id,
|
||||
ticks: context.ticks,
|
||||
syscall: context.syscall,
|
||||
name,
|
||||
files,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A context, which identifies either a process or a thread
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
@@ -118,6 +188,7 @@ pub struct Context {
|
||||
pub umask: usize,
|
||||
/// Status of context
|
||||
pub status: Status,
|
||||
pub status_reason: &'static str,
|
||||
/// Context running or not
|
||||
pub running: bool,
|
||||
/// CPU ID, if locked
|
||||
@@ -197,6 +268,7 @@ impl Context {
|
||||
sigmask: [0; 2],
|
||||
umask: 0o022,
|
||||
status: Status::Blocked,
|
||||
status_reason: "",
|
||||
running: false,
|
||||
cpu_id: None,
|
||||
ticks: 0,
|
||||
@@ -304,9 +376,10 @@ impl Context {
|
||||
}
|
||||
|
||||
/// Block the context, and return true if it was runnable before being blocked
|
||||
pub fn block(&mut self) -> bool {
|
||||
pub fn block(&mut self, reason: &'static str) -> bool {
|
||||
if self.status == Status::Runnable {
|
||||
self.status = Status::Blocked;
|
||||
self.status_reason = reason;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -317,6 +390,7 @@ impl Context {
|
||||
pub fn unblock(&mut self) -> bool {
|
||||
if self.status == Status::Blocked {
|
||||
self.status = Status::Runnable;
|
||||
self.status_reason = "";
|
||||
|
||||
if let Some(cpu_id) = self.cpu_id {
|
||||
if cpu_id != crate::cpu_id() {
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
use alloc::sync::Arc;
|
||||
use crate::event;
|
||||
use spin::RwLock;
|
||||
use crate::scheme::{self, SchemeId};
|
||||
use crate::scheme::{self, SchemeNamespace, SchemeId};
|
||||
use crate::syscall::error::{Result, Error, EBADF};
|
||||
|
||||
/// A file description
|
||||
#[derive(Debug)]
|
||||
pub struct FileDescription {
|
||||
/// The namespace the file was opened from (used for debugging)
|
||||
pub namespace: SchemeNamespace,
|
||||
/// The scheme that this file refers to
|
||||
pub scheme: SchemeId,
|
||||
/// The number the scheme uses to refer to this file
|
||||
|
||||
@@ -6,7 +6,7 @@ use core::alloc::{GlobalAlloc, Layout};
|
||||
use core::sync::atomic::Ordering;
|
||||
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
pub use self::context::{Context, ContextId, Status, WaitpidKey};
|
||||
pub use self::context::{Context, ContextId, ContextSnapshot, Status, WaitpidKey};
|
||||
pub use self::list::ContextList;
|
||||
pub use self::switch::switch;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ impl EventQueue {
|
||||
}
|
||||
|
||||
pub fn read(&self, events: &mut [Event]) -> Result<usize> {
|
||||
self.queue.receive_into(events, true).ok_or(Error::new(EINTR))
|
||||
self.queue.receive_into(events, true, "EventQueue::read").ok_or(Error::new(EINTR))
|
||||
}
|
||||
|
||||
pub fn write(&self, events: &[Event]) -> Result<usize> {
|
||||
|
||||
@@ -39,7 +39,7 @@ use core::{
|
||||
cmp,
|
||||
sync::atomic::Ordering
|
||||
};
|
||||
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
// ____ _
|
||||
// / ___| ___ ___ ___(_) ___ _ __ ___
|
||||
@@ -225,7 +225,9 @@ pub fn wait(pid: ContextId) -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
while !tracer.wait() {}
|
||||
//TODO: proper wait_condition mutex
|
||||
let m = Mutex::new(());
|
||||
while !tracer.wait(m.lock(), "ptrace::wait") {}
|
||||
|
||||
let contexts = context::contexts();
|
||||
let context = contexts.get(pid).ok_or(Error::new(ESRCH))?;
|
||||
@@ -269,7 +271,9 @@ pub fn breakpoint_callback(match_flags: PtraceFlags, event: Option<PtraceEvent>)
|
||||
)
|
||||
};
|
||||
|
||||
while !tracee.wait() {}
|
||||
//TODO: proper wait_condition mutex
|
||||
let m = Mutex::new(());
|
||||
while !tracee.wait(m.lock(), "ptrace::breakpoint_callback") {}
|
||||
|
||||
Some(flags)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ impl Scheme for DebugScheme {
|
||||
};
|
||||
|
||||
INPUT.call_once(init_input)
|
||||
.receive_into(buf, flags & O_NONBLOCK != O_NONBLOCK)
|
||||
.receive_into(buf, flags & O_NONBLOCK != O_NONBLOCK, "DebugScheme::read")
|
||||
.ok_or(Error::new(EINTR))
|
||||
}
|
||||
|
||||
|
||||
@@ -180,31 +180,29 @@ impl PipeRead {
|
||||
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
loop {
|
||||
{
|
||||
let mut vec = self.vec.lock();
|
||||
let mut vec = self.vec.lock();
|
||||
|
||||
let mut i = 0;
|
||||
while i < buf.len() {
|
||||
if let Some(b) = vec.pop_front() {
|
||||
buf[i] = b;
|
||||
i += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
let mut i = 0;
|
||||
while i < buf.len() {
|
||||
if let Some(b) = vec.pop_front() {
|
||||
buf[i] = b;
|
||||
i += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
event::trigger(self.scheme_id, self.write_id, EVENT_WRITE);
|
||||
if i > 0 {
|
||||
event::trigger(self.scheme_id, self.write_id, EVENT_WRITE);
|
||||
|
||||
return Ok(i);
|
||||
}
|
||||
return Ok(i);
|
||||
}
|
||||
|
||||
if Arc::weak_count(&self.vec) == 0 {
|
||||
return Ok(0);
|
||||
} else if self.flags.load(Ordering::SeqCst) & O_NONBLOCK == O_NONBLOCK {
|
||||
return Err(Error::new(EAGAIN));
|
||||
} else if ! self.condition.wait() {
|
||||
} else if ! self.condition.wait(vec, "PipeRead::read") {
|
||||
return Err(Error::new(EINTR));
|
||||
}
|
||||
}
|
||||
|
||||
35
src/scheme/sys/block.rs
Normal file
35
src/scheme/sys/block.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt::Write;
|
||||
use core::str;
|
||||
|
||||
use crate::context;
|
||||
use crate::syscall::error::Result;
|
||||
|
||||
pub fn resource() -> Result<Vec<u8>> {
|
||||
let mut string = String::new();
|
||||
|
||||
{
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
for (id, context_lock) in contexts.iter() {
|
||||
let context = context_lock.read();
|
||||
rows.push((*id, context.name.lock().clone(), context.status_reason));
|
||||
}
|
||||
}
|
||||
|
||||
for row in rows.iter() {
|
||||
let id: usize = row.0.into();
|
||||
let name = str::from_utf8(&row.1).unwrap_or(".");
|
||||
|
||||
let _ = writeln!(string, "{}: {}", id, name);
|
||||
|
||||
if ! row.2.is_empty() {
|
||||
let _ = writeln!(string, " {}", row.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(string.into_bytes())
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use crate::syscall::error::{Error, EBADF, EINVAL, ENOENT, Result};
|
||||
use crate::syscall::flag::{MODE_DIR, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
use crate::syscall::scheme::Scheme;
|
||||
|
||||
mod block;
|
||||
mod context;
|
||||
mod cpu;
|
||||
mod exe;
|
||||
@@ -40,6 +41,7 @@ impl SysScheme {
|
||||
pub fn new() -> SysScheme {
|
||||
let mut files: BTreeMap<&'static [u8], Box<SysFn>> = BTreeMap::new();
|
||||
|
||||
files.insert(b"block", Box::new(block::resource));
|
||||
files.insert(b"context", Box::new(context::resource));
|
||||
files.insert(b"cpu", Box::new(cpu::resource));
|
||||
files.insert(b"exe", Box::new(exe::resource));
|
||||
|
||||
@@ -97,7 +97,7 @@ impl UserInner {
|
||||
self.todo.send(packet);
|
||||
event::trigger(self.root_id, self.handle_id, EVENT_READ);
|
||||
|
||||
Error::demux(self.done.receive(&id))
|
||||
Error::demux(self.done.receive(&id, "UserInner::call_inner"))
|
||||
}
|
||||
|
||||
pub fn capture(&self, buf: &[u8]) -> Result<usize> {
|
||||
@@ -202,7 +202,7 @@ impl UserInner {
|
||||
// If unmounting, do not block so that EOF can be returned immediately
|
||||
let unmounting = self.unmounting.load(Ordering::SeqCst);
|
||||
let block = !(nonblock || unmounting);
|
||||
if let Some(count) = self.todo.receive_into(packet_buf, block) {
|
||||
if let Some(count) = self.todo.receive_into(packet_buf, block, "UserInner::read") {
|
||||
if count > 0 {
|
||||
// If we received requests, return them to the scheme handler
|
||||
Ok(count * mem::size_of::<Packet>())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use spin::{Mutex, RwLock};
|
||||
use spin::{Mutex, MutexGuard, RwLock};
|
||||
|
||||
use crate::context::{self, Context};
|
||||
|
||||
@@ -36,8 +36,8 @@ impl WaitCondition {
|
||||
len
|
||||
}
|
||||
|
||||
// Wait until notified. Returns false if resumed by a signal or the notify_signal function
|
||||
pub fn wait(&self) -> bool {
|
||||
// Wait until notified. Unlocks guard when blocking is ready. Returns false if resumed by a signal or the notify_signal function
|
||||
pub fn wait<T>(&self, guard: MutexGuard<T>, reason: &'static str) -> bool {
|
||||
let id;
|
||||
{
|
||||
let context_lock = {
|
||||
@@ -49,10 +49,12 @@ impl WaitCondition {
|
||||
{
|
||||
let mut context = context_lock.write();
|
||||
id = context.id;
|
||||
context.block();
|
||||
context.block(reason);
|
||||
}
|
||||
|
||||
self.contexts.lock().push(context_lock);
|
||||
|
||||
drop(guard);
|
||||
}
|
||||
|
||||
unsafe { context::switch(); }
|
||||
|
||||
@@ -22,13 +22,14 @@ impl<K, V> WaitMap<K, V> where K: Clone + Ord {
|
||||
self.inner.lock().remove(key)
|
||||
}
|
||||
|
||||
pub fn receive(&self, key: &K) -> V {
|
||||
pub fn receive(&self, key: &K, reason: &'static str) -> V {
|
||||
loop {
|
||||
if let Some(value) = self.receive_nonblock(key) {
|
||||
let mut inner = self.inner.lock();
|
||||
if let Some(value) = inner.remove(key) {
|
||||
return value;
|
||||
}
|
||||
//TODO: use false from wait condition to indicate EINTR
|
||||
let _ = self.condition.wait();
|
||||
let _ = self.condition.wait(inner, reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +42,15 @@ impl<K, V> WaitMap<K, V> where K: Clone + Ord {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn receive_any(&self) -> (K, V) {
|
||||
pub fn receive_any(&self, reason: &'static str) -> (K, V) {
|
||||
loop {
|
||||
if let Some(entry) = self.receive_any_nonblock() {
|
||||
return entry;
|
||||
let mut inner = self.inner.lock();
|
||||
if let Some(key) = inner.keys().next().cloned() {
|
||||
if let Some(entry) = inner.remove(&key).map(|value| (key, value)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
let _ = self.condition.wait();
|
||||
let _ = self.condition.wait(inner, reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,22 +28,23 @@ impl<T> WaitQueue<T> {
|
||||
self.inner.lock().is_empty()
|
||||
}
|
||||
|
||||
pub fn receive(&self) -> Option<T> {
|
||||
pub fn receive(&self, reason: &'static str) -> Option<T> {
|
||||
loop {
|
||||
if let Some(value) = self.inner.lock().pop_front() {
|
||||
let mut inner = self.inner.lock();
|
||||
if let Some(value) = inner.pop_front() {
|
||||
return Some(value);
|
||||
}
|
||||
if ! self.condition.wait() {
|
||||
if ! self.condition.wait(inner, reason) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn receive_into(&self, buf: &mut [T], block: bool) -> Option<usize> {
|
||||
pub fn receive_into(&self, buf: &mut [T], block: bool, reason: &'static str) -> Option<usize> {
|
||||
let mut i = 0;
|
||||
|
||||
if i < buf.len() && block {
|
||||
buf[i] = self.receive()?;
|
||||
buf[i] = self.receive(reason)?;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ impl<'a> ::core::fmt::Debug for ByteStr<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO: calling format_call with arguments from another process space will not work
|
||||
pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> String {
|
||||
match a {
|
||||
SYS_OPEN => format!(
|
||||
|
||||
@@ -142,6 +142,7 @@ pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
|
||||
let context = context_lock.read();
|
||||
return context.add_file(FileDescriptor {
|
||||
description: Arc::new(RwLock::new(FileDescription {
|
||||
namespace: scheme_ns,
|
||||
scheme: scheme_id,
|
||||
number: file_id,
|
||||
flags: flags & !O_CLOEXEC,
|
||||
@@ -163,6 +164,7 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
|
||||
|
||||
let read_fd = context.add_file(FileDescriptor {
|
||||
description: Arc::new(RwLock::new(FileDescription {
|
||||
namespace: context.ens,
|
||||
scheme: scheme_id,
|
||||
number: read_id,
|
||||
flags: O_RDONLY | flags & !O_ACCMODE & !O_CLOEXEC,
|
||||
@@ -172,6 +174,7 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
|
||||
|
||||
let write_fd = context.add_file(FileDescriptor {
|
||||
description: Arc::new(RwLock::new(FileDescription {
|
||||
namespace: context.ens,
|
||||
scheme: scheme_id,
|
||||
number: write_id,
|
||||
flags: O_WRONLY | flags & !O_ACCMODE & !O_CLOEXEC,
|
||||
@@ -293,6 +296,7 @@ fn duplicate_file(fd: FileHandle, buf: &[u8]) -> Result<FileDescriptor> {
|
||||
|
||||
Ok(FileDescriptor {
|
||||
description: Arc::new(RwLock::new(FileDescription {
|
||||
namespace: description.namespace,
|
||||
scheme: description.scheme,
|
||||
number: new_id,
|
||||
flags: description.flags,
|
||||
|
||||
@@ -66,7 +66,7 @@ pub fn futex(addr: &mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32)
|
||||
context.wake = Some(end);
|
||||
}
|
||||
|
||||
context.block();
|
||||
context.block("futex");
|
||||
}
|
||||
|
||||
futexes.push_back((addr as *mut i32 as usize, context_lock));
|
||||
|
||||
@@ -115,9 +115,10 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
|
||||
sigmask = context.sigmask;
|
||||
umask = context.umask;
|
||||
|
||||
if flags.contains(CLONE_VM) {
|
||||
cpu_id_opt = context.cpu_id;
|
||||
}
|
||||
// Uncomment to disable threads on different CPUs
|
||||
// if flags.contains(CLONE_VM) {
|
||||
// cpu_id_opt = context.cpu_id;
|
||||
// }
|
||||
|
||||
arch = context.arch.clone();
|
||||
|
||||
@@ -355,7 +356,7 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let mut context = context_lock.write();
|
||||
context.block();
|
||||
context.block("vfork");
|
||||
vfork = true;
|
||||
} else {
|
||||
vfork = false;
|
||||
@@ -1429,7 +1430,7 @@ pub fn sigreturn() -> Result<usize> {
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let mut context = context_lock.write();
|
||||
context.ksig_restore = true;
|
||||
context.block();
|
||||
context.block("sigreturn");
|
||||
}
|
||||
|
||||
let _ = unsafe { context::switch() };
|
||||
@@ -1538,7 +1539,7 @@ pub fn waitpid(pid: ContextId, status_ptr: usize, flags: WaitFlags) -> Result<Co
|
||||
Some(Ok(ContextId::from(0)))
|
||||
}
|
||||
} else {
|
||||
let (_wid, (w_pid, status)) = waitpid.receive_any();
|
||||
let (_wid, (w_pid, status)) = waitpid.receive_any("waitpid any");
|
||||
grim_reaper(w_pid, status)
|
||||
}
|
||||
} else if (pid.into() as isize) < 0 {
|
||||
@@ -1575,7 +1576,7 @@ pub fn waitpid(pid: ContextId, status_ptr: usize, flags: WaitFlags) -> Result<Co
|
||||
let (w_pid, status) = waitpid.receive(&WaitpidKey {
|
||||
pid: None,
|
||||
pgid: Some(pgid)
|
||||
});
|
||||
}, "waitpid pgid");
|
||||
grim_reaper(w_pid, status)
|
||||
}
|
||||
} else {
|
||||
@@ -1612,7 +1613,7 @@ pub fn waitpid(pid: ContextId, status_ptr: usize, flags: WaitFlags) -> Result<Co
|
||||
let (w_pid, status) = waitpid.receive(&WaitpidKey {
|
||||
pid: Some(pid),
|
||||
pgid: None
|
||||
});
|
||||
}, "waitpid pid");
|
||||
grim_reaper(w_pid, status)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ pub fn nanosleep(req: &TimeSpec, rem_opt: Option<&mut TimeSpec>) -> Result<usize
|
||||
let mut context = context_lock.write();
|
||||
|
||||
context.wake = Some(end);
|
||||
context.block();
|
||||
context.block("nanosleep");
|
||||
}
|
||||
|
||||
unsafe { context::switch(); }
|
||||
|
||||
Reference in New Issue
Block a user