mirror of
https://github.com/drasko/codezero.git
synced 2026-10-01 01:29:27 +02:00
l4_exit() works with a reasonable sched_die_sync()
Next: Killing other tasks more cleanly, and waiting on children
This commit is contained in:
+43
-1
@@ -8,13 +8,55 @@
|
|||||||
#include <capability.h>
|
#include <capability.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <tests.h>
|
#include <tests.h>
|
||||||
|
#include <l4lib/arch/syslib.h>
|
||||||
|
#include <l4lib/arch/syscalls.h>
|
||||||
|
#include <l4/api/space.h>
|
||||||
|
|
||||||
|
int exit_test_thread(void *arg)
|
||||||
|
{
|
||||||
|
l4_exit(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exit_test(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct task_ids ids;
|
||||||
|
|
||||||
|
/* Create and run a new thread */
|
||||||
|
if ((ret = thread_create(exit_test_thread, 0,
|
||||||
|
TC_SHARE_SPACE | TC_AS_PAGER,
|
||||||
|
&ids)) < 0) {
|
||||||
|
printf("Top-level simple_pager creation failed.\n");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait on it */
|
||||||
|
if ((ret = l4_thread_control(THREAD_WAIT, &ids)) >= 0)
|
||||||
|
printf("Success. Paged child returned %d\n", ret);
|
||||||
|
else
|
||||||
|
printf("Error. Wait on (%d) failed. err = %d\n",
|
||||||
|
ids.tid, ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
printf("%s: Container %s started\n",
|
printf("%s: Container %s started\n",
|
||||||
__CONTAINER__, __CONTAINER_NAME__);
|
__CONTAINER__, __CONTAINER_NAME__);
|
||||||
|
|
||||||
capability_test();
|
//capability_test();
|
||||||
|
|
||||||
|
//exit_test();
|
||||||
|
|
||||||
|
/* Now quit to demo self-paging quit */
|
||||||
|
l4_exit(0);
|
||||||
|
/* Now quit by null pointer */
|
||||||
|
// *((int *)0) = 5;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,8 +85,7 @@ int capability_test(void)
|
|||||||
*/
|
*/
|
||||||
if ((err = thread_create(simple_pager_thread,
|
if ((err = thread_create(simple_pager_thread,
|
||||||
&TEST_MUST_FAIL,
|
&TEST_MUST_FAIL,
|
||||||
TC_SHARE_SPACE |
|
TC_SHARE_SPACE, &ids)) < 0) {
|
||||||
TC_AS_PAGER, &ids)) < 0) {
|
|
||||||
printf("Top-level simple_pager creation failed.\n");
|
printf("Top-level simple_pager creation failed.\n");
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ extern struct scheduler scheduler;
|
|||||||
void sched_init_runqueue(struct runqueue *rq);
|
void sched_init_runqueue(struct runqueue *rq);
|
||||||
void sched_init_task(struct ktcb *task, int priority);
|
void sched_init_task(struct ktcb *task, int priority);
|
||||||
void sched_prepare_sleep(void);
|
void sched_prepare_sleep(void);
|
||||||
|
void sched_die_sync(void);
|
||||||
void sched_suspend_sync(void);
|
void sched_suspend_sync(void);
|
||||||
void sched_suspend_async(void);
|
void sched_suspend_async(void);
|
||||||
void sched_resume_sync(struct ktcb *task);
|
void sched_resume_sync(struct ktcb *task);
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ struct ktcb {
|
|||||||
l4id_t tid; /* Global thread id */
|
l4id_t tid; /* Global thread id */
|
||||||
l4id_t tgid; /* Global thread group id */
|
l4id_t tgid; /* Global thread group id */
|
||||||
|
|
||||||
|
/* Other related threads */
|
||||||
|
l4id_t pagerid;
|
||||||
|
|
||||||
/* Flags to indicate various task status */
|
/* Flags to indicate various task status */
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
@@ -73,11 +76,9 @@ struct ktcb {
|
|||||||
/* Lock for blocking thread state modifications via a syscall */
|
/* Lock for blocking thread state modifications via a syscall */
|
||||||
struct mutex thread_control_lock;
|
struct mutex thread_control_lock;
|
||||||
|
|
||||||
/* Other related threads */
|
|
||||||
l4id_t pagerid;
|
|
||||||
|
|
||||||
u32 ts_need_resched; /* Scheduling flag */
|
u32 ts_need_resched; /* Scheduling flag */
|
||||||
enum task_state state;
|
enum task_state state;
|
||||||
|
|
||||||
struct link task_list; /* Global task list. */
|
struct link task_list; /* Global task list. */
|
||||||
|
|
||||||
/* UTCB related, see utcb.txt in docs */
|
/* UTCB related, see utcb.txt in docs */
|
||||||
@@ -102,9 +103,7 @@ struct ktcb {
|
|||||||
struct pager *pager;
|
struct pager *pager;
|
||||||
|
|
||||||
/* Capability lists */
|
/* Capability lists */
|
||||||
struct cap_list cap_list; /* Own private capabilities */
|
struct cap_list cap_list; /* Own private capabilities */
|
||||||
struct cap_list tgroup_cap_list; /* Caps shared with thread group */
|
|
||||||
struct cap_list pager_cap_list; /* Caps shared with paged children */
|
|
||||||
|
|
||||||
/* Fields for ipc rendezvous */
|
/* Fields for ipc rendezvous */
|
||||||
struct waitqueue_head wqh_recv;
|
struct waitqueue_head wqh_recv;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ int capability_share(unsigned int share_flags)
|
|||||||
cap_list_move(&curcont->cap_list,
|
cap_list_move(&curcont->cap_list,
|
||||||
¤t->cap_list);
|
¤t->cap_list);
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
case CAP_SHARE_CHILD:
|
case CAP_SHARE_CHILD:
|
||||||
/*
|
/*
|
||||||
* Move own capabilities to paged-children
|
* Move own capabilities to paged-children
|
||||||
@@ -97,6 +98,7 @@ int capability_share(unsigned int share_flags)
|
|||||||
¤t->cap_list);
|
¤t->cap_list);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -200,7 +200,7 @@ void thread_destroy_current(void)
|
|||||||
/* Indicate we want to become zombie on suspend */
|
/* Indicate we want to become zombie on suspend */
|
||||||
current->flags |= TASK_EXITING;
|
current->flags |= TASK_EXITING;
|
||||||
|
|
||||||
sched_suspend_sync();
|
sched_die_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Runs a thread for the first time */
|
/* Runs a thread for the first time */
|
||||||
|
|||||||
@@ -144,8 +144,8 @@ int init_pager(struct pager *pager,
|
|||||||
page_align_up(pager->memsize),
|
page_align_up(pager->memsize),
|
||||||
MAP_USR_DEFAULT_FLAGS, TASK_PGD(task));
|
MAP_USR_DEFAULT_FLAGS, TASK_PGD(task));
|
||||||
|
|
||||||
/* Move capability list from dummy to task's cap list */
|
/* Move capability list from dummy to task's space cap list */
|
||||||
cap_list_move(&task->cap_list, ¤t->cap_list);
|
cap_list_move(&task->space->cap_list, ¤t->cap_list);
|
||||||
|
|
||||||
/* Initialize task scheduler parameters */
|
/* Initialize task scheduler parameters */
|
||||||
sched_init_task(task, TASK_PRIO_PAGER);
|
sched_init_task(task, TASK_PRIO_PAGER);
|
||||||
|
|||||||
@@ -226,6 +226,70 @@ void sched_resume_async(struct ktcb *task)
|
|||||||
RQ_ADD_FRONT);
|
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
|
||||||
|
|
||||||
|
void sched_die_sync(void)
|
||||||
|
{
|
||||||
|
/* Remove from its list, callers get -ESRCH */
|
||||||
|
tcb_remove(current);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there are any sleepers on any of the task's
|
||||||
|
* waitqueues, we need to wake those tasks up.
|
||||||
|
*/
|
||||||
|
wake_up_all(¤t->wqh_send, 0);
|
||||||
|
wake_up_all(¤t->wqh_recv, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're a self-paging thread. We're gonna
|
||||||
|
* delete ourself and disappear from the
|
||||||
|
* system as soon as we schedule
|
||||||
|
*/
|
||||||
|
preempt_disable();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TOO LONG!
|
||||||
|
*/
|
||||||
|
tcb_delete(current);
|
||||||
|
|
||||||
|
sched_rq_remove_task(current);
|
||||||
|
current->state = TASK_INACTIVE;
|
||||||
|
scheduler.prio_total -= current->priority;
|
||||||
|
BUG_ON(scheduler.prio_total < 0);
|
||||||
|
|
||||||
|
/* As soon as we schedule, we're gone */
|
||||||
|
preempt_enable();
|
||||||
|
schedule();
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: Could do these as sched_prepare_suspend()
|
* NOTE: Could do these as sched_prepare_suspend()
|
||||||
* + schedule() or need_resched = 1
|
* + schedule() or need_resched = 1
|
||||||
|
|||||||
+2
-4
@@ -31,8 +31,6 @@ void tcb_init(struct ktcb *new)
|
|||||||
mutex_init(&new->thread_control_lock);
|
mutex_init(&new->thread_control_lock);
|
||||||
|
|
||||||
cap_list_init(&new->cap_list);
|
cap_list_init(&new->cap_list);
|
||||||
cap_list_init(&new->tgroup_cap_list);
|
|
||||||
cap_list_init(&new->pager_cap_list);
|
|
||||||
|
|
||||||
/* Initialise task's scheduling state and parameters. */
|
/* Initialise task's scheduling state and parameters. */
|
||||||
sched_init_task(new, TASK_PRIO_NORMAL);
|
sched_init_task(new, TASK_PRIO_NORMAL);
|
||||||
@@ -71,8 +69,8 @@ void tcb_delete(struct ktcb *tcb)
|
|||||||
BUG_ON(tcb->wqh_send.sleepers > 0);
|
BUG_ON(tcb->wqh_send.sleepers > 0);
|
||||||
BUG_ON(tcb->wqh_recv.sleepers > 0);
|
BUG_ON(tcb->wqh_recv.sleepers > 0);
|
||||||
BUG_ON(!list_empty(&tcb->task_list));
|
BUG_ON(!list_empty(&tcb->task_list));
|
||||||
BUG_ON(!list_empty(&tcb->rq_list));
|
BUG_ON(!list_empty(&tcb->rq_list) && tcb != current);
|
||||||
BUG_ON(tcb->rq);
|
BUG_ON(tcb->rq && tcb != current);
|
||||||
BUG_ON(tcb->nlocks);
|
BUG_ON(tcb->nlocks);
|
||||||
BUG_ON(tcb->waiting_on);
|
BUG_ON(tcb->waiting_on);
|
||||||
BUG_ON(tcb->wq);
|
BUG_ON(tcb->wq);
|
||||||
|
|||||||
Reference in New Issue
Block a user