Reimplemented kill/suspend

It seems to work fine except an undefined instruction is generated
from posix userspace occasionally
This commit is contained in:
Bahadir Balban
2009-10-30 21:34:10 +02:00
parent f3c0a38fa9
commit c3c6c10cf7
10 changed files with 114 additions and 157 deletions

View File

@@ -226,41 +226,11 @@ void sched_resume_async(struct ktcb *task)
RQ_ADD_FRONT);
}
#if 0
/* FIXME: Disables preemption for unbounded time !!! */
void tcb_delete_schedule(void)
{
/* We lock all possible locks to do with */
address_space_lock();
/*
* Lock ktcb mutex cache so that nobody can get me
* during this period
*/
mutex_lock(&kernel_resources.ktcb_cache.lock);
tcb_delete(current);
preempt_disable();
sched_rq_remove_task(current);
current->state = TASK_INACTIVE;
scheduler.prio_total -= current->priority;
BUG_ON(scheduler.prio_total < 0);
ktcb_list_unlock();
address_space_list_unlock();
preempt_enable();
schedule();
}
#endif
/*
* A self-paging thread deletes itself,
* schedules and disappears from the system.
*/
void sched_die_pager(void)
void sched_pager_exit(void)
{
printk("Pager (%d) Exiting...\n", current->tid);
/* Remove from its list, callers get -ESRCH */
@@ -296,6 +266,7 @@ void sched_die_pager(void)
BUG();
}
#if 0
/*
* A paged-thread leaves the system and waits on
* its pager's task_dead queue.
@@ -362,13 +333,37 @@ void sched_die_child(void)
schedule();
BUG();
}
#endif
void sched_die_sync(void)
void sched_exit_sync(void)
{
if (current->tid == current->pagerid)
sched_die_pager();
else
sched_die_child();
struct ktcb *pager = tcb_find(current->pagerid);
/* Quit global list */
tcb_remove(current);
/* Wake up waiters */
wake_up_all(&current->wqh_send, 0);
wake_up_all(&current->wqh_recv, 0);
/* Go to exit list */
ktcb_list_add(current, &pager->child_exit_list);
preempt_disable();
/* Hint pager we're ready */
wake_up(&current->wqh_pager, 0);
sched_rq_remove_task(current);
current->state = TASK_INACTIVE;
current->flags &= ~TASK_SUSPENDING;
scheduler.prio_total -= current->priority;
BUG_ON(scheduler.prio_total < 0);
preempt_enable();
/* Quit */
schedule();
BUG();
}
/*
@@ -517,7 +512,7 @@ void schedule()
* If task is about to sleep and
* it has pending events, wake it up.
*/
if (current->flags & TASK_SUSPENDING &&
if ((current->flags & TASK_PENDING_SIGNAL) &&
current->state == TASK_SLEEPING)
wake_up_task(current, WAKEUP_INTERRUPT);

View File

@@ -30,8 +30,7 @@ void tcb_init(struct ktcb *new)
link_init(&new->task_list);
mutex_init(&new->thread_control_lock);
mutex_init(&new->task_dead_mutex);
link_init(&new->task_dead_list);
init_ktcb_list(&new->child_exit_list);
cap_list_init(&new->cap_list);
/* Initialise task's scheduling state and parameters. */
@@ -162,6 +161,15 @@ void tcb_remove(struct ktcb *new)
spin_unlock(&curcont->ktcb_list.list_lock);
}
void ktcb_list_remove(struct ktcb *new, struct ktcb_list *ktcb_list)
{
spin_lock(&ktcb_list->list_lock);
BUG_ON(list_empty(&new->task_list));
BUG_ON(--ktcb_list->count < 0);
list_remove(&new->task_list);
spin_unlock(&ktcb_list->list_lock);
}
/* Offsets for ktcb fields that are accessed from assembler */
unsigned int need_resched_offset = offsetof(struct ktcb, ts_need_resched);
unsigned int syscall_regs_offset = offsetof(struct ktcb, syscall_regs);