44#include <stdint.h>
55#include <stdbool.h>
66
7- // Состояние всех регистров x86_64 при прерывании
8- typedef struct {
9- uint64_t r15 , r14 , r13 , r12 , r11 , r10 , r9 , r8 ;
10- uint64_t rdi , rsi , rbp , rdx , rcx , rbx , rax ;
11- uint64_t interrupt_number , error_code ;
12- uint64_t rip , cs , rflags , rsp , ss ;
13- } __attribute__((packed )) stack_frame_t ;
14-
15- #define MAX_FD 32
16-
7+ // Состояния потока
178typedef enum {
189 TASK_STATE_RUNNABLE , // Готов к выполнению (находится в Run Queue)
1910 TASK_STATE_SLEEPING , // Спит по таймеру (находится в Sleep Queue)
2011 TASK_STATE_BLOCKED , // Заблокирован на мьютексе/семафоре/ожидании ввода (вне планировщика)
2112 TASK_STATE_ZOMBIE // Мертв, ожидает waitpid (вне планировщика)
2213} task_state_t ;
2314
15+ // === Контейнер ресурсов Процесса (Process Control Block) ===
2416typedef struct process {
25- uint64_t pid ; // Идентификатор процесса
17+ uint64_t pid ; // Идентификатор процесса (PID)
2618 uint64_t parent_pid ; // PID родительского процесса
27- uint64_t pgid ;
19+ uint64_t pgid ; // Группа процессов (PGID)
2820 uint64_t cr3 ; // Страничная таблица процесса (общее адресное пространство)
2921 uint64_t brk ; // Граница кучи процесса (общее выделение памяти)
3022 char cwd [256 ]; // Общий рабочий каталог процессов
@@ -38,7 +30,11 @@ typedef struct task {
3830 uint64_t rsp ; // Сохраненный указатель стека потока
3931 uint64_t id ; // Идентификатор потока (TID)
4032 task_state_t state ; // Текущее состояние потока
41- bool running ; // Совместимость
33+ bool running ; // Обратная совместимость
34+
35+ bool waiting ; // Ожидание в waitpid
36+ uint64_t wait_for ; // Кого именно ждем в waitpid
37+
4238 uint64_t kstack_at_bottom ; // Ядерный стек этого потока (для прерываний)
4339 uint64_t fs_base ; // Базовый адрес TLS этого потока
4440
@@ -47,129 +43,23 @@ typedef struct task {
4743
4844 uint64_t sleep_until ; // Таймер сна потока
4945 uint8_t fpu_state [512 ] __attribute__((aligned (16 )));
50- bool waiting ; // Флаг ожидания завершения дочернего процесса
51- uint64_t wait_for ;
5246
5347 // Сигналы (доставляются конкретному потоку)
5448 uint64_t sig_pending ;
5549 uint64_t sig_blocked ;
5650 uint64_t sig_handlers [32 ];
5751 uint64_t sig_restorer ;
5852
59- // Ссылки очереди планировщика
53+ // Очереди планировщика (ИСПОЛЬЗУЮТСЯ ИСКЛЮЧИТЕЛЬНО В sched.c)
54+ struct task * sched_next ;
55+ struct task * sched_prev ;
56+
57+ // Глобальный список всех потоков в системе (ИСПОЛЬЗУЮТСЯ В task.c / signal.c / waitpid)
6058 struct task * next ;
6159 struct task * prev ;
6260} task_t ;
6361
64- static inline void * task_fpu_area (task_t * t ) {
65- return (void * )(((uint64_t )t -> fpu_state + 15 ) & ~(uint64_t )15 );
66- }
67-
68- /* Кладёт в fpu-область задачи эталонное «чистое» состояние (fninit +
69- * MXCSR=0x1F80). Вызывать при создании каждой задачи. */
70- void task_fpu_init_area (task_t * t );
71-
72- extern task_t * current_task ;
73- void task_init ();
74- uint64_t schedule (uint64_t current_rsp ); // Вызывается из ассемблера
75- void yield (void );
76- void task_create (void (* entry )(), uint64_t arg1 , uint64_t arg2 , uint64_t cr3 );
77-
78- /* --- Этап 6b: System V AMD64 initial stack для musl / Linux-ABI бинарей ----
79- * Описывает данные для построения SysV-кадра на вершине пользовательского
80- * стека (argc / argv[] / NULL / envp[] / NULL / auxv / AT_NULL). Указатели
81- * argv_user/envp_user — это УЖЕ пользовательские адреса строк (напр. в argv-
82- * странице 0xB0000000), строки на стек НЕ копируются. Родной crt0 этот кадр
83- * игнорирует (читает argc/argv из регистров), поэтому детект ABI не нужен. */
84- typedef struct {
85- int argc ;
86- const uint64_t * argv_user ; /* argc пользовательских указателей на строки */
87- int envc ;
88- const uint64_t * envp_user ; /* envc указателей (может быть NULL при envc=0) */
89- uint64_t at_phdr ; /* адрес Program Headers в памяти процесса */
90- uint64_t at_phent ; /* размер одной записи PH */
91- uint64_t at_phnum ; /* число записей PH */
92- uint64_t at_entry ; /* точка входа ELF (e_entry) */
93- } sysv_args_t ;
94-
95- /* Полный конструктор задачи. sv != NULL и cr3 != 0 -> дополнительно строит
96- * SysV-кадр и ставит на него user-rsp. Возвращает созданную задачу. */
97- task_t * task_create_full (void (* entry )(), uint64_t arg1 , uint64_t arg2 ,
98- uint64_t cr3 , const sysv_args_t * sv );
99- bool task_exec (char * full_command );
100-
101- /* Этап 1b — execve. task_load_image() загружает ELF в НОВОЕ адресное
102- * пространство и готовит стек/TLS/argv (argv[] уже скопирован в память ядра).
103- * Переключение cr3 и освобождение старого пространства делает вызывающий. */
104- bool task_load_image (const char * path , char * const argv [], int argc ,
105- char * const envp [], int envc ,
106- uint64_t * out_entry , uint64_t * out_user_rsp ,
107- uint64_t * out_argv_ptr , uint64_t * out_envp_ptr ,
108- uint64_t * out_cr3 , uint64_t * out_fs_base );
109- void task_set_fs_base (uint64_t v );
110-
111- /* Этап 3: cwd текущего процесса (логический абсолютный путь). */
112- const char * task_current_cwd (void );
113- /* Сменить cwd текущего процесса на нормализованный target (логический
114- * абсолютный путь). Возвращает 0 при успехе, -1 при ошибке. */
115- int task_chdir (const char * path );
116- /* Разрешить пользовательский путь в имя для VFS (ext2): нормализует относ.
117- * cwd текущего процесса и убирает ведущий '/'. "/" -> "". */
118- void task_resolve_fs_path (const char * in , char * out , int outsz );
119-
120- /* --- Этап 1: процессная модель ------------------------------------------- *
121- * task_fork(): клонирует текущий процесс. parent_frame — сохранённый кадр
122- * прерывания (stack_frame_t*) из обработчика int 0x80, т.е. регистры
123- * родителя на момент syscall. Возвращает pid ребёнка родителю; ребёнок
124- * "вернётся" из того же int 0x80 со значением 0 в rax. */
125- uint64_t task_fork (stack_frame_t * parent_frame );
126-
127- /* Помечает текущий процесс зомби с кодом code, освобождает его адресное
128- * пространство и будит родителя, если тот ждёт в waitpid. Не возвращается
129- * (уходит в планировщик). Вызывается из обработчика SYS_EXIT. */
130- void task_exit_current (int code );
131-
132- /* Ждёт завершения ребёнка. pid > 0 — конкретный ребёнок, 0 — любой.
133- * Пишет код выхода в *status_out (kernel-указатель). Возвращает pid
134- * завершившегося ребёнка, либо -1 если у процесса нет таких детей (ECHILD).
135- * Блокирует (через yield) пока подходящий ребёнок не станет зомби. */
136- int64_t task_waitpid (uint64_t pid , int * status_out );
137- int64_t task_waitpid_ex (uint64_t pid , int * status_out , int nohang );
138- task_t * task_by_id (uint64_t pid );
139-
140- /* Этап 2: вернуть таблицу дескрипторов текущего процесса (для fs/fd.c). */
141- struct fd_table * task_current_fdt (void );
142-
143- void task_kill_self ();
144- bool task_terminate_by_pid (uint64_t pid );
145- void task_list_all ();
146-
147- // Доступ к глобальному списку задач (циклический односвязный).
148- // Возвращает голову, либо NULL, если планировщик ещё не поднят.
149- // Использовать с осторожностью: список — кольцо, идти до тех пор,
150- // пока next != head.
151- task_t * task_get_list_head (void );
152-
153- // Аккуратно убивает все пользовательские задачи кроме idle/init
154- // (id == 1). Используется в `killall` и SUPER+ALT+F10. Сама задача,
155- // если она пользовательская, должна позаботиться о yield()/kill_self
156- // отдельно — здесь мы только метим running=false; планировщик
157- // доразберётся в ближайшем тике.
158- // Возвращает кол-во убитых пользовательских задач.
159- int task_kill_all_user_count (void );
160-
161- // Удобная обёртка: то же самое, но без возврата кол-ва.
162- void task_kill_all_user (void );
163-
164- // Снимок задачи по индексу в кольце (начиная с головы, индексация 0..N-1).
165- // Заполняет out_pid/out_cr3/out_brk/out_running и возвращает true, если
166- // задача с таким индексом существует. iff false — кольцо короче.
167- typedef struct {
168- uint64_t pid ;
169- uint64_t cr3 ;
170- uint64_t brk ;
171- bool running ;
172- } task_snapshot_t ;
173- bool task_snapshot_at (int idx , task_snapshot_t * out );
62+ // Вспомогательный макрос для FPU-контекста, который у вас используется в ядре
63+ #define task_fpu_area (t ) (void*)(((uint64_t)(t)->fpu_state + 15) & ~(uint64_t)15)
17464
175- #endif
65+ #endif /* TASK_H */
0 commit comments