Skip to content

Commit

Permalink
Introduce user-defined task extended data
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Jun 13, 2024
1 parent 9aee385 commit 189c563
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

11 changes: 6 additions & 5 deletions modules/axhal/linker.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ SECTIONS
_sdata = .;
*(.data.boot_page_table)
. = ALIGN(4K);

__start_ax_task_ext = .;
*(ax_task_ext)
__stop_ax_task_ext = .;

*(.data .data.*)
*(.sdata .sdata.*)
*(.got .got.*)
Expand All @@ -53,13 +58,9 @@ SECTIONS
_percpu_load_start = .;
*(.percpu .percpu.*)
_percpu_load_end = .;
. = ALIGN(64);
_percpu_size_aligned = .;

. = _percpu_load_start + _percpu_size_aligned * %SMP%;
. = _percpu_load_start + ALIGN(64) * %SMP%;
}
. = _percpu_start + SIZEOF(.percpu);
_percpu_end = .;

. = ALIGN(4K);
_edata = .;
Expand Down
2 changes: 1 addition & 1 deletion modules/axhal/src/arch/x86_64/context.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::{arch::asm, fmt};
use memory_addr::VirtAddr;

#[cfg(feature = "irq")]
#[cfg(all(feature = "irq", feature = "uspace"))]
use x86_64::registers::rflags::RFlags;

#[cfg(feature = "uspace")]
Expand Down
2 changes: 2 additions & 0 deletions modules/axtask/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pub(crate) use crate::run_queue::{AxRunQueue, RUN_QUEUE};
#[doc(cfg(feature = "multitask"))]
pub use crate::task::{CurrentTask, TaskId, TaskInner};
#[doc(cfg(feature = "multitask"))]
pub use crate::task_ext::{TaskExtMut, TaskExtRef};
#[doc(cfg(feature = "multitask"))]
pub use crate::wait_queue::WaitQueue;

/// The reference type of a task.
Expand Down
2 changes: 2 additions & 0 deletions modules/axtask/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#![cfg_attr(not(test), no_std)]
#![feature(doc_cfg)]
#![feature(doc_auto_cfg)]
#![feature(linkage)]

