2022-12-07 15:02:46 +01:00
|
|
|
#pragma once
|
|
|
|
|
2023-01-05 21:50:53 +01:00
|
|
|
#include "arch/MMU.h"
|
2023-03-11 17:45:20 +01:00
|
|
|
#include "fs/VFS.h"
|
2023-07-09 20:38:04 +02:00
|
|
|
#include "memory/AddressSpace.h"
|
2023-07-10 19:46:57 +02:00
|
|
|
#include <bits/signal.h>
|
2022-12-07 15:02:46 +01:00
|
|
|
#include <luna/LinkedList.h>
|
2023-01-13 19:05:20 +01:00
|
|
|
#include <luna/OwnedPtr.h>
|
2022-12-07 15:02:46 +01:00
|
|
|
#include <luna/Result.h>
|
2022-12-18 18:43:17 +01:00
|
|
|
#include <luna/Stack.h>
|
2023-03-24 21:05:38 +01:00
|
|
|
#include <luna/StaticString.h>
|
2023-04-11 22:14:57 +02:00
|
|
|
#include <luna/String.h>
|
2022-12-07 15:02:46 +01:00
|
|
|
|
|
|
|
#ifdef ARCH_X86_64
|
|
|
|
#include "arch/x86_64/CPU.h"
|
|
|
|
#else
|
|
|
|
#error "Unknown architecture."
|
|
|
|
#endif
|
|
|
|
|
2022-12-07 15:14:58 +01:00
|
|
|
enum class ThreadState
|
|
|
|
{
|
2023-04-28 13:23:07 +02:00
|
|
|
None,
|
2022-12-07 15:14:58 +01:00
|
|
|
Idle,
|
|
|
|
Runnable,
|
2022-12-18 18:43:34 +01:00
|
|
|
Sleeping,
|
2023-05-04 23:03:31 +02:00
|
|
|
Waiting,
|
2023-03-23 22:25:56 +01:00
|
|
|
Exited,
|
2022-12-18 18:43:34 +01:00
|
|
|
Dying
|
2022-12-07 15:14:58 +01:00
|
|
|
};
|
|
|
|
|
2023-07-30 11:33:46 +02:00
|
|
|
struct OpenFileDescription : public Shareable
|
2023-03-11 17:45:20 +01:00
|
|
|
{
|
|
|
|
SharedPtr<VFS::Inode> inode;
|
|
|
|
int flags { 0 };
|
2023-03-12 14:43:58 +01:00
|
|
|
|
2023-07-27 19:21:23 +02:00
|
|
|
OpenFileDescription(SharedPtr<VFS::Inode>, int);
|
|
|
|
~OpenFileDescription();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FileDescriptor
|
|
|
|
{
|
|
|
|
SharedPtr<OpenFileDescription> description;
|
|
|
|
usize offset { 0 };
|
2023-08-03 17:47:18 +02:00
|
|
|
int flags { 0 };
|
2023-07-27 19:21:23 +02:00
|
|
|
|
2023-03-12 14:43:58 +01:00
|
|
|
bool should_append();
|
2023-03-19 11:25:14 +01:00
|
|
|
bool should_block();
|
2023-03-12 14:43:58 +01:00
|
|
|
bool is_writable();
|
|
|
|
bool is_readable();
|
2023-07-27 19:21:23 +02:00
|
|
|
|
|
|
|
SharedPtr<VFS::Inode> inode()
|
|
|
|
{
|
|
|
|
return description->inode;
|
|
|
|
}
|
|
|
|
|
2023-08-03 17:47:18 +02:00
|
|
|
int& status_flags()
|
2023-07-27 19:21:23 +02:00
|
|
|
{
|
|
|
|
return description->flags;
|
|
|
|
}
|
2023-03-11 17:45:20 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static constexpr int FD_MAX = 64;
|
|
|
|
|
2023-04-08 13:12:49 +02:00
|
|
|
struct Credentials
|
|
|
|
{
|
|
|
|
u32 uid { 0 };
|
|
|
|
u32 euid { 0 };
|
|
|
|
u32 suid { 0 };
|
|
|
|
u32 gid { 0 };
|
|
|
|
u32 egid { 0 };
|
|
|
|
u32 sgid { 0 };
|
|
|
|
};
|
|
|
|
|
2022-12-19 12:43:23 +01:00
|
|
|
struct Thread : public LinkedListNode<Thread>
|
2022-12-07 15:02:46 +01:00
|
|
|
{
|
|
|
|
Registers regs;
|
|
|
|
|
2023-07-26 21:32:00 +02:00
|
|
|
pid_t id;
|
|
|
|
pid_t pgid { 0 };
|
2022-12-07 15:02:46 +01:00
|
|
|
|
2023-04-08 13:12:49 +02:00
|
|
|
Credentials auth;
|
|
|
|
|
2023-05-20 12:48:07 +02:00
|
|
|
u64 user_ticks_self = 0;
|
|
|
|
u64 kernel_ticks_self = 0;
|
|
|
|
u64 user_ticks_children = 0;
|
|
|
|
u64 kernel_ticks_children = 0;
|
2022-12-07 15:02:46 +01:00
|
|
|
|
|
|
|
u64 ticks_left;
|
2022-12-07 15:55:58 +01:00
|
|
|
u64 sleep_ticks_left;
|
2022-12-07 15:02:46 +01:00
|
|
|
|
2022-12-18 18:43:17 +01:00
|
|
|
Stack stack;
|
2023-01-05 21:50:53 +01:00
|
|
|
Stack kernel_stack;
|
2022-12-18 18:43:17 +01:00
|
|
|
|
2023-07-09 20:38:04 +02:00
|
|
|
OwnedPtr<AddressSpace> address_space;
|
2023-03-12 13:57:38 +01:00
|
|
|
Option<FileDescriptor> fd_table[FD_MAX] = {};
|
2023-03-11 17:45:20 +01:00
|
|
|
|
|
|
|
Result<int> allocate_fd(int min);
|
2023-03-12 13:57:38 +01:00
|
|
|
Result<FileDescriptor*> resolve_fd(int fd);
|
2023-04-15 20:26:15 +02:00
|
|
|
Result<SharedPtr<VFS::Inode>> resolve_atfile(int dirfd, const String& path, bool allow_empty_path,
|
2023-05-20 21:46:31 +02:00
|
|
|
bool follow_last_symlink,
|
2023-04-15 20:26:15 +02:00
|
|
|
SharedPtr<VFS::Inode>* parent_inode = nullptr);
|
2023-01-11 23:01:47 +01:00
|
|
|
|
2023-07-10 19:46:57 +02:00
|
|
|
struct sigaction signal_handlers[NSIG];
|
|
|
|
sigset_t signal_mask { 0 };
|
2023-07-11 11:51:07 +02:00
|
|
|
sigset_t pending_signals { 0 };
|
2023-07-12 13:48:43 +02:00
|
|
|
bool interrupted { false };
|
2023-07-10 19:46:57 +02:00
|
|
|
|
2023-03-07 20:59:11 +01:00
|
|
|
FPData fp_data;
|
|
|
|
|
2022-12-07 15:14:58 +01:00
|
|
|
ThreadState state = ThreadState::Runnable;
|
|
|
|
|
2023-01-05 21:50:53 +01:00
|
|
|
bool is_kernel { true };
|
2023-07-11 11:51:07 +02:00
|
|
|
bool has_called_exec { false };
|
2023-01-05 21:50:53 +01:00
|
|
|
|
2023-07-10 20:16:06 +02:00
|
|
|
int status { 0 };
|
2023-03-23 22:25:56 +01:00
|
|
|
|
2023-05-26 22:27:49 +02:00
|
|
|
mode_t umask { 0 };
|
|
|
|
|
2023-03-24 21:05:38 +01:00
|
|
|
StaticString<128> name;
|
|
|
|
|
2023-04-11 22:14:57 +02:00
|
|
|
String current_directory_path = {};
|
|
|
|
SharedPtr<VFS::Inode> current_directory = {};
|
|
|
|
|
2023-05-04 22:58:04 +02:00
|
|
|
Thread* parent { nullptr };
|
2023-05-04 23:03:31 +02:00
|
|
|
Option<pid_t> child_being_waited_for = {};
|
2023-05-04 22:58:04 +02:00
|
|
|
|
2023-07-09 20:32:42 +02:00
|
|
|
PageDirectory* self_directory() const
|
|
|
|
{
|
2023-07-09 20:38:04 +02:00
|
|
|
return address_space->page_directory();
|
2023-07-09 20:32:42 +02:00
|
|
|
}
|
|
|
|
|
2023-06-25 20:09:40 +02:00
|
|
|
PageDirectory* active_directory { nullptr };
|
2023-01-05 21:50:53 +01:00
|
|
|
|
2023-07-10 20:16:06 +02:00
|
|
|
[[noreturn]] void exit_and_signal_parent(int status);
|
2023-06-19 12:33:25 +02:00
|
|
|
|
2022-12-07 15:14:58 +01:00
|
|
|
bool is_idle()
|
|
|
|
{
|
|
|
|
return state == ThreadState::Idle;
|
|
|
|
}
|
2022-12-07 15:02:46 +01:00
|
|
|
|
2023-05-04 23:35:54 +02:00
|
|
|
void wake_up()
|
|
|
|
{
|
|
|
|
state = ThreadState::Runnable;
|
|
|
|
}
|
|
|
|
|
2022-12-07 15:02:46 +01:00
|
|
|
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();
|
2022-12-17 10:50:49 +01:00
|
|
|
|
2023-03-18 23:45:48 +01:00
|
|
|
void set_return(u64 ret);
|
2023-07-10 19:46:57 +02:00
|
|
|
u64 return_register();
|
|
|
|
|
|
|
|
void process_pending_signals(Registers* current_regs);
|
|
|
|
|
2023-07-12 13:48:43 +02:00
|
|
|
bool will_invoke_signal_handler();
|
|
|
|
|
2023-07-10 19:46:57 +02:00
|
|
|
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);
|
2023-03-18 23:45:48 +01:00
|
|
|
|
2023-07-10 20:16:06 +02:00
|
|
|
void send_signal(int signo);
|
|
|
|
|
2022-12-17 10:50:49 +01:00
|
|
|
static void init();
|
2022-12-07 15:02:46 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
void switch_context(Thread* old_thread, Thread* new_thread, Registers* regs);
|
|
|
|
|
|
|
|
bool is_in_kernel(Registers* regs);
|
|
|
|
|
|
|
|
Result<Thread*> new_thread();
|
|
|
|
|
2023-07-26 21:32:00 +02:00
|
|
|
pid_t next_thread_id();
|
2023-07-12 19:23:06 +02:00
|
|
|
|
2023-01-02 13:07:29 +01:00
|
|
|
extern LinkedList<Thread> g_threads;
|