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/pagetable.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/hart_state.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 struct hart_state* saved_hstate;
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
84 struct hart_state* hstate;
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 sigregistry* 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)
170 return proc ? proc->mm : NULL;
174 vmroot(struct proc_info* proc)
176 return proc ? proc->mm->vmroot : 0;
179 static inline vm_regions_t*
180 vmregions(struct proc_info* proc)
182 return proc ? &proc->mm->regions : NULL;
186 static inline unsigned int
187 procvm_asid(struct proc_mm* mm)
189 return mm->proc->pid;
193 block_current_thread()
195 block_thread(current_thread);
199 pause_current_thread()
201 pause_thread(current_thread);
205 resume_current_thread()
207 resume_thread(current_thread);
210 static inline int syscall_result(int retval) {
211 return (current_thread->syscall_ret = retval);
215 * @brief Spawn a process with arbitary entry point.
216 * The inherit priviledge level is deduced automatically
217 * from the given entry point
219 * @param created returned created main thread
220 * @param entry entry point
221 * @param with_ustack whether to pre-allocate a user stack with it
225 spawn_process(struct thread** created, ptr_t entry, bool with_ustack);
228 * @brief Spawn a process that housing a given executable image as well as
229 * program argument and environment setting
231 * @param created returned created main thread
232 * @param path file system path to executable
233 * @param argv arguments passed to executable
234 * @param envp environment variables passed to executable
238 spawn_process_usr(struct thread** created, char* path,
239 const char** argv, const char** envp);
242 * @brief 分配并初始化一个进程控制块
244 * @return struct proc_info*
255 init_proc_user_space(struct proc_info* pcb);
258 * @brief 向系统发布一个进程,使其可以被调度。
263 commit_process(struct proc_info* process);
266 destroy_process(pid_t pid);
269 delete_process(struct proc_info* proc);
272 * @brief 复制当前进程(LunaixOS的类 fork (unix) 实现)
279 * @brief 创建新进程(LunaixOS的类 CreateProcess (Windows) 实现)
290 terminate_current(int exit_code);
293 terminate_proccess(struct proc_info* proc, int exit_code);
296 orphaned_proc(pid_t pid);
299 get_process(pid_t pid);
302 ========= Thread =========
306 commit_thread(struct thread* thread);
309 alloc_thread(struct proc_info* process);
312 destory_thread(struct thread* thread);
315 terminate_thread(struct thread* thread, ptr_t val);
318 terminate_current_thread(ptr_t val);
321 create_thread(struct proc_info* proc, bool with_ustack);
324 start_thread(struct thread* th, ptr_t entry);
327 spawn_kthread(ptr_t entry) {
328 assert(kernel_process(__current));
330 struct thread* th = create_thread(__current, false);
333 start_thread(th, entry);
337 exit_thread(void* val);
340 thread_release_mem(struct thread* thread);
343 ========= Signal =========
346 #define pending_sigs(thread) ((thread)->sigctx.sig_pending)
347 #define raise_signal(thread, sig) sigset_add(pending_sigs(thread), sig)
348 #define sigact_of(proc, sig) ((proc)->sigreg->signals[(sig)])
349 #define set_sigact(proc, sig, sigact) ((proc)->sigreg->signals[(sig)] = (sigact))
351 static inline struct sigact*
352 active_signal(struct thread* thread) {
353 struct sigctx* sigctx = &thread->sigctx;
354 struct sigregistry* sigreg = thread->process->sigreg;
355 return sigreg->signals[sigctx->sig_active];
359 sigactive_push(struct thread* thread, int active_sig) {
360 struct sigctx* sigctx = &thread->sigctx;
361 int prev_active = sigctx->sig_active;
363 assert(sigact_of(thread->process, active_sig));
365 sigctx->sig_order[active_sig] = prev_active;
366 sigctx->sig_active = active_sig;
370 sigactive_pop(struct thread* thread) {
371 struct sigctx* sigctx = &thread->sigctx;
372 int active_sig = sigctx->sig_active;
374 sigctx->sig_active = sigctx->sig_order[active_sig];
375 sigctx->sig_order[active_sig] = active_sig;
379 proc_setsignal(struct proc_info* proc, signum_t signum);
382 thread_setsignal(struct thread* thread, signum_t signum);
385 #endif /* __LUNAIX_PROCESS_H */