diff options
author | dzwdz | 2022-08-18 14:11:31 +0200 |
---|---|---|
committer | dzwdz | 2022-08-18 14:11:31 +0200 |
commit | 0ed2f796d7723af8321f35d4ef5e6781ea41e36d (patch) | |
tree | c4b64981d0d2bfddd597eb05e84cd1a781d253e1 /src/kernel | |
parent | 7a3f292c8316239182f30fa8f3a5e5a14cca587c (diff) |
syscall/fork: FORK_SHAREMEM for primitive "threads"
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/proc.c | 23 | ||||
-rw-r--r-- | src/kernel/proc.h | 3 |
2 files changed, 24 insertions, 2 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 2e765c7..906fc29 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -50,7 +50,17 @@ struct process *process_fork(struct process *parent, int flags) { struct process *child = kmalloc(sizeof *child); memset(child, 0, sizeof *child); - child->pages = pagedir_copy(parent->pages); + if (flags & FORK_SHAREMEM) { + if (!parent->pages_refcount) { + parent->pages_refcount = kmalloc(sizeof *parent->pages_refcount); + *parent->pages_refcount = 1; + } + *parent->pages_refcount += 1; + child->pages_refcount = parent->pages_refcount; + child->pages = parent->pages; + } else { + child->pages = pagedir_copy(parent->pages); + } child->regs = parent->regs; child->state = parent->state; assert(child->state == PS_RUNNING); // not copying the state union @@ -152,7 +162,16 @@ void process_kill(struct process *p, int ret) { p->execbuf.buf = NULL; } - pagedir_free(p->pages); + if (p->pages_refcount) { + assert(*p->pages_refcount != 0); + *p->pages_refcount -= 1; + if (*p->pages_refcount == 0) { + kfree(p->pages_refcount); + pagedir_free(p->pages); + } + } else { + pagedir_free(p->pages); + } // TODO VULN unbounded recursion struct process *c2; diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 27327c4..e7946b2 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -20,6 +20,9 @@ enum process_state { struct process { struct pagedir *pages; + /* if NULL, refcount == 1. kmalloc'd */ + uint64_t *pages_refcount; + struct registers regs; struct process *sibling, *child, *parent; |