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 #225

Merged
merged 1 commit into from
Dec 19, 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
178 changes: 104 additions & 74 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ members = [
"src/lib/twizzler-futures",
"src/lib/dynlink",
"src/lib/secgate",
"src/lib/twizzler",
"src/rt/monitor",
"src/rt/monitor-api",
"src/rt/monitor/tests/montest",
Expand Down
16 changes: 6 additions & 10 deletions src/lib/twizzler-abi/src/syscall/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,31 @@ impl ObjectSource {
}
}

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Default)]
#[repr(C)]
/// The backing memory type for this object. Currently doesn't do anything.
pub enum BackingType {
/// The default, let the kernel decide based on the [LifetimeType] of the object.
#[default]
Normal = 0,
}

impl Default for BackingType {
fn default() -> Self {
Self::Normal
}
}

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Default)]
#[repr(C)]
/// The base lifetime type of the object. Note that this does not ensure that the object is stored
/// in a specific type of memory, the kernel is allowed to migrate objects with the Normal
/// [BackingType] as it sees fit. For more information on object lifetime, see [the book](https://twizzler-operating-system.github.io/nightly/book/object_lifetime.html).
pub enum LifetimeType {
/// This object is volatile, and is expected to be deleted after a power cycle.
#[default]
Volatile = 0,
/// This object is persistent, and should be deleted only after an explicit delete call.
Persistent = 1,
}

bitflags! {
/// Flags to pass to the object create system call.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct ObjectCreateFlags: u32 {
}
}
Expand All @@ -83,7 +79,7 @@ bitflags! {
}
}

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Default)]
#[repr(C)]
/// Full object creation specification, minus ties.
pub struct ObjectCreate {
Expand Down
10 changes: 10 additions & 0 deletions src/lib/twizzler/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "twizzler"
version = "0.99.0"
edition = "2021"

[dependencies]
bitflags = "2"
thiserror = "2"
twizzler-rt-abi = { path = "../../abi/rt-abi" }
twizzler-abi = { path = "../../lib/twizzler-abi" }
4 changes: 4 additions & 0 deletions src/lib/twizzler/src/alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod arena;
pub mod invbox;

pub trait Allocator {}
14 changes: 14 additions & 0 deletions src/lib/twizzler/src/alloc/arena.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use super::Allocator;
use crate::object::Object;

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

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

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

impl Allocator for ArenaAllocator {}
5 changes: 5 additions & 0 deletions src/lib/twizzler/src/alloc/invbox.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use crate::{marker::Invariant, ptr::InvPtr};

pub struct InvBox<T: Invariant> {
raw: InvPtr<T>,
}
1 change: 1 addition & 0 deletions src/lib/twizzler/src/collections.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod vec;
Empty file.
11 changes: 11 additions & 0 deletions src/lib/twizzler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(negative_impls)]
#![feature(auto_traits)]
#![feature(strict_provenance)]
#![feature(allocator_api)]

pub mod alloc;
pub mod collections;
pub mod marker;
pub mod object;
pub mod ptr;
pub mod tx;
58 changes: 58 additions & 0 deletions src/lib/twizzler/src/marker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Marker types for invariance, store side-effects, and base types.

/// Indicates that a type is _invariant_ and thus can be stored in an object.
///
/// # Safety
/// The implementation must ensure that the type is invariant, meaning that the type must:
/// - Be FFI safe.
/// - Be stable in-memory (independent of architecture). This means, among other things, that the
/// type must be fixed-width. For example, usize is not `Invariant`.
pub unsafe trait Invariant {}

unsafe impl Invariant for u8 {}
unsafe impl Invariant for u16 {}
unsafe impl Invariant for u32 {}
unsafe impl Invariant for u64 {}
unsafe impl Invariant for bool {}
unsafe impl Invariant for i8 {}
unsafe impl Invariant for i16 {}
unsafe impl Invariant for i32 {}
unsafe impl Invariant for i64 {}

unsafe impl Invariant for f64 {}
unsafe impl Invariant for f32 {}

unsafe impl Invariant for () {}

unsafe impl<T: Invariant, const N: usize> Invariant for [T; N] {}

unsafe impl<T: Invariant> Invariant for (T,) {}

unsafe impl<T: Invariant> Invariant for Option<T> {}
unsafe impl<R: Invariant, E: Invariant> Invariant for Result<R, E> {}

/// The type may move between objects without side effects. Notably, this is
/// not implemented for invariant pointers or types that contain them, since an invariant pointer
/// may reference an object's Foreign Object Table. This is a little restrictive (technically
/// intra-object pointers are safe to move intra-object), but it's the best we can do at
/// compile-time.
///
/// # Safety
/// The implementation must ensure that no store side effects must occur when writing this value to
/// object memory.
pub unsafe auto trait StoreCopy {}

/// A zero-sized phantom marker for indicating that the containing type has a side effect when
/// storing (e.g. it has an invariant pointer).
#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, Debug)]
pub struct PhantomStoreEffect;

impl !StoreCopy for PhantomStoreEffect {}
impl !Unpin for PhantomStoreEffect {}

pub trait BaseType {
/// The fingerprint of this type.
fn fingerprint() -> u64 {
0
}
}
115 changes: 115 additions & 0 deletions src/lib/twizzler/src/object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//! Traits and types for working with objects.

use std::marker::PhantomData;

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

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

mod builder;
mod fot;
mod meta;

/// Operations common to structured objects.
pub trait TypedObject {
/// The base type of this object.
type Base: BaseType;

/// Returns a resolved reference to the object's base.
fn base(&self) -> Ref<'_, Self::Base>;
}

