Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 #include <sos/assert.h> 019 #include <sos/assert.h>
020 #include <sos/list.h> 020 #include <sos/list.h>
021 #include <sos/kmem_slab.h> 021 #include <sos/kmem_slab.h>
022 #include <hwcore/irq.h> 022 #include <hwcore/irq.h>
023 #include <drivers/bochs.h> 023 #include <drivers/bochs.h>
024 024
025 #include <sos/umem_vmm.h> 025 #include <sos/umem_vmm.h>
026 026
027 #include "process.h" 027 #include "process.h"
028 028
029 #define SOS_PROCESS_MAX_OPENED_FILES 64 !! 029
030 #define SOS_PROCESS_MAX_NAMELEN 32 !! 030 #define SOS_PROCESS_MAX_NAMELEN 32
031 031
032 032
033 033
034 034
035 035
036 036
037 037
038 038
039 struct sos_process 039 struct sos_process
040 { 040 {
041 char name[SOS_PROCESS_MAX_NAMELEN]; 041 char name[SOS_PROCESS_MAX_NAMELEN];
042 042
043 043
044 struct sos_umem_vmm_as *address_space; 044 struct sos_umem_vmm_as *address_space;
045 045
046 046
047 047
048 struct sos_thread *thread_list; 048 struct sos_thread *thread_list;
049 sos_count_t nb_threads; 049 sos_count_t nb_threads;
050 050
051 051
052 sos_count_t ref_cnt; 052 sos_count_t ref_cnt;
053 053
054 <<
055 struct sos_fs_opened_file * fds[SOS_PROCESS_ <<
056 <<
057 <<
058 struct sos_fs_opened_file * root; <<
059 <<
060 <<
061 struct sos_fs_opened_file * cwd; <<
062 <<
063 struct sos_process *prev, *next; 054 struct sos_process *prev, *next;
064 }; 055 };
065 056
066 057
067 058
068 static struct sos_process *process_list = NULL 059 static struct sos_process *process_list = NULL;
069 060
070 061
071 062
072 struct sos_kslab_cache *cache_struct_process; 063 struct sos_kslab_cache *cache_struct_process;
073 064
074 065
075 066
076 067
077 068
078 void sos_process_dumplist(void) !! 069 void sos_process_dumplist()
079 { 070 {
080 struct sos_thread * cur_thr = sos_thread_get 071 struct sos_thread * cur_thr = sos_thread_get_current();
081 struct sos_process * proc; 072 struct sos_process * proc;
082 int nb_procs; 073 int nb_procs;
083 074
084 sos_bochs_printf("<ps>\n"); 075 sos_bochs_printf("<ps>\n");
085 list_foreach(process_list, proc, nb_procs) 076 list_foreach(process_list, proc, nb_procs)
086 { 077 {
087 struct sos_thread * thr; 078 struct sos_thread * thr;
088 int nb_thrs; 079 int nb_thrs;
089 080
090 sos_bochs_printf(" proc@%p: '%s', %d th 081 sos_bochs_printf(" proc@%p: '%s', %d threads, %d refs\n",
091 proc, proc->name?proc-> 082 proc, proc->name?proc->name:"(none)",
092 proc->nb_threads, proc- 083 proc->nb_threads, proc->ref_cnt);
093 084
094 list_foreach_forward_named(proc->thread_ 085 list_foreach_forward_named(proc->thread_list, thr, nb_thrs,
095 prev_in_proce 086 prev_in_process, next_in_process)
096 { 087 {
097 if (thr == cur_thr) 088 if (thr == cur_thr)
098 sos_bochs_printf(" thr@%p: [CUR 089 sos_bochs_printf(" thr@%p: [CURRENT]\n", thr);
099 else 090 else
100 sos_bochs_printf(" thr@%p: %cst 091 sos_bochs_printf(" thr@%p: %cstate=%d eip=%p\n",
101 thr, 092 thr,
102 sos_cpu_context_i 093 sos_cpu_context_is_in_user_mode(thr->cpu_state)?'u':'k',
103 thr->state, 094 thr->state,
104 (void*)sos_cpu_co 095 (void*)sos_cpu_context_get_PC(thr->cpu_state));
105 } 096 }
106 } 097 }
107 sos_bochs_printf(" ======= %d processes === 098 sos_bochs_printf(" ======= %d processes =======\n", nb_procs);
108 sos_bochs_printf("</ps>\n"); 099 sos_bochs_printf("</ps>\n");
109 } 100 }
110 101
111 102
112 sos_ret_t sos_process_subsystem_setup() 103 sos_ret_t sos_process_subsystem_setup()
113 { 104 {
114 105
115 cache_struct_process = sos_kmem_cache_create 106 cache_struct_process = sos_kmem_cache_create("struct_process",
116 107 sizeof(struct sos_process),
117 108 3,
118 109 0,
119 110 SOS_KSLAB_CREATE_MAP
120 111 | SOS_KSLAB_CREATE_ZERO);
121 if (! cache_struct_process) 112 if (! cache_struct_process)
122 return -SOS_ENOMEM; 113 return -SOS_ENOMEM;
123 114
124 return SOS_OK; 115 return SOS_OK;
125 } 116 }
126 117
127 118
128 struct sos_process *sos_process_create(const c 119 struct sos_process *sos_process_create(const char *name,
129 sos_boo 120 sos_bool_t do_copy_current_process)
130 { 121 {
131 sos_ret_t retval = SOS_OK; <<
132 sos_ui32_t flags; 122 sos_ui32_t flags;
133 struct sos_process *proc; 123 struct sos_process *proc;
134 124
135 <<
136 proc = (struct sos_process*) sos_kmem_cache_ 125 proc = (struct sos_process*) sos_kmem_cache_alloc(cache_struct_process, 0);
137 if (! proc) 126 if (! proc)
138 return NULL; 127 return NULL;
139 128
140 129
141 130
142 131
143 <<
144 if (do_copy_current_process) <<
145 { <<
146 struct sos_process * myself = sos_thread <<
147 int fd; <<
148 <<
149 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENE <<
150 if (NULL != myself->fds[fd]) <<
151 { <<
152 retval = sos_fs_duplicate_opened_f <<
153 <<
154 <<
155 if (SOS_OK != retval) <<
156 goto end_create_proc; <<
157 } <<
158 <<
159 retval = sos_fs_duplicate_opened_file(my <<
160 pr <<
161 & <<
162 if (SOS_OK != retval) <<
163 goto end_create_proc; <<
164 <<
165 retval = sos_fs_duplicate_opened_file(my <<
166 pr <<
167 & <<
168 if (SOS_OK != retval) <<
169 goto end_create_proc; <<
170 } <<
171 <<
172 if (do_copy_current_process) 132 if (do_copy_current_process)
173 proc->address_space = sos_umem_vmm_duplica 133 proc->address_space = sos_umem_vmm_duplicate_current_thread_as(proc);
174 else 134 else
175 proc->address_space = sos_umem_vmm_create_ 135 proc->address_space = sos_umem_vmm_create_empty_as(proc);
176 136
177 if (NULL == proc->address_space) 137 if (NULL == proc->address_space)
178 { 138 {
179 139
180 retval = -SOS_ENOMEM; !! 140 sos_kmem_cache_free((sos_vaddr_t)proc);
181 goto end_create_proc; !! 141 return NULL;
182 } 142 }
183 143
184 if (!name) 144 if (!name)
185 { 145 {
186 struct sos_thread * cur_thr = sos_thread 146 struct sos_thread * cur_thr = sos_thread_get_current();
187 if (do_copy_current_process) 147 if (do_copy_current_process)
188 name = cur_thr->process->name; 148 name = cur_thr->process->name;
189 else 149 else
190 name = "[UNNAMED]"; 150 name = "[UNNAMED]";
191 } 151 }
192 152
193 strzcpy(proc->name, name, SOS_PROCESS_MAX_NA 153 strzcpy(proc->name, name, SOS_PROCESS_MAX_NAMELEN);
194 154
195 155
196 sos_disable_IRQs(flags); 156 sos_disable_IRQs(flags);
197 list_add_tail(process_list, proc); 157 list_add_tail(process_list, proc);
198 sos_restore_IRQs(flags); 158 sos_restore_IRQs(flags);
199 159
200 160
201 proc->ref_cnt = 1; 161 proc->ref_cnt = 1;
202 <<
203 end_create_proc: <<
204 if (SOS_OK != retval) <<
205 { <<
206 int fd; <<
207 <<
208 <<
209 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENE <<
210 if (NULL != proc->fds[fd]) <<
211 { <<
212 sos_fs_close(proc->fds[fd]); <<
213 proc->fds[fd] = NULL; <<
214 } <<
215 <<
216 if (proc->root) <<
217 sos_fs_close(proc->root); <<
218 if (proc->cwd) <<
219 sos_fs_close(proc->cwd); <<
220 proc->root = proc->cwd = NULL; <<
221 <<
222 sos_kmem_cache_free((sos_vaddr_t) proc); <<
223 proc = NULL; <<
224 } <<
225 <<
226 return proc; 162 return proc;
227 } 163 }
228 164
229 165
230 inline 166 inline
231 sos_ret_t sos_process_ref(struct sos_process * 167 sos_ret_t sos_process_ref(struct sos_process *proc)
232 { 168 {
233 sos_ui32_t flags; 169 sos_ui32_t flags;
234 sos_disable_IRQs(flags); 170 sos_disable_IRQs(flags);
235 proc->ref_cnt ++; 171 proc->ref_cnt ++;
236 sos_restore_IRQs(flags); 172 sos_restore_IRQs(flags);
237 return SOS_OK; 173 return SOS_OK;
238 } 174 }
239 175
240 176
241 sos_count_t sos_process_get_nb_threads(const s 177 sos_count_t sos_process_get_nb_threads(const struct sos_process *proc)
242 { 178 {
243 sos_count_t retval; 179 sos_count_t retval;
244 sos_ui32_t flags; 180 sos_ui32_t flags;
245 sos_disable_IRQs(flags); 181 sos_disable_IRQs(flags);
246 retval = proc->nb_threads; 182 retval = proc->nb_threads;
247 sos_restore_IRQs(flags); 183 sos_restore_IRQs(flags);
248 return retval; 184 return retval;
249 } 185 }
250 186
251 187
252 struct sos_mm_context * 188 struct sos_mm_context *
253 sos_process_get_mm_context(const struct sos_pr 189 sos_process_get_mm_context(const struct sos_process *proc)
254 { 190 {
255 return sos_umem_vmm_get_mm_context(proc->add 191 return sos_umem_vmm_get_mm_context(proc->address_space);
256 } 192 }
257 193
258 194
259 struct sos_umem_vmm_as * 195 struct sos_umem_vmm_as *
260 sos_process_get_address_space(const struct sos 196 sos_process_get_address_space(const struct sos_process *proc)
261 { 197 {
262 return proc->address_space; 198 return proc->address_space;
263 } 199 }
264 200
265 201
266 sos_ret_t sos_process_set_address_space(struct 202 sos_ret_t sos_process_set_address_space(struct sos_process *proc,
267 struct 203 struct sos_umem_vmm_as *new_as)
268 { 204 {
269 int fd; <<
270 <<
271 <<
272 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENED_FI <<
273 if ( (NULL != proc->fds[fd]) <<
274 && (proc->fds[fd]->open_flags & SOS_F <<
275 { <<
276 sos_fs_close(proc->fds[fd]); <<
277 proc->fds[fd] = NULL; <<
278 } <<
279 <<
280 if (proc->address_space) 205 if (proc->address_space)
281 { 206 {
282 sos_ret_t retval = sos_umem_vmm_delete_a 207 sos_ret_t retval = sos_umem_vmm_delete_as(proc->address_space);
283 if (SOS_OK != retval) 208 if (SOS_OK != retval)
284 return retval; 209 return retval;
285 } 210 }
286 211
287 proc->address_space = new_as; 212 proc->address_space = new_as;
288 return SOS_OK; 213 return SOS_OK;
289 } 214 }
290 215
291 216
292 struct sos_fs_opened_file * <<
293 sos_process_get_root(const struct sos_process <<
294 { <<
295 return proc->root; <<
296 } <<
297 <<
298 <<
299 struct sos_fs_opened_file * <<
300 sos_process_get_cwd(const struct sos_process * <<
301 { <<
302 return proc->cwd; <<
303 } <<
304 <<
305 <<
306 struct sos_fs_opened_file * <<
307 sos_process_get_opened_file(const struct sos_p <<
308 int fd) <<
309 { <<
310 if ((fd < 0) || (fd >= SOS_PROCESS_MAX_OPENE <<
311 return NULL; <<
312 return proc->fds[fd]; <<
313 } <<
314 <<
315 <<
316 sos_ret_t <<
317 sos_process_chroot(struct sos_process *proc, <<
318 struct sos_fs_opened_file * <<
319 struct sos_fs_opened_file * <<
320 { <<
321 *old_root = proc->root; <<
322 proc->root = new_root; <<
323 <<
324 return SOS_OK; <<
325 } <<
326 <<
327 <<
328 sos_ret_t <<
329 sos_process_chdir(struct sos_process *proc, <<
330 struct sos_fs_opened_file * <<
331 struct sos_fs_opened_file ** <<
332 { <<
333 *old_cwd = proc->cwd; <<
334 proc->cwd = new_cwd; <<
335 <<
336 return SOS_OK; <<
337 } <<
338 <<
339 <<
340 sos_ret_t <<
341 sos_process_register_opened_file(struct sos_pr <<
342 struct sos_fs <<
343 { <<
344 int i; <<
345 for (i = 0 ; i < SOS_PROCESS_MAX_OPENED_FILE <<
346 if (NULL == proc->fds[i]) <<
347 { <<
348 proc->fds[i] = of; <<
349 return i; <<
350 } <<
351 <<
352 return -SOS_EMFILE; <<
353 } <<
354 <<
355 <<
356 sos_ret_t <<
357 sos_process_unregister_opened_file(struct sos_ <<
358 int fd) <<
359 { <<
360 if ((fd < 0) || (fd >= SOS_PROCESS_MAX_OPENE <<
361 return -SOS_EBADF; <<
362 <<
363 proc->fds[fd] = NULL; <<
364 return SOS_OK; <<
365 } <<
366 <<
367 <<
368 <<
369 217
370 218
371 219
372 220
373 221
374 sos_ret_t sos_process_register_thread(struct s 222 sos_ret_t sos_process_register_thread(struct sos_process *in_proc,
375 struct s 223 struct sos_thread *thr)
376 { 224 {
377 sos_ui32_t flags; 225 sos_ui32_t flags;
378 226
379 227
380 SOS_ASSERT_FATAL(in_proc->ref_cnt > 0); 228 SOS_ASSERT_FATAL(in_proc->ref_cnt > 0);
381 229
382 230
383 231
384 SOS_ASSERT_FATAL(thr->state == SOS_THR_CREAT 232 SOS_ASSERT_FATAL(thr->state == SOS_THR_CREATED);
385 233
386 234
387 thr->process = in_proc; 235 thr->process = in_proc;
388 236
389 237
390 sos_process_ref(in_proc); 238 sos_process_ref(in_proc);
391 239
392 240
393 sos_disable_IRQs(flags); 241 sos_disable_IRQs(flags);
394 list_add_tail_named(in_proc->thread_list, th 242 list_add_tail_named(in_proc->thread_list, thr,
395 prev_in_process, next_in 243 prev_in_process, next_in_process);
396 in_proc->nb_threads ++; 244 in_proc->nb_threads ++;
397 sos_restore_IRQs(flags); 245 sos_restore_IRQs(flags);
398 246
399 return SOS_OK; 247 return SOS_OK;
400 } 248 }
401 249
402 250
403 251
404 252
405 sos_ret_t sos_process_unref(struct sos_process 253 sos_ret_t sos_process_unref(struct sos_process *proc)
406 { 254 {
407 sos_ui32_t flags; 255 sos_ui32_t flags;
408 sos_ret_t retval; 256 sos_ret_t retval;
409 int fd; <<
410 257
411 SOS_ASSERT_FATAL(proc->ref_cnt > 0); 258 SOS_ASSERT_FATAL(proc->ref_cnt > 0);
412 259
413 sos_disable_IRQs(flags); 260 sos_disable_IRQs(flags);
414 proc->ref_cnt --; 261 proc->ref_cnt --;
415 if (proc->ref_cnt > 0) 262 if (proc->ref_cnt > 0)
416 { 263 {
417 sos_restore_IRQs(flags); 264 sos_restore_IRQs(flags);
418 return -SOS_EBUSY; 265 return -SOS_EBUSY;
419 } 266 }
420 list_delete(process_list, proc); 267 list_delete(process_list, proc);
421 sos_restore_IRQs(flags); 268 sos_restore_IRQs(flags);
422 <<
423 <<
424 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENED_FI <<
425 if (NULL != proc->fds[fd]) <<
426 { <<
427 sos_fs_close(proc->fds[fd]); <<
428 proc->fds[fd] = NULL; <<
429 } <<
430 <<
431 sos_fs_close(proc->root); <<
432 sos_fs_close(proc->cwd); <<
433 proc->root = proc->cwd = NULL; <<
434 269
435 270
436 retval = sos_umem_vmm_delete_as(proc->addres 271 retval = sos_umem_vmm_delete_as(proc->address_space);
437 SOS_ASSERT_FATAL(SOS_OK == retval); 272 SOS_ASSERT_FATAL(SOS_OK == retval);
438 273
439 274
440 sos_kmem_cache_free((sos_vaddr_t)proc); 275 sos_kmem_cache_free((sos_vaddr_t)proc);
441 276
442 return SOS_OK; 277 return SOS_OK;
443 } 278 }
444 279
445 280
446 sos_ret_t sos_process_unregister_thread(struct 281 sos_ret_t sos_process_unregister_thread(struct sos_thread *thr)
447 { 282 {
448 sos_ui32_t flags; 283 sos_ui32_t flags;
449 struct sos_process * in_proc = thr->process; 284 struct sos_process * in_proc = thr->process;
450 285
451 SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBI 286 SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBIE);
452 287
453 288
454 thr->process = NULL; 289 thr->process = NULL;
455 sos_disable_IRQs(flags); 290 sos_disable_IRQs(flags);
456 list_delete_named(in_proc->thread_list, thr, 291 list_delete_named(in_proc->thread_list, thr,
457 prev_in_process, next_in_p 292 prev_in_process, next_in_process);
458 SOS_ASSERT_FATAL(in_proc->nb_threads > 0); 293 SOS_ASSERT_FATAL(in_proc->nb_threads > 0);
459 in_proc->nb_threads --; 294 in_proc->nb_threads --;
460 sos_restore_IRQs(flags); 295 sos_restore_IRQs(flags);
461 296
462 297
463 sos_process_unref(in_proc); 298 sos_process_unref(in_proc);
464 299
465 return SOS_OK; 300 return SOS_OK;
466 } 301 }
467 302
468 303
469 sos_ret_t sos_process_set_name(struct sos_proc 304 sos_ret_t sos_process_set_name(struct sos_process * proc,
470 const char * ne 305 const char * new_name)
471 { 306 {
472 strzcpy(proc->name, new_name, SOS_PROCESS_MA 307 strzcpy(proc->name, new_name, SOS_PROCESS_MAX_NAMELEN);
473 return SOS_OK; 308 return SOS_OK;
474 } 309 }