Rev 2827 | Rev 2848 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2827 | Rev 2839 | ||
|---|---|---|---|
| Line 356... | Line 356... | ||
| 356 | thread_attach(t, task); |
356 | thread_attach(t, task); |
| 357 | 357 | ||
| 358 | return t; |
358 | return t; |
| 359 | } |
359 | } |
| 360 | 360 | ||
| - | 361 | /** Destroy thread structure of an unattached thread. |
|
| - | 362 | * |
|
| - | 363 | * Thread t must only have been created and never attached. |
|
| - | 364 | */ |
|
| - | 365 | void thread_unattached_free(thread_t *t) |
|
| - | 366 | { |
|
| - | 367 | slab_free(thread_slab, t); |
|
| - | 368 | } |
|
| - | 369 | ||
| - | 370 | ||
| 361 | /** Destroy thread memory structure |
371 | /** Destroy thread memory structure |
| 362 | * |
372 | * |
| 363 | * Detach thread from all queues, cpus etc. and destroy it. |
373 | * Detach thread from all queues, cpus etc. and destroy it. |
| 364 | * |
374 | * |
| 365 | * Assume thread->lock is held!! |
375 | * Assume thread->lock is held!! |
| Line 396... | Line 406... | ||
| 396 | task_destroy(t->task); |
406 | task_destroy(t->task); |
| 397 | 407 | ||
| 398 | slab_free(thread_slab, t); |
408 | slab_free(thread_slab, t); |
| 399 | } |
409 | } |
| 400 | 410 | ||
| - | 411 | /** Attach thread to the given task. |
|
| - | 412 | * |
|
| - | 413 | * The task's lock must already be held and interrupts must be disabled. |
|
| - | 414 | * |
|
| - | 415 | * @param t Thread to be attached to the task. |
|
| - | 416 | * @param task Task to which the thread is to be attached. |
|
| - | 417 | */ |
|
| - | 418 | static void _thread_attach_task(thread_t *t, task_t *task) |
|
| - | 419 | { |
|
| - | 420 | atomic_inc(&task->refcount); |
|
| - | 421 | atomic_inc(&task->lifecount); |
|
| - | 422 | ||
| - | 423 | /* FIXME: this must be done very carefully.. an unstoppable |
|
| - | 424 | thread cannot appear just-so, it must be possible to catch it. */ |
|
| - | 425 | if (t->flags & THREAD_FLAG_USPACE) |
|
| - | 426 | ++task->not_stoppable_count; |
|
| - | 427 | list_append(&t->th_link, &task->th_head); |
|
| - | 428 | } |
|
| - | 429 | ||
| - | 430 | /** Add thread to the threads tree. |
|
| - | 431 | * |
|
| - | 432 | * Interrupts must be already disabled. |
|
| - | 433 | * |
|
| - | 434 | * @param t Thread to be attached to the task. |
|
| - | 435 | * @param task Task to which the thread is to be attached. |
|
| - | 436 | */ |
|
| - | 437 | static void _thread_attach_tree(thread_t *t) |
|
| - | 438 | { |
|
| - | 439 | /* |
|
| - | 440 | * Register this thread in the system-wide list. |
|
| - | 441 | */ |
|
| - | 442 | spinlock_lock(&threads_lock); |
|
| - | 443 | avltree_insert(&threads_tree, &t->threads_tree_node); |
|
| - | 444 | spinlock_unlock(&threads_lock); |
|
| - | 445 | } |
|
| - | 446 | ||
| - | 447 | ||
| 401 | /** Make the thread visible to the system. |
448 | /** Make the thread visible to the system. |
| 402 | * |
449 | * |
| 403 | * Attach the thread structure to the current task and make it visible in the |
450 | * Attach the thread structure to the current task and make it visible in the |
| 404 | * threads_tree. |
451 | * threads_tree. |
| 405 | * |
452 | * |
| Line 408... | Line 455... | ||
| 408 | */ |
455 | */ |
| 409 | void thread_attach(thread_t *t, task_t *task) |
456 | void thread_attach(thread_t *t, task_t *task) |
| 410 | { |
457 | { |
| 411 | ipl_t ipl; |
458 | ipl_t ipl; |
| 412 | 459 | ||
| - | 460 | ipl = interrupts_disable(); |
|
| - | 461 | ||
| 413 | /* |
462 | /* |
| 414 | * Attach to the current task. |
463 | * Attach to the current task. |
| 415 | */ |
464 | */ |
| - | 465 | spinlock_lock(&task->lock); |
|
| - | 466 | _thread_attach_task(t, task); |
|
| - | 467 | spinlock_unlock(&task->lock); |
|
| - | 468 | ||
| - | 469 | /* |
|
| - | 470 | * Register this thread in the system-wide list. |
|
| - | 471 | */ |
|
| - | 472 | _thread_attach_tree(t); |
|
| - | 473 | ||
| - | 474 | interrupts_restore(ipl); |
|
| - | 475 | } |
|
| - | 476 | ||
| - | 477 | /** Attach thread to a task given by its ID. |
|
| - | 478 | * |
|
| - | 479 | * Unlike thread_attach(), this function allows to attach a thread |
|
| - | 480 | * to an arbitrary task. |
|
| - | 481 | * |
|
| - | 482 | * @param t Thread to be attached to the task. |
|
| - | 483 | * @param taskid Task id to which the thread is to be attached. |
|
| - | 484 | * @return An error code from errno.h |
|
| - | 485 | */ |
|
| - | 486 | int thread_attach_by_id(thread_t *t, task_id_t taskid) |
|
| - | 487 | { |
|
| - | 488 | ipl_t ipl; |
|
| - | 489 | task_t *task; |
|
| - | 490 | ||
| 416 | ipl = interrupts_disable(); |
491 | ipl = interrupts_disable(); |
| - | 492 | ||
| - | 493 | spinlock_lock(&tasks_lock); |
|
| - | 494 | task = task_find_by_id(taskid); |
|
| - | 495 | if (task == NULL) { |
|
| - | 496 | spinlock_unlock(&tasks_lock); |
|
| - | 497 | interrupts_restore(ipl); |
|
| - | 498 | return ENOENT; |
|
| - | 499 | } |
|
| - | 500 | ||
| 417 | spinlock_lock(&task->lock); |
501 | spinlock_lock(&task->lock); |
| 418 | atomic_inc(&task->refcount); |
502 | spinlock_unlock(&tasks_lock); |
| - | 503 | ||
| - | 504 | /* |
|
| - | 505 | * Attach to the current task. |
|
| - | 506 | */ |
|
| 419 | atomic_inc(&task->lifecount); |
507 | _thread_attach_task(t, task); |
| 420 | 508 | ||
| 421 | /* FIXME: this must be done very carefully.. an unstoppable |
- | |
| 422 | thread cannot appear just-so, it must be possible to catch it. */ |
- | |
| 423 | if (t->flags & THREAD_FLAG_USPACE) |
- | |
| 424 | ++task->not_stoppable_count; |
- | |
| 425 | list_append(&t->th_link, &task->th_head); |
- | |
| 426 | spinlock_unlock(&task->lock); |
509 | spinlock_unlock(&task->lock); |
| 427 | 510 | ||
| 428 | /* |
511 | /* |
| 429 | * Register this thread in the system-wide list. |
512 | * Register this thread in the system-wide list. |
| 430 | */ |
513 | */ |
| 431 | spinlock_lock(&threads_lock); |
- | |
| 432 | avltree_insert(&threads_tree, &t->threads_tree_node); |
- | |
| 433 | spinlock_unlock(&threads_lock); |
514 | _thread_attach_tree(t); |
| 434 | 515 | ||
| 435 | interrupts_restore(ipl); |
516 | interrupts_restore(ipl); |
| - | 517 | ||
| - | 518 | return EOK; |
|
| 436 | } |
519 | } |
| 437 | 520 | ||
| - | 521 | ||
| 438 | /** Terminate thread. |
522 | /** Terminate thread. |
| 439 | * |
523 | * |
| 440 | * End current thread execution and switch it to the exiting state. All pending |
524 | * End current thread execution and switch it to the exiting state. All pending |
| 441 | * timeouts are executed. |
525 | * timeouts are executed. |
| 442 | */ |
526 | */ |