aboutsummaryrefslogtreecommitdiff
path: root/common/tcb.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-05-24 23:28:37 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-05-24 23:28:37 +0300
commit018624dd5b1692b88f7b2e85652ea7b898043b6d (patch)
tree0aa018640dc6bd5ebca7120df95dca4269be61d6 /common/tcb.c
parent4123ec776d3769728e1e12379887da34c12ee8f8 (diff)
downloadkmi-018624dd5b1692b88f7b2e85652ea7b898043b6d.tar.gz
kmi-018624dd5b1692b88f7b2e85652ea7b898043b6d.zip
make process loading more generic
Diffstat (limited to 'common/tcb.c')
-rw-r--r--common/tcb.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/common/tcb.c b/common/tcb.c
index 6904208..0809829 100644
--- a/common/tcb.c
+++ b/common/tcb.c
@@ -6,6 +6,7 @@
#include <apos/tcb.h>
#include <arch/cpu.h>
#include <apos/mem.h>
+#include <apos/conf.h>
#include <apos/pmem.h>
#include <apos/vmem.h>
#include <apos/nodes.h>
@@ -54,6 +55,45 @@ static id_t __alloc_tid(struct tcb *t)
return ERR_NF;
}
+/* TODO: add error checking */
+static vm_t __setup_call_stack(struct tcb *t, size_t bytes)
+{
+ pm_t offset = 0;
+ size_t pages = __pages(bytes);
+ vmflags_t flags = VM_V | VM_R | VM_W | VM_U;
+ for (size_t i = 1; i <= pages; ++i) {
+ offset = alloc_page(BASE_PAGE, offset);
+ map_vpage(t->b_r, offset, PROC_STACK_TOP - BASE_PAGE_SIZE * i,
+ flags, BASE_PAGE);
+ }
+
+ return PROC_STACK_TOP - BASE_PAGE_SIZE * pages;
+}
+
+static vm_t __setup_thread_stack(struct tcb *t, size_t bytes)
+{
+ return alloc_uvmem(t, bytes, VM_V | VM_R | VM_W | VM_U);
+}
+
+stat_t alloc_stacks(struct tcb *t)
+{
+ struct tcb *p = is_proc(t) ? t : t->proc;
+
+ t->thread_stack = __setup_thread_stack(p, __thread_stack_size);
+ if (!t->thread_stack)
+ return ERR_OOMEM;
+
+ t->call_stack = __setup_call_stack(p, __call_stack_size);
+ if (!t->call_stack)
+ return ERR_OOMEM;
+
+ /* TODO: this only allows for a global stack size, what if a user wants
+ * per thread stack sizes? */
+ t->thread_stack_top = t->thread_stack + __thread_stack_size;
+ t->call_stack_top = t->call_stack + __call_stack_size;
+ return OK;
+}
+
struct tcb *create_thread(struct tcb *p)
{
hard_assert(tcbs, 0);
@@ -70,13 +110,17 @@ struct tcb *create_thread(struct tcb *p)
tcbs[tid] = t;
t->tid = tid;
- if (p) {
+ if (likely(p)) {
t->pid = p->pid;
t->proc = p;
} else {
+ init_uvmem(t, UVMEM_START, UVMEM_END);
t->pid = t->tid;
+ p = t;
}
+ t->b_r = create_vmem();
+
return t;
}
@@ -93,13 +137,12 @@ struct tcb *create_proc(struct tcb *p)
hard_assert(tcbs, 0);
/* create a new thread outside the current process */
- struct tcb *n = create_thread(0);
- n->b_r = create_vmem();
+ struct tcb *n = create_thread(NULL);
+ if (!n)
+ return 0;
if (likely(p))
__clone_proc(p, n); /* we have a parent thread */
- else
- init_uvmem(n, UVMEM_START, UVMEM_END);
return n;
}