Rev 2802 | Rev 3137 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2802 | Rev 3063 | ||
---|---|---|---|
Line 126... | Line 126... | ||
126 | 126 | ||
127 | spinlock_unlock(&tasks_lock); |
127 | spinlock_unlock(&tasks_lock); |
128 | interrupts_restore(ipl); |
128 | interrupts_restore(ipl); |
129 | 129 | ||
130 | #ifdef CONFIG_DEBUG |
130 | #ifdef CONFIG_DEBUG |
131 | printf("Killing task %llu\n", id); |
131 | printf("Killing task %" PRIu64 "\n", id); |
132 | #endif |
132 | #endif |
133 | task_kill(id); |
133 | task_kill(id); |
134 | thread_usleep(10000); |
134 | thread_usleep(10000); |
135 | } else { |
135 | } else { |
136 | spinlock_unlock(&tasks_lock); |
136 | spinlock_unlock(&tasks_lock); |
Line 231... | Line 231... | ||
231 | 231 | ||
232 | free(t); |
232 | free(t); |
233 | TASK = NULL; |
233 | TASK = NULL; |
234 | } |
234 | } |
235 | 235 | ||
236 | /** Create new task with 1 thread and run it |
- | |
237 | * |
- | |
238 | * @param program_addr Address of program executable image. |
- | |
239 | * @param name Program name. |
- | |
240 | * |
- | |
241 | * @return Task of the running program or NULL on error. |
- | |
242 | */ |
- | |
243 | task_t *task_run_program(void *program_addr, char *name) |
- | |
244 | { |
- | |
245 | as_t *as; |
- | |
246 | as_area_t *a; |
- | |
247 | unsigned int rc; |
- | |
248 | thread_t *t; |
- | |
249 | task_t *task; |
- | |
250 | uspace_arg_t *kernel_uarg; |
- | |
251 | - | ||
252 | as = as_create(0); |
- | |
253 | ASSERT(as); |
- | |
254 | - | ||
255 | rc = elf_load((elf_header_t *) program_addr, as); |
- | |
256 | if (rc != EE_OK) { |
- | |
257 | as_destroy(as); |
- | |
258 | return NULL; |
- | |
259 | } |
- | |
260 | - | ||
261 | kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
- | |
262 | kernel_uarg->uspace_entry = |
- | |
263 | (void *) ((elf_header_t *) program_addr)->e_entry; |
- | |
264 | kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS; |
- | |
265 | kernel_uarg->uspace_thread_function = NULL; |
- | |
266 | kernel_uarg->uspace_thread_arg = NULL; |
- | |
267 | kernel_uarg->uspace_uarg = NULL; |
- | |
268 | - | ||
269 | task = task_create(as, name); |
- | |
270 | ASSERT(task); |
- | |
271 | - | ||
272 | /* |
- | |
273 | * Create the data as_area. |
- | |
274 | */ |
- | |
275 | a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
- | |
276 | LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
- | |
277 | AS_AREA_ATTR_NONE, &anon_backend, NULL); |
- | |
278 | - | ||
279 | /* |
- | |
280 | * Create the main thread. |
- | |
281 | */ |
- | |
282 | t = thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE, |
- | |
283 | "uinit", false); |
- | |
284 | ASSERT(t); |
- | |
285 | - | ||
286 | thread_ready(t); |
- | |
287 | - | ||
288 | return task; |
- | |
289 | } |
- | |
290 | - | ||
291 | /** Syscall for reading task ID from userspace. |
236 | /** Syscall for reading task ID from userspace. |
292 | * |
237 | * |
293 | * @param uspace_task_id Userspace address of 8-byte buffer where to store |
238 | * @param uspace_task_id Userspace address of 8-byte buffer where to store |
294 | * current task ID. |
239 | * current task ID. |
295 | * |
240 | * |
Line 303... | Line 248... | ||
303 | */ |
248 | */ |
304 | return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, |
249 | return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, |
305 | sizeof(TASK->taskid)); |
250 | sizeof(TASK->taskid)); |
306 | } |
251 | } |
307 | 252 | ||
- | 253 | unative_t sys_task_spawn(void *image, size_t size) |
|
- | 254 | { |
|
- | 255 | void *kimage = malloc(size, 0); |
|
- | 256 | if (kimage == NULL) |
|
- | 257 | return ENOMEM; |
|
- | 258 | ||
- | 259 | int rc = copy_from_uspace(kimage, image, size); |
|
- | 260 | if (rc != EOK) |
|
- | 261 | return rc; |
|
- | 262 | ||
- | 263 | uspace_arg_t *kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
|
- | 264 | if (kernel_uarg == NULL) { |
|
- | 265 | free(kimage); |
|
- | 266 | return ENOMEM; |
|
- | 267 | } |
|
- | 268 | ||
- | 269 | kernel_uarg->uspace_entry = |
|
- | 270 | (void *) ((elf_header_t *) kimage)->e_entry; |
|
- | 271 | kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS; |
|
- | 272 | kernel_uarg->uspace_thread_function = NULL; |
|
- | 273 | kernel_uarg->uspace_thread_arg = NULL; |
|
- | 274 | kernel_uarg->uspace_uarg = NULL; |
|
- | 275 | ||
- | 276 | as_t *as = as_create(0); |
|
- | 277 | if (as == NULL) { |
|
- | 278 | free(kernel_uarg); |
|
- | 279 | free(kimage); |
|
- | 280 | return ENOMEM; |
|
- | 281 | } |
|
- | 282 | ||
- | 283 | unsigned int erc = elf_load((elf_header_t *) kimage, as); |
|
- | 284 | if (erc != EE_OK) { |
|
- | 285 | as_destroy(as); |
|
- | 286 | free(kernel_uarg); |
|
- | 287 | free(kimage); |
|
- | 288 | return ENOENT; |
|
- | 289 | } |
|
- | 290 | ||
- | 291 | as_area_t *area = as_area_create(as, |
|
- | 292 | AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
|
- | 293 | LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
|
- | 294 | AS_AREA_ATTR_NONE, &anon_backend, NULL); |
|
- | 295 | if (area == NULL) { |
|
- | 296 | as_destroy(as); |
|
- | 297 | free(kernel_uarg); |
|
- | 298 | free(kimage); |
|
- | 299 | return ENOMEM; |
|
- | 300 | } |
|
- | 301 | ||
- | 302 | task_t *task = task_create(as, "app"); |
|
- | 303 | if (task == NULL) { |
|
- | 304 | as_destroy(as); |
|
- | 305 | free(kernel_uarg); |
|
- | 306 | free(kimage); |
|
- | 307 | return ENOENT; |
|
- | 308 | } |
|
- | 309 | ||
- | 310 | // FIXME: control the capabilities |
|
- | 311 | cap_set(task, cap_get(TASK)); |
|
- | 312 | ||
- | 313 | thread_t *thread = thread_create(uinit, kernel_uarg, task, |
|
- | 314 | THREAD_FLAG_USPACE, "user", false); |
|
- | 315 | if (thread == NULL) { |
|
- | 316 | task_destroy(task); |
|
- | 317 | as_destroy(as); |
|
- | 318 | free(kernel_uarg); |
|
- | 319 | free(kimage); |
|
- | 320 | return ENOENT; |
|
- | 321 | } |
|
- | 322 | ||
- | 323 | thread_ready(thread); |
|
- | 324 | ||
- | 325 | return EOK; |
|
- | 326 | } |
|
- | 327 | ||
308 | /** Find task structure corresponding to task ID. |
328 | /** Find task structure corresponding to task ID. |
309 | * |
329 | * |
310 | * The tasks_lock must be already held by the caller of this function |
330 | * The tasks_lock must be already held by the caller of this function |
311 | * and interrupts must be disabled. |
331 | * and interrupts must be disabled. |
312 | * |
332 | * |
Line 418... | Line 438... | ||
418 | spinlock_lock(&t->lock); |
438 | spinlock_lock(&t->lock); |
419 | 439 | ||
420 | uint64_t cycles; |
440 | uint64_t cycles; |
421 | char suffix; |
441 | char suffix; |
422 | order(task_get_accounting(t), &cycles, &suffix); |
442 | order(task_get_accounting(t), &cycles, &suffix); |
423 | 443 | ||
424 | if (sizeof(void *) == 4) |
444 | #ifdef __32_BITS__ |
425 | printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd %6zd", |
445 | printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %7ld %6ld", |
426 | t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
446 | t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
427 | t->refcount, atomic_get(&t->active_calls)); |
447 | atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
428 | else |
448 | #endif |
- | 449 | ||
- | 450 | #ifdef __64_BITS__ |
|
429 | printf("%-6llu %-10s %-3ld %#18zx %#18zx %9llu%c %7zd %6zd", |
451 | printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %7ld %6ld", |
430 | t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
452 | t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
431 | t->refcount, atomic_get(&t->active_calls)); |
453 | atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
- | 454 | #endif |
|
- | 455 | ||
432 | for (j = 0; j < IPC_MAX_PHONES; j++) { |
456 | for (j = 0; j < IPC_MAX_PHONES; j++) { |
433 | if (t->phones[j].callee) |
457 | if (t->phones[j].callee) |
434 | printf(" %zd:%#zx", j, t->phones[j].callee); |
458 | printf(" %d:%p", j, t->phones[j].callee); |
435 | } |
459 | } |
436 | printf("\n"); |
460 | printf("\n"); |
437 | 461 | ||
438 | spinlock_unlock(&t->lock); |
462 | spinlock_unlock(&t->lock); |
439 | return true; |
463 | return true; |
Line 445... | Line 469... | ||
445 | ipl_t ipl; |
469 | ipl_t ipl; |
446 | 470 | ||
447 | /* Messing with task structures, avoid deadlock */ |
471 | /* Messing with task structures, avoid deadlock */ |
448 | ipl = interrupts_disable(); |
472 | ipl = interrupts_disable(); |
449 | spinlock_lock(&tasks_lock); |
473 | spinlock_lock(&tasks_lock); |
450 | 474 | ||
451 | if (sizeof(void *) == 4) { |
475 | #ifdef __32_BITS__ |
452 | printf("taskid name ctx address as " |
476 | printf("taskid name ctx address as " |
453 | "cycles threads calls callee\n"); |
477 | "cycles threads calls callee\n"); |
454 | printf("------ ---------- --- ---------- ---------- " |
478 | printf("------ ---------- --- ---------- ---------- " |
455 | "---------- ------- ------ ------>\n"); |
479 | "---------- ------- ------ ------>\n"); |
456 | } else { |
480 | #endif |
- | 481 | ||
- | 482 | #ifdef __64_BITS__ |
|
457 | printf("taskid name ctx address as " |
483 | printf("taskid name ctx address as " |
458 | "cycles threads calls callee\n"); |
484 | "cycles threads calls callee\n"); |
459 | printf("------ ---------- --- ------------------ ------------------ " |
485 | printf("------ ---------- --- ------------------ ------------------ " |
460 | "---------- ------- ------ ------>\n"); |
486 | "---------- ------- ------ ------>\n"); |
461 | } |
487 | #endif |
462 | 488 | ||
463 | avltree_walk(&tasks_tree, task_print_walker, NULL); |
489 | avltree_walk(&tasks_tree, task_print_walker, NULL); |
464 | 490 | ||
465 | spinlock_unlock(&tasks_lock); |
491 | spinlock_unlock(&tasks_lock); |
466 | interrupts_restore(ipl); |
492 | interrupts_restore(ipl); |