Skip to content

Commit

Permalink
Twizzler crate: vec implementation of simple pushing and get (#242)
Browse files Browse the repository at this point in the history
* Implementing tests for vec.

* Working on vec.

* Simple vec push and get working.

* Fix condvar bug.

* Rebase.

* Fix vec object commit.

* Update ABI.
  • Loading branch information
dbittman authored Jan 13, 2025
1 parent 1f029aa commit 01b8180
Show file tree
Hide file tree
Showing 25 changed files with 521 additions and 153 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/abi
2 changes: 1 addition & 1 deletion src/kernel/src/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ extern "C" fn soft_timeout_clock() {
drop(tq);
timeout.call();
} else {
TIMEOUT_THREAD_CONDVAR.wait(tq, true);
TIMEOUT_THREAD_CONDVAR.wait(tq);
}
}
}
Expand Down
49 changes: 24 additions & 25 deletions src/kernel/src/condvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,47 +34,46 @@ impl CondVar {
}
}

pub fn wait<'a, T>(
&self,
mut guard: SpinLockGuard<'a, T>,
istate: bool,
) -> SpinLockGuard<'a, T> {
#[track_caller]
pub fn wait<'a, T>(&self, mut guard: SpinLockGuard<'a, T>) -> SpinLockGuard<'a, T> {
let current_thread =
current_thread_ref().expect("cannot call wait before threading is enabled");
crate::interrupt::set(false);
let mut inner = self.inner.lock();
inner.queue.insert(current_thread);
drop(inner);
let current_thread = current_thread_ref().unwrap();
let critical_guard = current_thread.enter_critical();
let res = unsafe {
guard.force_unlock();
current_thread_ref()
.unwrap()
.set_state(ExecutionState::Sleeping);
crate::sched::schedule(false);
current_thread_ref()
.unwrap()
.set_state(ExecutionState::Running);
crate::syscall::sync::finish_blocking(critical_guard);
guard.force_relock()
};
let current_thread = current_thread_ref().unwrap();
let mut inner = self.inner.lock();
inner.queue.find_mut(&current_thread.objid()).remove();
drop(inner);
crate::interrupt::set(istate);
res
}

