#pragma once #include "fs/FileDescriptor.h" #include "interrupts/Context.h" #include "memory/AddressSpace.h" #include "memory/UserHeap.h" #include "sys/elf/Image.h" #define TASK_MAX_FDS 32 enum class BlockReason { None, Reading, Waiting, }; struct Task { enum TaskState { Idle, Running, Sleeping, Dying, Blocking, Exited }; uint64_t id; uint64_t ppid; Context regs; int64_t task_sleep = 0; int64_t exit_status; int64_t task_time = 0; int uid; int euid; int gid; int egid; Task* next_task = nullptr; Task* prev_task = nullptr; uint64_t allocated_stack = 0; TaskState state; uint64_t cpu_time = 0; char floating_region[512] __attribute__((aligned(16))); bool floating_saved = false; bool user_task = true; bool is_user_task(); ELFImage* image = nullptr; Descriptor files[TASK_MAX_FDS]; AddressSpace address_space; UserHeap allocator; int alloc_fd(); int alloc_fd_greater_than_or_equal(int base_fd); void save_context(Context* context); void restore_context(Context* context); void save_floating(); void restore_floating(); void switch_to_address_space(); bool has_died(); char name[128]; mode_t umask; BlockReason block_reason; union { struct { size_t size; int fd; char* buf; } blocking_read_info; struct { int64_t pid; int* wstatus; } blocking_wait_info; }; void resume(); bool is_still_blocking(); Descriptor* descriptor_from_fd(int fd, int& error); bool is_superuser(); private: void resume_read(); void resume_wait(); bool is_read_still_blocking(); bool is_wait_still_blocking(); };