From e30cd339e271b0d16dbecf6c521fa06c3a05e3f1 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Wed, 8 Jun 2022 22:46:55 +0300 Subject: continue documentation --- include/apos/tcb.h | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 232 insertions(+), 6 deletions(-) (limited to 'include/apos/tcb.h') diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 1a633be..4d4b3d5 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -10,65 +10,291 @@ #include #include /* arch-specific data */ -/* process(/main) threads don't have any previous threads */ +/** + * Check if thread is process thread. + * + * @param t Thread to check. + * @return \c true if thread is process thread, \c false otherwise. + */ #define is_proc(t) (t->rid == t->tid) + +/** + * Check if thread is in RPC. + * + * @param t Thread to check. + * @return \c true if thread is in RPC, \c false otherwise. + */ #define is_rpc(t) (t->rid == t->pid) +/** + * Get the process thread of current thread. + * + * @param t Thread whose effective process thread to get. + * @return The process thread of the current thread. + */ #define get_proc(t) (get_tcb(t->eid)) + +/** + * Get the root process thread of current thread. + * + * @param t Thread whose root process thread to get. + * @return The root process thread of the current thread. + */ #define get_rproc(t) (get_tcb(t->rid)) /* forward declaration */ struct tcb; +/** Convenience structure for \see tcb. */ struct tcb_ctx { + /** Virtual address space of context. */ struct vmem *vmem; + + /** Next thread in context. */ struct tcb *next; + + /** Previous thread in context. */ struct tcb *prev; }; +/** Thread control block. Main way to handle threads. */ struct tcb { + /** Arch-specific data. */ struct arch_tcbd tcbd; - /* mapping data */ + /** Memory mapping data. */ struct mem_region_root sp_r; + /** + * Effective process ID. + * + * This is the ID on which globally visible stuff should occur, such as + * memory allocations etc. + * + * When a thread is in an RPC, and a \ref SYS_IPC_FWD request occurs, the \c + * eid of the thread remains the same, whereas in a regular \c + * SYS_IPC_REQ the \c eid if replaced with the \ref pid of the + * process the thread is visiting. + */ id_t eid; + + /** + * Actual process ID. + * + * This, along with \ref eid, creates the backbone of the IPC process ID + * handling. + */ id_t pid; + /** + * Root process ID. + * + * ID of the process that spawned the thread, and the process the thread + * should belong to when not in an RPC. + */ id_t rid; + + /** Thread ID. */ id_t tid; + /* TODO: implement cpu_id to hardware cpu ID translation, first in + * riscv. */ + /** Cpu currently executing this thread. */ + id_t cpu_id; + + /** Address of callback function in servers. */ vm_t callback; + /** Address of this thread's stack base. */ vm_t thread_stack; + + /** Address of this thread's stack top. */ vm_t thread_stack_top; + + /* TODO: Check if each thread should be allowed more than just one + * region of thread local storage. */ + /** Possible thread local storage. */ vm_t thread_storage; + /** Process context of thread. */ struct tcb_ctx proc; + + /** RPC context of thread. */ struct tcb_ctx rpc; }; +/** + * Initialize thread control subsystem. + */ void init_tcbs(); + +/** + * Destroy thread control subsystem. + */ void destroy_tcbs(); +/** + * Create a new thread. + * + * If \c p is \c NULL, then a new process context is created for the thread. + * Otherwise, the thread is inserted into \c p. + * + * The thread is allocated a virtual address space, as well as a kernel stack + * and the \ref tcb structure itself with a unique thread ID. If in a new + * process context, a new process address space is created as well. + * + * Userspace stack is allocated with \ref alloc_stacks(). + * + * @todo Thread local storage? + * + * @param p Process context within to create the thread. + * @return Pointer to created \ref tcb. + */ struct tcb *create_thread(struct tcb *p); + +/** + * Create a new process. + * + * Sets up a new thread in a new process context. If there is a parent thread, + * its memory regions are copied but made COW. + * @see create_thread(). + * + * @todo COW handling. + * + * @param p Parent process. + * @return Pointer to created \ref tcb. + */ struct tcb *create_proc(struct tcb *p); + +/** + * Destroy a thread. + * + * Frees data associated with thread and frees up the thread ID. + * At least currently does not allow \c t to be a process thread. + * + * @todo Other return values? + * + * @param t Thread to destroy. + * @return \ref OK on success, \ref ERR_NOINIT if called without initializing + * subsystem and \ref ERR_INVAL if called with a process thread. + */ stat_t destroy_thread(struct tcb *t); + +/** + * Destroy a process. + * + * Frees all data associated with the process and destroys all threads within + * it. + * + * @param p Process to destroy. + * @return \ref OK on success, \ref ERR_NOINIT if called without initializing + * subsystem and \ref ERR_INVAL if called without a process thread. + */ stat_t destroy_proc(struct tcb *p); +/** + * Attach a thread to an RPC context. + * + * Essentially inserts thread \c t into the process \c r, with access to the + * same memory except for the RPC stack. + * + * @param r Process to attach to. + * @param t Thread to attach. + * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. + */ stat_t attach_rpc(struct tcb *r, struct tcb *t); + +/** + * Detach a thread from an RPC context. + * + * \see attach_rpc(). + * + * @param r Process to detach from. + * @param t Thread to detach. + * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. + * + * @todo Should probably check that thread exists in the process? + */ stat_t detach_rpc(struct tcb *r, struct tcb *t); + +/** + * Attach a thread in a process context. + * + * @param r Process to attach to. + * @param t Thread to attach. + * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. + */ stat_t attach_proc(struct tcb *r, struct tcb *t); + +/** + * Detach a thread from a process context. + * + * @param r Process to detach from. + * @param t Thread to detach. + * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. + */ stat_t detach_proc(struct tcb *r, struct tcb *t); +/** + * Get currently executing thread. + * + * @return Current \ref tcb. + */ struct tcb *cur_tcb(); + +/** + * Get currently executing process. + * + * @return Current process \ref tcb. + */ struct tcb *cur_proc(); -void use_tcb(struct tcb *); +/** + * Set \c t as current \ref tcb. + * + * @param t Thread to mark as current. + */ +void use_tcb(struct tcb *t); + +/** + * Get \ref tcb corresponding to thread with ID \c tid. + * + * @param tid Thread ID. + * @return Corresponding \ref tcb or \c NULL if not found. + */ struct tcb *get_tcb(id_t tid); -stat_t clone_proc_maps(struct tcb *); -stat_t clone_rpc_maps(struct tcb *); -stat_t alloc_stacks(struct tcb *); +/** + * Clone process context memory mappings. + * + * Essentially make sure all threads in the process have identical memory + * mappings. + * + * @param p Process whose memory mappings to clone. + * @return \ref OK on success, something else otherwise. + * @todo Check up on return codes. + */ +stat_t clone_proc_maps(struct tcb *p); + +/** + * Clone RPC context memory mappings. + * + * @see clone_proc_maps(). + * + * @param r Server whose memory mappings to clone to threads in RPC to it. + * @return \ref OK on success, something else otherwise. + * @todo Check up on return codes. + */ +stat_t clone_rpc_maps(struct tcb *r); + +/** + * Allocate stacks for thread. + * + * Both user stack and RPC stack. + * + * @param t Thread whose stacks to allocate. + * @return \ref OK on success, \ref ERR_OOMEM if out of memory. + */ +stat_t alloc_stacks(struct tcb *t); #endif /* APOS_TCB_H */ -- cgit v1.3