Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2838 → Rev 2839

/branches/tracing/kernel/generic/src/proc/thread.c
358,6 → 358,16
return t;
}
 
/** Destroy thread structure of an unattached thread.
*
* Thread t must only have been created and never attached.
*/
void thread_unattached_free(thread_t *t)
{
slab_free(thread_slab, t);
}
 
 
/** Destroy thread memory structure
*
* Detach thread from all queues, cpus etc. and destroy it.
398,6 → 408,43
slab_free(thread_slab, t);
}
 
/** Attach thread to the given task.
*
* The task's lock must already be held and interrupts must be disabled.
*
* @param t Thread to be attached to the task.
* @param task Task to which the thread is to be attached.
*/
static void _thread_attach_task(thread_t *t, task_t *task)
{
atomic_inc(&task->refcount);
atomic_inc(&task->lifecount);
 
/* FIXME: this must be done very carefully.. an unstoppable
thread cannot appear just-so, it must be possible to catch it. */
if (t->flags & THREAD_FLAG_USPACE)
++task->not_stoppable_count;
list_append(&t->th_link, &task->th_head);
}
 
/** Add thread to the threads tree.
*
* Interrupts must be already disabled.
*
* @param t Thread to be attached to the task.
* @param task Task to which the thread is to be attached.
*/
static void _thread_attach_tree(thread_t *t)
{
/*
* Register this thread in the system-wide list.
*/
spinlock_lock(&threads_lock);
avltree_insert(&threads_tree, &t->threads_tree_node);
spinlock_unlock(&threads_lock);
}
 
 
/** Make the thread visible to the system.
*
* Attach the thread structure to the current task and make it visible in the
410,31 → 457,68
{
ipl_t ipl;
 
ipl = interrupts_disable();
 
/*
* Attach to the current task.
*/
spinlock_lock(&task->lock);
_thread_attach_task(t, task);
spinlock_unlock(&task->lock);
 
/*
* Register this thread in the system-wide list.
*/
_thread_attach_tree(t);
interrupts_restore(ipl);
}
 
/** Attach thread to a task given by its ID.
*
* Unlike thread_attach(), this function allows to attach a thread
* to an arbitrary task.
*
* @param t Thread to be attached to the task.
* @param taskid Task id to which the thread is to be attached.
* @return An error code from errno.h
*/
int thread_attach_by_id(thread_t *t, task_id_t taskid)
{
ipl_t ipl;
task_t *task;
 
ipl = interrupts_disable();
 
spinlock_lock(&tasks_lock);
task = task_find_by_id(taskid);
if (task == NULL) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
spinlock_lock(&task->lock);
atomic_inc(&task->refcount);
atomic_inc(&task->lifecount);
spinlock_unlock(&tasks_lock);
 
/* FIXME: this must be done very carefully.. an unstoppable
thread cannot appear just-so, it must be possible to catch it. */
if (t->flags & THREAD_FLAG_USPACE)
++task->not_stoppable_count;
list_append(&t->th_link, &task->th_head);
/*
* Attach to the current task.
*/
_thread_attach_task(t, task);
 
spinlock_unlock(&task->lock);
 
/*
* Register this thread in the system-wide list.
*/
spinlock_lock(&threads_lock);
avltree_insert(&threads_tree, &t->threads_tree_node);
spinlock_unlock(&threads_lock);
_thread_attach_tree(t);
interrupts_restore(ipl);
 
return EOK;
}
 
 
/** Terminate thread.
*
* End current thread execution and switch it to the exiting state. All pending