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); |