Rev 2802 | Rev 3137 | Go to most recent revision | Show entire file | Regard 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 |
236 | /** Syscall for reading task ID from userspace. |
237 | * |
237 | * |
238 | * @param program_addr Address of program executable image. |
238 | * @param uspace_task_id Userspace address of 8-byte buffer where to store |
239 | * @param name Program name. |
239 | * current task ID. |
240 | * |
240 | * |
241 | * @return Task of the running program or NULL on error. |
241 | * @return 0 on success or an error code from @ref errno.h. |
242 | */ |
242 | */ |
243 | task_t *task_run_program(void *program_addr, char *name) |
243 | unative_t sys_task_get_id(task_id_t *uspace_task_id) |
244 | { |
244 | { |
245 | as_t *as; |
245 | /* |
246 | as_area_t *a; |
246 | * No need to acquire lock on TASK because taskid |
247 | unsigned int rc; |
247 | * remains constant for the lifespan of the task. |
248 | thread_t *t; |
248 | */ |
249 | task_t *task; |
249 | return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, |
250 | uspace_arg_t *kernel_uarg; |
250 | sizeof(TASK->taskid)); |
251 | 251 | } |
|
252 | as = as_create(0); |
- | |
253 | ASSERT(as); |
- | |
254 | 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 | ||
255 | rc = elf_load((elf_header_t *) program_addr, as); |
259 | int rc = copy_from_uspace(kimage, image, size); |
256 | if (rc != EE_OK) { |
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) { |
|
257 | as_destroy(as); |
265 | free(kimage); |
258 | return NULL; |
266 | return ENOMEM; |
259 | } |
267 | } |
260 | 268 | ||
261 | kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
- | |
262 | kernel_uarg->uspace_entry = |
269 | kernel_uarg->uspace_entry = |
263 | (void *) ((elf_header_t *) program_addr)->e_entry; |
270 | (void *) ((elf_header_t *) kimage)->e_entry; |
264 | kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS; |
271 | kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS; |
265 | kernel_uarg->uspace_thread_function = NULL; |
272 | kernel_uarg->uspace_thread_function = NULL; |
266 | kernel_uarg->uspace_thread_arg = NULL; |
273 | kernel_uarg->uspace_thread_arg = NULL; |
267 | kernel_uarg->uspace_uarg = NULL; |
274 | kernel_uarg->uspace_uarg = NULL; |
268 | 275 | ||
269 | task = task_create(as, name); |
276 | as_t *as = as_create(0); |
- | 277 | if (as == NULL) { |
|
- | 278 | free(kernel_uarg); |
|
270 | ASSERT(task); |
279 | free(kimage); |
- | 280 | return ENOMEM; |
|
- | 281 | } |
|
271 | 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; |
|
272 | /* |
289 | } |
273 | * Create the data as_area. |
- | |
274 | */ |
290 | |
- | 291 | as_area_t *area = as_area_create(as, |
|
275 | a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
292 | AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
276 | LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
293 | LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
277 | AS_AREA_ATTR_NONE, &anon_backend, NULL); |
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 | } |
|
278 | 301 | ||
279 | /* |
- | |
- | 302 | task_t *task = task_create(as, "app"); |
|
280 | * Create the main thread. |
303 | if (task == NULL) { |
281 | */ |
304 | as_destroy(as); |
282 | t = thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE, |
305 | free(kernel_uarg); |
283 | "uinit", false); |
306 | free(kimage); |
284 | ASSERT(t); |
307 | return ENOENT; |
- | 308 | } |
|
285 | 309 | ||
- | 310 | // FIXME: control the capabilities |
|
286 | thread_ready(t); |
311 | cap_set(task, cap_get(TASK)); |
287 | 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); |
|
288 | return task; |
320 | return ENOENT; |
289 | } |
321 | } |
290 | 322 | ||
291 | /** Syscall for reading task ID from userspace. |
- | |
292 | * |
- | |
293 | * @param uspace_task_id Userspace address of 8-byte buffer where to store |
- | |
294 | * current task ID. |
323 | thread_ready(thread); |
295 | * |
- | |
296 | * @return 0 on success or an error code from @ref errno.h. |
- | |
297 | */ |
- | |
298 | unative_t sys_task_get_id(task_id_t *uspace_task_id) |
- | |
299 | { |
324 | |
300 | /* |
- | |
301 | * No need to acquire lock on TASK because taskid |
- | |
302 | * remains constant for the lifespan of the task. |
- | |
303 | */ |
325 | return EOK; |
304 | return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, |
- | |
305 | sizeof(TASK->taskid)); |
- | |
306 | } |
326 | } |
307 | 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 |
Line 419... | Line 439... | ||
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 446... | Line 470... | ||
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); |