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