aboutsummaryrefslogtreecommitdiff
path: root/src/proc/task.rs
blob: 5cbe2f66e1dc5bc131d5c612d2c884fdf4ee4e4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use crate::arch::x86_64::arch_regs;
use crate::defs::*;
use crate::io::*;
use core::arch::asm;

/// currently only kernelSp and Context are important.
/// the task struct will be placed on the starting addr (low addr) of the kernel stack.
/// therefore we can retrive the task struct at anytime by masking the kernel stack
#[repr(C)]
#[repr(packed)]
pub struct Task {
	pub magic: u64,
	pub task_id: u32,
	pub kernel_stack: u64,
	// pub user_stack: u64,
	pub context: arch_regs::Context64,
	pub state: TaskState,
}

pub enum TaskState {
	Run,
	Block,
	Dead,
	Eating,
	Purr,
	Meow,
	Angry,
}

#[no_mangle]
pub extern "C" fn _task_entry() -> ! {
	println!("I'm Mr.Meeseeks, look at me~");
	unsafe { asm!("hlt") };
	panic!("shoud not reach");
}

extern "C" {
	fn context_swap(from_ctx: u64, to_ctx: u64);
	fn context_swap_to(to_ctx: u64);
}

impl Task {
	/// create new task. This is tricky because the task struct sits at the
	/// bottom of the kernel stack, so that you can get the current task by
	/// masking the stack pointer.
	/// 1. allocate the kernel stack with predefined size and make sure the
	///    address is properly aligned
	/// 2. cast a task struct onto the stack
	/// 3. set whatever fields necessary in the task struct, including a magic
	/// 4. create a new stack frame, and update the stack pointer in the context,
	///	   so that when first swapped to, the task will immediately "return to"
	///	   the _func_ptr
	pub fn new(_id: u32, _func_ptr: u64) -> Self {
		todo!()
	}
}