/// Operations common to all objects, with raw pointers.
pub trait RawObject {
/// Get the underlying runtime handle for this object.
fn handle(&self) -> &ObjectHandle;

/// Get the object ID.
fn id(&self) -> ObjID {
self.handle().id()
}

/// Get a const pointer to the object base.
fn base_ptr<T>(&self) -> *const T {
self.lea(NULLPAGE_SIZE, size_of::<T>()).unwrap().cast()
}

/// Get a mut pointer to the object base.
fn base_mut_ptr<T>(&self) -> *mut T {
self.lea_mut(NULLPAGE_SIZE, size_of::<T>()).unwrap().cast()
}

/// Get a const pointer to the object metadata.
fn meta_ptr(&self) -> *const MetaInfo {
self.handle().meta().cast()
}

/// Get a mut pointer to the object metadata.
fn meta_mut_ptr(&self) -> *mut MetaInfo {
self.handle().meta().cast()
}

/// Get a const pointer to a given FOT entry.
fn fote_ptr(&self, idx: usize) -> Option<*const FotEntry> {
let offset: isize = (1 + idx).try_into().ok()?;
unsafe { Some((self.meta_ptr() as *const FotEntry).offset(-offset)) }
}

/// Get a mut pointer to a given FOT entry.
fn fote_ptr_mut(&self, idx: usize) -> Option<*mut FotEntry> {
let offset: isize = (1 + idx).try_into().ok()?;
unsafe { Some((self.meta_mut_ptr() as *mut FotEntry).offset(-offset)) }
}

/// Get a const pointer to given range of the object.
fn lea(&self, offset: usize, _len: usize) -> Option<*const u8> {
Some(unsafe { self.handle().start().add(offset) as *const u8 })
}

/// Get a mut pointer to given range of the object.
fn lea_mut(&self, offset: usize, _len: usize) -> Option<*mut u8> {
Some(unsafe { self.handle().start().add(offset) as *mut u8 })
}

/// If the pointer is local to this object, return the offset into the object. Otherwise, return
/// None.
fn ptr_local(&self, ptr: *const u8) -> Option<usize> {
if ptr.addr() >= self.handle().start().addr()
&& ptr.addr() < self.handle().start().addr() + MAX_SIZE
{
Some(ptr.addr() - self.handle().start().addr())
} else {
None
}
}
}

impl RawObject for ObjectHandle {
fn handle(&self) -> &ObjectHandle {
self
}
}

pub struct Object<Base> {
handle: ObjectHandle,
_pd: PhantomData<*const Base>,
}

impl<Base> RawObject for Object<Base> {
fn handle(&self) -> &ObjectHandle {
&self.handle
}
}

impl<Base: BaseType> TypedObject for Object<Base> {
type Base = Base;

fn base(&self) -> Ref<'_, Self::Base> {
todo!()
}
}
53 changes: 53 additions & 0 deletions src/lib/twizzler/src/object/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::{alloc::AllocError, marker::PhantomData, mem::MaybeUninit};

use thiserror::Error;
use twizzler_abi::syscall::{ObjectCreate, ObjectCreateError};
use twizzler_rt_abi::object::{MapError, ObjectHandle};

use super::RawObject;
use crate::marker::BaseType;

#[derive(Clone, Copy, Debug, Error)]
/// Possible errors from creating an object.
pub enum CreateError {
#[error(transparent)]
Create(#[from] ObjectCreateError),
#[error(transparent)]
Map(#[from] MapError),
#[error(transparent)]
Alloc(#[from] AllocError),
}

/// An object builder, for constructing objects using a builder API.
pub struct ObjectBuilder<Base: BaseType> {
spec: ObjectCreate,
_pd: PhantomData<Base>,
}

impl<Base: BaseType> ObjectBuilder<Base> {
/// Make a new object builder.
pub fn new(spec: ObjectCreate) -> Self {
Self {
spec,
_pd: PhantomData,
}
}
}

impl<Base: BaseType> Default for ObjectBuilder<Base> {
fn default() -> Self {
Self::new(ObjectCreate::default())
}
}

/// An uninitialized object, used during object construction.
pub struct UninitObject<T> {
handle: ObjectHandle,
_pd: PhantomData<*mut MaybeUninit<T>>,
}

impl<T> RawObject for UninitObject<T> {
fn handle(&self) -> &ObjectHandle {
&self.handle
}
}
34 changes: 34 additions & 0 deletions src/lib/twizzler/src/object/fot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::sync::atomic::AtomicU32;

use thiserror::Error;

bitflags::bitflags! {
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct FotFlags : u32 {
const RESERVED = 1;
const ACTIVE = 2;
const RESOLVER = 4;
}
}

pub type ResolverFn = extern "C" fn(ResolveRequest) -> Result<FotResolve, FotError>;

#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Error)]
pub enum FotError {
#[error("invalid FOT index")]
InvalidIndex,
#[error("invalid FOT entry")]
InvalidFotEntry,
}

pub struct ResolveRequest {}

pub struct FotResolve {}

#[repr(C)]
pub struct FotEntry {
pub values: [u64; 2],
pub resolver: u64,
pub flags: AtomicU32,
}
1 change: 1 addition & 0 deletions src/lib/twizzler/src/object/meta.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub use twizzler_abi::meta::*;
7 changes: 7 additions & 0 deletions src/lib/twizzler/src/ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod global;
mod invariant;
mod resolved;

pub use global::*;
pub use invariant::*;
pub use resolved::*;
11 changes: 11 additions & 0 deletions src/lib/twizzler/src/ptr/global.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use std::marker::PhantomData;

use twizzler_abi::object::ObjID;

#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Ord, Eq, Hash)]
/// A global pointer, containing a fully qualified object ID and offset.
pub struct GlobalPtr<T> {
id: ObjID,
offset: usize,
_pd: PhantomData<*const T>,
}
Loading
Loading