mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Exiting tasks use EXITING signal and change states to TASK_DEAD
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#define THREAD_SUSPEND 0x0002
|
||||
#define THREAD_DESTROY 0x0003
|
||||
#define THREAD_RECYCLE 0x0004
|
||||
#define THREAD_WAIT 0x0005
|
||||
|
||||
#define THREAD_CREATE_MASK 0x0FF0
|
||||
#define TC_SHARE_CAPS 0x0010 /* Share all thread capabilities */
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#define CAP_TCTRL_RUN (1 << 2)
|
||||
#define CAP_TCTRL_SUSPEND (1 << 3)
|
||||
#define CAP_TCTRL_RECYCLE (1 << 4)
|
||||
#define CAP_TCTRL_WAIT (1 << 5)
|
||||
|
||||
/* Exchange registers capability */
|
||||
#define CAP_EXREGS_RW_PAGER (1 << 0)
|
||||
|
||||
@@ -61,7 +61,6 @@ extern struct scheduler scheduler;
|
||||
void sched_init_runqueue(struct runqueue *rq);
|
||||
void sched_init_task(struct ktcb *task, int priority);
|
||||
void sched_prepare_sleep(void);
|
||||
void sched_exit_pager(void);
|
||||
void sched_exit_sync(void);
|
||||
void sched_suspend_sync(void);
|
||||
void sched_suspend_async(void);
|
||||
|
||||
@@ -110,7 +110,7 @@ cap_all_others = \
|
||||
\t\t\t\t.type = CAP_TYPE_TCTRL | CAP_RTYPE_CONTAINER,
|
||||
\t\t\t\t.access = CAP_TCTRL_CREATE | CAP_TCTRL_DESTROY
|
||||
\t\t\t\t | CAP_TCTRL_SUSPEND | CAP_TCTRL_RUN
|
||||
\t\t\t\t | CAP_TCTRL_RECYCLE,
|
||||
\t\t\t\t | CAP_TCTRL_RECYCLE | CAP_TCTRL_WAIT,
|
||||
\t\t\t\t.start = 0, .end = 0, .size = 0,
|
||||
\t\t\t},
|
||||
\t\t\t[%d] = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¤t->wqh_pager, 0);
|
||||
|
||||
schedule();
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: Could do these as sched_prepare_suspend()
|
||||
* + schedule() or need_resched = 1
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user