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
125 proc = (struct sos_process*) sos_kmem_cache_ 135 proc = (struct sos_process*) sos_kmem_cache_alloc(cache_struct_process, 0);
126 if (! proc) 136 if (! proc)
127 return NULL; 137 return NULL;
128 138
129 139
130 140
131 141
132 !! 142
133 proc->mm_context = sos_mm_context_create(); !! 143 if (do_copy_current_process)
134 if (NULL == proc->mm_context) !! 144 {
>> 145 struct sos_process * myself = sos_thread_get_current()->process;
>> 146 int fd;
>> 147
>> 148 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENED_FILES ; fd++)
>> 149 if (NULL != myself->fds[fd])
>> 150 {
>> 151 retval = sos_fs_duplicate_opened_file(myself->fds[fd],
>> 152 proc,
>> 153 & proc->fds[fd]);
>> 154 if (SOS_OK != retval)
>> 155 goto end_create_proc;
>> 156 }
>> 157
>> 158 retval = sos_fs_duplicate_opened_file(myself->root,
>> 159 proc,
>> 160 & proc->root);
>> 161 if (SOS_OK != retval)
>> 162 goto end_create_proc;
>> 163
>> 164 retval = sos_fs_duplicate_opened_file(myself->cwd,
>> 165 proc,
>> 166 & proc->cwd);
>> 167 if (SOS_OK != retval)
>> 168 goto end_create_proc;
>> 169 }
>> 170
>> 171 if (do_copy_current_process)
>> 172 proc->address_space = sos_umem_vmm_duplicate_current_thread_as(proc);
>> 173 else
>> 174 proc->address_space = sos_umem_vmm_create_empty_as(proc);
>> 175
>> 176 if (NULL == proc->address_space)
135 { 177 {
136 178
137 sos_kmem_cache_free((sos_vaddr_t)proc); !! 179 retval = -SOS_ENOMEM;
138 return NULL; !! 180 goto end_create_proc;
139 } 181 }
140 182
141 if (!name) 183 if (!name)
142 { 184 {
>> 185 struct sos_thread * cur_thr = sos_thread_get_current();
>> 186 if (do_copy_current_process)
>> 187 name = cur_thr->process->name;
>> 188 else
143 name = "[UNNAMED]"; 189 name = "[UNNAMED]";
144 } 190 }
145 191
146 strzcpy(proc->name, name, SOS_PROCESS_MAX_NA 192 strzcpy(proc->name, name, SOS_PROCESS_MAX_NAMELEN);
147 193
148 194
149 sos_disable_IRQs(flags); 195 sos_disable_IRQs(flags);
150 list_add_tail(process_list, proc); 196 list_add_tail(process_list, proc);
151 sos_restore_IRQs(flags); 197 sos_restore_IRQs(flags);
152 198
153 199
154 proc->ref_cnt = 1; 200 proc->ref_cnt = 1;
>> 201
>> 202 end_create_proc:
>> 203 if (SOS_OK != retval)
>> 204 {
>> 205 int fd;
>> 206
>> 207
>> 208 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENED_FILES ; fd++)
>> 209 if (NULL != proc->fds[fd])
>> 210 sos_fs_close(proc->fds[fd]);
>> 211
>> 212 if (proc->root)
>> 213 sos_fs_close(proc->root);
>> 214 if (proc->cwd)
>> 215 sos_fs_close(proc->cwd);
>> 216
>> 217 sos_kmem_cache_free((sos_vaddr_t) proc);
>> 218 proc = NULL;
>> 219 }
>> 220
155 return proc; 221 return proc;
156 } 222 }
157 223
158 224
159 inline 225 inline
160 sos_ret_t sos_process_ref(struct sos_process * 226 sos_ret_t sos_process_ref(struct sos_process *proc)
161 { 227 {
162 sos_ui32_t flags; 228 sos_ui32_t flags;
163 sos_disable_IRQs(flags); 229 sos_disable_IRQs(flags);
164 proc->ref_cnt ++; 230 proc->ref_cnt ++;
165 sos_restore_IRQs(flags); 231 sos_restore_IRQs(flags);
166 return SOS_OK; 232 return SOS_OK;
167 } 233 }
168 234
169 235
170 sos_count_t sos_process_get_nb_threads(const s 236 sos_count_t sos_process_get_nb_threads(const struct sos_process *proc)
171 { 237 {
172 sos_count_t retval; 238 sos_count_t retval;
173 sos_ui32_t flags; 239 sos_ui32_t flags;
174 sos_disable_IRQs(flags); 240 sos_disable_IRQs(flags);
175 retval = proc->nb_threads; 241 retval = proc->nb_threads;
176 sos_restore_IRQs(flags); 242 sos_restore_IRQs(flags);
177 return retval; 243 return retval;
178 } 244 }
179 245
180 246
181 struct sos_mm_context * 247 struct sos_mm_context *
182 sos_process_get_mm_context(const struct sos_pr 248 sos_process_get_mm_context(const struct sos_process *proc)
183 { 249 {
184 return proc->mm_context; !! 250 return sos_umem_vmm_get_mm_context(proc->address_space);
>> 251 }
>> 252
>> 253
>> 254 struct sos_umem_vmm_as *
>> 255 sos_process_get_address_space(const struct sos_process *proc)
>> 256 {
>> 257 return proc->address_space;
>> 258 }
>> 259
>> 260
>> 261 sos_ret_t sos_process_set_address_space(struct sos_process *proc,
>> 262 struct sos_umem_vmm_as *new_as)
>> 263 {
>> 264 int fd;
>> 265
>> 266
>> 267 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENED_FILES ; fd++)
>> 268 if ( (NULL != proc->fds[fd])
>> 269 && (! (proc->fds[fd]->open_flags & SOS_FS_OPEN_KEEPONEXEC)) )
>> 270 sos_fs_close(proc->fds[fd]);
>> 271
>> 272 if (proc->address_space)
>> 273 {
>> 274 sos_ret_t retval = sos_umem_vmm_delete_as(proc->address_space);
>> 275 if (SOS_OK != retval)
>> 276 return retval;
>> 277 }
>> 278
>> 279 proc->address_space = new_as;
>> 280 return SOS_OK;
>> 281 }
>> 282
>> 283
>> 284 struct sos_fs_opened_file *
>> 285 sos_process_get_root(const struct sos_process *proc)
>> 286 {
>> 287 return proc->root;
185 } 288 }
186 289
187 290
>> 291 struct sos_fs_opened_file *
>> 292 sos_process_get_cwd(const struct sos_process *proc)
>> 293 {
>> 294 return proc->cwd;
>> 295 }
>> 296
>> 297
>> 298 struct sos_fs_opened_file *
>> 299 sos_process_get_opened_file(const struct sos_process *proc,
>> 300 int fd)
>> 301 {
>> 302 if ((fd < 0) || (fd >= SOS_PROCESS_MAX_OPENED_FILES))
>> 303 return NULL;
>> 304 return proc->fds[fd];
>> 305 }
>> 306
>> 307
>> 308 sos_ret_t
>> 309 sos_process_chroot(struct sos_process *proc,
>> 310 struct sos_fs_opened_file * new_root,
>> 311 struct sos_fs_opened_file ** old_root)
>> 312 {
>> 313 *old_root = proc->root;
>> 314 proc->root = new_root;
>> 315
>> 316 return SOS_OK;
>> 317 }
>> 318
>> 319
>> 320 sos_ret_t
>> 321 sos_process_chdir(struct sos_process *proc,
>> 322 struct sos_fs_opened_file * new_cwd,
>> 323 struct sos_fs_opened_file ** old_cwd)
>> 324 {
>> 325 *old_cwd = proc->cwd;
>> 326 proc->cwd = new_cwd;
>> 327
>> 328 return SOS_OK;
>> 329 }
>> 330
>> 331
>> 332 sos_ret_t
>> 333 sos_process_register_opened_file(struct sos_process *proc,
>> 334 struct sos_fs_opened_file * of)
>> 335 {
>> 336 int i;
>> 337 for (i = 0 ; i < SOS_PROCESS_MAX_OPENED_FILES ; i++)
>> 338 if (NULL == proc->fds[i])
>> 339 {
>> 340 proc->fds[i] = of;
>> 341 return i;
>> 342 }
>> 343
>> 344 return -SOS_EMFILE;
>> 345 }
>> 346
>> 347
>> 348 sos_ret_t
>> 349 sos_process_unregister_opened_file(struct sos_process *proc,
>> 350 int fd)
>> 351 {
>> 352 if ((fd < 0) || (fd >= SOS_PROCESS_MAX_OPENED_FILES))
>> 353 return -SOS_EBADF;
>> 354
>> 355 proc->fds[fd] = NULL;
>> 356 return SOS_OK;
>> 357 }
>> 358
>> 359
>> 360
188 361
189 362
190 363
191 364
192 365
193 sos_ret_t sos_process_register_thread(struct s 366 sos_ret_t sos_process_register_thread(struct sos_process *in_proc,
194 struct s 367 struct sos_thread *thr)
195 { 368 {
196 sos_ui32_t flags; 369 sos_ui32_t flags;
197 370
198 371
199 SOS_ASSERT_FATAL(in_proc->ref_cnt > 0); 372 SOS_ASSERT_FATAL(in_proc->ref_cnt > 0);
200 373
201 374
202 375
203 SOS_ASSERT_FATAL(thr->state == SOS_THR_CREAT 376 SOS_ASSERT_FATAL(thr->state == SOS_THR_CREATED);
204 377
205 378
206 thr->process = in_proc; 379 thr->process = in_proc;
207 380
208 381
209 sos_process_ref(in_proc); 382 sos_process_ref(in_proc);
210 383
211 384
212 sos_disable_IRQs(flags); 385 sos_disable_IRQs(flags);
213 list_add_tail_named(in_proc->thread_list, th 386 list_add_tail_named(in_proc->thread_list, thr,
214 prev_in_process, next_in 387 prev_in_process, next_in_process);
215 in_proc->nb_threads ++; 388 in_proc->nb_threads ++;
216 sos_restore_IRQs(flags); 389 sos_restore_IRQs(flags);
217 390
218 return SOS_OK; 391 return SOS_OK;
219 } 392 }
220 393
221 394
222 395
223 396
224 sos_ret_t sos_process_unref(struct sos_process 397 sos_ret_t sos_process_unref(struct sos_process *proc)
225 { 398 {
226 sos_ui32_t flags; 399 sos_ui32_t flags;
227 sos_ret_t retval; 400 sos_ret_t retval;
>> 401 int fd;
228 402
229 SOS_ASSERT_FATAL(proc->ref_cnt > 0); 403 SOS_ASSERT_FATAL(proc->ref_cnt > 0);
230 404
231 sos_disable_IRQs(flags); 405 sos_disable_IRQs(flags);
232 proc->ref_cnt --; 406 proc->ref_cnt --;
233 if (proc->ref_cnt > 0) 407 if (proc->ref_cnt > 0)
234 { 408 {
235 sos_restore_IRQs(flags); 409 sos_restore_IRQs(flags);
236 return -SOS_EBUSY; 410 return -SOS_EBUSY;
237 } 411 }
238 list_delete(process_list, proc); 412 list_delete(process_list, proc);
239 sos_restore_IRQs(flags); 413 sos_restore_IRQs(flags);
240 414
241 !! 415
242 retval = sos_mm_context_unref(proc->mm_conte !! 416 for (fd = 0 ; fd < SOS_PROCESS_MAX_OPENED_FILES ; fd++)
>> 417 if (NULL != proc->fds[fd])
>> 418 sos_fs_close(proc->fds[fd]);
>> 419
>> 420 sos_fs_close(proc->root);
>> 421 sos_fs_close(proc->cwd);
>> 422
>> 423
>> 424 retval = sos_umem_vmm_delete_as(proc->address_space);
243 SOS_ASSERT_FATAL(SOS_OK == retval); 425 SOS_ASSERT_FATAL(SOS_OK == retval);
244 426
245 427
246 sos_kmem_cache_free((sos_vaddr_t)proc); 428 sos_kmem_cache_free((sos_vaddr_t)proc);
247 429
248 return SOS_OK; 430 return SOS_OK;
249 } 431 }
250 432
251 433
252 sos_ret_t sos_process_unregister_thread(struct 434 sos_ret_t sos_process_unregister_thread(struct sos_thread *thr)
253 { 435 {
254 sos_ui32_t flags; 436 sos_ui32_t flags;
255 struct sos_process * in_proc = thr->process; 437 struct sos_process * in_proc = thr->process;
256 438
257 SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBI 439 SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBIE);
258 440
259 441
260 thr->process = NULL; 442 thr->process = NULL;
261 sos_disable_IRQs(flags); 443 sos_disable_IRQs(flags);
262 list_delete_named(in_proc->thread_list, thr, 444 list_delete_named(in_proc->thread_list, thr,
263 prev_in_process, next_in_p 445 prev_in_process, next_in_process);
264 SOS_ASSERT_FATAL(in_proc->nb_threads > 0); 446 SOS_ASSERT_FATAL(in_proc->nb_threads > 0);
265 in_proc->nb_threads --; 447 in_proc->nb_threads --;
266 sos_restore_IRQs(flags); 448 sos_restore_IRQs(flags);
267 449
268 450
269 sos_process_unref(in_proc); 451 sos_process_unref(in_proc);
270 452
271 return SOS_OK; 453 return SOS_OK;
272 } 454 }
273 455
274 456
275 sos_ret_t sos_process_set_name(struct sos_proc 457 sos_ret_t sos_process_set_name(struct sos_process * proc,
276 const char * ne 458 const char * new_name)
277 { 459 {
278 strzcpy(proc->name, new_name, SOS_PROCESS_MA 460 strzcpy(proc->name, new_name, SOS_PROCESS_MAX_NAMELEN);
279 return SOS_OK; 461 return SOS_OK;
280 } 462 }