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