MOS Source Code
Loading...
Searching...
No Matches
fork.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
5#include "mos/mm/mm.h"
7#include "mos/tasks/signal.h"
8
13#include <mos/mm/cow.h>
15#include <mos/mos_global.h>
17#include <mos/syslog/printk.h>
18#include <mos/tasks/process.h>
20#include <mos/tasks/thread.h>
21#include <mos_stdlib.h>
22#include <mos_string.h>
23
24extern const char *vmap_type_str[];
25
27{
29
30 process_t *child_p = process_allocate(parent, parent->name);
31 if (unlikely(!child_p))
32 {
33 pr_emerg("failed to allocate process for fork");
34 return NULL;
35 }
36
38
39 pr_demph(process, "process %d forked to %d", parent->pid, child_p->pid);
40
41 mm_lock_ctx_pair(parent->mm, child_p->mm);
42 list_foreach(vmap_t, vmap_p, parent->mm->mmaps)
43 {
44 vmap_t *child_vmap = NULL;
45 switch (vmap_p->type)
46 {
47 case VMAP_TYPE_SHARED: child_vmap = mm_clone_vmap_locked(vmap_p, child_p->mm); break;
48 case VMAP_TYPE_PRIVATE: child_vmap = cow_clone_vmap_locked(child_p->mm, vmap_p); break;
49 default: mos_panic("unknown vmap"); break;
50 }
51 pr_dinfo2(process, "fork vmap %d->%d: %10s, %pvm -> %pvm", parent->pid, child_p->pid, vmap_type_str[vmap_p->type], (void *) vmap_p, (void *) child_vmap);
52 vmap_finalise_init(child_vmap, vmap_p->content, vmap_p->type);
53 }
54
55 mm_unlock_ctx_pair(parent->mm, child_p->mm);
56
57 // copy the parent's files
58 for (int i = 0; i < MOS_PROCESS_MAX_OPEN_FILES; i++)
59 {
60 fd_type file = parent->files[i];
61 if (io_valid(file.io))
62 {
63 child_p->files[i].io = io_ref(file.io);
64 child_p->files[i].flags = file.flags;
65 }
66 }
67
68 child_p->signal_info = parent->signal_info;
70
71 // copy the thread
72 thread_t *const parent_thread = current_thread;
73 thread_t *child_t = thread_allocate(child_p, parent_thread->mode);
74 pr_dinfo2(process, "fork: thread %d->%d", parent_thread->tid, child_t->tid);
75 child_t->u_stack = parent_thread->u_stack;
76 child_t->name = strdup(parent_thread->name);
78 stack_init(&child_t->k_stack, (void *) kstack_blk, MOS_STACK_PAGES_KERNEL * MOS_PAGE_SIZE);
79 spinlock_acquire(&parent_thread->signal_info.lock);
80 child_t->signal_info.mask = parent_thread->signal_info.mask;
81 list_foreach(sigpending_t, sig, parent_thread->signal_info.pending)
82 {
83 sigpending_t *new_sig = kmalloc(sigpending_slab);
85 new_sig->signal = sig->signal;
87 }
88 spinlock_release(&parent_thread->signal_info.lock);
89
90 platform_context_clone(parent_thread, child_t);
91
92 hashmap_put(&process_table, child_p->pid, child_p);
93 thread_complete_init(child_t);
94 scheduler_add_thread(child_t);
95 return child_p;
96}
#define MOS_ASSERT(cond)
Definition assert.h:14
#define MOS_PROCESS_MAX_OPEN_FILES
Definition autoconf.h:26
#define MOS_PAGE_SIZE
Definition autoconf.h:6
#define MOS_STACK_PAGES_KERNEL
Definition autoconf.h:28
vmap_t * cow_clone_vmap_locked(mm_context_t *target_mmctx, vmap_t *source_vmap)
Copy-on-write a page range.
Definition cow.c:62
process_t * process_do_fork(process_t *parent)
Definition fork.c:26
const char * vmap_type_str[]
Definition process.c:44
dentry_t * dentry_ref_up_to(dentry_t *dentry, dentry_t *root)
Increment the reference count of a dentry up to a given dentry.
MOSAPI void stack_init(downwards_stack_t *stack, void *mem_region_bottom, size_t size)
Definition stack.c:8
slab_t * sigpending_slab
Definition signal.c:50
MOSAPI void * hashmap_put(hashmap_t *map, uintn key, void *value)
Definition hashmap.c:68
MOSAPI char * strdup(const char *src)
MOSAPI void linked_list_init(list_node_t *head_node)
Initialise a circular double linked list.
Definition list.c:15
#define list_foreach(t, v, h)
Iterate over a list.
Definition list.h:83
#define list_node(element)
Get the ‘list_node’ of a list element. This is exactly the reverse of ‘list_entry’ above.
Definition list.h:68
MOSAPI void list_node_prepend(list_node_t *head, list_node_t *item)
Definition list.c:63
#define phyframe_va(frame)
Definition mm.h:79
void vmap_finalise_init(vmap_t *vmap, vmap_content_t content, vmap_type_t type)
Finalize the initialization of a vmap object.
Definition mm.c:257
void mm_unlock_ctx_pair(mm_context_t *ctx1, mm_context_t *ctx2)
Definition mm.c:111
phyframe_t * mm_get_free_pages(size_t npages)
Definition mm.c:55
void mm_lock_ctx_pair(mm_context_t *ctx1, mm_context_t *ctx2)
Lock and unlock a pair of mm_context_t objects.
Definition mm.c:95
@ VMAP_TYPE_PRIVATE
Definition mm.h:31
@ VMAP_TYPE_SHARED
Definition mm.h:32
vmap_t * mm_clone_vmap_locked(vmap_t *src_vmap, mm_context_t *dst_ctx)
Remap a block of virtual memory from one page table to another, i.e. copy the mappings.
Definition paging.c:132
dentry_t * root_dentry
Definition vfs.c:36
io_t * io_ref(io_t *io)
Definition io.c:73
__nodiscard bool io_valid(const io_t *io)
Definition io.c:127
#define unlikely(x)
Definition mos_global.h:40
#define mos_panic(fmt,...)
Definition panic.h:55
#define NULL
Definition pb_syshdr.h:46
#define current_thread
Definition platform.h:30
#define pr_emerg(fmt,...)
Definition printk.h:39
#define pr_demph(feat, fmt,...)
Definition printk.h:29
#define pr_dinfo2(feat, fmt,...)
Definition printk.h:27
should_inline bool process_is_valid(const process_t *process)
Definition process.h:23
hashmap_t process_table
Definition process.c:34
process_t * process_allocate(process_t *parent, const char *name)
Definition process.c:55
void platform_context_clone(const thread_t *from, thread_t *to)
void scheduler_add_thread(thread_t *thread)
Add a thread to the scheduler, so that it can be scheduled.
Definition schedule.c:78
#define spinlock_acquire(lock)
Definition spinlock.h:61
#define spinlock_release(lock)
Definition spinlock.h:62
fd_flags_t flags
Definition task_types.h:37
io_t * io
Definition task_types.h:36
A node in a linked list.
Definition list.h:27
list_head mmaps
Definition platform.h:83
waitlist_t sigchild_waitlist
the parent is waiting for a child to exit, if not empty
Definition task_types.h:31
mm_context_t * mm
Definition task_types.h:59
process_signal_info_t signal_info
signal handling info
Definition task_types.h:64
dentry_t * working_directory
Definition task_types.h:60
const char * name
Definition task_types.h:46
fd_type files[MOS_PROCESS_MAX_OPEN_FILES]
Definition task_types.h:54
pid_t pid
Definition task_types.h:45
A pending signal.
Definition signal.h:24
signal_t signal
Definition signal.h:26
list_head pending
list of pending signals
Definition task_types.h:70
sigset_t mask
pending signals mask
Definition task_types.h:71
thread_mode mode
user-mode thread or kernel-mode
Definition task_types.h:81
downwards_stack_t u_stack
user-mode stack
Definition task_types.h:84
downwards_stack_t k_stack
kernel-mode stack
Definition task_types.h:85
const char * name
Definition task_types.h:78
tid_t tid
Definition task_types.h:77
thread_signal_info_t signal_info
Definition task_types.h:91
Definition mm.h:58
vmap_content_t content
Definition mm.h:70
thread_t * thread_allocate(process_t *owner, thread_mode tflags)
Definition thread.c:31
thread_t * thread_complete_init(thread_t *thread)
Definition thread.c:156
unsigned long ptr_t
Definition types.h:25
__BEGIN_DECLS void waitlist_init(waitlist_t *list)
Definition wait.c:23