Kernel: Process is not reference counted any more

This was not necessary and it made things needlessly complicated
This commit is contained in:
Bananymous 2023-04-19 00:34:18 +03:00
parent c5b006bf19
commit 7bd4593748
11 changed files with 91 additions and 69 deletions

View File

@ -15,15 +15,15 @@ namespace LibELF
{
BAN::Vector<uint8_t> data;
int fd = TRY(Kernel::Process::current()->open(file_path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Kernel::Process::current()->close(fd)); });
int fd = TRY(Kernel::Process::current().open(file_path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Kernel::Process::current().close(fd)); });
stat st;
TRY(Kernel::Process::current()->fstat(fd, &st));
TRY(Kernel::Process::current().fstat(fd, &st));
TRY(data.resize(st.st_size));
TRY(Kernel::Process::current()->read(fd, data.data(), data.size()));
TRY(Kernel::Process::current().read(fd, data.data(), data.size()));
elf = new ELF(BAN::move(data));
ASSERT(elf);

View File

@ -13,7 +13,7 @@
namespace Kernel
{
class Process : BAN::RefCounted<Process>
class Process
{
BAN_NON_COPYABLE(Process);
BAN_NON_MOVABLE(Process);
@ -22,8 +22,8 @@ namespace Kernel
using entry_t = Thread::entry_t;
public:
static BAN::ErrorOr<BAN::RefPtr<Process>> create_kernel(entry_t, void*);
static BAN::ErrorOr<BAN::RefPtr<Process>> create_userspace(void(*)());
static BAN::ErrorOr<Process*> create_kernel(entry_t, void*);
static BAN::ErrorOr<Process*> create_userspace(void(*)());
~Process();
[[noreturn]] void exit();
@ -52,10 +52,11 @@ namespace Kernel
BAN::ErrorOr<BAN::String> working_directory() const;
BAN::ErrorOr<void> set_working_directory(BAN::StringView);
static BAN::RefPtr<Process> current() { return Thread::current().process(); }
static Process& current() { return Thread::current().process(); }
private:
Process(pid_t);
static Process* create_process();
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
@ -81,8 +82,6 @@ namespace Kernel
BAN::Vector<Thread*> m_threads;
TTY* m_tty { nullptr };
friend class BAN::RefPtr<Process>;
};
}

View File

@ -26,7 +26,7 @@ namespace Kernel
};
public:
static BAN::ErrorOr<Thread*> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr);
static BAN::ErrorOr<Thread*> create(entry_t, void*, Process*);
~Thread();
void jump_userspace(uintptr_t rip);
@ -46,22 +46,22 @@ namespace Kernel
size_t stack_size() const { return m_stack_size; }
static Thread& current() ;
BAN::RefPtr<Process> process();
Process& process();
private:
Thread(pid_t tid, BAN::RefPtr<Process>);
Thread(pid_t tid, Process*);
BAN::ErrorOr<void> initialize(entry_t, void*);
void on_exit();
private:
static constexpr size_t m_stack_size = 4096 * 1;
void* m_stack_base = nullptr;
uintptr_t m_rip = 0;
uintptr_t m_rsp = 0;
const pid_t m_tid = 0;
State m_state { State::NotStarted };
BAN::RefPtr<Process> m_process;
void* m_stack_base { nullptr };
uintptr_t m_rip { 0 };
uintptr_t m_rsp { 0 };
const pid_t m_tid { 0 };
State m_state { State::NotStarted };
Process* m_process { nullptr };
friend class Scheduler;
};

View File

@ -37,15 +37,15 @@ namespace Kernel
BAN::ErrorOr<Font> Font::load(BAN::StringView path)
{
int fd = TRY(Process::current()->open(path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current()->close(fd)); });
int fd = TRY(Process::current().open(path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current().close(fd)); });
stat st;
TRY(Process::current()->fstat(fd, &st));
TRY(Process::current().fstat(fd, &st));
BAN::Vector<uint8_t> file_data;
TRY(file_data.resize(st.st_size));
TRY(Process::current()->read(fd, file_data.data(), st.st_size));
TRY(Process::current().read(fd, file_data.data(), st.st_size));
if (file_data.size() < 4)
return BAN::Error::from_error_code(ErrorCode::Font_FileTooSmall);

View File