pub fn signal(&self) {
let mut inner = self.inner.lock();
let mut node = inner.queue.front_mut();
let mut threads_to_wake = Vec::new();
while let Some(t) = node.remove() {
threads_to_wake.push(t);
}
let mut threads_to_wake = Vec::with_capacity(8);
loop {
let mut inner = self.inner.lock();
if inner.queue.is_empty() {
break;
}
let mut node = inner.queue.front_mut();
while let Some(t) = node.remove() {
threads_to_wake.push(t);
if threads_to_wake.len() == 8 {
break;
}
}

drop(inner);
for t in threads_to_wake {
schedule_thread(t);
drop(inner);
for t in threads_to_wake.drain(..) {
schedule_thread(t);
}
}
}

Expand Down Expand Up @@ -128,9 +127,9 @@ mod tests {
if *inner != 0 {
break 'inner;
}
cv2.wait(inner, true);
cv2.wait(inner);
}
handle.1.wait(true);
handle.1.wait();
}
}
}
2 changes: 1 addition & 1 deletion src/kernel/src/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ extern "C" fn soft_interrupt_waker() {
handle_interrupt(ints[i]);
}
} else {
INT_THREAD_CONDVAR.wait(iq, true);
INT_THREAD_CONDVAR.wait(iq);
}
}
}
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 @@ -165,7 +165,7 @@ pub fn idle_main() -> ! {
|| test_main(),
)
.1
.wait(true);
.wait();
}
start_new_init();
}
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ mod test {
.collect();

for handle in handles {
handle.1.wait(true);
handle.1.wait();
}
let inner = lock.lock();
let val = *inner;
Expand Down
4 changes: 2 additions & 2 deletions src/kernel/src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ impl<C> Default for Outstanding<C> {

impl<C: Copy> Outstanding<C> {
pub fn wait(&self) -> C {
let mut data = self.data.lock();
loop {
let data = self.data.lock();
if let Some(c) = &*data {
return *c;
}
data = self.cv.wait(data, true);
self.cv.wait(data);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/kernel/src/random/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ pub fn getrandom(out: &mut [u8], nonblocking: bool) -> bool {
.lock();
if entropy_sources.has_sources() {
entropy_sources.contribute_entropy(acc.borrow_mut());
acc.try_fill_random_data(out)
.expect("Should be seeded now & therefore shouldn't return an error");
let _ = acc.try_fill_random_data(out).inspect_err(|_| {
logln!("warning -- should be seeded now & therefore shouldn't return an error")
});
drop((entropy_sources, acc));
return getrandom(out, nonblocking);
}
Expand Down
11 changes: 8 additions & 3 deletions src/kernel/src/spinlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl<T, Relax: RelaxStrategy> GenericSpinlock<T, Relax> {
let interrupt_state = crate::interrupt::disable();
let ticket = self.next_ticket.0.fetch_add(1, Ordering::Relaxed);
let mut iters = 0;
let caller = core::panic::Location::caller().clone();
spin_wait_until(
|| {
if self.current.0.load(Ordering::Acquire) != ticket {
Expand All @@ -69,7 +70,6 @@ impl<T, Relax: RelaxStrategy> GenericSpinlock<T, Relax> {
Relax::relax(iters);
},
);
let caller = core::panic::Location::caller().clone();
unsafe { *self.locked_from.get().as_mut().unwrap() = Some(caller) };
LockGuard {
lock: self,
Expand Down Expand Up @@ -123,11 +123,16 @@ impl<T, Relax: RelaxStrategy> LockGuard<'_, T, Relax> {
pub unsafe fn force_unlock(&mut self) {
self.dont_unlock_on_drop = true;
self.lock.release();
crate::interrupt::set(self.interrupt_state);
}

pub unsafe fn force_relock(self) -> Self {
self.lock.lock()
let mut new_guard = self.lock.lock();
new_guard.interrupt_state = self.interrupt_state;
new_guard
}

pub fn int_state(&self) -> bool {
self.interrupt_state
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/kernel/src/thread/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ pub struct KthreadClosure<F, R> {

impl<F, R> KthreadClosure<F, R> {
/// Wait for the other thread to finish and provide the result.
pub fn wait(self: Arc<Self>, istate: bool) -> R {
#[track_caller]
pub fn wait(self: Arc<Self>) -> R {
let caller = core::panic::Location::caller();
loop {
current_processor().cleanup_exited();
let guard = self.result.lock();
Expand All @@ -113,7 +115,7 @@ impl<F, R> KthreadClosure<F, R> {
// we initialize the MaybeUninit.
return unsafe { guard.1.assume_init_read() };
}
self.signal.wait(guard, istate);
self.signal.wait(guard);
}
}
}
Expand Down Expand Up @@ -187,7 +189,7 @@ mod test {
fn test_closure() {
let x = super::run_closure_in_new_thread(Priority::default_user(), || 42)
.1
.wait(true);
.wait();
assert_eq!(42, x);
}
}
2 changes: 1 addition & 1 deletion src/kernel/src/thread/suspend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,6 @@ mod test {
assert_eq!(cur, cur2);
exit_flag.store(true, Ordering::SeqCst);
test_thread.0.unsuspend_thread();
test_thread.1.wait(true);
test_thread.1.wait();
}
}
39 changes: 38 additions & 1 deletion src/lib/twizzler/src/alloc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::alloc::{AllocError, Layout};

use crate::{ptr::GlobalPtr, tx::TxHandle};
use crate::{
ptr::{GlobalPtr, RefSlice, RefSliceMut},
tx::TxHandle,
};

pub mod arena;
mod global;
Expand All @@ -24,6 +27,40 @@ pub trait Allocator {
self.dealloc(ptr, layout);
Ok(())
}

fn realloc(
&self,
ptr: GlobalPtr<u8>,
layout: Layout,
newsize: usize,
) -> Result<GlobalPtr<u8>, AllocError> {
let new_layout =
Layout::from_size_align(newsize, layout.align()).map_err(|_| AllocError)?;

let new_alloc = self.alloc(new_layout)?;
unsafe {
if !ptr.is_null() {
let new_res = new_alloc.resolve().mutable();
let mut new_slice = RefSliceMut::from_ref(new_res, new_layout.size());
let old_res = ptr.resolve();
let old_slice = RefSlice::from_ref(old_res, layout.size());
let copy_len = std::cmp::min(old_slice.len(), new_slice.len());
new_slice.as_slice_mut()[0..copy_len]
.copy_from_slice(&old_slice.as_slice()[0..copy_len]);
}
}
Ok(new_alloc)
}

fn realloc_tx(
&self,
ptr: GlobalPtr<u8>,
layout: Layout,
newsize: usize,
_tx: &impl TxHandle,
) -> Result<GlobalPtr<u8>, AllocError> {
self.realloc(ptr, layout, newsize)
}
}

pub trait SingleObjectAllocator {}
4 changes: 2 additions & 2 deletions src/lib/twizzler/src/collections/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ mod tests {
object::{ObjectBuilder, TypedObject},
};

#[test]
//#[test]
fn simple() {
let arena = ArenaObject::new().unwrap();
let alloc = arena.allocator();
Expand All @@ -59,7 +59,7 @@ mod tests {
assert_eq!(rnode0.value, 3);
}

#[test]
//#[test]
fn with_boxes() {
struct Node {
data: InvBox<u32, ArenaAllocator>,
Expand Down
Loading

0 comments on commit 01b8180

Please sign in to comment.