Luna/kernel/src/thread/Thread.h
apio 3ad23eab21
kernel: Add support for supplementary groups (1/2)
Adds support for supplementary groups internally in the kernel.
No userspace support.
2023-11-22 18:49:40 +01:00

182 lines
3.7 KiB
C++

#pragma once
#include "arch/MMU.h"
#include "fs/OpenFileDescription.h"
#include "fs/VFS.h"
#include "memory/AddressSpace.h"
#include <bits/signal.h>
#include <luna/Bitset.h>
#include <luna/LinkedList.h>
#include <luna/OwnedPtr.h>
#include <luna/Result.h>
#include <luna/Stack.h>
#include <luna/StaticString.h>
#include <luna/String.h>
#ifdef ARCH_X86_64
#include "arch/x86_64/CPU.h"
#else
#error "Unknown architecture."
#endif
class Timer;
enum class ThreadState
{
None,
Idle,
Runnable,
Sleeping,
Waiting,
Stopped,
Exited,
Dying
};
static constexpr int FD_MAX = 64;
struct Credentials
{
u32 uid { 0 };
u32 euid { 0 };
u32 suid { 0 };
u32 gid { 0 };
u32 egid { 0 };
u32 sgid { 0 };
};
struct Thread : public LinkedListNode<Thread>
{
Registers regs;
pid_t id;
pid_t pgid { 0 };
pid_t sid { 0 };
Credentials auth;
Vector<gid_t> extra_groups;
u64 user_ticks_self = 0;
u64 kernel_ticks_self = 0;
u64 user_ticks_children = 0;
u64 kernel_ticks_children = 0;
u64 ticks_left;
u64 sleep_ticks_left;
int promises { -1 };
int execpromises { -1 };
Stack stack;
Stack kernel_stack;
OwnedPtr<AddressSpace> address_space;
Option<FileDescriptor> fd_table[FD_MAX] = {};
Result<int> allocate_fd(int min);
Result<FileDescriptor*> resolve_fd(int fd);
Result<SharedPtr<VFS::Inode>> resolve_atfile(int dirfd, const String& path, bool allow_empty_path,
bool follow_last_symlink,
SharedPtr<VFS::Inode>* parent_inode = nullptr);
struct sigaction signal_handlers[NSIG];
Bitset<sigset_t> signal_mask { 0 };
Bitset<sigset_t> pending_signals { 0 };
bool interrupted { false };
SharedPtr<VFS::Inode> controlling_terminal;
bool unrestricted_task { false };
FPData fp_data;
ThreadState state = ThreadState::Runnable;
bool is_kernel { true };
bool has_called_exec { false };
int status { 0 };
mode_t umask { 0 };
Timer real_timer;
Timer virtual_timer;
Timer profiling_timer;
Clock virtual_clock;
Clock profiling_clock;
StaticString<128> cmdline;
String current_directory_path = {};
SharedPtr<VFS::Inode> current_directory = {};
Thread* parent { nullptr };
Option<pid_t> child_being_waited_for = {};
PageDirectory* self_directory() const
{
return address_space->page_directory();
}
PageDirectory* active_directory { nullptr };
[[noreturn]] void exit_and_signal_parent(int status);
bool is_idle()
{
return state == ThreadState::Idle;
}
void wake_up()
{
state = ThreadState::Runnable;
}
bool is_session_leader()
{
return id == sid;
}
void init_regs_kernel();
void init_regs_user();
void set_arguments(u64 arg1, u64 arg2, u64 arg3, u64 arg4);
void set_ip(u64 ip);
u64 ip();
void set_sp(u64 sp);
u64 sp();
void set_return(u64 ret);
u64 return_register();
void process_pending_signals(Registers* current_regs);
bool will_ignore_pending_signal();
bool deliver_signal(int signo, Registers* current_regs);
void sigreturn(Registers* current_regs);
Result<u64> push_mem_on_stack(const u8* mem, usize size);
Result<u64> pop_mem_from_stack(u8* mem, usize size);
void stop();
void resume();
void send_signal(int signo);
static void init();
};
void switch_context(Thread* old_thread, Thread* new_thread, Registers* regs);
bool is_in_kernel(Registers* regs);
Result<Thread*> new_thread();
pid_t next_thread_id();
extern LinkedList<Thread> g_threads;