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 | */ |