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()
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
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
>> 142
>> 143 if (do_copy_current_process)
>> 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
132 if (do_copy_current_process) 171 if (do_copy_current_process)
133 proc->address_space = sos_umem_vmm_duplica 172 proc->address_space = sos_umem_vmm_duplicate_current_thread_as(proc);
134 else 173 else
135 proc->address_space = sos_umem_vmm_create_ 174 proc->address_space = sos_umem_vmm_create_empty_as(proc);
136 175
137 if (NULL == proc->address_space) 176 if (NULL == proc->address_space)
138 { 177 {
139 178
140 sos_kmem_cache_free((sos_vaddr_t)proc); !! 179 retval = -SOS_ENOMEM;
141 return NULL; !! 180 goto end_create_proc;
142 } 181 }
143 182
144 if (!name) 183 if (!name)
145 { 184 {
146 struct sos_thread * cur_thr = sos_thread 185 struct sos_thread * cur_thr = sos_thread_get_current();
147 if (do_copy_current_process) 186 if (do_copy_current_process)
148 name = cur_thr->process->name; 187 name = cur_thr->process->name;
149 else 188 else
150 name = "[UNNAMED]"; 189 name = "[UNNAMED]";
151 } 190 }
152 191
153 strzcpy(proc->name, name, SOS_PROCESS_MAX_NA 192 strzcpy(proc->name, name, SOS_PROCESS_MAX_NAMELEN);
154 193
155 194
156 sos_disable_IRQs(flags); 195 sos_disable_IRQs(flags);
157 list_add_tail(process_list, proc); 196 list_add_tail(process_list, proc);
158 sos_restore_IRQs(flags); 197 sos_restore_IRQs(flags);
159 198
160 199
161 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
162 return proc; 221 return proc;
163 } 222 }
164 223
165 224
166 inline 225 inline
167 sos_ret_t sos_process_ref(struct sos_process * 226 sos_ret_t sos_process_ref(struct sos_process *proc)
168 { 227 {
169 sos_ui32_t flags; 228 sos_ui32_t flags;
170 sos_disable_IRQs(flags); 229 sos_disable_IRQs(flags);
171 proc->ref_cnt ++; 230 proc->ref_cnt ++;
172 sos_restore_IRQs(flags); 231 sos_restore_IRQs(flags);
173 return SOS_OK; 232 return SOS_OK;
174 } 233 }
175 234
176 235
177 sos_count_t sos_process_get_nb_threads(const s 236 sos_count_t sos_process_get_nb_threads(const struct sos_process *proc)
178 { 237 {
179 sos_count_t retval; 238 sos_count_t retval;
180 sos_ui32_t flags; 239 sos_ui32_t flags;
181 sos_disable_IRQs(flags); 240 sos_disable_IRQs(flags);
182 retval = proc->nb_threads; 241 retval = proc->nb_threads;
183 sos_restore_IRQs(flags); 242 sos_restore_IRQs(flags);
184 return retval; 243 return retval;
185 } 244 }
186 245
187 246
188 struct sos_mm_context * 247 struct sos_mm_context *
189 sos_process_get_mm_context(const struct sos_pr 248 sos_process_get_mm_context(const struct sos_process *proc)
190 { 249 {
191 return sos_umem_vmm_get_mm_context(proc->add 250 return sos_umem_vmm_get_mm_context(proc->address_space);
192 } 251 }
193 252
194 253
195 struct sos_umem_vmm_as * 254 struct sos_umem_vmm_as *
196 sos_process_get_address_space(const struct sos 255 sos_process_get_address_space(const struct sos_process *proc)
197 { 256 {
198 return proc->address_space; 257 return proc->address_space;
199 } 258 }
200 259
201 260
202 sos_ret_t sos_process_set_address_space(struct 261 sos_ret_t sos_process_set_address_space(struct sos_process *proc,
203 struct 262 struct sos_umem_vmm_as *new_as)
204 { 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
205 if (proc->address_space) 272 if (proc->address_space)
206 { 273 {
207 sos_ret_t retval = sos_umem_vmm_delete_a 274 sos_ret_t retval = sos_umem_vmm_delete_as(proc->address_space);
208 if (SOS_OK != retval) 275 if (SOS_OK != retval)
209 return retval; 276 return retval;
210 } 277 }
211 278
212 proc->address_space = new_as; 279 proc->address_space = new_as;
213 return SOS_OK; 280 return SOS_OK;
214 } 281 }
215 282
216 283
>> 284 struct sos_fs_opened_file *
>> 285 sos_process_get_root(const struct sos_process *proc)
>> 286 {
>> 287 return proc->root;
>> 288 }
>> 289
>> 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
217 361
218 362
219 363
220 364
221 365
222 sos_ret_t sos_process_register_thread(struct s 366 sos_ret_t sos_process_register_thread(struct sos_process *in_proc,
223 struct s 367 struct sos_thread *thr)
224 { 368 {
225 sos_ui32_t flags; 369 sos_ui32_t flags;
226 370
227 371
228 SOS_ASSERT_FATAL(in_proc->ref_cnt > 0); 372 SOS_ASSERT_FATAL(in_proc->ref_cnt > 0);
229 373
230 374
231 375
232 SOS_ASSERT_FATAL(thr->state == SOS_THR_CREAT 376 SOS_ASSERT_FATAL(thr->state == SOS_THR_CREATED);
233 377
234 378
235 thr->process = in_proc; 379 thr->process = in_proc;
236 380
237 381
238 sos_process_ref(in_proc); 382 sos_process_ref(in_proc);
239 383
240 384
241 sos_disable_IRQs(flags); 385 sos_disable_IRQs(flags);
242 list_add_tail_named(in_proc->thread_list, th 386 list_add_tail_named(in_proc->thread_list, thr,
243 prev_in_process, next_in 387 prev_in_process, next_in_process);
244 in_proc->nb_threads ++; 388 in_proc->nb_threads ++;
245 sos_restore_IRQs(flags); 389 sos_restore_IRQs(flags);
246 390
247 return SOS_OK; 391 return SOS_OK;
248 } 392 }
249 393
250 394
251 395
252 396
253 sos_ret_t sos_process_unref(struct sos_process 397 sos_ret_t sos_process_unref(struct sos_process *proc)
254 { 398 {
255 sos_ui32_t flags; 399 sos_ui32_t flags;
256 sos_ret_t retval; 400 sos_ret_t retval;
>> 401 int fd;
257 402
258 SOS_ASSERT_FATAL(proc->ref_cnt > 0); 403 SOS_ASSERT_FATAL(proc->ref_cnt > 0);
259 404
260 sos_disable_IRQs(flags); 405 sos_disable_IRQs(flags);
261 proc->ref_cnt --; 406 proc->ref_cnt --;
262 if (proc->ref_cnt > 0) 407 if (proc->ref_cnt > 0)
263 { 408 {
264 sos_restore_IRQs(flags); 409 sos_restore_IRQs(flags);
265 return -SOS_EBUSY; 410 return -SOS_EBUSY;
266 } 411 }
267 list_delete(process_list, proc); 412 list_delete(process_list, proc);
268 sos_restore_IRQs(flags); 413 sos_restore_IRQs(flags);
>> 414
>> 415
>> 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);
269 422
270 423
271 retval = sos_umem_vmm_delete_as(proc->addres 424 retval = sos_umem_vmm_delete_as(proc->address_space);
272 SOS_ASSERT_FATAL(SOS_OK == retval); 425 SOS_ASSERT_FATAL(SOS_OK == retval);
273 426
274 427
275 sos_kmem_cache_free((sos_vaddr_t)proc); 428 sos_kmem_cache_free((sos_vaddr_t)proc);
276 429
277 return SOS_OK; 430 return SOS_OK;
278 } 431 }
279 432
280 433
281 sos_ret_t sos_process_unregister_thread(struct 434 sos_ret_t sos_process_unregister_thread(struct sos_thread *thr)
282 { 435 {
283 sos_ui32_t flags; 436 sos_ui32_t flags;
284 struct sos_process * in_proc = thr->process; 437 struct sos_process * in_proc = thr->process;
285 438
286 SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBI 439 SOS_ASSERT_FATAL(thr->state == SOS_THR_ZOMBIE);
287 440
288 441
289 thr->process = NULL; 442 thr->process = NULL;
290 sos_disable_IRQs(flags); 443 sos_disable_IRQs(flags);
291 list_delete_named(in_proc->thread_list, thr, 444 list_delete_named(in_proc->thread_list, thr,
292 prev_in_process, next_in_p 445 prev_in_process, next_in_process);
293 SOS_ASSERT_FATAL(in_proc->nb_threads > 0); 446 SOS_ASSERT_FATAL(in_proc->nb_threads > 0);
294 in_proc->nb_threads --; 447 in_proc->nb_threads --;
295 sos_restore_IRQs(flags); 448 sos_restore_IRQs(flags);
296 449
297 450
298 sos_process_unref(in_proc); 451 sos_process_unref(in_proc);
299 452
300 return SOS_OK; 453 return SOS_OK;
301 } 454 }
302 455
303 456
304 sos_ret_t sos_process_set_name(struct sos_proc 457 sos_ret_t sos_process_set_name(struct sos_process * proc,
305 const char * ne 458 const char * new_name)
306 { 459 {
307 strzcpy(proc->name, new_name, SOS_PROCESS_MA 460 strzcpy(proc->name, new_name, SOS_PROCESS_MAX_NAMELEN);
308 return SOS_OK; 461 return SOS_OK;
309 } 462 }