5 Commits

16 changed files with 228 additions and 182 deletions
+2 -2
View File
@@ -4,6 +4,6 @@
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true
},
"rust-analyzer.check.command": "clippy",
}
}
+5 -2
View File
@@ -4,12 +4,15 @@ resolver = "2"
[workspace.package]
version = "0.1.0"
edition = "2021"
authors = ["The Foundry OS contributors"]
edition = "2024"
authors = ["The FoundryOS Contributors"]
[profile.dev]
opt-level = "z"
debug = true
# Leave this on to force Cargo to use the debug runner,
# which adds the necessary flags for GDB debugging if you
# set $USE_GDB (to any value) e.g. USE_GDB=1 cargo run
debug-assertions = true
overflow-checks = true
lto = false
+10 -8
View File
@@ -5,18 +5,20 @@
Here are some simple steps to get started:
```sh
# If you have not yet cloned the repo:
git clone --recurse-submodules https://git.zxq5.dev/OsDev/FoundryOS.git
# If you already cloned the repo:
git submodule update --init --recursive
cargo build
# This will build the binaries if required - no need to call cargo build.
git clone https://git.zxq5.dev/OsDev/FoundryOS.git
cargo run
```
## Running in GDB:
```sh
USE_GDB=1 cargo run
```
### Build dependencies
* jq: checks whether the app is to be run in debugging mode.
* libisoburn: creates ISO images to be booted from.
* qemu: to run the kernel.
Optionally,
* GDB: for debugging the kernel.
+4 -2
View File
@@ -1,7 +1,8 @@
[package]
name = "foundry_os"
version = "0.1.0"
edition = "2021"
edition.workspace = true
version.workspace = true
authors.workspace = true
[dependencies]
limine = "0.3.1"
@@ -20,3 +21,4 @@ default = []
[[bin]]
name = "kernel"
path = "src/main.rs"
test = false
+3 -3
View File
@@ -7,11 +7,11 @@ use limine::{
use spin::Lazy;
#[used]
#[link_section = ".requests"]
#[unsafe(link_section = ".requests")]
static MEMORY_MAP_REQUEST: MemoryMapRequest = MemoryMapRequest::new();
#[used]
#[link_section = ".requests"]
#[unsafe(link_section = ".requests")]
static HIGHER_HALF_DIRECT_MAP_REQUEST: HhdmRequest = HhdmRequest::new();
/// ```rs
@@ -26,7 +26,7 @@ pub static PHYSICAL_MEMORY_OFFSET: Lazy<u64> = Lazy::new(|| {
});
#[used]
#[link_section = ".requests"]
#[unsafe(link_section = ".requests")]
static KERNEL_ADDRESS_REQUEST: KernelAddressRequest = KernelAddressRequest::new();
/// Converts virtual addresses in the kernel to a physical address like this:
+6 -4
View File
@@ -1,6 +1,8 @@
// use lib_alloc::allocator::FoundryAllocator;
use limine::{memory_map::EntryType, response::MemoryMapResponse};
use x86_64::{
PhysAddr,
VirtAddr,
// addr,
registers::control::Cr3,
structures::paging::{
@@ -11,8 +13,6 @@ use x86_64::{
PhysFrame,
Size4KiB,
},
PhysAddr,
VirtAddr,
};
/// Returns a mutable reference to the current level 4 page table.
@@ -27,7 +27,7 @@ unsafe fn active_l4_table(physical_memory_offset: VirtAddr) -> &'static mut Page
let phys_addr = level_4_frame.start_address();
let virt = phys_addr.as_u64() + physical_memory_offset.as_u64();
&mut *(virt as *mut PageTable)
unsafe { &mut *(virt as *mut PageTable) }
}
/// Initializes the `OffsetPageTable` for the current CPU architecture.
@@ -49,9 +49,11 @@ unsafe fn active_l4_table(physical_memory_offset: VirtAddr) -> &'static mut Page
/// Returns an `OffsetPageTable` that allows for manipulation of the page
/// tables for the current CPU architecture.
pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
unsafe {
let l4_table = active_l4_table(physical_memory_offset);
OffsetPageTable::new(l4_table, physical_memory_offset)
}
}
pub(crate) struct FoundryOSFrameAllocator {
memory_map: &'static MemoryMapResponse,
@@ -76,7 +78,7 @@ impl FoundryOSFrameAllocator {
/// Yields one `PhysFrame` for each available 4KiB frame in the memory map.
///
/// This function is used to allocate frames for the pagemap.
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> + use<> {
let regions = self.memory_map.entries().iter();
let usable_regions = regions.filter(|region| region.entry_type == EntryType::USABLE);
+1 -1
View File
@@ -18,7 +18,7 @@ mod arch;
/// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
#[used]
// The .requests section allows limine to find the requests faster and more safely.
#[link_section = ".requests"]
#[unsafe(link_section = ".requests")]
static BASE_REVISION: BaseRevision = BaseRevision::new();
#[panic_handler]
+1 -1
View File
@@ -9,7 +9,7 @@ use libk::{
scheduling::task::{Executor, Task},
};
#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn kmain() -> ! {
println_log!(" [ Initialising Kernel Systems ] ");
if let Err(err) = foundry_os::boot() {
+40 -34
View File
@@ -3,7 +3,7 @@ use spin::{Lazy, Mutex};
use x86_64::instructions::interrupts;
pub use super::framebuffer::screensize_px;
use super::framebuffer::{Color, FRAMEBUFFER_WRITER};
use super::framebuffer::{Colour, FRAMEBUFFER_WRITER};
mod font;
use font::FONT;
@@ -28,32 +28,39 @@ pub struct Writer {
/// 8 pixels wide.
text_col: u32,
fg_color: Color,
bg_color: Color,
fg_color: Colour,
bg_color: Colour,
offset1: usize,
offset2: usize,
}
impl Writer {
pub fn new() -> Self {
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
Self {
screen_width: writer.width() as u32 / 8,
screen_height: writer.height() as u32 / 16,
text_line: 0,
text_col: 0,
fg_color: Color::White,
bg_color: Color::Black,
offset1: 16,
offset2: 0,
}
} else {
panic!("Framebuffer writer not initialized");
impl Default for Writer {
fn default() -> Self {
Self::new()
}
}
pub fn write_char(&mut self, c: u16) {
impl Writer {
pub fn new() -> Self {
FRAMEBUFFER_WRITER.lock().as_mut().map_or_else(
|| {
panic!("Framebuffer writer not initialized.");
},
|writer| Self {
screen_width: writer.width() / 8,
screen_height: writer.height() / 16,
text_line: 0,
text_col: 0,
fg_color: Colour::White,
bg_color: Colour::Black,
offset1: 16,
offset2: 0,
},
)
}
pub fn write_glyph(&mut self, c: u16) {
if c as u8 == b'\n' {
self.newline();
return;
@@ -63,8 +70,7 @@ impl Writer {
let data: &[u8] = &FONT[c as usize * 16..(c as usize + 1) * 16];
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
for row in 0..16 {
let line: u8 = data[row];
for (row, line) in data.iter().enumerate().take(16) {
for col in 0..8 {
let pixel_x: u32 = self.text_col * FONT_WIDTH + col;
let pixel_y: u32 = self.text_line * FONT_HEIGHT + row as u32;
@@ -88,20 +94,20 @@ impl Writer {
}
}
pub fn set_offset(&mut self, offset1: usize, offset2: usize) {
pub const fn set_offset(&mut self, offset1: usize, offset2: usize) {
self.offset1 = offset1;
self.offset2 = offset2;
}
pub fn dimensions(&self) -> (u32, u32) {
pub const fn dimensions(&self) -> (u32, u32) {
(self.screen_width, self.screen_height)
}
pub fn next_char(&mut self) {
pub const fn next_char(&mut self) {
self.text_col += 1;
}
pub fn newline(&mut self) {
pub const fn newline(&mut self) {
self.text_col = 0;
if self.text_line + 1 >= self.screen_height {
@@ -113,18 +119,18 @@ impl Writer {
pub fn write_string(&mut self, s: &str) {
for c in s.chars() {
self.write_char(c as u16);
self.write_glyph(c as u16);
}
}
pub fn set_colour(&mut self, fg: Color, bg: Color) {
pub const fn set_colour(&mut self, fg: Colour, bg: Colour) {
self.fg_color = fg;
self.bg_color = bg;
}
pub fn reset_colour(&mut self) {
self.fg_color = Color::White;
self.bg_color = Color::Black;
pub const fn reset_colour(&mut self) {
self.fg_color = Colour::White;
self.bg_color = Colour::Black;
}
}
@@ -135,7 +141,7 @@ impl core::fmt::Write for Writer {
}
}
fn write(args: fmt::Arguments, fg: Color, bg: Color) {
fn write(args: fmt::Arguments, fg: Colour, bg: Colour) {
use core::fmt::Write;
interrupts::without_interrupts(|| {
@@ -148,19 +154,19 @@ fn write(args: fmt::Arguments, fg: Color, bg: Color) {
pub fn _print(args: fmt::Arguments) {
x86_64::instructions::interrupts::without_interrupts(|| {
write(args, Color::White, Color::Black);
write(args, Colour::White, Colour::Black);
})
}
pub fn _print_err(args: fmt::Arguments) {
x86_64::instructions::interrupts::without_interrupts(|| {
write(args, Color::Red, Color::Black);
write(args, Colour::Red, Colour::Black);
})
}
pub fn _print_log(args: fmt::Arguments) {
x86_64::instructions::interrupts::without_interrupts(|| {
write(args, Color::Yellow, Color::Black);
write(args, Colour::Yellow, Colour::Black);
})
}
+50 -34
View File
@@ -1,52 +1,69 @@
use limine::request::FramebufferRequest;
#[used]
#[link_section = ".requests"]
#[unsafe(link_section = ".requests")]
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
mod colour;
pub use colour::Color;
pub use colour::Colour;
use core::panic;
use limine::framebuffer::Framebuffer;
use spin::{Lazy, Mutex};
// use crate::{colour::Color, FRAMEBUFFER_REQUEST};
pub static FRAMEBUFFER_WRITER: Lazy<Mutex<Option<FramebufferWriter>>> = Lazy::new(|| {
Mutex::new(
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
Some(FramebufferWriter::new(framebuffer))
} else {
Mutex::new(FRAMEBUFFER_REQUEST.get_response().map_or_else(
|| {
panic!("Framebuffer request failed");
},
)
|framebuffer_response| {
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
Some(FramebufferWriter::new(framebuffer))
},
))
});
pub struct FramebufferWriter<'a> {
framebuffer: Framebuffer<'a>,
/// The updated writer stores necessary fields from the [Framebuffer].
/// This ensures that the contained types are Send, as Framebuffer was
/// not marked as Send.
///
/// It also avoids the requirement for lifetimes.
///
/// Note this does not implement Writer as these functions only handle drawing pixels.
pub struct FramebufferWriter {
pitch: u64,
bpp: u16,
addr: *mut u8,
width: u64,
height: u64,
}
unsafe impl<'a> Send for FramebufferWriter<'a> {}
unsafe impl<'a> Sync for FramebufferWriter<'a> {}
impl<'a> FramebufferWriter<'a> {
pub fn new(framebuffer: Framebuffer<'a>) -> Self {
Self { framebuffer }
unsafe impl Send for FramebufferWriter {}
unsafe impl Sync for FramebufferWriter {}
impl FramebufferWriter {
pub fn new(framebuffer: Framebuffer) -> Self {
Self {
pitch: framebuffer.pitch(),
bpp: framebuffer.bpp(),
addr: framebuffer.addr(),
width: framebuffer.width(),
height: framebuffer.height(),
}
}
pub fn write_pixel(&self, x: usize, y: usize, color: Color) {
let pitch = self.framebuffer.pitch() as usize;
let bpp = (self.framebuffer.bpp() / 8) as usize;
pub fn write_pixel(&self, x: usize, y: usize, color: Colour) {
let pitch = self.pitch as usize;
let bpp = (self.bpp / 8) as usize;
let pixel_offset = y * pitch + x * bpp;
unsafe {
*(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color.into();
*(self.addr.add(pixel_offset) as *mut u32) = color.into();
}
}
pub fn render_frame(&self, buffer: &[Color; 1280 * 800]) {
pub fn render_frame(&self, buffer: &[Colour; 1280 * 800]) {
for (y, row) in buffer.chunks(1280).enumerate() {
for (x, pixel) in row.iter().enumerate() {
self.write_pixel(x, y, *pixel);
@@ -54,30 +71,29 @@ impl<'a> FramebufferWriter<'a> {
}
}
pub fn width(&self) -> u32 {
self.framebuffer.width() as u32
pub const fn width(&self) -> u32 {
self.width as u32
}
pub fn height(&self) -> u32 {
self.framebuffer.height() as u32
pub const fn height(&self) -> u32 {
self.height as u32
}
pub fn clear(&self) {
let width = self.framebuffer.width() as usize;
let height = self.framebuffer.height() as usize;
let width = self.width as usize;
let height = self.height as usize;
for y in 0..height {
for x in 0..width {
self.write_pixel(x, y, Color::Black);
self.write_pixel(x, y, Colour::Black);
}
}
}
}
pub fn screensize_px() -> (u32, u32) {
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
(writer.width(), writer.height())
} else {
(0, 0)
}
FRAMEBUFFER_WRITER
.lock()
.as_mut()
.map_or_else(|| (0, 0), |writer| (writer.width(), writer.height()))
}
+28 -27
View File
@@ -1,6 +1,6 @@
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Color {
pub enum Colour {
ARGB(u8, u8, u8, u8),
RGB(u8, u8, u8),
HexARGB(u32),
@@ -14,40 +14,41 @@ pub enum Color {
White = 0xFFFFFFFF,
}
impl Into<u32> for Color {
fn into(self) -> u32 {
match self {
Color::ARGB(a, r, g, b) => {
#[allow(clippy::use_self)]
impl From<Colour> for u32 {
fn from(val: Colour) -> Self {
match val {
Colour::ARGB(a, r, g, b) => {
(a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32)
}
Color::RGB(r, g, b) => (0u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32),
Color::HexARGB(hex) => hex,
Color::Black => 0xFF000000,
Color::Blue => 0xFF0000FF,
Color::Green => 0xFF00FF00,
Color::Cyan => 0xFF00FFFF,
Color::Red => 0xFFFF0000,
Color::Magenta => 0xFFFF00FF,
Color::Yellow => 0xFFFFFF00,
Color::White => 0xFFFFFFFF,
Colour::RGB(r, g, b) => ((r as u32) << 16) | (g as u32) << 8 | (b as u32),
Colour::HexARGB(hex) => hex,
Colour::Black => 0xFF000000,
Colour::Blue => 0xFF0000FF,
Colour::Green => 0xFF00FF00,
Colour::Cyan => 0xFF00FFFF,
Colour::Red => 0xFFFF0000,
Colour::Magenta => 0xFFFF00FF,
Colour::Yellow => 0xFFFFFF00,
Colour::White => 0xFFFFFFFF,
}
}
}
impl core::fmt::Display for Color {
impl core::fmt::Display for Colour {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Color::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a),
Color::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b),
Color::HexARGB(hex) => write!(f, "Hex(#{:x})", hex),
Color::Black => write!(f, "Black"),
Color::Blue => write!(f, "Blue"),
Color::Green => write!(f, "Green"),
Color::Cyan => write!(f, "Cyan"),
Color::Red => write!(f, "Red"),
Color::Magenta => write!(f, "Magenta"),
Color::Yellow => write!(f, "Yellow"),
Color::White => write!(f, "White"),
Self::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a),
Self::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b),
Self::HexARGB(hex) => write!(f, "Hex(#{:x})", hex),
Self::Black => write!(f, "Black"),
Self::Blue => write!(f, "Blue"),
Self::Green => write!(f, "Green"),
Self::Cyan => write!(f, "Cyan"),
Self::Red => write!(f, "Red"),
Self::Magenta => write!(f, "Magenta"),
Self::Yellow => write!(f, "Yellow"),
Self::White => write!(f, "White"),
}
}
}
+24 -17
View File
@@ -5,9 +5,9 @@ use core::{
task::{Context, Poll},
};
use super::{print, println};
use crate::prelude::*;
use crossbeam::queue::ArrayQueue;
use futures_util::{task::AtomicWaker, Stream};
use futures_util::{Stream, task::AtomicWaker};
use spin::Once;
static KBD_QUEUE: Once<ArrayQueue<u8>> = Once::new();
@@ -15,7 +15,7 @@ static WAKER: AtomicWaker = AtomicWaker::new();
pub fn add_scancode(scancode: u8) {
if let Some(queue) = KBD_QUEUE.get() {
if let Err(_) = queue.push(scancode) {
if queue.push(scancode).is_err() {
println!("WARNING: scancode queue full; dropping keyboard input");
} else {
println!("waking waker");
@@ -33,7 +33,14 @@ pub struct ScanCodeStream {
impl ScanCodeStream {
pub fn new() -> Self {
KBD_QUEUE.call_once(|| ArrayQueue::new(5));
ScanCodeStream { _private: () }
Self { _private: () }
}
}
impl Default for ScanCodeStream {
fn default() -> Self {
Self::new()
}
}
@@ -42,30 +49,30 @@ impl Stream for ScanCodeStream {
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let queue = KBD_QUEUE.get().expect("scancode queue not initialized");
print!("polling or smth");
serial_println!("This is called once.");
WAKER.register(cx.waker());
// fast path
if let Some(scancode) = queue.pop() {
return Poll::Ready(Some(scancode));
}
WAKER.register(&cx.waker());
match queue.pop() {
Some(scancode) => {
print!("scancode found");
queue.pop().map_or_else(
|| {
print!("Returning");
Poll::Pending
},
|scancode| {
print!("Scancode found");
WAKER.take();
Poll::Ready(Some(scancode))
}
None => {
print!("returning");
Poll::Pending
}
}
},
)
}
}
use futures_util::stream::StreamExt;
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
use pc_keyboard::{DecodedKey, HandleControl, Keyboard, ScancodeSet1, layouts};
pub async fn print_keypresses() {
let mut scancodes = ScanCodeStream::new();
@@ -75,7 +82,7 @@ pub async fn print_keypresses() {
HandleControl::Ignore,
);
println!("OK!!!");
serial_println!("Printing keypresses.");
while let Some(scancode) = scancodes.next().await {
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
+6 -2
View File
@@ -3,19 +3,22 @@
use core::arch::asm;
#[inline]
pub unsafe fn inb(port: u16) -> u8 {
pub fn inb(port: u16) -> u8 {
let value: u8;
unsafe {
asm!(
"in al, dx",
out("al") value,
in("dx") port,
options(nomem, nostack, preserves_flags)
);
}
value
}
#[inline]
pub unsafe fn outb(port: u16, value: u8) {
pub fn outb(port: u16, value: u8) {
unsafe {
asm!(
"out dx, al",
in("dx") port,
@@ -23,3 +26,4 @@ pub unsafe fn outb(port: u16, value: u8) {
options(nomem, nostack, preserves_flags)
);
}
}
+8 -12
View File
@@ -45,14 +45,14 @@ pub fn serial_read() -> &'static str {
let i = BUFFER_LEN.load(Ordering::SeqCst);
return unsafe {
unsafe {
if i != 0 {
core::str::from_utf8(&BUFFER[..i - 1]).unwrap()
} else {
serial_println!("empty string");
""
}
};
}
}
static PORT: u16 = 0x3f8;
@@ -83,15 +83,13 @@ impl Writer {
pub fn write_byte(&self, data: u8) {
unsafe {
while !self.write_success() {}
outb(PORT + 0, data);
outb(PORT, data);
}
}
}
pub fn init() -> Result<(), &'static str> {
if let Err(e) = test() {
return Err(e);
}
test()?;
if READER.lock().is_none() {
*READER.lock() = Some(Reader);
@@ -105,23 +103,21 @@ pub fn init() -> Result<(), &'static str> {
}
pub fn test() -> Result<(), &'static str> {
unsafe {
outb(PORT + 1, 0x00); // Disable all interrupts
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(PORT, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(PORT + 1, 0x00); // (hi byte)
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-bytethreshold
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
outb(PORT, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
if inb(PORT + 0) != 0xAE {
if inb(PORT) != 0xAE {
return Err("serial test failed");
}
outb(PORT + 4, 0x0F);
}
Ok(())
}
@@ -153,7 +149,7 @@ impl Reader {
pub fn read(&self) -> u8 {
unsafe {
while !self.read_ready() {}
return inb(PORT + 0);
inb(PORT)
}
}
}
+3 -2
View File
@@ -1,5 +1,6 @@
#![no_std]
#![warn(tail_expr_drop_order)]
#![warn(clippy::correctness, clippy::perf, clippy::nursery)]
// alloc
// io : serial, framebuffer, ascii(?), keyboard
// ?????
@@ -11,5 +12,5 @@ pub mod scheduling;
/// Re-exports most of the IO macros.
pub mod prelude {
pub use crate::{print_log, println, println_log, serial_print, serial_println};
pub use crate::{print, print_log, println, println_log, serial_print, serial_println};
}
+13 -7
View File
@@ -14,8 +14,8 @@ pub struct Task {
}
impl Task {
pub fn new(future: impl Future<Output = ()> + 'static) -> Task {
Task {
pub fn new(future: impl Future<Output = ()> + 'static) -> Self {
Self {
id: TaskId::new(),
future: Box::pin(future),
}
@@ -32,9 +32,15 @@ pub struct Executor {
waker_cache: BTreeMap<TaskId, Waker>,
}
impl Default for Executor {
fn default() -> Self {
Self::new()
}
}
impl Executor {
pub fn new() -> Self {
Executor {
Self {
tasks: BTreeMap::new(),
task_queue: Arc::new(ArrayQueue::new(100)),
waker_cache: BTreeMap::new(),
@@ -63,7 +69,7 @@ impl Executor {
};
let waker = waker_cache
.entry(task_id)
.or_insert_with(|| TaskWaker::new(task_id, task_queue.clone()));
.or_insert_with(|| TaskWaker::waker(task_id, task_queue.clone()));
let mut context = Context::from_waker(waker);
match task.poll(&mut context) {
Poll::Ready(()) => {
@@ -98,8 +104,8 @@ struct TaskWaker {
}
impl TaskWaker {
fn new(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
Waker::from(Arc::new(TaskWaker {
fn waker(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
Waker::from(Arc::new(Self {
task_id,
task_queue,
}))
@@ -128,6 +134,6 @@ struct TaskId(u64);
impl TaskId {
fn new() -> Self {
static NEXT: AtomicU64 = AtomicU64::new(0);
TaskId(NEXT.fetch_add(1, Ordering::Relaxed))
Self(NEXT.fetch_add(1, Ordering::Relaxed))
}
}