aboutsummaryrefslogtreecommitdiff
path: root/include/apos/tcb.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/apos/tcb.h')
-rw-r--r--include/apos/tcb.h238
1 files changed, 232 insertions, 6 deletions
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 <apos/types.h>
#include <arch/tcb.h> /* 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 */