Luna/kernel/src/thread/Thread.cpp
apio 77dcfab5ef
All checks were successful
continuous-integration/drone/push Build is passing
kernel: Run the initialization process in a thread
This way we can give it more stack and also reclaim it later!
2023-04-28 13:23:07 +02:00

88 lines
2.1 KiB
C++

#include "thread/Thread.h"
#include "memory/MemoryManager.h"
#include <bits/atfile.h>
#include <bits/open-flags.h>
#include <luna/Alloc.h>
#include <luna/Atomic.h>
#include <luna/PathParser.h>
static Atomic<u64> g_next_id;
LinkedList<Thread> g_threads;
void Thread::init()
{
g_next_id = 2;
}
Result<Thread*> new_thread()
{
Thread* const thread = TRY(make<Thread>());
thread->id = g_next_id++;
return thread;
}
Result<int> Thread::allocate_fd(int min)
{
if (min < 0 || min >= FD_MAX) return err(EINVAL);
for (int i = min; i < FD_MAX; i++)
{
// FIXME: Possible race condition if multiple threads share a FileDescriptorTable? Let's not worry about it for
// now, we're still a long way away from reaching that point.
if (!fd_table[i].has_value()) { return i; }
}
return err(EMFILE);
}
Result<FileDescriptor*> Thread::resolve_fd(int fd)
{
if (fd < 0 || fd >= FD_MAX) return err(EBADF);
Option<FileDescriptor>& maybe_descriptor = fd_table[fd];
if (!maybe_descriptor.has_value()) return err(EBADF);
return maybe_descriptor.value_ptr();
}
Result<SharedPtr<VFS::Inode>> Thread::resolve_atfile(int dirfd, const String& path, bool allow_empty_path,
SharedPtr<VFS::Inode>* parent_inode)
{
if (parent_inode) *parent_inode = this->current_directory;
if (PathParser::is_absolute(path.view())) return VFS::resolve_path(path.chars(), this->auth);
if (dirfd == AT_FDCWD) return VFS::resolve_path(path.chars(), this->auth, this->current_directory);
auto descriptor = TRY(resolve_fd(dirfd));
if (parent_inode) *parent_inode = descriptor->inode;
if (path.is_empty() && allow_empty_path) return descriptor->inode;
return VFS::resolve_path(path.chars(), this->auth, descriptor->inode);
}
bool FileDescriptor::should_append()
{
return flags & O_APPEND;
}
bool FileDescriptor::should_block()
{
return !(flags & O_NONBLOCK);
}
bool FileDescriptor::is_readable()
{
return flags & O_RDONLY;
}
bool FileDescriptor::is_writable()
{
return flags & O_WRONLY;
}