Exiting tasks use EXITING signal and change states to TASK_DEAD

This commit is contained in:
Bahadir Balban
2009-10-31 23:13:19 +02:00
parent 5ed93b6563
commit 850c645d77
9 changed files with 54 additions and 5 deletions

View File

@@ -54,6 +54,12 @@ int thread_suspend(struct ktcb *task)
return thread_signal(task, TASK_SUSPENDING, TASK_INACTIVE);
}
int thread_exit(struct ktcb *task)
{
return thread_signal(task, TASK_EXITING, TASK_DEAD);
}
static inline int TASK_IS_CHILD(struct ktcb *task)
{
return (((task) != current) &&
@@ -62,7 +68,7 @@ static inline int TASK_IS_CHILD(struct ktcb *task)
int thread_destroy_child(struct ktcb *task)
{
thread_suspend(task);
thread_exit(task);
tcb_remove(task);
@@ -71,7 +77,7 @@ int thread_destroy_child(struct ktcb *task)
wake_up_all(&task->wqh_recv, WAKEUP_INTERRUPT);
BUG_ON(task->wqh_pager.sleepers > 0);
BUG_ON(task->state != TASK_INACTIVE);
BUG_ON(task->state != TASK_DEAD);
tcb_delete(task);
return 0;
@@ -100,7 +106,12 @@ void thread_destroy_self()
{
thread_destroy_children();
sched_suspend_sync();
sched_exit_sync();
}
int thread_wait(struct ktcb *task)
{
return 0;
}
int thread_destroy(struct ktcb *task)
@@ -177,6 +188,8 @@ int thread_start(struct ktcb *task)
if (!mutex_trylock(&task->thread_control_lock))
return -EAGAIN;
/* FIXME: Refuse to run dead tasks */
/* Notify scheduler of task resume */
sched_resume_async(task);
@@ -404,6 +417,9 @@ int sys_thread_control(unsigned int flags, struct task_ids *ids)
case THREAD_RECYCLE:
ret = thread_recycle(task);
break;
case THREAD_WAIT:
ret = thread_wait(task);
break;
default:
ret = -EINVAL;

View File

@@ -282,7 +282,11 @@ void data_abort_handler(u32 faulted_pc, u32 fsr, u32 far)
if (current->flags & TASK_SUSPENDING) {
BUG_ON(current->nlocks);
sched_suspend_sync();
} else if (current->flags & TASK_EXITING) {
BUG_ON(current->nlocks);
sched_exit_sync();
}
return;
error:
@@ -311,7 +315,11 @@ void prefetch_abort_handler(u32 faulted_pc, u32 fsr, u32 far, u32 lr)
if (current->flags & TASK_SUSPENDING) {
BUG_ON(current->nlocks);
sched_suspend_sync();
} else if (current->flags & TASK_EXITING) {
BUG_ON(current->nlocks);
sched_exit_sync();
}
return;
error:

View File

@@ -437,6 +437,11 @@ struct capability *cap_match_thread(struct capability *cap,
if (!(cap->access & CAP_TCTRL_RECYCLE))
return 0;
break;
case THREAD_WAIT:
if (!(cap->access & CAP_TCTRL_WAIT))
return 0;
break;
default:
/* We refuse to accept anything else */
return 0;

View File

@@ -225,6 +225,22 @@ void sched_resume_async(struct ktcb *task)
RQ_ADD_FRONT);
}
/* Same as suspend, task state and flags are different */
void sched_exit_sync(void)
{
preempt_disable();
sched_rq_remove_task(current);
current->state = TASK_DEAD;
current->flags &= ~TASK_EXITING;
preempt_enable();
if (current->pagerid != current->tid)
wake_up(&current->wqh_pager, 0);
schedule();
}
/*
* NOTE: Could do these as sched_prepare_suspend()
* + schedule() or need_resched = 1

View File

@@ -170,6 +170,9 @@ int syscall(syscall_context_t *regs, unsigned long swi_addr)
if (current->flags & TASK_SUSPENDING) {
BUG_ON(current->nlocks);
sched_suspend_sync();
} else if (current->flags & TASK_EXITING) {
BUG_ON(current->nlocks);
sched_exit_sync();
}
return ret;