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