Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Twizzler crate stubs for transactions and pointers. #226

Merged
merged 2 commits into from
Dec 30, 2024
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
24 changes: 22 additions & 2 deletions src/lib/twizzler/src/alloc/arena.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
use super::Allocator;
use crate::object::Object;
use crate::{object::Object, ptr::GlobalPtr};

pub struct ArenaAllocator {
pub struct ArenaObject {
obj: Object<ArenaBase>,
}

impl ArenaObject {
pub fn new() -> Self {
todo!()
}

pub fn allocator(&self) -> ArenaAllocator {
todo!()
}
}

pub struct ArenaAllocator {
ptr: GlobalPtr<ArenaBase>,
}

impl ArenaAllocator {
pub fn new(ptr: GlobalPtr<ArenaBase>) -> Self {
Self { ptr }
}
}

#[repr(C)]
pub struct ArenaBase {}

Expand Down
59 changes: 57 additions & 2 deletions src/lib/twizzler/src/alloc/invbox.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
use crate::{marker::Invariant, ptr::InvPtr};
use super::Allocator;
use crate::{
marker::{Invariant, Storable},
ptr::InvPtr,
tx::{Result, TxHandle},
};

pub struct InvBox<T: Invariant> {
pub struct InvBox<T: Invariant, Alloc: Allocator> {
raw: InvPtr<T>,
alloc: Alloc,
}

impl<T: Invariant, Alloc: Allocator> InvBox<T, Alloc> {
pub unsafe fn from_invptr(raw: InvPtr<T>, alloc: Alloc) -> Self {
todo!()
}

pub fn new_in(val: T, alloc: Alloc, tx: &impl TxHandle) -> Result<Storable<Self>> {
todo!()
}
}

mod tests {
use super::InvBox;
use crate::{
alloc::arena::{ArenaAllocator, ArenaBase, ArenaObject},
marker::{BaseType, Storable},
object::{ObjectBuilder, TypedObject},
tx::TxHandle,
};

struct Foo {
x: InvBox<u32, ArenaAllocator>,
}

impl Foo {
pub fn new_in(
target: &impl TxHandle,
ptr: Storable<InvBox<u32, ArenaAllocator>>,
) -> Storable<Self> {
//ptr.check_target(target);
unsafe {
Storable::new(Foo {
x: ptr.into_inner_unchecked(),
})
}
}
}

impl BaseType for Foo {}
fn box_simple() {
let builder = ObjectBuilder::<Foo>::default();
let alloc = ArenaObject::new().allocator();
let obj = builder
.build_with(|uo| Foo::new_in(&uo, InvBox::new_in(3, alloc, &uo).unwrap()))
.unwrap();
let base = obj.base();
assert_eq!(*base.x.raw.resolve(), 3);
}
}
34 changes: 34 additions & 0 deletions src/lib/twizzler/src/marker.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Marker types for invariance, store side-effects, and base types.

use std::mem::MaybeUninit;

/// Indicates that a type is _invariant_ and thus can be stored in an object.
///
/// # Safety
Expand Down Expand Up @@ -50,9 +52,41 @@ pub struct PhantomStoreEffect;
impl !StoreCopy for PhantomStoreEffect {}
impl !Unpin for PhantomStoreEffect {}

#[derive(Debug)]
pub struct Storable<T>(MaybeUninit<T>, Option<()>);

unsafe impl<T> StoreCopy for Storable<T> {}

impl<T: StoreCopy> From<T> for Storable<T> {
fn from(value: T) -> Self {
Self(MaybeUninit::new(value), None)
}
}

impl<T: StoreCopy> Storable<T> {
pub fn into_inner(self) -> T {
unsafe { self.0.assume_init() }
}
}

impl<T> Storable<T> {
pub unsafe fn new(value: T) -> Self {
Self(MaybeUninit::new(value), None)
}

pub unsafe fn into_inner_unchecked(self) -> T {
unsafe { self.0.assume_init() }
}
}

pub trait BaseType {
/// The fingerprint of this type.
fn fingerprint() -> u64 {
0
}
}

impl BaseType for u8 {}
impl BaseType for u16 {}
impl BaseType for u32 {}
impl BaseType for u64 {}
18 changes: 12 additions & 6 deletions src/lib/twizzler/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

use std::marker::PhantomData;

use fot::FotEntry;
use twizzler_abi::{
meta::MetaInfo,
object::{ObjID, MAX_SIZE, NULLPAGE_SIZE},
};
use twizzler_abi::object::{ObjID, MAX_SIZE, NULLPAGE_SIZE};
use twizzler_rt_abi::object::ObjectHandle;

use crate::{marker::BaseType, ptr::Ref};
use crate::{marker::BaseType, ptr::Ref, tx::TxObject};

mod builder;
mod fot;
mod meta;

pub use builder::*;
pub use fot::*;
pub use meta::*;

/// Operations common to structured objects.
pub trait TypedObject {
/// The base type of this object.
Expand Down Expand Up @@ -100,6 +100,12 @@ pub struct Object<Base> {
_pd: PhantomData<*const Base>,
}

impl<Base> Object<Base> {
pub fn tx(self) -> crate::tx::Result<TxObject<Base>> {
todo!()
}
}

impl<Base> RawObject for Object<Base> {
fn handle(&self) -> &ObjectHandle {
&self.handle
Expand Down
77 changes: 75 additions & 2 deletions src/lib/twizzler/src/object/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use thiserror::Error;
use twizzler_abi::syscall::{ObjectCreate, ObjectCreateError};
use twizzler_rt_abi::object::{MapError, ObjectHandle};

use super::RawObject;
use crate::marker::BaseType;
use super::{Object, RawObject};
use crate::{
marker::{BaseType, Storable, StoreCopy},
tx::TxHandle,
};

#[derive(Clone, Copy, Debug, Error)]
/// Possible errors from creating an object.
Expand All @@ -19,6 +22,7 @@ pub enum CreateError {
}

/// An object builder, for constructing objects using a builder API.
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct ObjectBuilder<Base: BaseType> {
spec: ObjectCreate,
_pd: PhantomData<Base>,
Expand All @@ -34,6 +38,22 @@ impl<Base: BaseType> ObjectBuilder<Base> {
}
}

impl<Base: BaseType + StoreCopy> ObjectBuilder<Base> {
pub fn build(&self, base: Base) -> Result<Object<Base>, CreateError> {
todo!()
}
}

impl<Base: BaseType> ObjectBuilder<Base> {
pub fn build_with<F, SB>(self, ctor: F) -> Result<Object<Base>, CreateError>
where
F: FnOnce(UninitObject<Base>) -> SB,
SB: Into<Storable<Base>>,
{
todo!()
}
}

impl<Base: BaseType> Default for ObjectBuilder<Base> {
fn default() -> Self {
Self::new(ObjectCreate::default())
Expand All @@ -51,3 +71,56 @@ impl<T> RawObject for UninitObject<T> {
&self.handle
}
}

impl<B> TxHandle for UninitObject<B> {
fn tx_mut(&self, data: *const u8, len: usize) -> crate::tx::Result<*mut u8> {
todo!()
}
}
mod tests {
use super::ObjectBuilder;
use crate::{
marker::{BaseType, Storable, StoreCopy},
object::TypedObject,
ptr::{InvPtr, Ref},
tx::TxHandle,
};

fn builder_simple() {
let builder = ObjectBuilder::default();
let obj = builder.build(42u32).unwrap();
let base = obj.base();
assert_eq!(*base, 42);
}

struct Foo {
ptr: InvPtr<u32>,
}

impl BaseType for Foo {}

impl Foo {
pub fn new_in(target: &impl TxHandle, ptr: Storable<InvPtr<u32>>) -> Storable<Self> {
unsafe {
Storable::new(Foo {
ptr: ptr.into_inner_unchecked(),
})
}
}
}

fn builder_complex() {
let builder = ObjectBuilder::default();
let obj_1 = builder.build_with(|_uo| 42u32).unwrap();
let base = obj_1.base();
assert_eq!(*base, 42);

let builder = ObjectBuilder::<Foo>::default();
let obj = builder
.build_with(|uo| Foo::new_in(&uo, InvPtr::new_in(&uo, base)))
.unwrap();
let base_foo = obj.base();
let r = base_foo.ptr.resolve();
assert_eq!(*r, 42);
}
}
16 changes: 15 additions & 1 deletion src/lib/twizzler/src/ptr/invariant.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use std::marker::PhantomData;

use crate::marker::{Invariant, PhantomStoreEffect};
use super::{GlobalPtr, Ref};
use crate::{
marker::{Invariant, PhantomStoreEffect, Storable},
tx::TxHandle,
};

#[repr(C)]
#[derive(Debug, PartialEq, PartialOrd, Ord, Eq)]
Expand All @@ -9,3 +13,13 @@ pub struct InvPtr<T: Invariant> {
_pse: PhantomStoreEffect,
_pd: PhantomData<*const T>,
}

impl<T: Invariant> InvPtr<T> {
pub fn new_in(target: &impl TxHandle, global: impl Into<GlobalPtr<T>>) -> Storable<Self> {
todo!()
}

pub fn resolve<'a>(&self) -> Ref<'a, T> {
todo!()
}
}
47 changes: 46 additions & 1 deletion src/lib/twizzler/src/ptr/resolved.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,54 @@
use std::marker::PhantomData;
use std::{
marker::PhantomData,
ops::{Deref, DerefMut},
};

use twizzler_rt_abi::object::ObjectHandle;

use super::GlobalPtr;

pub struct Ref<'obj, T> {
ptr: *const T,
handle: *const ObjectHandle,
_pd: PhantomData<&'obj T>,
}

impl<'obj, T> Deref for Ref<'obj, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref().unwrap_unchecked() }
}
}

impl<'a, T> From<Ref<'a, T>> for GlobalPtr<T> {
fn from(value: Ref<'a, T>) -> Self {
todo!()
}
}

pub struct RefMut<'obj, T> {
ptr: *mut T,
handle: *const ObjectHandle,
_pd: PhantomData<&'obj mut T>,
}

impl<'obj, T> Deref for RefMut<'obj, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref().unwrap_unchecked() }
}
}

impl<'obj, T> DerefMut for RefMut<'obj, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.as_mut().unwrap_unchecked() }
}
}

impl<'a, T> From<RefMut<'a, T>> for GlobalPtr<T> {
fn from(value: RefMut<'a, T>) -> Self {
todo!()
}
}
Loading
Loading