sched: implement various ways to end tasks and threads
This commit is contained in:
78
sched/task.c
78
sched/task.c
@@ -222,13 +222,13 @@ kern_status_t task_add_channel(
|
||||
{
|
||||
channel->c_id = id;
|
||||
|
||||
if (!task->b_channels.b_root) {
|
||||
task->b_channels.b_root = &channel->c_node;
|
||||
btree_insert_fixup(&task->b_channels, &channel->c_node);
|
||||
if (!task->t_channels.b_root) {
|
||||
task->t_channels.b_root = &channel->c_node;
|
||||
btree_insert_fixup(&task->t_channels, &channel->c_node);
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
struct btree_node *cur = task->b_channels.b_root;
|
||||
struct btree_node *cur = task->t_channels.b_root;
|
||||
while (1) {
|
||||
struct channel *cur_node
|
||||
= BTREE_CONTAINER(struct channel, c_node, cur);
|
||||
@@ -255,7 +255,7 @@ kern_status_t task_add_channel(
|
||||
cur = next;
|
||||
}
|
||||
|
||||
btree_insert_fixup(&task->b_channels, &channel->c_node);
|
||||
btree_insert_fixup(&task->t_channels, &channel->c_node);
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ BTREE_DEFINE_SIMPLE_GET(
|
||||
|
||||
struct channel *task_get_channel(struct task *task, unsigned int id)
|
||||
{
|
||||
return get_channel_with_id(&task->b_channels, id);
|
||||
return get_channel_with_id(&task->t_channels, id);
|
||||
}
|
||||
|
||||
struct task *task_from_tid(tid_t id)
|
||||
@@ -280,6 +280,72 @@ struct task *task_from_tid(tid_t id)
|
||||
return t;
|
||||
}
|
||||
|
||||
void task_exit(int status)
|
||||
{
|
||||
struct task *self = current_task();
|
||||
unsigned long flags;
|
||||
task_lock_irqsave(self, &flags);
|
||||
struct task *parent = self->t_parent;
|
||||
|
||||
if (parent) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_lock_irqsave(parent, &flags);
|
||||
task_lock(self);
|
||||
queue_delete(&parent->t_children, &self->t_child_entry);
|
||||
task_unlock(parent);
|
||||
}
|
||||
|
||||
struct thread *cur_thread = current_thread();
|
||||
|
||||
self->t_state = TASK_STOPPED;
|
||||
cur_thread->tr_state = THREAD_STOPPED;
|
||||
|
||||
struct queue_entry *cur = queue_first(&self->t_threads);
|
||||
while (cur) {
|
||||
struct queue_entry *next = queue_next(cur);
|
||||
struct thread *thread
|
||||
= QUEUE_CONTAINER(struct thread, tr_parent_entry, cur);
|
||||
|
||||
if (thread == cur_thread) {
|
||||
cur = next;
|
||||
continue;
|
||||
}
|
||||
|
||||
thread_lock(thread);
|
||||
thread_kill(thread);
|
||||
queue_delete(&self->t_threads, cur);
|
||||
thread_unlock(thread);
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
object_unref(&self->t_address_space->s_base);
|
||||
spin_lock_t *handles_lock = &self->t_handles_lock;
|
||||
struct handle_table *handles = self->t_handles;
|
||||
spin_lock(&self->t_handles_lock);
|
||||
|
||||
pmap_switch(get_kernel_pmap());
|
||||
pmap_destroy(self->t_pmap);
|
||||
|
||||
task_unlock(self);
|
||||
handle_table_destroy(handles);
|
||||
|
||||
printk("thread %s[%u.%u] killed",
|
||||
self->t_name,
|
||||
self->t_id,
|
||||
cur_thread->tr_id);
|
||||
printk("task %s[%u] killed (%u, %u)",
|
||||
self->t_name,
|
||||
self->t_id,
|
||||
self->t_base.ob_refcount,
|
||||
self->t_base.ob_handles);
|
||||
spin_unlock_irqrestore(handles_lock, flags);
|
||||
|
||||
while (1) {
|
||||
schedule(SCHED_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
kern_status_t task_open_handle(
|
||||
struct task *task,
|
||||
struct object *obj,
|
||||
|
||||
Reference in New Issue
Block a user