1 #ifndef __LUNAIX_PROCESS_H
2 #define __LUNAIX_PROCESS_H
4 #include <lunaix/clock.h>
5 #include <lunaix/ds/waitq.h>
7 #include <lunaix/iopoll.h>
8 #include <lunaix/mm/mm.h>
9 #include <lunaix/mm/page.h>
10 #include <lunaix/mm/region.h>
11 #include <lunaix/signal.h>
12 #include <lunaix/timer.h>
13 #include <lunaix/types.h>
14 #include <lunaix/spike.h>
15 #include <lunaix/pcontext.h>
24 Group Dt: whether this process is terminated.
44 #define PS_GrBP (PS_PAUSED | PS_BLOCKED | PS_STOPPED)
45 #define PS_GrDT (PS_TERMNAT | PS_DESTROY)
46 #define PS_Rn (PS_RUNNING | PS_CREATED)
48 #define proc_terminated(proc) (((proc)->state) & PS_GrDT)
49 #define proc_hanged(proc) (((proc)->state) & PS_BLOCKED)
50 #define proc_runnable(proc) (!(proc)->state || !(((proc)->state) & ~PS_Rn))
53 #define TH_DETACHED 0b0001
55 #define thread_detached(th) ((th)->flags & TH_DETACHED)
56 #define detach_thread(th) ((th)->flags |= TH_DETACHED)
63 isr_param* saved_ictx;
64 } __attribute__((packed));
70 struct llist_header sleepers;
78 Any change to *critical section*, including layout, size
79 must be reflected in arch/i386/interrupt.S.inc to avoid
86 }; // *critical section
98 ptr_t kstack; // process local kernel stack
99 struct mm_region* ustack; // process local user stack (NULL for kernel thread)
104 struct proc_info* process;
105 struct llist_header proc_sibs; // sibling to process-local threads
106 struct llist_header sched_sibs; // sibling to scheduler (global) threads
107 struct sigctx sigctx;
113 // active thread, must be at the very beginning
114 struct thread* th_active;
116 struct llist_header threads;
119 struct llist_header tasks;
121 struct llist_header siblings;
122 struct llist_header children;
123 struct llist_header grp_member;
126 struct proc_info* parent;
136 struct sigregister* sigreg;
137 struct v_fdtable* fdtable;
144 struct iopoll pollctx;
147 extern volatile struct proc_info* __current;
148 extern volatile struct thread* current_thread;
151 * @brief Check if current process belong to kernel itself
154 #define kernel_process(proc) (!(proc)->pid)
156 #define resume_thread(th) (th)->state = PS_READY
157 #define pause_thread(th) (th)->state = PS_PAUSED
158 #define block_thread(th) (th)->state = PS_BLOCKED
160 static inline void must_inline
161 set_current_executing(struct thread* thread)
163 current_thread = thread;
164 __current = thread->process;
167 static inline struct proc_mm*
168 vmspace(struct proc_info* proc)
174 vmroot(struct proc_info* proc)
176 return proc->mm->vmroot;
179 static inline vm_regions_t*
180 vmregions(struct proc_info* proc)
182 return &proc->mm->regions;
186 block_current_thread()
188 block_thread(current_thread);
192 pause_current_thread()
194 pause_thread(current_thread);
198 resume_current_thread()
200 resume_thread(current_thread);
203 static inline int syscall_result(int retval) {
204 return (current_thread->syscall_ret = retval);
208 * @brief Spawn a process with arbitary entry point.
209 * The inherit priviledge level is deduced automatically
210 * from the given entry point
212 * @param created returned created main thread
213 * @param entry entry point
214 * @param with_ustack whether to pre-allocate a user stack with it
218 spawn_process(struct thread** created, ptr_t entry, bool with_ustack);
221 * @brief Spawn a process that housing a given executable image as well as
222 * program argument and environment setting
224 * @param created returned created main thread
225 * @param path file system path to executable
226 * @param argv arguments passed to executable
227 * @param envp environment variables passed to executable
231 spawn_process_usr(struct thread** created, char* path,
232 const char** argv, const char** envp);
235 * @brief 分配并初始化一个进程控制块
237 * @return struct proc_info*
248 init_proc_user_space(struct proc_info* pcb);
251 * @brief 向系统发布一个进程,使其可以被调度。
256 commit_process(struct proc_info* process);
259 destroy_process(pid_t pid);
262 delete_process(struct proc_info* proc);
265 * @brief 复制当前进程(LunaixOS的类 fork (unix) 实现)
272 * @brief 创建新进程(LunaixOS的类 CreateProcess (Windows) 实现)
283 terminate_current(int exit_code);
286 terminate_proccess(struct proc_info* proc, int exit_code);
289 orphaned_proc(pid_t pid);
292 get_process(pid_t pid);
295 ========= Thread =========
299 commit_thread(struct thread* thread);
302 alloc_thread(struct proc_info* process);
305 destory_thread(ptr_t vm_mnt, struct thread* thread);
308 terminate_thread(struct thread* thread, ptr_t val);
311 terminate_current_thread(ptr_t val);
314 create_thread(struct proc_info* proc, ptr_t vm_mnt, bool with_ustack);
317 start_thread(struct thread* th, ptr_t vm_mnt, ptr_t entry);
320 spawn_kthread(ptr_t entry) {
321 assert(kernel_process(__current));
323 struct thread* th = create_thread(__current, VMS_SELF, false);
326 start_thread(th, VMS_SELF, entry);
330 exit_thread(void* val);
333 thread_release_mem(struct thread* thread, ptr_t vm_mnt);
336 ========= Signal =========
339 #define pending_sigs(thread) ((thread)->sigctx.sig_pending)
340 #define raise_signal(thread, sig) sigset_add(pending_sigs(thread), sig)
341 #define sigact_of(proc, sig) ((proc)->sigreg->signals[(sig)])
342 #define set_sigact(proc, sig, sigact) ((proc)->sigreg->signals[(sig)] = (sigact))
344 static inline struct sigact*
345 active_signal(struct thread* thread) {
346 struct sigctx* sigctx = &thread->sigctx;
347 struct sigregister* sigreg = thread->process->sigreg;
348 return sigreg->signals[sigctx->sig_active];
352 sigactive_push(struct thread* thread, int active_sig) {
353 struct sigctx* sigctx = &thread->sigctx;
354 int prev_active = sigctx->sig_active;
356 assert(sigact_of(thread->process, active_sig));
358 sigctx->sig_order[active_sig] = prev_active;
359 sigctx->sig_active = active_sig;
363 sigactive_pop(struct thread* thread) {
364 struct sigctx* sigctx = &thread->sigctx;
365 int active_sig = sigctx->sig_active;
367 sigctx->sig_active = sigctx->sig_order[active_sig];
368 sigctx->sig_order[active_sig] = active_sig;
372 proc_setsignal(struct proc_info* proc, signum_t signum);
375 thread_setsignal(struct thread* thread, signum_t signum);
378 #endif /* __LUNAIX_PROCESS_H */