fix(clippy): make clippy = host libs + riscv programs (shared PROGRAMS); libkos alloc spinlock (was unlocked across threads); keystore Account; gpu Rect; factory Entry; Default impls, let-chains, div_ceil, iter loops

This commit is contained in:
2026-10-28 01:17:21 +01:00
parent 91f7d28834
commit c4871320a0
20 changed files with 188 additions and 134 deletions

View File

@@ -1,6 +1,8 @@
use core::alloc::{GlobalAlloc, Layout};
use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::ptr;
use core::sync::atomic::{AtomicBool, Ordering};
const PAGE_SIZE: usize = 4096;
@@ -10,6 +12,8 @@ struct FreeBlock {
}
pub struct KosAllocator {
/// A program's threads share the heap: one at a time in the free list.
locked: AtomicBool,
inner: UnsafeCell<AllocatorInner>,
}
@@ -24,12 +28,45 @@ unsafe impl Sync for KosAllocator {}
impl KosAllocator {
pub const fn new() -> Self {
Self {
locked: AtomicBool::new(false),
inner: UnsafeCell::new(AllocatorInner { free_list: ptr::null_mut() }),
}
}
fn inner_mut(&self) -> &mut AllocatorInner {
unsafe { &mut *self.inner.get() }
fn lock(&self) -> Locked<'_> {
while self.locked.compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed).is_err() {
core::hint::spin_loop();
}
Locked(self)
}
}
impl Default for KosAllocator {
fn default() -> Self {
Self::new()
}
}
/// The free list, held until dropped.
struct Locked<'a>(&'a KosAllocator);
impl Deref for Locked<'_> {
type Target = AllocatorInner;
fn deref(&self) -> &AllocatorInner {
// Only one `Locked` exists at a time.
unsafe { &*self.0.inner.get() }
}
}
impl DerefMut for Locked<'_> {
fn deref_mut(&mut self) -> &mut AllocatorInner {
unsafe { &mut *self.0.inner.get() }
}
}
impl Drop for Locked<'_> {
fn drop(&mut self) {
self.0.locked.store(false, Ordering::Release);
}
}
@@ -103,7 +140,7 @@ impl AllocatorInner {
unsafe impl GlobalAlloc for KosAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let inner = self.inner_mut();
let mut inner = self.lock();
let size = layout.size().max(core::mem::size_of::<FreeBlock>());
let align = layout.align();
@@ -113,7 +150,7 @@ unsafe impl GlobalAlloc for KosAllocator {
}
// Alignment can cost up to `align` bytes of the block.
let pages_needed = (size + align + PAGE_SIZE - 1) / PAGE_SIZE;
let pages_needed = (size + align).div_ceil(PAGE_SIZE);
let block = inner.request_pages(pages_needed);
if block.is_null() {
return ptr::null_mut();
@@ -124,7 +161,7 @@ unsafe impl GlobalAlloc for KosAllocator {
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
let inner = self.inner_mut();
let mut inner = self.lock();
let size = layout.size().max(core::mem::size_of::<FreeBlock>());
inner.add_to_free_list(ptr, size);
}

View File

@@ -12,12 +12,17 @@ use types::time::Ticks;
pub fn exit() -> ! {
let _ = call0(SYS_EXIT);
loop {}
// The kernel does not return from an exit.
loop {
core::hint::spin_loop();
}
}
pub fn exit_thread() -> ! {
let _ = call0(SYS_EXIT_THREAD);
loop {}
loop {
core::hint::spin_loop();
}
}
pub fn yield_now() {
@@ -28,7 +33,9 @@ pub fn yield_now() {
/// call fails and this spins, since there is nothing sensible to return.
pub fn halt(control: CapSlot) -> ! {
let _ = raw(SYS_HALT, [control.value() as usize, 0, 0, 0, 0, 0]);
loop {}
loop {
yield_now();
}
}
pub fn get_time() -> Ticks {