Some not-very-well working progress on grouply exit.

Going to start from scratch.
This commit is contained in:
Bahadir Balban
2009-10-30 19:52:52 +02:00
parent ee7621b2df
commit f3c0a38fa9
7 changed files with 39 additions and 69 deletions

View File

@@ -44,7 +44,7 @@ container_head_init(struct container_head *chead)
/* Hash table for all existing tasks */ /* Hash table for all existing tasks */
struct ktcb_list { struct ktcb_list {
struct link list; struct link list;
struct mutex list_lock; struct spinlock list_lock;
int count; int count;
}; };

View File

@@ -80,7 +80,8 @@ struct ktcb {
enum task_state state; enum task_state state;
struct link task_list; /* Global task list. */ struct link task_list; /* Global task list. */
struct ktcb_list task_dead; /* List of dead children */ struct link task_dead_list; /* List of dead children */
struct mutex task_dead_mutex; /* Dead children list mutex */
/* UTCB related, see utcb.txt in docs */ /* UTCB related, see utcb.txt in docs */
unsigned long utcb_address; /* Virtual ref to task's utcb area */ unsigned long utcb_address; /* Virtual ref to task's utcb area */
@@ -156,7 +157,6 @@ void tcb_delete(struct ktcb *tcb);
void ktcb_list_add(struct ktcb *new, struct ktcb_list *ktcb_list); void ktcb_list_add(struct ktcb *new, struct ktcb_list *ktcb_list);
void __ktcb_list_add_nolock(struct ktcb *new, struct ktcb_list *ktcb_list);
void init_ktcb_list(struct ktcb_list *ktcb_list); void init_ktcb_list(struct ktcb_list *ktcb_list);
void task_update_utcb(struct ktcb *task); void task_update_utcb(struct ktcb *task);
int tcb_check_and_lazy_map_utcb(struct ktcb *task); int tcb_check_and_lazy_map_utcb(struct ktcb *task);

View File

@@ -184,29 +184,29 @@ void thread_destroy_current(void)
struct ktcb *task, *n; struct ktcb *task, *n;
/* Signal death to all threads under control of this pager */ /* Signal death to all threads under control of this pager */
mutex_lock(&curcont->ktcb_list.list_lock); spin_lock(&curcont->ktcb_list.list_lock);
list_foreach_removable_struct(task, n, list_foreach_removable_struct(task, n,
&curcont->ktcb_list.list, &curcont->ktcb_list.list,
task_list) { task_list) {
if (task->tid == current->tid || if (task->tid == current->tid ||
task->pagerid != current->tid) task->pagerid != current->tid)
continue; continue;
mutex_unlock(&curcont->ktcb_list.list_lock); spin_unlock(&curcont->ktcb_list.list_lock);
/* Here we wait for each to die */ /* Here we wait for each to die */
thread_suspend(task, TASK_EXITING); thread_suspend(task, TASK_EXITING);
mutex_lock(&curcont->ktcb_list.list_lock); spin_lock(&curcont->ktcb_list.list_lock);
} }
mutex_unlock(&curcont->ktcb_list.list_lock); spin_unlock(&curcont->ktcb_list.list_lock);
/* Destroy all children */ /* Destroy all children */
mutex_lock(&current->task_dead.list_lock); mutex_lock(&current->task_dead_mutex);
list_foreach_removable_struct(task, n, list_foreach_removable_struct(task, n,
&current->task_dead.list, &current->task_dead_list,
task_list) { task_list) {
tcb_delete(task); tcb_delete(task);
} }
mutex_unlock(&current->task_dead.list_lock); mutex_unlock(&current->task_dead_mutex);
/* Destroy self */ /* Destroy self */
sched_die_sync(); sched_die_sync();

View File

@@ -308,6 +308,7 @@ void dump_undef_abort(u32 undef_addr)
{ {
dprintk("Undefined instruction at address: ", undef_addr); dprintk("Undefined instruction at address: ", undef_addr);
printascii("Halting system...\n"); printascii("Halting system...\n");
BUG();
} }
extern int current_irq_nest_count; extern int current_irq_nest_count;

View File

@@ -262,6 +262,7 @@ void tcb_delete_schedule(void)
*/ */
void sched_die_pager(void) void sched_die_pager(void)
{ {
printk("Pager (%d) Exiting...\n", current->tid);
/* Remove from its list, callers get -ESRCH */ /* Remove from its list, callers get -ESRCH */
tcb_remove(current); tcb_remove(current);
@@ -301,7 +302,7 @@ void sched_die_pager(void)
*/ */
void sched_die_child(void) void sched_die_child(void)
{ {
int err; int locked;
/* /*
* Find pager, he _must_ be there because he never * Find pager, he _must_ be there because he never
@@ -309,9 +310,10 @@ void sched_die_child(void)
*/ */
struct ktcb *pager = tcb_find(current->pagerid); struct ktcb *pager = tcb_find(current->pagerid);
/* Lock its task_dead queue */ do {
if ((err = mutex_lock(&pager->task_dead.list_lock)) < 0) /* Busy spin without disabling preemption */
return err; locked = mutex_trylock(&pager->task_dead_mutex);
} while (!locked);
/* Remove from container task list, /* Remove from container task list,
* callers get -ESRCH */ * callers get -ESRCH */
@@ -335,7 +337,7 @@ void sched_die_child(void)
* Add self to pager's dead tasks list, * Add self to pager's dead tasks list,
* to be deleted by pager * to be deleted by pager
*/ */
__ktcb_list_add_nolock(current, &pager->task_dead); list_insert(&current->task_list, &pager->task_dead_list);
/* Now quit the scheduler */ /* Now quit the scheduler */
preempt_disable(); preempt_disable();
@@ -356,21 +358,17 @@ void sched_die_child(void)
* Unlock task_dead queue, * Unlock task_dead queue,
* pager can safely delete us * pager can safely delete us
*/ */
mutex_unlock(&pager->task_dead.list_lock); mutex_unlock(&pager->task_dead_mutex);
schedule(); schedule();
BUG(); BUG();
} }
void sched_die_sync(void) void sched_die_sync(void)
{ {
/* if (current->tid == current->pagerid)
* Infinitely retry if mutexes get interrupted sched_die_pager();
*/ else
while (1) sched_die_child();
if (current->tid == current->pagerid)
sched_die_pager();
else
sched_die_child();
} }
/* /*
@@ -397,17 +395,6 @@ void sched_suspend_sync(void)
BUG_ON(scheduler.prio_total < 0); BUG_ON(scheduler.prio_total < 0);
preempt_enable(); preempt_enable();
/*
* Async wake up any waiting pagers
*
* If we're not a pager, then a pager must have
* signalled us to suspend, and it must have been
* waiting for us to wake it up when we suspend.
* We do it here.
*
* If though, we _are_ a pager that is suspending,
* we silently do so. Noone is waiting us.
*/
if (current->pagerid != current->tid) if (current->pagerid != current->tid)
wake_up(&current->wqh_pager, 0); wake_up(&current->wqh_pager, 0);
@@ -426,17 +413,6 @@ void sched_suspend_async(void)
/* This will make sure we yield soon */ /* This will make sure we yield soon */
preempt_enable(); preempt_enable();
/*
* Async wake up any waiting pagers
*
* If we're not a pager, then a pager must have
* signalled us to suspend, and it must have been
* waiting for us to wake it up when we suspend.
* We do it here.
*
* If though, we _are_ a pager that is suspending,
* we silently do so. Noone is waiting us.
*/
if (current->pagerid != current->tid) if (current->pagerid != current->tid)
wake_up_task(tcb_find(current->pagerid), 0); wake_up_task(tcb_find(current->pagerid), 0);

View File

@@ -20,7 +20,7 @@
void init_ktcb_list(struct ktcb_list *ktcb_list) void init_ktcb_list(struct ktcb_list *ktcb_list)
{ {
memset(ktcb_list, 0, sizeof(*ktcb_list)); memset(ktcb_list, 0, sizeof(*ktcb_list));
mutex_init(&ktcb_list->list_lock); spin_lock_init(&ktcb_list->list_lock);
link_init(&ktcb_list->list); link_init(&ktcb_list->list);
} }
@@ -30,8 +30,8 @@ void tcb_init(struct ktcb *new)
link_init(&new->task_list); link_init(&new->task_list);
mutex_init(&new->thread_control_lock); mutex_init(&new->thread_control_lock);
init_ktcb_list(&new->task_dead); mutex_init(&new->task_dead_mutex);
link_init(&new->task_dead_list);
cap_list_init(&new->cap_list); cap_list_init(&new->cap_list);
/* Initialise task's scheduling state and parameters. */ /* Initialise task's scheduling state and parameters. */
@@ -104,14 +104,14 @@ struct ktcb *tcb_find_by_space(l4id_t spid)
{ {
struct ktcb *task; struct ktcb *task;
mutex_lock(&curcont->ktcb_list.list_lock); spin_lock(&curcont->ktcb_list.list_lock);
list_foreach_struct(task, &curcont->ktcb_list.list, task_list) { list_foreach_struct(task, &curcont->ktcb_list.list, task_list) {
if (task->space->spid == spid) { if (task->space->spid == spid) {
mutex_unlock(&curcont->ktcb_list.list_lock); spin_unlock(&curcont->ktcb_list.list_lock);
return task; return task;
} }
} }
mutex_unlock(&curcont->ktcb_list.list_lock); spin_unlock(&curcont->ktcb_list.list_lock);
return 0; return 0;
} }
@@ -122,51 +122,44 @@ struct ktcb *tcb_find(l4id_t tid)
if (current->tid == tid) if (current->tid == tid)
return current; return current;
mutex_lock(&curcont->ktcb_list.list_lock); spin_lock(&curcont->ktcb_list.list_lock);
list_foreach_struct(task, &curcont->ktcb_list.list, task_list) { list_foreach_struct(task, &curcont->ktcb_list.list, task_list) {
if (task->tid == tid) { if (task->tid == tid) {
mutex_unlock(&curcont->ktcb_list.list_lock); spin_unlock(&curcont->ktcb_list.list_lock);
return task; return task;
} }
} }
mutex_unlock(&curcont->ktcb_list.list_lock); spin_unlock(&curcont->ktcb_list.list_lock);
return 0; return 0;
} }
void ktcb_list_add(struct ktcb *new, struct ktcb_list *ktcb_list) void ktcb_list_add(struct ktcb *new, struct ktcb_list *ktcb_list)
{ {
mutex_lock(&ktcb_list->list_lock); spin_lock(&ktcb_list->list_lock);
BUG_ON(!list_empty(&new->task_list));
BUG_ON(!++ktcb_list->count);
list_insert(&new->task_list, &ktcb_list->list);
mutex_unlock(&ktcb_list->list_lock);
}
void __ktcb_list_add_nolock(struct ktcb *new, struct ktcb_list *ktcb_list)
{
BUG_ON(!list_empty(&new->task_list)); BUG_ON(!list_empty(&new->task_list));
BUG_ON(!++ktcb_list->count); BUG_ON(!++ktcb_list->count);
list_insert(&new->task_list, &ktcb_list->list); list_insert(&new->task_list, &ktcb_list->list);
spin_unlock(&ktcb_list->list_lock);
} }
void tcb_add(struct ktcb *new) void tcb_add(struct ktcb *new)
{ {
struct container *c = new->container; struct container *c = new->container;
mutex_lock(&c->ktcb_list.list_lock); spin_lock(&c->ktcb_list.list_lock);
BUG_ON(!list_empty(&new->task_list)); BUG_ON(!list_empty(&new->task_list));
BUG_ON(!++c->ktcb_list.count); BUG_ON(!++c->ktcb_list.count);
list_insert(&new->task_list, &c->ktcb_list.list); list_insert(&new->task_list, &c->ktcb_list.list);
mutex_unlock(&c->ktcb_list.list_lock); spin_unlock(&c->ktcb_list.list_lock);
} }
void tcb_remove(struct ktcb *new) void tcb_remove(struct ktcb *new)
{ {
mutex_lock(&curcont->ktcb_list.list_lock); spin_lock(&curcont->ktcb_list.list_lock);
BUG_ON(list_empty(&new->task_list)); BUG_ON(list_empty(&new->task_list));
BUG_ON(--curcont->ktcb_list.count < 0); BUG_ON(--curcont->ktcb_list.count < 0);
list_remove_init(&new->task_list); list_remove_init(&new->task_list);
mutex_unlock(&curcont->ktcb_list.list_lock); spin_unlock(&curcont->ktcb_list.list_lock);
} }
/* Offsets for ktcb fields that are accessed from assembler */ /* Offsets for ktcb fields that are accessed from assembler */

View File

@@ -132,7 +132,7 @@ int mutex_lock(struct mutex *mutex)
/* Did we wake up normally or get interrupted */ /* Did we wake up normally or get interrupted */
if (current->flags & TASK_INTERRUPTED) { if (current->flags & TASK_INTERRUPTED) {
printk("Thread (%d) interrupted on mutex sleep\n", current->tid); printk("XXXXXXXXXXXXXXXX (%d) Interrupted\n", current->tid);
current->flags &= ~TASK_INTERRUPTED; current->flags &= ~TASK_INTERRUPTED;
return -EINTR; return -EINTR;
} }