refactor: Optimize the signal context overhead
[lunaix-os.git] / lunaix-os / includes / lunaix / process.h
1 #ifndef __LUNAIX_PROCESS_H
2 #define __LUNAIX_PROCESS_H
3
4 #include <arch/x86/interrupts.h>
5 #include <lunaix/clock.h>
6 #include <lunaix/ds/waitq.h>
7 #include <lunaix/fs.h>
8 #include <lunaix/mm/mm.h>
9 #include <lunaix/mm/region.h>
10 #include <lunaix/signal.h>
11 #include <lunaix/timer.h>
12 #include <lunaix/types.h>
13 #include <stdint.h>
14
15 // 虽然内核不是进程,但为了区分,这里使用Pid=-1来指代内核。这主要是方便物理页所有权检查。
16 #define KERNEL_PID -1
17
18 /*
19     |C|Bk|De|Tn|Pu|Rn|
20          \----/
21             Dt
22
23     Group Dt: whether this process is terminated.
24
25     Rn: Running
26     Tn: Terminated
27     De: Destoryed
28     Pu: Paused
29     Bk: Blocked
30     C : Created
31 */
32
33 #define PS_READY 0
34 #define PS_RUNNING 1
35 #define PS_TERMNAT 2
36 #define PS_DESTROY 4
37 #define PS_PAUSED 8
38 #define PS_BLOCKED 16
39 #define PS_CREATED 32
40
41 #define PS_GrBP (PS_PAUSED | PS_BLOCKED)
42 #define PS_GrDT (PS_TERMNAT | PS_DESTROY)
43
44 #define proc_terminated(proc) (((proc)->state) & PS_GrDT)
45 #define proc_hanged(proc) (((proc)->state) & PS_BLOCKED)
46 #define proc_runnable(proc) (((proc)->state) & PS_PAUSED)
47
48 #define PROC_FINPAUSE 1
49
50 struct sigact
51 {
52     struct sigact* prev;
53     sigset_t sa_mask;
54     void* sa_actor;
55     void* sa_handler;
56     pid_t sender;
57 };
58
59 struct sighail
60 {
61     sigset_t sig_pending;
62     sigset_t sig_mask;
63     struct sigact* inprogress;
64     struct sigact signals[_SIG_NUM];
65 };
66
67 struct proc_sig
68 {
69     int sig_num;
70     void* sigact;
71     void* sighand;
72     isr_param* saved_ictx;
73 } __attribute__((packed));
74
75 struct proc_info
76 {
77     /*
78         Any change to *critical section*, including layout, size
79         must be reflected in kernel/asm/x86/interrupt.S to avoid
80         disaster!
81      */
82
83     /* ---- critical section start ---- */
84
85     pid_t pid;                // offset = 0
86     struct proc_info* parent; // offset = 4
87     isr_param* intr_ctx;      // offset = 8
88     ptr_t ustack_top;         // offset = 84 -> 56 -> 60 -> 12
89     ptr_t page_table;         // offset = 88 -> 60 -> 64 -> 16
90
91     /* ---- critical section end ---- */
92
93     struct llist_header tasks;
94     struct llist_header siblings;
95     struct llist_header children;
96     struct llist_header grp_member;
97     waitq_t waitqueue;
98
99     struct
100     {
101         struct llist_header sleepers;
102         time_t wakeup_time;
103         time_t alarm_time;
104     } sleep;
105
106     struct proc_mm mm;
107     time_t created;
108     u8_t state;
109     int32_t exit_code;
110     int32_t k_status;
111     int flags;
112     struct sighail sigctx;
113     struct v_fdtable* fdtable;
114     struct v_dnode* cwd;
115     pid_t pgid;
116 };
117
118 extern volatile struct proc_info* __current;
119
120 static inline void
121 block_current()
122 {
123     __current->state = PS_BLOCKED;
124 }
125
126 static inline void
127 pause_current()
128 {
129     __current->state = PS_PAUSED;
130 }
131
132 static inline void
133 resume_current()
134 {
135     __current->state = PS_RUNNING;
136 }
137
138 /**
139  * @brief 分配并初始化一个进程控制块
140  *
141  * @return struct proc_info*
142  */
143 struct proc_info*
144 alloc_process();
145
146 /**
147  * @brief 初始化进程用户空间
148  *
149  * @param pcb
150  */
151 void
152 init_proc_user_space(struct proc_info* pcb);
153
154 /**
155  * @brief 向系统发布一个进程,使其可以被调度。
156  *
157  * @param process
158  */
159 void
160 commit_process(struct proc_info* process);
161
162 pid_t
163 destroy_process(pid_t pid);
164
165 void
166 copy_kernel_stack(struct proc_info* proc, ptr_t kstack_from);
167
168 /**
169  * @brief 复制当前进程(LunaixOS的类 fork (unix) 实现)
170  *
171  */
172 pid_t
173 dup_proc();
174
175 /**
176  * @brief 创建新进程(LunaixOS的类 CreateProcess (Windows) 实现)
177  *
178  */
179 void
180 new_proc();
181
182 /**
183  * @brief 终止(退出)当前进程
184  *
185  */
186 void
187 terminate_proc(int exit_code);
188
189 int
190 orphaned_proc(pid_t pid);
191
192 struct proc_info*
193 get_process(pid_t pid);
194
195 void
196 proc_setsignal(struct proc_info* proc, int signum);
197
198 #endif /* __LUNAIX_PROCESS_H */