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
NOTE: we assume all fields in Task are only modified by the task itself,
i.e. no task should modify another task’s state. (this may change though, in
which case we will need some atomics)
TODO: the mm is heap allocated object (vec of vmas). But the task struct
doesn’t have a lifetime. Must cleanup the memory used by the mm itself when
exiting a task.
not to confuse with a integer TID. A TaskID identifies a task and locate
it. In this case the TaskID wraps around the task struct’s address. The
reason why the scheduler doesn’t directly store Box<Task> (or alike) is that
the smart pointer types automatically drops the owned values when their
lifetime end. For now want to have manual control of when, where and how I
drop the Task because there could be more plans than just freeing the memory
currently don’t differentiate between running and ready states because the
scheduler push the next task to the back of the queue. i.e. the running task
is also “ready” in the run_queue