use alloc::{collections::BTreeMap, format};
use core::sync::atomic::{AtomicU64, Ordering};
use ax_api::{
modules::ax_sync::Mutex,
task::{AxTaskHandle, ax_spawn, ax_wait_for_exit, ax_yield_now},
};
use ax_posix_api::ctypes::Tid;
use log::{info, warn};
const DEFAULT_STACK_SIZE: usize = ax_api::config::TASK_STACK_SIZE;
static NEXT_TASK_NAME: AtomicU64 = AtomicU64::new(1);
static TASK_TABLE: Mutex<BTreeMap<u64, AxTaskHandle>> = Mutex::new(BTreeMap::new());
pub fn insert_task(handle: AxTaskHandle) -> u64 {
let tid = handle.id();
TASK_TABLE.lock().insert(tid, handle);
tid
}
pub fn take_task(tid: u64) -> Option<AxTaskHandle> {
TASK_TABLE.lock().remove(&tid)
}
#[unsafe(no_mangle)]
pub fn sys_spawn2(
func: extern "C" fn(usize),
arg: usize,
_prio: u8,
stack_size: usize,
_core_id: isize,
) -> Tid {
let actual_stack = if stack_size == 0 {
DEFAULT_STACK_SIZE
} else {
stack_size
};
let name = format!(
"hermit-thread-{}",
NEXT_TASK_NAME.fetch_add(1, Ordering::Relaxed)
);
let handle = ax_spawn(
move || {
func(arg);
},
name,
actual_stack,
);
info!(
"called sys_spawn2: func={:?}, arg={}, stack_size={}",
func as *const (), arg, actual_stack
);
info!("created new thread with tid {}", handle.id());
insert_task(handle) as Tid
}
#[unsafe(no_mangle)]
pub fn sys_join(tid: Tid) -> i32 {
match take_task(tid as u64) {
Some(handle) => ax_wait_for_exit(handle),
None => {
warn!("[sys_join] Unknown tid {}", tid);
-1
}
}
}
#[unsafe(no_mangle)]
pub fn sys_yield() {
ax_yield_now();
}