Subversion Repositories HelenOS

Rev

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