@ -11,19 +11,33 @@
namespace Kernel
{
static pid_t s_next_pid = 1;
static BAN::Vector<Process*> s_processes;
static SpinLock s_process_lock;
BAN::ErrorOr<BAN::RefPtr<Process>> Process::create_kernel(entry_t entry, void* data)
Process* Process::create_process()
{
auto process = TRY(BAN::RefPtr<Process>::create(s_next_pid++));
static pid_t s_next_pid = 1;
auto* process = new Process(s_next_pid++);
ASSERT(process);
s_process_lock.lock();
MUST(s_processes.push_back(process));
s_process_lock.unlock();
return process;
}
BAN::ErrorOr<Process*> Process::create_kernel(entry_t entry, void* data)
{
auto* process = create_process();
TRY(process->m_working_directory.push_back('/'));
TRY(process->add_thread(entry, data));
return process;
}
BAN::ErrorOr<BAN::RefPtr<Process>> Process::create_userspace(void(*entry)())
BAN::ErrorOr<Process*> Process::create_userspace(void(*entry)())
{
auto process = TRY(BAN::RefPtr<Process>::create(s_next_pid++));
auto* process = create_process();
TRY(process->m_working_directory.push_back('/'));
TRY(process->init_stdio());

View File

@ -27,7 +27,7 @@ namespace Kernel
ASSERT(s_instance == nullptr);
s_instance = new Scheduler();
ASSERT(s_instance);
s_instance->m_idle_thread = TRY(Thread::create([](void*) { for (;;) asm volatile("hlt"); }));
s_instance->m_idle_thread = TRY(Thread::create([](void*) { for (;;) asm volatile("hlt"); }, nullptr, nullptr));
return {};
}
@ -247,11 +247,11 @@ namespace Kernel
{
VERIFY_CLI();
pid_t pid = m_current_thread->thread->process()->pid();
pid_t pid = m_current_thread->thread->process().pid();
remove_threads(m_blocking_threads, it->thread->process()->pid() == pid);
remove_threads(m_sleeping_threads, it->thread->process()->pid() == pid);
remove_threads(m_active_threads, it != m_current_thread && it->thread->process()->pid() == pid);
remove_threads(m_blocking_threads, it->thread->process().pid() == pid);
remove_threads(m_sleeping_threads, it->thread->process().pid() == pid);
remove_threads(m_active_threads, it != m_current_thread && it->thread->process().pid() == pid);
delete m_current_thread->thread;
remove_and_advance_current_thread();

View File

@ -22,14 +22,14 @@ namespace Kernel
static void TTY_PRINT(Args&&... args)
{
BAN::String message = BAN::String::formatted(BAN::forward<Args>(args)...);
MUST(Process::current()->write(STDOUT_FILENO, message.data(), message.size()));
MUST(Process::current().write(STDOUT_FILENO, message.data(), message.size()));
}
template<typename... Args>
static void TTY_PRINTLN(Args&&... args)
{
TTY_PRINT(BAN::forward<Args>(args)...);
MUST(Process::current()->write(STDOUT_FILENO, "\n", 1));
MUST(Process::current().write(STDOUT_FILENO, "\n", 1));
}
static auto s_default_prompt = "\\[\e[32m\\]user\\[\e[m\\]:\\[\e[34m\\]\\w\\[\e[m\\]# "sv;
@ -59,7 +59,7 @@ namespace Kernel
{
MUST(set_prompt(s_default_prompt));
MUST(m_buffer.push_back(""sv));
MUST(Process::current()->set_termios(termios { .canonical = false, .echo = false }));
MUST(Process::current().set_termios(termios { .canonical = false, .echo = false }));
}
BAN::ErrorOr<void> Shell::set_prompt(BAN::StringView prompt)
@ -89,7 +89,7 @@ namespace Kernel
break;
case 'w':
{
auto working_directory = TRY(Process::current()->working_directory());
auto working_directory = TRY(Process::current().working_directory());
TRY(m_prompt.append(working_directory));
m_prompt_length += working_directory.size();
break;
@ -112,7 +112,7 @@ namespace Kernel
void Shell::run()
{
auto getch = [this] { uint8_t ch; MUST(Process::current()->read(STDIN_FILENO, &ch, 1)); return ch; };
auto getch = [this] { uint8_t ch; MUST(Process::current().read(STDIN_FILENO, &ch, 1)); return ch; };
MUST(m_buffer.push_back(""sv));
@ -130,7 +130,7 @@ namespace Kernel
while ((current.back() & 0xC0) == 0x80)
current.pop_back();
current.pop_back();
MUST(Process::current()->write(STDOUT_FILENO, "\b \b", 3));
MUST(Process::current().write(STDOUT_FILENO, "\b \b", 3));
}
continue;
}
@ -171,7 +171,7 @@ namespace Kernel
continue;
}
MUST(Process::current()->write(STDOUT_FILENO, &ch, 1));
MUST(Process::current().write(STDOUT_FILENO, &ch, 1));
if (ch != '\n')
{
@ -334,7 +334,7 @@ argument_done:
for (int i = 0; i < 100; i++)
{
lock.lock();
MUST(Process::create_kernel([](void*) { MUST(Process::current()->init_stdio()); TTY_PRINTLN("####"); Process::current()->exit(); }, nullptr));
MUST(Process::create_kernel([](void*) { MUST(Process::current().init_stdio()); TTY_PRINTLN("####"); Process::current().exit(); }, nullptr));
PIT::sleep(5);
kmalloc_dump_info();
lock.unlock();
@ -406,7 +406,7 @@ argument_done:
SpinLock spinlock;
thread_data_t thread_data = { this, spinlock, arguments };
spinlock.lock();
TRY(Process::current()->add_thread(function, &thread_data));
TRY(Process::current().add_thread(function, &thread_data));
while (spinlock.is_locked());
}
else if (arguments.front() == "memory")
@ -508,15 +508,15 @@ argument_done:
if (arguments.size() == 2)
TRY(path.append(arguments[1]));
else
TRY(path.append(TRY(Process::current()->working_directory())));
TRY(path.append(TRY(Process::current().working_directory())));
int fd = TRY(Process::current()->open(path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current()->close(fd)); });
int fd = TRY(Process::current().open(path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current().close(fd)); });
BAN::Vector<BAN::String> all_entries;
BAN::Vector<BAN::String> entries;
while (!(entries = TRY(Process::current()->read_directory_entries(fd))).empty())
while (!(entries = TRY(Process::current().read_directory_entries(fd))).empty())
{
TRY(all_entries.reserve(all_entries.size() + entries.size()));
for (auto& entry : entries)
@ -533,7 +533,7 @@ argument_done:
BAN::String entry_path;
TRY(entry_path.append(entry_prefix));
TRY(entry_path.append(entry));
TRY(Process::current()->stat(entry_path, &st));
TRY(Process::current().stat(entry_path, &st));
Inode::Mode mode { st.st_mode };
@ -554,14 +554,14 @@ argument_done:
return {};
}
int fd = TRY(Process::current()->open(arguments[1], O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current()->close(fd)); });
int fd = TRY(Process::current().open(arguments[1], O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current().close(fd)); });
char* buffer = new char[1024];
BAN::ScopeGuard buffer_guard([buffer] { delete[] buffer; });
ASSERT(buffer);
while (size_t n_read = TRY(Process::current()->read(fd, buffer, sizeof(buffer))))
while (size_t n_read = TRY(Process::current().read(fd, buffer, sizeof(buffer))))
TTY_PRINT("{}", BAN::StringView(buffer, n_read));
TTY_PRINTLN("");
}
@ -574,7 +574,7 @@ argument_done:
}
stat st;
TRY(Process::current()->stat(arguments[1], &st));
TRY(Process::current().stat(arguments[1], &st));
Inode::Mode mode { st.st_mode };
@ -604,7 +604,7 @@ argument_done:
return {};
}
BAN::StringView path = arguments.size() == 2 ? arguments[1].sv() : "/"sv;
TRY(Process::current()->set_working_directory(path));
TRY(Process::current().set_working_directory(path));
TRY(update_prompt());
}
else if (arguments.front() == "touch")
@ -614,7 +614,7 @@ argument_done:
TTY_PRINTLN("usage 'touch path'");
return {};
}
TRY(Process::current()->creat(arguments[1], 0));
TRY(Process::current().creat(arguments[1], 0));
}
else if (arguments.front() == "cksum")
{
@ -630,15 +630,15 @@ argument_done:
for (size_t i = 1; i < arguments.size(); i++)
{
int fd = TRY(Process::current()->open(arguments[i], O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current()->close(fd)); });
int fd = TRY(Process::current().open(arguments[i], O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current().close(fd)); });
uint32_t crc32 = 0;
uint32_t total_read = 0;
while (true)
{
size_t n_read = TRY(Process::current()->read(fd, buffer, sizeof(buffer)));
size_t n_read = TRY(Process::current().read(fd, buffer, sizeof(buffer)));
if (n_read == 0)
break;
for (size_t j = 0; j < n_read; j++)
@ -660,7 +660,7 @@ argument_done:
TTY_PRINTLN("usage: 'mount partition directory'");
return {};
}
TRY(Process::current()->mount(arguments[1], arguments[2]));
TRY(Process::current().mount(arguments[1], arguments[2]));
}
else if (arguments.front() == "loadfont")
{

View File

@ -7,12 +7,12 @@ namespace Kernel
void sys_exit()
{
Process::current()->exit();
Process::current().exit();
}
int sys_read(int fd, void* buffer, size_t size)
{
auto res = Process::current()->read(fd, buffer, size);
auto res = Process::current().read(fd, buffer, size);
if (res.is_error())
return res.error().get_error_code();
return 0;
@ -20,7 +20,7 @@ namespace Kernel
int sys_write(int fd, const void* buffer, size_t size)
{
auto res = Process::current()->write(fd, buffer, size);
auto res = Process::current().write(fd, buffer, size);
if (res.is_error())
return res.error().get_error_code();
return 0;

View File

@ -59,11 +59,11 @@ namespace Kernel
[](void* tty_)
{
TTY* tty = (TTY*)tty_;
int fd = MUST(Process::current()->open("/dev/input0"sv, O_RDONLY));
int fd = MUST(Process::current().open("/dev/input0"sv, O_RDONLY));
while (true)
{
Input::KeyEvent event;
MUST(Process::current()->read(fd, &event, sizeof(event)));
MUST(Process::current().read(fd, &event, sizeof(event)));
tty->on_key(event);
}
}, this)

View File

@ -19,7 +19,7 @@ namespace Kernel
memcpy((void*)rsp, (void*)&value, size);
}
BAN::ErrorOr<Thread*> Thread::create(entry_t entry, void* data, BAN::RefPtr<Process> process)
BAN::ErrorOr<Thread*> Thread::create(entry_t entry, void* data, Process* process)
{
static pid_t next_tid = 1;
auto* thread = new Thread(next_tid++, process);
@ -29,7 +29,7 @@ namespace Kernel
return thread;
}
Thread::Thread(pid_t tid, BAN::RefPtr<Process> process)
Thread::Thread(pid_t tid, Process* process)
: m_tid(tid), m_process(process)
{}
@ -38,9 +38,10 @@ namespace Kernel
return Scheduler::get().current_thread();
}
BAN::RefPtr<Process> Thread::process()
Process& Thread::process()
{
return m_process;
ASSERT(m_process);
return *m_process;
}
BAN::ErrorOr<void> Thread::initialize(entry_t entry, void* data)

View File

@ -143,6 +143,7 @@ extern "C" void kernel_main()
TTY* tty1 = new TTY(terminal_driver);
ASSERT(tty1);
dprintln("TTY initialized");
Memory::Heap::initialize();
dprintln("Heap initialzed");
@ -164,7 +165,7 @@ extern "C" void kernel_main()
MUST(Scheduler::initialize());
Scheduler& scheduler = Scheduler::get();
MUST(scheduler.add_thread(MUST(Thread::create(init2, tty1))));
MUST(scheduler.add_thread(MUST(Thread::create(init2, tty1, nullptr))));
scheduler.start();
ASSERT_NOT_REACHED();
@ -189,18 +190,25 @@ static void init2(void* tty1)
[](void*)
{
MUST(LibELF::ELF::load_from_file("/bin/test"sv));
Process::current()->exit();
Process::current().exit();
}, nullptr
));
return;
MUST(Process::create_kernel(
[](void*)
{
}, nullptr
));
jump_userspace();
return;
MUST(Process::create_kernel(
[](void*)
{
MUST(Process::current()->init_stdio());
MUST(Process::current().init_stdio());
Shell* shell = new Shell();
ASSERT(shell);
shell->run();