* Port previous ethernet scheme

* Add ipd

* Fix initfs rebuilds, use QEMU user networking addresses in ipd

* Add tcp/udp, netutils, dns, and network config

* Add fsync to network driver

* Add dns, router, subnet by default

* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks

* Add orbital server, WIP

* Add futex

* Add orbutils and orbital

* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad

* Add orbital assets

* Update orbital

* Update to add login manager

* Add blocking primitives, block for most things except waitpid, update orbital

* Wait in waitpid and IRQ, improvements for other waits

* Fevent in root scheme

* WIP: Switch to using fevent

* Reorganize

* Event based e1000d driver

* Superuser-only access to some network schemes, display, and disk

* Superuser root and irq schemes

* Fix orbital
This commit is contained in:
Jeremy Soller 2016-10-13 17:21:42 -06:00 committed by GitHub
parent 372d44f88c
commit 224c43f761
92 changed files with 3415 additions and 473 deletions

View file

@ -1,12 +1,13 @@
use alloc::arc::Arc;
use alloc::boxed::Box;
use collections::{BTreeMap, Vec, VecDeque};
use collections::{BTreeMap, Vec};
use spin::Mutex;
use arch;
use context::file::File;
use context::memory::{Grant, Memory, SharedMemory};
use syscall::data::Event;
use super::file::File;
use super::memory::{Grant, Memory, SharedMemory};
use sync::{WaitCondition, WaitQueue};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Status {
@ -36,6 +37,10 @@ pub struct Context {
pub running: bool,
/// Context is halting parent
pub vfork: bool,
/// Context is being waited on
pub waitpid: Arc<WaitCondition>,
/// Context should wake up at specified time
pub wake: Option<(u64, u64)>,
/// The architecture specific context
pub arch: arch::context::Context,
/// Kernel FX
@ -53,7 +58,7 @@ pub struct Context {
/// The current working directory
pub cwd: Arc<Mutex<Vec<u8>>>,
/// Kernel events
pub events: Arc<Mutex<VecDeque<Event>>>,
pub events: Arc<WaitQueue<Event>>,
/// The process environment
pub env: Arc<Mutex<BTreeMap<Box<[u8]>, Arc<Mutex<Vec<u8>>>>>>,
/// The open files in the scheme
@ -73,6 +78,8 @@ impl Context {
status: Status::Blocked,
running: false,
vfork: false,
waitpid: Arc::new(WaitCondition::new()),
wake: None,
arch: arch::context::Context::new(),
kfx: None,
kstack: None,
@ -81,7 +88,7 @@ impl Context {
stack: None,
grants: Arc::new(Mutex::new(Vec::new())),
cwd: Arc::new(Mutex::new(Vec::new())),
events: Arc::new(Mutex::new(VecDeque::new())),
events: Arc::new(WaitQueue::new()),
env: Arc::new(Mutex::new(BTreeMap::new())),
files: Arc::new(Mutex::new(Vec::new()))
}
@ -128,6 +135,24 @@ impl Context {
}
}
pub fn block(&mut self) -> bool {
if self.status == Status::Runnable {
self.status = Status::Blocked;
true
} else {
false
}
}
pub fn unblock(&mut self) -> bool {
if self.status == Status::Blocked {
self.status = Status::Runnable;
true
} else {
false
}
}
/// Add a file to the lowest available slot.
/// Return the file descriptor number or None if no slot was found
pub fn add_file(&self, file: File) -> Option<usize> {

View file

@ -1,11 +1,12 @@
use alloc::arc::{Arc, Weak};
use collections::{BTreeMap, VecDeque};
use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
use collections::BTreeMap;
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
use context;
use sync::WaitQueue;
use syscall::data::Event;
type EventList = Weak<Mutex<VecDeque<Event>>>;
type EventList = Weak<WaitQueue<Event>>;
type Registry = BTreeMap<(usize, usize), BTreeMap<(usize, usize), EventList>>;
@ -67,9 +68,8 @@ pub fn trigger(scheme_id: usize, id: usize, flags: usize, data: usize) {
let registry = registry();
if let Some(event_lists) = registry.get(&(scheme_id, id)) {
for entry in event_lists.iter() {
if let Some(event_list_lock) = entry.1.upgrade() {
let mut event_list = event_list_lock.lock();
event_list.push_back(Event {
if let Some(event_list) = entry.1.upgrade() {
event_list.send(Event {
id: (entry.0).1,
flags: flags,
data: data

View file

@ -16,36 +16,55 @@ pub unsafe fn switch() -> bool {
arch::interrupt::pause();
}
let from_ptr = {
let contexts = contexts();
let context_lock = contexts.current().expect("context::switch: Not inside of context");
let mut context = context_lock.write();
context.deref_mut() as *mut Context
};
let from_ptr;
let mut to_ptr = 0 as *mut Context;
for (pid, context_lock) in contexts().iter() {
if *pid > (*from_ptr).id {
{
let contexts = contexts();
{
let context_lock = contexts.current().expect("context::switch: Not inside of context");
let mut context = context_lock.write();
if context.status == Status::Runnable && ! context.running {
to_ptr = context.deref_mut() as *mut Context;
break;
}
from_ptr = context.deref_mut() as *mut Context;
}
}
if to_ptr as usize == 0 {
for (pid, context_lock) in contexts().iter() {
if *pid < (*from_ptr).id {
let check_context = |context: &mut Context| -> bool {
if context.status == Status::Blocked && context.wake.is_some() {
let wake = context.wake.expect("context::switch: wake not set");
let current = arch::time::monotonic();
if current.0 > wake.0 || (current.0 == wake.0 && current.1 >= wake.1) {
context.unblock();
}
}
if context.status == Status::Runnable && ! context.running {
true
} else {
false
}
};
for (pid, context_lock) in contexts.iter() {
if *pid > (*from_ptr).id {
let mut context = context_lock.write();
if context.status == Status::Runnable && ! context.running {
if check_context(&mut context) {
to_ptr = context.deref_mut() as *mut Context;
break;
}
}
}
}
if to_ptr as usize == 0 {
for (pid, context_lock) in contexts.iter() {
if *pid < (*from_ptr).id {
let mut context = context_lock.write();
if check_context(&mut context) {
to_ptr = context.deref_mut() as *mut Context;
break;
}
}
}
}
};
if to_ptr as usize == 0 {
// Unset global lock if no context found