Skip to content

Commit

Permalink
Simple vec push and get working.
Browse files Browse the repository at this point in the history
  • Loading branch information
dbittman committed Jan 10, 2025
1 parent 49f0578 commit 7a5e08e
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 64 deletions.
6 changes: 1 addition & 5 deletions src/bin/init/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn main() {
.unwrap();
debug!("device manager is up!");

//initialize_pager();
initialize_pager();
std::mem::forget(dev_comp);

run_tests("test_bins", false);
Expand Down Expand Up @@ -170,10 +170,6 @@ fn run_tests(test_list_name: &str, benches: bool) {
let str = String::from_utf8(bytes.to_vec()).unwrap();
let mut test_failed = false;
for line in str.split("\n").filter(|l| !l.is_empty()) {
if !line.starts_with("twizzler-") {
println!("skipping test {}", line);
continue;
}
println!("STARTING TEST {}", line);
let test_comp = monitor_api::CompartmentLoader::new(
line,
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pub fn idle_main() -> ! {
start_entropy_contribution_thread();

#[cfg(test)]
if is_test_mode() && false {
if is_test_mode() {
// Run tests on a high priority thread, so any threads spawned by tests
// don't preempt the testing thread.
crate::thread::entry::run_closure_in_new_thread(
Expand Down
76 changes: 37 additions & 39 deletions src/lib/twizzler/src/collections/vec.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use std::{
alloc::{AllocError, Layout},
mem::MaybeUninit,
ops::{Index, IndexMut},
};

use twizzler_abi::{
klog_println,
object::{MAX_SIZE, NULLPAGE_SIZE},
};
use twizzler_abi::object::{MAX_SIZE, NULLPAGE_SIZE};

use crate::{
alloc::{Allocator, SingleObjectAllocator},
Expand All @@ -27,6 +23,7 @@ impl<T: Invariant> VecInner<T> {
fn do_realloc<Alloc: Allocator>(
&mut self,
newcap: usize,
newlen: usize,
alloc: &Alloc,
tx: &TxObject<()>,
) -> crate::tx::Result<RefMut<T>> {
Expand All @@ -37,22 +34,13 @@ impl<T: Invariant> VecInner<T> {

let new_layout = Layout::array::<T>(newcap).map_err(|_| AllocError)?;
let old_layout = Layout::array::<T>(self.cap).map_err(|_| AllocError)?;
klog_println!("rea: {:?} {:?}", old_layout, new_layout);

klog_println!("resolve global");
let old_global = self.start.global().cast();
klog_println!("realloc_tx");
let new_alloc = alloc.realloc_tx(old_global, old_layout, new_layout.size(), tx)?;

klog_println!("set");
self.start = InvPtr::new(tx, new_alloc.cast())?;
klog_println!(
"invptr set to: {} {} .. {:p}",
self.start.fot_index(),
self.start.offset(),
self
);
self.cap = newcap;
self.len = newlen;

Ok(unsafe { new_alloc.cast::<T>().resolve().owned().mutable() })
}
Expand All @@ -74,10 +62,8 @@ impl Allocator for VecObjectAlloc {
if layout.size() > MAX_SIZE - NULLPAGE_SIZE * 4 {
return Err(std::alloc::AllocError);
}
klog_println!("getting object handle");
let obj = twizzler_rt_abi::object::twz_rt_get_object_handle((self as *const Self).cast())
.unwrap();
klog_println!("got it!");
Ok(GlobalPtr::new(obj.id(), (NULLPAGE_SIZE * 2) as u64))
}

Expand Down Expand Up @@ -113,7 +99,8 @@ impl<T: Invariant, Alloc: Allocator> Vec<T, Alloc> {
fn get_slice_grow(
&self,
tx: impl AsRef<TxObject>,
) -> crate::tx::Result<RefSliceMut<'_, MaybeUninit<T>>> {
) -> crate::tx::Result<RefMut<'_, MaybeUninit<T>>> {
let oldlen = self.inner.len;
if self.inner.len == self.inner.cap {
if self.inner.start.raw() as usize + size_of::<T>() * self.inner.cap
>= MAX_SIZE - NULLPAGE_SIZE
Expand All @@ -122,30 +109,31 @@ impl<T: Invariant, Alloc: Allocator> Vec<T, Alloc> {
}
let newcap = std::cmp::max(self.inner.cap, 1) * 2;
let inner = self.inner.get_mut(tx.as_ref())?;
let r = inner.do_realloc(newcap, &self.alloc, tx.as_ref())?;
Ok(Self::maybe_uninit_slice(r, newcap))
let r = inner.do_realloc(newcap, oldlen + 1, &self.alloc, tx.as_ref())?;
Ok(Self::maybe_uninit_slice(r, newcap)
.get_mut(oldlen)
.unwrap()
.owned())
} else {
self.inner.get_mut(tx.as_ref())?.len += 1;
Ok(Self::maybe_uninit_slice(
unsafe { self.inner.start.resolve().mutable() },
self.inner.cap,
))
)
.get_mut(oldlen)
.unwrap()
.owned())
}
}

fn do_push(&self, item: T, tx: impl AsRef<TxObject>) -> crate::tx::Result<()> {
klog_println!("do_push: 0");
let mut r = self.get_slice_grow(&tx)?;
klog_println!("do_push: 2");

// write item, tracking in tx
tx.as_ref().write_uninit(&mut r[self.inner.len], item)?;
klog_println!("do_push: 3");
self.inner.get_mut(tx.as_ref())?.len += 1;
klog_println!("do_push: x");
tx.as_ref().write_uninit(&mut *r, item)?;
Ok(())
}

fn len(&self) -> usize {
pub fn len(&self) -> usize {
self.inner.len
}
}
Expand All @@ -169,9 +157,8 @@ impl<T: Invariant, Alloc: Allocator + SingleObjectAllocator> Vec<T, Alloc> {
where
F: FnOnce(TxRef<MaybeUninit<T>>) -> crate::tx::Result<TxRef<T>>,
{
let mut slice = self.get_slice_grow(&tx)?;
let ptr = &mut slice.as_slice_mut()[self.inner.len];
let txref = unsafe { TxRef::new(tx, ptr) };
let mut r = self.get_slice_grow(&tx)?;
let txref = unsafe { TxRef::new(tx, &mut *r) };
let val = ctor(txref)?;
val.into_tx().commit()?;
Ok(())
Expand Down Expand Up @@ -213,26 +200,24 @@ mod tests {

#[test]
fn simple_push() {
twizzler_abi::klog_println!("A");
let vobj = ObjectBuilder::default()
.build_inplace(|tx| tx.write(Vec::new_in(VecObjectAlloc)))
.unwrap();

twizzler_abi::klog_println!("B");
let tx = vobj.tx().unwrap();
twizzler_abi::klog_println!("B1");
tx.base().push(Simple { x: 42 }, &tx).unwrap();
twizzler_abi::klog_println!("B2");
tx.base().push(Simple { x: 43 }, &tx).unwrap();
let vobj = tx.commit().unwrap();

twizzler_abi::klog_println!("C: {}", vobj.base().len());
let base = vobj.base();
assert_eq!(base.len(), 2);
let item = base.get(0).unwrap();
assert_eq!(item.x, 42);
twizzler_abi::klog_println!("Z");
let item2 = base.get(1).unwrap();
assert_eq!(item2.x, 43);
}

//#[test]
#[test]
fn simple_push_vo() {
let mut vec_obj = VecObject::new(ObjectBuilder::default()).unwrap();
vec_obj.push(Simple { x: 42 }).unwrap();
Expand All @@ -241,6 +226,19 @@ mod tests {
assert_eq!(item.x, 42);
}

#[test]
fn many_push_vo() {
let mut vec_obj = VecObject::new(ObjectBuilder::default()).unwrap();
for i in 0..100 {
vec_obj.push(Simple { x: i * i }).unwrap();
}

for i in 0..100 {
let item = vec_obj.get(i as usize).unwrap();
assert_eq!(item.x, i * i);
}
}

//#[test]
fn node_push() {
let simple_obj = ObjectBuilder::default().build(Simple { x: 3 }).unwrap();
Expand Down
20 changes: 20 additions & 0 deletions src/lib/twizzler/src/ptr/resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ impl<'a, T> Drop for Ref<'a, T> {
pub struct RefMut<'obj, T> {
ptr: *mut T,
handle: *const ObjectHandle,
owned: bool,
_pd: PhantomData<&'obj mut T>,
}

Expand All @@ -112,6 +113,7 @@ impl<'obj, T> RefMut<'obj, T> {
Self {
ptr,
handle,
owned: false,
_pd: PhantomData,
}
}
Expand All @@ -120,6 +122,7 @@ impl<'obj, T> RefMut<'obj, T> {
RefMut {
ptr: self.ptr.cast(),
handle: self.handle,
owned: self.owned,
_pd: PhantomData,
}
}
Expand All @@ -135,6 +138,15 @@ impl<'obj, T> RefMut<'obj, T> {
pub fn global(&self) -> GlobalPtr<T> {
GlobalPtr::new(self.handle().id(), self.offset())
}

pub fn owned<'b>(&self) -> RefMut<'b, T> {
RefMut {
ptr: self.ptr,
owned: true,
handle: Box::into_raw(Box::new(self.handle().clone())),
_pd: PhantomData,
}
}
}

impl<'obj, T> Deref for RefMut<'obj, T> {
Expand All @@ -157,6 +169,14 @@ impl<'a, T> From<RefMut<'a, T>> for GlobalPtr<T> {
}
}

impl<'a, T> Drop for RefMut<'a, T> {
fn drop(&mut self) {
if self.owned {
let _boxed = unsafe { Box::from_raw(self.handle as *mut ObjectHandle) };
}
}
}

pub struct RefSlice<'a, T> {
ptr: Ref<'a, T>,
len: usize,
Expand Down
31 changes: 18 additions & 13 deletions src/lib/twizzler/src/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ mod object;
mod reference;
mod unsafetx;

use std::{alloc::AllocError, mem::MaybeUninit};
use std::{alloc::AllocError, cell::UnsafeCell, mem::MaybeUninit};

pub use batch::*;
pub use object::*;
pub use reference::*;
use twizzler_abi::klog_println;
use twizzler_rt_abi::object::MapError;
pub use unsafetx::*;

use crate::{
Expand All @@ -23,7 +24,6 @@ pub trait TxHandle {
fn tx_mut(&self, data: *const u8, len: usize) -> Result<*mut u8>;

fn write_uninit<T>(&self, target: &mut MaybeUninit<T>, value: T) -> Result<&mut T> {
klog_println!("==> write uninit {:p}", target);
let ptr = self
.tx_mut((target as *mut MaybeUninit<T>).cast(), size_of::<T>())?
.cast::<MaybeUninit<T>>();
Expand Down Expand Up @@ -60,28 +60,33 @@ pub enum TxError {
/// Create error
#[error("create error")]
CreateError(#[from] CreateError),
/// Map error
#[error("mapping error")]
MapError(#[from] MapError),
}

#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
#[repr(transparent)]
pub struct TxCell<T>(T);
pub struct TxCell<T>(UnsafeCell<T>);

impl<T: Clone> Clone for TxCell<T> {
fn clone(&self) -> Self {
Self(UnsafeCell::new(unsafe {
self.0.get().as_ref().unwrap().clone()
}))
}
}

impl<T> TxCell<T> {
pub fn new(inner: T) -> Self {
Self(inner)
Self(UnsafeCell::new(inner))
}

pub unsafe fn as_mut(&self) -> &mut T {
unsafe {
((&self.0 as *const T) as *mut T)
.cast::<T>()
.as_mut()
.unwrap_unchecked()
}
unsafe { self.0.get().as_mut().unwrap_unchecked() }
}

pub fn get_mut(&self, tx: &impl TxHandle) -> Result<&mut T> {
let inner = &self.0 as *const T;
let inner = self.0.get();
let ptr = tx.tx_mut(inner.cast(), size_of::<T>())?;
unsafe { Ok(ptr.cast::<T>().as_mut().unwrap_unchecked()) }
}
Expand All @@ -91,7 +96,7 @@ impl<T> std::ops::Deref for TxCell<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.0
unsafe { self.0.get().as_ref().unwrap() }
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/lib/twizzler/src/tx/object.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{marker::PhantomData, mem::MaybeUninit};

use twizzler_rt_abi::object::ObjectHandle;
use twizzler_rt_abi::object::{MapFlags, ObjectHandle};

use super::{Result, TxHandle};
use crate::{
Expand All @@ -26,9 +26,11 @@ impl<T> TxObject<T> {
}

pub fn commit(self) -> Result<Object<T>> {
let this = std::hint::black_box(self);
let handle = self.handle;
let new_obj =
unsafe { Object::map_unchecked(handle.id(), MapFlags::READ | MapFlags::WRITE) }?;
// TODO: commit tx
Ok(unsafe { Object::from_handle_unchecked(this.handle) })
Ok(new_obj)
}

pub fn abort(self) -> Object<T> {
Expand Down Expand Up @@ -113,6 +115,7 @@ mod tests {
let mut tx = obj.tx().unwrap();
let mut base = tx.base_mut();
base.x = 42;
drop(base);
let obj = tx.commit().unwrap();
assert_eq!(obj.base().x, 42);
}
Expand Down
2 changes: 0 additions & 2 deletions src/rt/reference/src/runtime/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,7 @@ impl ObjectHandleManager {

/// Get an object handle from a pointer to within that object.
pub fn get_handle(&mut self, ptr: *const u8) -> Option<object_handle> {
tracing::info!("in get_handle");
let handle = self.cache.activate_from_ptr(ptr)?;
tracing::info!("in get_handle: done: {:p}", handle.runtime_info);
let oh = ObjectHandle::from_raw(handle);
let oh2 = oh.clone().into_raw();
std::mem::forget(oh);
Expand Down
2 changes: 1 addition & 1 deletion src/rt/reference/src/runtime/object/handlecache.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::BTreeMap;

use tracing::info as trace;
use tracing::trace;
use twizzler_abi::object::MAX_SIZE;
use twizzler_rt_abi::bindings::object_handle;

Expand Down

0 comments on commit 7a5e08e

Please sign in to comment.