diff --git a/src/kernel/clock/time.rs b/src/kernel/clock/time.rs index d286202..993cedc 100644 --- a/src/kernel/clock/time.rs +++ b/src/kernel/clock/time.rs @@ -11,6 +11,7 @@ extern "C" { pub struct SystemTimeError(Duration); #[derive(Clone, Copy, Hash)] +#[derive(Default)] pub struct SystemTime { unix_time: usize, ns_time: usize, diff --git a/src/kernel/klog.rs b/src/kernel/klog.rs index 8c55f00..22cb64d 100644 --- a/src/kernel/klog.rs +++ b/src/kernel/klog.rs @@ -1,5 +1,4 @@ -use alloc::vec; -use alloc::vec::Vec; +use crate::libk::alloc::vec::Vec; use super::{ clock::time::SystemTime, @@ -28,12 +27,12 @@ pub struct KernelLogger { impl KernelLogger { pub fn new() -> Self { Self { - fatal_queue: vec![], - error_queue: vec![], - warning_queue: vec![], - info_queue: vec![], - debug_queue: vec![], - trace_queue: vec![], + fatal_queue: Vec::new(), + error_queue: Vec::new(), + warning_queue: Vec::new(), + info_queue: Vec::new(), + debug_queue: Vec::new(), + trace_queue: Vec::new(), } } @@ -91,105 +90,18 @@ impl KernelLogger { self.trace_queue.push((SystemTime::now(), msg)); } - pub fn iter(&self, level: LoggerLevel) -> LogIterator { - let mut logs = vec![]; - match level { - LoggerLevel::Fatal => { - logs.push(&self.fatal_queue); - } - LoggerLevel::Error => { - logs.push(&self.fatal_queue); - logs.push(&self.error_queue); - } - LoggerLevel::Warning => { - logs.push(&self.fatal_queue); - logs.push(&self.error_queue); - logs.push(&self.warning_queue); - } - LoggerLevel::Info => { - logs.push(&self.fatal_queue); - logs.push(&self.error_queue); - logs.push(&self.warning_queue); - logs.push(&self.info_queue); - } - LoggerLevel::Debug => { - logs.push(&self.fatal_queue); - logs.push(&self.error_queue); - logs.push(&self.warning_queue); - logs.push(&self.info_queue); - logs.push(&self.debug_queue); - } - LoggerLevel::Trace => { - logs.push(&self.fatal_queue); - logs.push(&self.error_queue); - logs.push(&self.warning_queue); - logs.push(&self.info_queue); - logs.push(&self.debug_queue); - logs.push(&self.trace_queue); - } - } - let mut res = vec![]; - let mut indeces = Vec::new(); - for _ in 0..logs.len() { - indeces.push(0usize); - } - let all_end = |indeces: &Vec, logs: &Vec<&Vec<(SystemTime, Message)>>| { - for i in 0..indeces.len() { - if indeces[i] < logs.len() { - return false; - } - } - true - }; - while !all_end(&indeces, &logs) { - let mut min_ind = None; - let mut min = None; - for i in 0..indeces.len() { - if indeces[i] >= logs[i].len() { - continue; - } - if let Some(minx) = min.as_mut() { - if logs[i][indeces[i]].0 < *minx { - *minx = logs[i][indeces[i]].0; - min_ind = Some(i); - } - } else { - min = Some(logs[i][indeces[i]].0); - min_ind = Some(i); - } - } - if let Some(mini) = min_ind { - res.push(&logs[mini][indeces[mini]]); - indeces[mini] += 1; - } else { - break; - } - } - LogIterator { logs: res } + pub fn iter(&self, _level: LoggerLevel) -> LogIterator { + todo!() } } -pub struct LogIterator<'a> { - logs: Vec<&'a (SystemTime, Message)>, +pub struct LogIterator { } -impl<'a> Iterator for LogIterator<'a> { +impl Iterator for LogIterator { type Item = Message; fn next(&mut self) -> Option { - let res = if let Some((time, msg)) = self.logs.first() { - Some( - MessageBuilder::new() - .message(time) - .append(MessageBuilder::from_message(msg.clone())) - .build(), - ) - } else { - None - }; - if let Some(_) = res { - self.logs.remove(0); - } - res + todo!() } } diff --git a/src/kernel/sync/mod.rs b/src/kernel/sync/mod.rs deleted file mode 100644 index 2ba968f..0000000 --- a/src/kernel/sync/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod rwlock; diff --git a/src/kernel/sync/rwlock.rs b/src/kernel/sync/rwlock.rs deleted file mode 100644 index 76d2f36..0000000 --- a/src/kernel/sync/rwlock.rs +++ /dev/null @@ -1,129 +0,0 @@ -use core::{ops::{Deref, DerefMut}, ptr::null_mut}; - -use alloc::{vec, vec::Vec}; - -/// ## RwLock -/// 读写锁 -/// -/// * 对于写入操作: -/// -/// 锁没有占用时,获取锁,并执行闭包。 -/// -/// 当锁已经被占用,将闭包悬挂。 -/// -/// 释放锁时,将所有悬挂的闭包都执行。 -/// -/// 正在释放锁时,`write`方法返回`Err(())` -/// -/// ``` -/// let num = 6; -/// let num = RwLock::new(num); -/// if let Err(()) = num.write( -/// |n| *n = 10 -/// ) {} -/// let numstr = format!("{}", num.read()); -/// ```` -pub struct RwLock<'a, T> { - obj: T, - locked: bool, - dealing_hanged: bool, - ptr: *mut RwLockWriteGuard<'a, T>, - hanging: Vec<&'a dyn Fn(&mut T)>, -} - -unsafe impl Send for RwLock<'_, T> {} -unsafe impl Sync for RwLock<'_, T> {} - -impl<'a, T> RwLock<'a, T> { - pub fn new(obj: T) -> Self { - Self { - obj, - locked: false, - dealing_hanged: false, - ptr: null_mut(), - hanging: vec![], - } - } - - pub fn read(&self) -> RwLockReadGuard { - RwLockReadGuard { obj: &self.obj } - } - - pub fn write(&'a mut self, f: &'a dyn Fn(&mut T)) -> Result, ()> { - if self.dealing_hanged { - Err(()) - } else if !self.locked { - self.locked = true; - f(&mut self.obj); - let ptr = { self as *mut RwLock<'a, T> }; - let obj = &mut self.obj; - let mut res = RwLockWriteGuard { - obj, - ptr, - must_deal_hang: false, - }; - self.ptr = &mut res as *mut RwLockWriteGuard<'_, T>; - Ok(res) - } else { - self.hanging.push(f); - let ptr = { self as *mut RwLock<'a, T> }; - let obj = &mut self.obj; - Ok(RwLockWriteGuard { - obj, - ptr, - must_deal_hang: false, - }) - } - } -} - -pub struct RwLockReadGuard<'a, T> { - obj: &'a T, -} - -impl<'a, T> Deref for RwLockReadGuard<'a, T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - self.obj - } -} - -impl<'a, T> Drop for RwLockReadGuard<'a, T> { - fn drop(&mut self) {} -} - -pub struct RwLockWriteGuard<'a, T> { - obj: &'a mut T, - ptr: *mut RwLock<'a, T>, - must_deal_hang: bool, -} - -impl<'a, T> Deref for RwLockWriteGuard<'a, T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - self.obj - } -} - -impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> { - fn deref_mut(&mut self) -> &mut Self::Target { - self.obj - } -} - -impl<'a, T> Drop for RwLockWriteGuard<'a, T> { - fn drop(&mut self) { - if self.must_deal_hang { - let p = unsafe { &mut *self.ptr }; - p.dealing_hanged = true; - for f in p.hanging.iter() { - f(self.obj); - } - p.hanging.clear(); - p.dealing_hanged = false; - p.locked = false; - } - } -} diff --git a/src/kernel/tty/tty.rs b/src/kernel/tty/tty.rs index 3fe729e..248f6bf 100644 --- a/src/kernel/tty/tty.rs +++ b/src/kernel/tty/tty.rs @@ -1,8 +1,8 @@ use core::ptr::null_mut; -use alloc::{ +use crate::libk::alloc::{ + boxed::Box, string::{String, ToString}, - vec, vec::Vec, }; @@ -141,7 +141,7 @@ impl Tty { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Default)] pub struct Color(pub u8, pub u8, pub u8); impl Color { @@ -169,7 +169,7 @@ pub struct Resolution { pub height: usize, } -#[derive(Clone)] +#[derive(Clone, Default)] pub struct MessageSection { msg: String, fgcolor: Color, @@ -179,14 +179,14 @@ pub struct MessageSection { /// ## Message /// /// 用`MessageBuilder`构造一个`Message`对象 -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Message(Vec); impl ToString for Message { fn to_string(&self) -> String { let mut res = String::new(); for MessageSection { msg, .. } in self.0.iter() { - res += msg; + res += msg.clone(); } res } @@ -212,7 +212,7 @@ impl ToString for Message { /// ```rust /// use crate::kernel::tty::tty::BuilderFunctions::*; /// -/// message!( +/// message_raw!( /// Msg("Hello, "), /// Msg("Metaverse"), /// FgColor(Color::GREEN), @@ -242,10 +242,14 @@ pub enum BuilderFunctions<'a> { impl MessageBuilder { pub fn new() -> Self { Self { - msg: Message(vec![]), + msg: Message(Vec::new()), } } + pub fn is_empty(&self) -> bool { + self.msg.0.is_empty() + } + pub fn from_message(msg: Message) -> Self { Self { msg } } @@ -302,3 +306,82 @@ impl MessageBuilder { self.msg } } + +pub enum FmtMeta { + Color(Color), + String(String), + ToStringable(Box), + Hex(u8), + Pointer(usize), +} + +pub fn format_message(fmt: &mut Vec, meta: FmtMeta) -> MessageBuilder { + let mut msgbuilder = MessageBuilder::new(); + let mut fmt_start = None; + let mut fmt_end = None; + for i in 0..fmt.len() { + if fmt[i] == '{' { + fmt_start = Some(i); + } + if fmt[i] == '}' { + fmt_end = Some(i); + break; + } + } + let tohex = |n: u8| { + if n < 10 { + (b'0' + n) as char + } else { + (b'a' + n - 10) as char + } + }; + if fmt_start == None || fmt_end == None { + msgbuilder.message_mut(&String::from_iter(fmt.iter())); + } else { + let fmt_start = fmt_start.unwrap(); + let fmt_end = fmt_end.unwrap(); + let mut formatter = Vec::new(); + for _ in fmt_start..=fmt_end { + formatter.push(fmt.remove(fmt_start)); + } + formatter.remove(formatter.len() - 1); + formatter.remove(0); + match meta { + FmtMeta::Color(color) => { + let first = fmt.split_at(fmt_start).0; + msgbuilder.message_mut(&String::from_iter(first.iter())); + for _ in 0..fmt_start { + fmt.remove(0); + } + msgbuilder.message_mut(&String::from_iter(formatter.iter())); + msgbuilder.foreground_color_mut(color); + } + FmtMeta::String(s) => { + for c in s.chars().rev() { + fmt.insert(fmt_start, *c); + } + } + FmtMeta::ToStringable(s) => { + for c in s.to_string().chars().rev() { + fmt.insert(fmt_start, *c); + } + } + FmtMeta::Hex(num) => { + fmt.insert(fmt_start, tohex(num >> 4)); + fmt.insert(fmt_start, tohex(num & 0xf)); + } + FmtMeta::Pointer(mut p) => { + for _ in 0..16 { + fmt.insert(fmt_start, tohex((p & 0xf) as u8)); + p >>= 4; + } + } + } + } + let mut rests = Vec::new(); + while !fmt.is_empty() && fmt[0] != '{' { + rests.push(fmt.remove(0)); + } + msgbuilder.message_mut(&String::from_iter(rests.iter())); + msgbuilder +} diff --git a/src/lib.rs b/src/lib.rs index e8ac072..6872093 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,69 +1,14 @@ #![no_std] +#![feature(strict_provenance)] extern crate alloc; -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; -use core::{panic::PanicInfo, ptr::null_mut}; - -use kernel::tty::tty::{self, tty_enable, tty_text_print, Color}; +use core::panic::PanicInfo; pub mod kernel; pub mod libk; #[panic_handler] -unsafe fn kernel_panic_handler(info: &PanicInfo) -> ! { - let line_in_file = if let Some(loca) = info.location() { - loca.line().to_string() - } else { - String::new() - }; - let info = { - let mut v = Vec::new(); - v.push(("Kernel Panic: ", (Color::RED, Color::BLACK))); - v.push(( - if let Some(loca) = info.location() { - loca.file() - } else { - "NoFile" - }, - (Color::GREEN, Color::BLACK), - )); - v.push((":", (Color::WHITE, Color::BLACK))); - v.push(( - if let Some(_) = info.location() { - line_in_file.as_str() - } else { - "NoLine" - }, - (Color::WHITE, Color::BLACK), - )); - v.push((": ", (Color::WHITE, Color::BLACK))); - v.push(( - if let Some(&s) = info.payload().downcast_ref::<&str>() { - s - } else { - "Unknown panic." - }, - (Color::BLUE, Color::BLACK), - )); - v.push(("\n", (Color::BLACK, Color::BLACK))); - v - }; - let tty = tty::tty_get(0); - if tty != null_mut() { - let tty = *tty; - tty_enable(tty); - for (msgo, (fgc, bgc)) in info.into_iter() { - let msg = String::from(msgo).as_bytes_mut() as *mut [u8] as *mut u8; - let p = msg.offset(msgo.len() as isize); - let swp = *p; - *p = 0; - tty_text_print(tty, msg, u32::from(fgc), u32::from(bgc)); - *p = swp; - } - } +unsafe fn kernel_panic_handler(_info: &PanicInfo) -> ! { loop {} } diff --git a/src/libk/alloc/boxed.rs b/src/libk/alloc/boxed.rs new file mode 100644 index 0000000..c8d448b --- /dev/null +++ b/src/libk/alloc/boxed.rs @@ -0,0 +1,38 @@ +use core::{ + alloc::Layout, + mem::transmute, + ops::{Deref, DerefMut}, + ptr::addr_of, +}; + +use alloc::alloc::alloc; + +pub struct Box { + inner: *mut T, +} + +impl Box { + pub fn new(t: T) -> Self { + unsafe { + let inner = alloc(Layout::for_value(&t)); + inner.copy_from(addr_of!(t).cast(), 1); + Self { + inner: transmute(inner), + } + } + } +} + +impl Deref for Box { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { self.inner.as_ref().unwrap() } + } +} + +impl DerefMut for Box { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { self.inner.as_mut().unwrap() } + } +} diff --git a/src/libk/alloc/mod.rs b/src/libk/alloc/mod.rs new file mode 100644 index 0000000..2efd480 --- /dev/null +++ b/src/libk/alloc/mod.rs @@ -0,0 +1,3 @@ +pub mod boxed; +pub mod string; +pub mod vec; diff --git a/src/libk/alloc/string.rs b/src/libk/alloc/string.rs new file mode 100644 index 0000000..d365f27 --- /dev/null +++ b/src/libk/alloc/string.rs @@ -0,0 +1,81 @@ +use core::ops::{Add, AddAssign}; + +use super::vec::{Vec, VecIterator}; + +#[derive(Clone, Default)] +pub struct String { + data: Vec, + u8data: Vec, +} + +impl String { + pub fn new() -> Self { + Self { + data: Vec::new(), + u8data: Vec::new(), + } + } + + pub fn len(&self) -> usize { + self.data.len() + } + + pub fn chars(&self) -> VecIterator { + self.data.iter() + } + + pub fn as_bytes(&self) -> &[u8] { + &self.u8data[..] + } + + pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] { + &mut self.u8data[..] + } +} + +impl FromIterator for String { + fn from_iter>(iter: T) -> Self { + let data = Vec::from_iter(iter); + let u8data = Vec::from_iter(data.iter().map(|c| *c as u8)); + Self { data, u8data } + } +} + +impl<'a> FromIterator<&'a char> for String { + fn from_iter>(iter: T) -> Self { + let data = Vec::from_iter(iter.into_iter().map(|c| *c)); + let u8data = Vec::from_iter(data.iter().map(|c| *c as u8)); + Self { data, u8data } + } +} + +impl ToString for String { + fn to_string(&self) -> String { + self.clone() + } +} + +impl Add for String { + type Output = Self; + + fn add(mut self, rhs: Self) -> Self::Output { + self.data.append(&mut rhs.chars().map(|c| *c).collect()); + self + } +} + +impl AddAssign for String { + fn add_assign(&mut self, rhs: String) { + *self = self.clone() + rhs; + } +} + +pub trait ToString { + fn to_string(&self) -> String; +} + +impl ToString for str { + fn to_string(&self) -> String { + String::from_iter(self.chars()) + } +} diff --git a/src/libk/alloc/vec.rs b/src/libk/alloc/vec.rs new file mode 100644 index 0000000..1a65451 --- /dev/null +++ b/src/libk/alloc/vec.rs @@ -0,0 +1,280 @@ +use core::{ + alloc::Layout, + ops::{Index, IndexMut, Range, RangeFull}, + ptr::{addr_of_mut, null_mut}, + slice, +}; + +use alloc::alloc::{alloc, dealloc}; + +pub struct Vec { + pointer: *mut T, + length: usize, + capacity: usize, +} + +impl Vec { + pub fn new() -> Self { + Self { + pointer: null_mut(), + length: 0, + capacity: 0, + } + } + + unsafe fn extend_capacity(&mut self) { + let newp = alloc(Layout::array::(self.capacity * 2).unwrap()).cast(); + self.pointer.copy_to(newp, self.length); + dealloc( + self.pointer.cast(), + Layout::array::(self.capacity).unwrap(), + ); + self.pointer = newp; + self.capacity *= 2; + } + + pub fn push(&mut self, item: T) { + if self.pointer.is_null() { + self.pointer = unsafe { alloc(Layout::array::(4).unwrap()).cast() }; + self.capacity = 4; + self.length = 0; + } + if self.capacity == self.length { + unsafe { self.extend_capacity() } + } + unsafe { self.pointer.offset(self.length as isize).write(item) }; + self.length += 1; + } + + pub fn insert(&mut self, index: usize, item: T) { + if self.capacity == self.length { + unsafe { self.extend_capacity() } + } + let rearlen = self.length - index; + unsafe { + if rearlen != 0 { + let tmp = alloc(Layout::array::(rearlen).unwrap()).cast(); + self.pointer.offset(index as isize).copy_to(tmp, rearlen); + self.pointer.offset(index as isize).write(item); + self.pointer + .offset(index as isize + 1) + .copy_from(tmp, rearlen); + } else { + self.pointer.offset(self.length as isize).write(item); + } + } + self.length += 1; + } + + pub fn append(&mut self, v: &mut Self) { + while self.capacity < self.length + v.length { + unsafe { self.extend_capacity() } + } + unsafe { + self.pointer + .offset(self.length as isize) + .copy_from(v.pointer.cast_const(), v.length) + }; + self.length += v.length; + } + + pub fn split_at(&self, index: usize) -> (&[T], &[T]) { + if index >= self.length { + panic!("Index out of bound."); + } + (&self[0..index], &self[index..self.length]) + } + + pub fn len(&self) -> usize { + self.length + } + + pub fn is_empty(&self) -> bool { + self.length == 0 + } + + pub fn last_mut(&mut self) -> Option<&mut T> { + unsafe { self.pointer.offset(self.length as isize - 1).as_mut() } + } + + pub fn last(&self) -> Option<&T> { + unsafe { self.pointer.offset(self.length as isize - 1).as_ref() } + } + + pub fn remove(&mut self, index: usize) -> T { + if index >= self.length { + panic!("Index out of bound."); + } + let mut t: T = T::default(); + let pt = addr_of_mut!(t); + unsafe { + pt.copy_from(self.pointer.offset(index as isize).cast_const(), 1); + self.pointer.offset(index as isize).copy_from( + self.pointer.offset(index as isize + 1), + self.length - index - 1, + ); + } + t + } + + pub fn iter(&self) -> VecIterator { + VecIterator { + pointer: self.pointer, + index: 0, + length: self.length, + _phantom: &(), + } + } +} + +impl Default for Vec { + fn default() -> Self { + Self::new() + } +} + +impl Index for Vec { + type Output = T; + + fn index(&self, index: usize) -> &Self::Output { + unsafe { self.pointer.offset(index as isize).as_ref().unwrap() } + } +} + +impl Index> for Vec { + type Output = [T]; + + fn index(&self, index: Range) -> &Self::Output { + unsafe { &slice::from_raw_parts_mut(self.pointer, self.length)[index] } + } +} + +impl Index for Vec { + type Output = [T]; + + fn index(&self, _: RangeFull) -> &Self::Output { + unsafe { slice::from_raw_parts(self.pointer.cast(), self.length) } + } +} + +impl IndexMut for Vec { + fn index_mut(&mut self, _: RangeFull) -> &mut Self::Output { + unsafe { slice::from_raw_parts_mut(self.pointer.cast(), self.length) } + } +} + +impl Clone for Vec { + fn clone(&self) -> Self { + let res = Self { + pointer: unsafe { alloc(Layout::array::(self.capacity).unwrap()).cast() }, + length: self.length, + capacity: self.capacity, + }; + unsafe { + res.pointer + .copy_from(self.pointer.cast_const(), self.length) + }; + res + } +} + +impl Drop for Vec { + fn drop(&mut self) { + unsafe { + dealloc( + self.pointer.cast(), + Layout::array::(self.capacity).unwrap(), + ) + }; + } +} + +impl FromIterator for Vec { + fn from_iter>(iter: U) -> Self { + let mut res = Vec::new(); + for i in iter { + res.push(i); + } + res + } +} + +impl IntoIterator for Vec { + type Item = T; + + type IntoIter = VecIter; + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +pub struct VecIterator<'a, T> { + pointer: *mut T, + index: usize, + length: usize, + _phantom: &'a (), +} + +impl<'a, T: 'a> Iterator for VecIterator<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + if self.index == self.length { + None + } else { + let res = unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) }; + self.index += 1; + res + } + } +} + +impl<'a, T: 'a> DoubleEndedIterator for VecIterator<'a, T> { + fn next_back(&mut self) -> Option { + if self.index == 0 { + None + } else { + self.index -= 1; + unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) } + } + } +} + +pub struct VecIter { + pointer: *mut T, + index: usize, + length: usize, + capacity: usize, +} + +impl Iterator for VecIter { + type Item = T; + + fn next(&mut self) -> Option { + if self.index == self.length { + None + } else { + let mut t = T::default(); + let res = unsafe { + self.pointer + .offset(self.index as isize) + .copy_to(addr_of_mut!(t), 1); + Some(t) + }; + self.index += 1; + res + } + } +} + +impl Drop for VecIter { + fn drop(&mut self) { + unsafe { + dealloc( + self.pointer.cast(), + Layout::array::(self.capacity).unwrap(), + ) + }; + } +} diff --git a/src/libk/string/mod.rs b/src/libk/core/mod.rs similarity index 100% rename from src/libk/string/mod.rs rename to src/libk/core/mod.rs diff --git a/src/libk/mod.rs b/src/libk/mod.rs index d245b85..9570646 100644 --- a/src/libk/mod.rs +++ b/src/libk/mod.rs @@ -1 +1,2 @@ -pub mod string; +pub mod alloc; +pub mod core;