MOS Source Code
Loading...
Searching...
No Matches
fork.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
5#include "mos/mm/mm.hpp"
8
13#include <mos/mm/cow.hpp>
15#include <mos/mos_global.h>
17#include <mos/syslog/printk.hpp>
18#include <mos/tasks/process.hpp>
20#include <mos/tasks/thread.hpp>
21#include <mos_stdlib.hpp>
22#include <mos_string.hpp>
23
25{
27
28 auto child_p = Process::New(parent, parent->name);
29 if (unlikely(!child_p))
30 {
31 pr_emerg("failed to allocate process for fork");
32 return NULL;
33 }
34
35 child_p->working_directory = dentry_ref_up_to(parent->working_directory, root_dentry);
36
37 pr_demph(process, "process %d forked to %d", parent->pid, child_p->pid);
38
39 mm_lock_ctx_pair(parent->mm, child_p->mm);
40 list_foreach(vmap_t, vmap_p, parent->mm->mmaps)
41 {
42 PtrResult<vmap_t> child_vmap = [&]()
43 {
44 switch (vmap_p->type)
45 {
46 case VMAP_TYPE_SHARED: return mm_clone_vmap_locked(vmap_p, child_p->mm); break;
47 case VMAP_TYPE_PRIVATE: return cow_clone_vmap_locked(child_p->mm, vmap_p); break;
48 default: mos_panic("unknown vmap"); break;
49 }
50 }();
51
52 if (child_vmap.isErr())
53 {
54 mos_panic("failed to clone vmap");
55 }
56
57 pr_dinfo2(process, "fork vmap %d->%d: %10s, %pvm -> %pvm", parent->pid, child_p->pid, get_vmap_type_str(vmap_p->type), (void *) vmap_p,
58 (void *) child_vmap.get());
59 vmap_finalise_init(child_vmap.get(), vmap_p->content, vmap_p->type);
60 }
61
62 mm_unlock_ctx_pair(parent->mm, child_p->mm);
63
64 // copy the parent's files
65 for (int i = 0; i < MOS_PROCESS_MAX_OPEN_FILES; i++)
66 {
67 fd_type file = parent->files[i];
68 if (io_valid(file.io))
69 {
70 child_p->files[i].io = io_ref(file.io);
71 child_p->files[i].flags = file.flags;
72 }
73 }
74
75 child_p->signal_info = parent->signal_info;
76 waitlist_init(&child_p->signal_info.sigchild_waitlist);
77
78 // copy the thread
79 const auto parent_thread = current_thread;
80 const auto child_t = thread_allocate(child_p, parent_thread->mode);
81 pr_dinfo2(process, "fork: thread %d->%d", parent_thread->tid, child_t->tid);
82 child_t->u_stack = parent_thread->u_stack;
83 child_t->name = parent_thread->name;
85 stack_init(&child_t->k_stack, (void *) kstack_blk, MOS_STACK_PAGES_KERNEL * MOS_PAGE_SIZE);
86 spinlock_acquire(&parent_thread->signal_info.lock);
87 child_t->signal_info.mask = parent_thread->signal_info.mask;
88 list_foreach(sigpending_t, sig, parent_thread->signal_info.pending)
89 {
92 new_sig->signal = sig->signal;
93 list_node_prepend(&child_t->signal_info.pending, list_node(new_sig));
94 }
95 spinlock_release(&parent_thread->signal_info.lock);
96
97 platform_context_clone(parent_thread, child_t);
98
99 ProcessTable.insert(child_p->pid, child_p);
100 thread_complete_init(child_t);
101 scheduler_add_thread(child_t);
102 return child_p;
103}
#define MOS_ASSERT(cond)
Definition assert.hpp: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
bool isErr() const
Definition types.hpp:81
T * get() const
Definition types.hpp:76
PtrResult< vmap_t > cow_clone_vmap_locked(MMContext *target_mmctx, vmap_t *source_vmap)
Copy-on-write a page range.
Definition cow.cpp:62
Process * process_do_fork(Process *parent)
Definition fork.cpp:24
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.cpp:8
MOSAPI void linked_list_init(list_node_t *head_node)
Initialise a circular double linked list.
Definition list.cpp:15
#define list_foreach(t, v, h)
Iterate over a list.
Definition list.hpp:89
#define list_node(element)
Get the ‘list_node’ of a list element. This is exactly the reverse of ‘list_entry’ above.
Definition list.hpp:74
MOSAPI void list_node_prepend(list_node_t *head, list_node_t *item)
Definition list.cpp:63
#define phyframe_va(frame)
Definition mm.hpp:80
void mm_lock_ctx_pair(MMContext *ctx1, MMContext *ctx2)
Lock and unlock a pair of MMContext objects.
Definition mm.cpp:88
void vmap_finalise_init(vmap_t *vmap, vmap_content_t content, vmap_type_t type)
Finalize the initialization of a vmap object.
Definition mm.cpp:250
void mm_unlock_ctx_pair(MMContext *ctx1, MMContext *ctx2)
Definition mm.cpp:104
phyframe_t * mm_get_free_pages(size_t npages)
Definition mm.cpp:48
@ VMAP_TYPE_PRIVATE
Definition mm.hpp:32
@ VMAP_TYPE_SHARED
Definition mm.hpp:33
PtrResult< vmap_t > mm_clone_vmap_locked(vmap_t *src_vmap, MMContext *dst_ctx)
Remap a block of virtual memory from one page table to another, i.e. copy the mappings.
Definition paging.cpp:133
dentry_t * root_dentry
Definition vfs.cpp:35
io_t * io_ref(io_t *io)
Definition io.cpp:74
__nodiscard bool io_valid(const io_t *io)
Definition io.cpp:128
#define unlikely(x)
Definition mos_global.h:40
T * create(Args &&...args)
Definition allocator.hpp:10
#define mos_panic(fmt,...)
Definition panic.hpp:51
#define NULL
Definition pb_syshdr.h:46
#define current_thread
Definition platform.hpp:32
#define pr_emerg(fmt,...)
Definition printk.hpp:39
#define pr_demph(feat, fmt,...)
Definition printk.hpp:29
#define pr_dinfo2(feat, fmt,...)
Definition printk.hpp:27
should_inline bool process_is_valid(const Process *process)
Definition process.hpp:25
const char * get_vmap_type_str(vmap_type_t type)
Definition process.cpp:51
mos::HashMap< pid_t, Process * > ProcessTable
Definition process.cpp:36
void platform_context_clone(const Thread *from, Thread *to)
void scheduler_add_thread(Thread *thread)
Add a thread to the scheduler, so that it can be scheduled.
Definition schedule.cpp:78
#define spinlock_acquire(lock)
Definition spinlock.hpp:64
#define spinlock_release(lock)
Definition spinlock.hpp:65
list_head mmaps
Definition platform.hpp:88
mos::string name
static Process * New(Process *parent, mos::string_view name)
process_signal_info_t signal_info
signal handling info
dentry_t * working_directory
MMContext * mm
fd_type files[MOS_PROCESS_MAX_OPEN_FILES]
pid_t pid
fd_flags_t flags
io_t * io
A pending signal.
Definition signal.hpp:25
signal_t signal
Definition signal.hpp:27
Definition mm.hpp:59
Thread * thread_allocate(Process *owner, thread_mode tflags)
Definition thread.cpp:37
Thread * thread_complete_init(Thread *thread)
Definition thread.cpp:165
unsigned long ptr_t
Definition types.h:21
void waitlist_init(waitlist_t *list)
Definition wait.cpp:15