Kernel: Allow creationg of empty processes and manual registration

You can now create kernel processes without any threads, add the
needed threads and only then register the process and its threads
to the scheduler.
This commit is contained in:
Bananymous 2023-09-27 00:29:45 +03:00
parent 1d470fb5ba
commit 09c1aa44d8
2 changed files with 15 additions and 8 deletions

View File

@ -38,11 +38,13 @@ namespace Kernel
}; };
public: public:
static Process* create_kernel();
static Process* create_kernel(entry_t, void*); static Process* create_kernel(entry_t, void*);
static BAN::ErrorOr<Process*> create_userspace(const Credentials&, BAN::StringView); static BAN::ErrorOr<Process*> create_userspace(const Credentials&, BAN::StringView);
~Process(); ~Process();
void cleanup_function(); void cleanup_function();
void register_to_scheduler();
void exit(int status, int signal); void exit(int status, int signal);
static void for_each_process(const BAN::Function<BAN::Iteration(Process&)>& callback); static void for_each_process(const BAN::Function<BAN::Iteration(Process&)>& callback);
@ -138,7 +140,6 @@ namespace Kernel
private: private:
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp); Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0); static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0);
static void register_process(Process*);
// Load an elf file to virtual address space of the current page table // Load an elf file to virtual address space of the current page table
static BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> load_elf_for_exec(const Credentials&, BAN::StringView file_path, const BAN::String& cwd); static BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> load_elf_for_exec(const Credentials&, BAN::StringView file_path, const BAN::String& cwd);

View File

@ -78,22 +78,29 @@ namespace Kernel
return process; return process;
} }
void Process::register_process(Process* process) void Process::register_to_scheduler()
{ {
s_process_lock.lock(); s_process_lock.lock();
MUST(s_processes.push_back(process)); MUST(s_processes.push_back(this));
s_process_lock.unlock(); s_process_lock.unlock();
for (auto* thread : process->m_threads) for (auto* thread : m_threads)
MUST(Scheduler::get().add_thread(thread)); MUST(Scheduler::get().add_thread(thread));
} }
Process* Process::create_kernel()
{
auto* process = create_process({ 0, 0, 0, 0 }, 0);
MUST(process->m_working_directory.push_back('/'));
return process;
}
Process* Process::create_kernel(entry_t entry, void* data) Process* Process::create_kernel(entry_t entry, void* data)
{ {
auto* process = create_process({ 0, 0, 0, 0 }, 0); auto* process = create_process({ 0, 0, 0, 0 }, 0);
MUST(process->m_working_directory.push_back('/')); MUST(process->m_working_directory.push_back('/'));
auto* thread = MUST(Thread::create_kernel(entry, data, process)); auto* thread = MUST(Thread::create_kernel(entry, data, process));
process->add_thread(thread); process->add_thread(thread);
register_process(process); process->register_to_scheduler();
return process; return process;
} }
@ -146,7 +153,7 @@ namespace Kernel
auto* thread = MUST(Thread::create_userspace(process)); auto* thread = MUST(Thread::create_userspace(process));
process->add_thread(thread); process->add_thread(thread);
register_process(process); process->register_to_scheduler();
return process; return process;
} }
@ -353,8 +360,7 @@ namespace Kernel
// FIXME: this should be able to fail // FIXME: this should be able to fail
Thread* thread = MUST(Thread::current().clone(forked, rsp, rip)); Thread* thread = MUST(Thread::current().clone(forked, rsp, rip));
forked->add_thread(thread); forked->add_thread(thread);
forked->register_to_scheduler();
register_process(forked);
return forked->pid(); return forked->pid();
} }