aboutsummaryrefslogtreecommitdiff
path: root/common/tcb.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-05-22 15:05:39 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-05-22 15:05:39 +0300
commit5793a61eb824a7b97e9bab5913b595a778205cef (patch)
treef31931b924058cb6474b80cd02472940ad8cfcd5 /common/tcb.c
parenta4851206bef5ceecef18b3fde5be6918a67cca21 (diff)
downloadkmi-5793a61eb824a7b97e9bab5913b595a778205cef.tar.gz
kmi-5793a61eb824a7b97e9bab5913b595a778205cef.zip
improved tcb handling in preparation for processes
Diffstat (limited to 'common/tcb.c')
-rw-r--r--common/tcb.c98
1 files changed, 82 insertions, 16 deletions
diff --git a/common/tcb.c b/common/tcb.c
index 212e20f..32c31e1 100644
--- a/common/tcb.c
+++ b/common/tcb.c
@@ -2,6 +2,7 @@
#include <arch/cpu.h>
#include <apos/mem.h>
#include <apos/pmem.h>
+#include <apos/vmem.h>
#include <apos/nodes.h>
#include <apos/types.h>
#include <apos/assert.h>
@@ -12,7 +13,6 @@
static id_t start_tid;
static size_t num_tids;
-static struct node_root root;
static struct tcb **tcbs;
/* if we ever support systems with massive amounts of cpus, this should probably
@@ -31,8 +31,7 @@ void init_tcbs()
void destroy_tcbs()
{
- destroy_nodes(&root);
- free_page(MM_O2, (pm_t)tcbs);
+ free_page(MM_O1, (pm_t)tcbs);
}
static id_t __alloc_tid(struct tcb *t)
@@ -50,10 +49,9 @@ static id_t __alloc_tid(struct tcb *t)
return ERR_NF;
}
-struct tcb *new_thread()
+struct tcb *create_thread(struct tcb *p)
{
- if (unlikely(!tcbs))
- return 0;
+ hard_assert(tcbs, 0);
vm_t bottom = alloc_page(MM_O0, 0);
/* move tcb to top of kernel stack, keeping alignment in check
@@ -67,20 +65,80 @@ struct tcb *new_thread()
tcbs[tid] = t;
t->tid = tid;
+ if (p) {
+ t->pid = p->pid;
+ t->proc = p;
+ } else {
+ t->pid = t->tid;
+ }
+
return t;
}
-void destroy_thread(struct tcb *t)
+static stat_t __clone_proc(struct tcb *p, struct tcb *n)
+{
+ /* TODO: clone memory regions, and mark them MR_COW, as well as copy
+ * bm_branch tree but with VM_W off, also at some point write COW
+ * handler */
+ return OK;
+}
+
+struct tcb *create_proc(struct tcb *p)
{
- if (unlikely(!tcbs))
- return;
+ hard_assert(tcbs, 0);
- /* remove thread id from list */
- tcbs[t->tid] = 0;
+ /* create a new thread outside the current process */
+ struct tcb *n = create_thread(0);
+ n->b_r = create_vmem();
- /* free associated kernel stack */
+ if (likely(p))
+ __clone_proc(p, n); /* we have a parent thread */
+ else
+ init_uvmem(n, UVMEM_START, UVMEM_END);
+
+ return n;
+}
+
+static stat_t __destroy_thread_data(struct tcb *t)
+{
+ /* free vm_branch */
+ destroy_vmem(t->b_r);
+
+ /* free associated kernel stack and the structure itself */
vm_t bottom = align_down((vm_t)t, __o_size(MM_O0));
free_page(MM_O0, (pm_t)bottom);
+
+ return OK;
+}
+
+stat_t destroy_thread(struct tcb *t)
+{
+ hard_assert(tcbs, ERR_NOINIT);
+ hard_assert(!is_proc(t), ERR_INVAL);
+
+ /* remove thread id from list */
+ tcbs[t->tid] = 0;
+
+ /* remove thread from process list */
+ if (t->next)
+ t->next->prev = t->prev;
+
+ if (t->prev)
+ t->prev->next = t->next;
+
+ return __destroy_thread_data(t);
+}
+
+stat_t destroy_proc(struct tcb *p)
+{
+ hard_assert(tcbs, ERR_NOINIT);
+ hard_assert(is_proc(p), ERR_INVAL);
+
+ for (struct tcb *iter = p; (iter = iter->next);)
+ destroy_thread(iter);
+
+ catastrophic_assert(destroy_uvmem(p));
+ return __destroy_thread_data(p);
}
struct tcb *cur_tcb()
@@ -88,6 +146,15 @@ struct tcb *cur_tcb()
return cpu_tcb[cpu_id()];
}
+struct tcb *cur_proc()
+{
+ struct tcb *t = cur_tcb();
+ if (likely(is_proc(t)))
+ return t;
+ else
+ return t->proc;
+}
+
void use_tcb(struct tcb *t)
{
cpu_tcb[cpu_id()] = t;
@@ -95,18 +162,17 @@ void use_tcb(struct tcb *t)
struct tcb *get_tcb(id_t tid)
{
- if (unlikely(!tcbs))
- return 0;
+ hard_assert(tcbs, 0);
return tcbs[tid];
}
stat_t clone_tcb_maps(struct tcb *r)
{
- hard_assert(r && !r->parent, ERR_INVAL);
+ hard_assert(r && is_proc(r), ERR_INVAL);
struct tcb *t = r;
while ((t = t->next)) {
- stat_t ret = clone_vmbranch(r->b_r, t->b_r);
+ stat_t ret = clone_uvmem(r->b_r, t->b_r);
if (ret)
return ret;
}