#[cfg(test)]
mod tests;
Expand All @@ -40,6 +41,7 @@ cfg_if::cfg_if! {

mod run_queue;
mod task;
mod task_ext;
mod api;
mod wait_queue;

Expand Down
2 changes: 2 additions & 0 deletions modules/axtask/src/run_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ fn gc_entry() {
}

pub(crate) fn init() {
// Put the subsequent execution into the `main` task.
const IDLE_TASK_STACK_SIZE: usize = 4096;
let idle_task = TaskInner::new(|| crate::run_idle(), "idle".into(), IDLE_TASK_STACK_SIZE);
IDLE_TASK.with_current(|i| i.init_by(idle_task.clone()));
Expand All @@ -226,6 +227,7 @@ pub(crate) fn init() {
}

pub(crate) fn init_secondary() {
// Put the subsequent execution into the `idle` task.
let idle_task = TaskInner::new_init("idle".into());
idle_task.set_state(TaskState::Running);
IDLE_TASK.with_current(|i| i.init_by(idle_task.clone()));
Expand Down
16 changes: 16 additions & 0 deletions modules/axtask/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use axhal::tls::TlsArea;
use axhal::arch::TaskContext;
use memory_addr::{align_up_4k, VirtAddr};

use crate::task_ext::AxTaskExt;
use crate::{AxRunQueue, AxTask, AxTaskRef, WaitQueue};

/// A unique identifier for a thread.
Expand Down Expand Up @@ -52,6 +53,7 @@ pub struct TaskInner {

kstack: Option<TaskStack>,
ctx: UnsafeCell<TaskContext>,
task_ext: AxTaskExt,

#[cfg(feature = "tls")]
tls: TlsArea,
Expand Down Expand Up @@ -109,6 +111,19 @@ impl TaskInner {
.wait_until(|| self.state() == TaskState::Exited);
Some(self.exit_code.load(Ordering::Acquire))
}

/// Returns the pointer to the user-defined task extended data.
///
/// # Safety
///
/// The caller should not access the pointer directly, use [`TaskExtRef::task_ext`]
/// or [`TaskExtMut::task_ext_mut`] instead.
///
/// [`TaskExtRef::task_ext`]: crate::task_ext::TaskExtRef::task_ext
/// [`TaskExtMut::task_ext_mut`]: crate::task_ext::TaskExtMut::task_ext_mut
pub unsafe fn task_ext_ptr(&self) -> *mut u8 {
self.task_ext.as_ptr()
}
}

// private methods
Expand All @@ -132,6 +147,7 @@ impl TaskInner {
wait_for_exit: WaitQueue::new(),
kstack: None,
ctx: UnsafeCell::new(TaskContext::new()),
task_ext: AxTaskExt::alloc(),
#[cfg(feature = "tls")]
tls: TlsArea::alloc(),
}
Expand Down
108 changes: 108 additions & 0 deletions modules/axtask/src/task_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//! User-defined task extended data.
extern "C" {
fn __start_ax_task_ext();
fn __stop_ax_task_ext();
}

#[no_mangle]
#[linkage = "weak"]
#[link_section = "ax_task_ext"]
static __AX_TASK_EXT: () = ();

pub(crate) struct AxTaskExt {
ptr: *mut u8,
}

impl AxTaskExt {
fn size() -> usize {
__stop_ax_task_ext as usize - __start_ax_task_ext as usize
}

pub(crate) fn as_ptr(&self) -> *mut u8 {
self.ptr
}

pub(crate) fn alloc() -> Self {
let size = Self::size();
let ptr = if size == 0 {
core::ptr::null_mut()
} else {
let layout = core::alloc::Layout::from_size_align(size, 0x10).unwrap();
let dst = unsafe { alloc::alloc::alloc(layout) };
let src = &__AX_TASK_EXT as *const _ as *const u8;
unsafe { core::ptr::copy_nonoverlapping(src, dst, size) };
dst
};
Self { ptr }
}
}

impl Drop for AxTaskExt {
fn drop(&mut self) {
if !self.ptr.is_null() {
let layout = core::alloc::Layout::from_size_align(Self::size(), 0x10).unwrap();
unsafe { alloc::alloc::dealloc(self.ptr, layout) };
}
}
}

/// A trait to convert [`TaskInner::task_ext_ptr`] to the reference of the
/// concrete type.
///
/// [`TaskInner::task_ext_ptr`]: crate::TaskInner::task_ext_ptr
pub trait TaskExtRef<T: Sized> {
/// Get a reference to the task extended data.
fn task_ext(&self) -> &T;
}

/// A trait to convert [`TaskInner::task_ext_ptr`] to the mutable reference of
/// the concrete type.
///
/// [`TaskInner::task_ext_ptr`]: crate::TaskInner::task_ext_ptr
pub trait TaskExtMut<T: Sized> {
/// Get a mutable reference to the task extended data.
fn task_ext_mut(&mut self) -> &mut T;
}

/// Define the task extended data.
///
/// It automatically implements [`TaskExtRef`] and [`TaskExtMut`] for
/// [`TaskInner`].
///
/// # Example
///
/// ```no_run
/// use axtask::{def_task_ext, TaskExtRef};
///
/// pub struct TaskExtImpl {
/// proc_id: usize,
/// }
///
/// def_task_ext!(TaskExtImpl, TaskExtImpl { proc_id: 0 });
///
/// let task = axtask::spawn(|| {});
/// assert_eq!(task.task_ext().proc_id, 0);
/// ```
///
/// [`TaskInner`]: crate::TaskInner
#[macro_export]
macro_rules! def_task_ext {
($task_ext_struct:ty, $default:expr) => {
#[no_mangle]
#[link_section = "ax_task_ext"]
static __AX_TASK_EXT: $task_ext_struct = $default;

impl $crate::TaskExtRef<$task_ext_struct> for $crate::TaskInner {
fn task_ext(&self) -> &$task_ext_struct {
unsafe { &*(self.task_ext_ptr() as *const $task_ext_struct) }
}
}

impl $crate::TaskExtMut<$task_ext_struct> for $crate::TaskInner {
fn task_ext_mut(&mut self) -> &mut $task_ext_struct {
unsafe { &mut *(self.task_ext_ptr() as *mut $task_ext_struct) }
}
}
};
}
3 changes: 2 additions & 1 deletion variants/monolithic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ axstd = { path = "../../ulib/axstd", features = ["paging"] }
axhal = { path = "../../modules/axhal", features = ["uspace"] }
axlog = { path = "../../modules/axlog" }
axconfig = { path = "../../modules/axconfig" }
axruntime = { path = "../../modules/axruntime" }
axtask = { path = "../../modules/axtask" }
axruntime = { path = "../../modules/axruntime", features = ["multitask"] }
memory_addr = { path = "../../crates/memory_addr" }
9 changes: 9 additions & 0 deletions variants/monolithic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ extern crate axlog;
extern crate alloc;
extern crate axstd;

mod task;

use memory_addr::VirtAddr;

use axhal::arch::UspaceContext;
use axhal::mem::virt_to_phys;
use axhal::paging::MappingFlags;
use axruntime::KERNEL_PAGE_TABLE;
use axtask::TaskExtRef;

const USER_STACK_SIZE: usize = 4096;

Expand Down Expand Up @@ -73,6 +76,12 @@ fn run_apps() -> ! {
.unwrap();

let ctx = UspaceContext::new(entry_vaddr.into(), ustack_top, 2333);
let pid = axtask::current().task_ext().proc_id;
let parent = axtask::current().task_ext().parent;
warn!("pid = {}", pid);
warn!("parent = {}", parent);
assert_eq!(pid, 233);
assert_eq!(parent, 456);

info!(
"Enter user space: entry={:#x}, ustack={:#x}, kstack={:#x}",
Expand Down
15 changes: 15 additions & 0 deletions variants/monolithic/src/task.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pub struct TaskExt {
pub proc_id: usize,
pub parent: usize,
}

impl TaskExt {
pub const fn default() -> Self {
Self {
proc_id: 233,
parent: 456,
}
}
}

axtask::def_task_ext!(TaskExt, TaskExt::default());

0 comments on commit 189c563

Please sign in to comment.