Use only a stack of tasks for nosv
The running task is inferred from the task on top of the stack. Also, allow a nested task to execute when there are others in the stack.
This commit is contained in:
parent
26a29d3eda
commit
70891355ec
6
emu.h
6
emu.h
@ -286,10 +286,8 @@ struct ovni_ethread {
|
||||
/* FIXME: Use a table with registrable pointers to custom data
|
||||
* structures */
|
||||
|
||||
/* nosv task */
|
||||
struct nosv_task *task;
|
||||
/* nosv effective task, which is what is currently executing */
|
||||
struct nosv_task *running_task;
|
||||
/* nOS-V stack of tasks: points to the runnable task. */
|
||||
struct nosv_task *task_stack;
|
||||
|
||||
/* Channels are used to output the emulator state in PRV */
|
||||
struct ovni_chan chan[CHAN_MAX];
|
||||
|
41
emu_nosv.c
41
emu_nosv.c
@ -113,9 +113,10 @@ pre_task_create(struct ovni_emu *emu)
|
||||
static void
|
||||
pre_task_execute(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
struct nosv_task *task, *top;
|
||||
int taskid;
|
||||
|
||||
top = emu->cur_thread->task_stack;
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
||||
@ -132,13 +133,16 @@ pre_task_execute(struct ovni_emu *emu)
|
||||
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||
die("thread state is not running\n");
|
||||
|
||||
if(emu->cur_thread->task != NULL)
|
||||
die("thread already has a task\n");
|
||||
if(top == task)
|
||||
die("thread already has assigned task %d\n", taskid);
|
||||
|
||||
if(top && top->state != TASK_ST_RUNNING)
|
||||
die("cannot execute a nested task from a non-running task\n");
|
||||
|
||||
task->state = TASK_ST_RUNNING;
|
||||
task->thread = emu->cur_thread;
|
||||
DL_PREPEND(emu->cur_thread->task, task);
|
||||
emu->cur_thread->running_task = task;
|
||||
|
||||
DL_PREPEND(emu->cur_thread->task_stack, task);
|
||||
|
||||
dbg("task id=%d runs now\n", task->id);
|
||||
}
|
||||
@ -146,9 +150,10 @@ pre_task_execute(struct ovni_emu *emu)
|
||||
static void
|
||||
pre_task_pause(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
struct nosv_task *task, *top;
|
||||
int taskid;
|
||||
|
||||
top = emu->cur_thread->task_stack;
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
||||
@ -162,14 +167,12 @@ pre_task_pause(struct ovni_emu *emu)
|
||||
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||
die("thread state is not running\n");
|
||||
|
||||
if(emu->cur_thread->task != task)
|
||||
if(top != task)
|
||||
die("thread has assigned a different task\n");
|
||||
|
||||
if(emu->cur_thread != task->thread)
|
||||
die("task is assigned to a different thread\n");
|
||||
|
||||
emu->cur_thread->running_task = NULL;
|
||||
|
||||
task->state = TASK_ST_PAUSED;
|
||||
|
||||
dbg("task id=%d pauses\n", task->id);
|
||||
@ -178,9 +181,10 @@ pre_task_pause(struct ovni_emu *emu)
|
||||
static void
|
||||
pre_task_resume(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
struct nosv_task *task, *top;
|
||||
int taskid;
|
||||
|
||||
top = emu->cur_thread->task_stack;
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
||||
@ -194,14 +198,12 @@ pre_task_resume(struct ovni_emu *emu)
|
||||
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||
die("thread is not running\n");
|
||||
|
||||
if(emu->cur_thread->task != task)
|
||||
if(top != task)
|
||||
die("thread has assigned a different task\n");
|
||||
|
||||
if(emu->cur_thread != task->thread)
|
||||
die("task is assigned to a different thread\n");
|
||||
|
||||
emu->cur_thread->running_task = task;
|
||||
|
||||
task->state = TASK_ST_RUNNING;
|
||||
|
||||
dbg("task id=%d resumes\n", task->id);
|
||||
@ -211,9 +213,10 @@ pre_task_resume(struct ovni_emu *emu)
|
||||
static void
|
||||
pre_task_end(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
struct nosv_task *task, *top;
|
||||
int taskid;
|
||||
|
||||
top = emu->cur_thread->task_stack;
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
||||
@ -227,7 +230,7 @@ pre_task_end(struct ovni_emu *emu)
|
||||
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||
die("thread is not running\n");
|
||||
|
||||
if(emu->cur_thread->task != task)
|
||||
if(top != task)
|
||||
die("thread has assigned a different task\n");
|
||||
|
||||
if(emu->cur_thread != task->thread)
|
||||
@ -235,8 +238,8 @@ pre_task_end(struct ovni_emu *emu)
|
||||
|
||||
task->state = TASK_ST_DEAD;
|
||||
task->thread = NULL;
|
||||
DL_DELETE(emu->cur_thread->task, task);
|
||||
emu->cur_thread->running_task = emu->cur_thread->task;
|
||||
|
||||
DL_DELETE(emu->cur_thread->task_stack, task);
|
||||
|
||||
dbg("task id=%d ends\n", task->id);
|
||||
}
|
||||
@ -320,7 +323,7 @@ pre_task(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *prev_task, *next_task;
|
||||
|
||||
prev_task = emu->cur_thread->running_task;
|
||||
prev_task = emu->cur_thread->task_stack;
|
||||
|
||||
switch(emu->cur_ev->header.value)
|
||||
{
|
||||
@ -333,7 +336,7 @@ pre_task(struct ovni_emu *emu)
|
||||
abort();
|
||||
}
|
||||
|
||||
next_task = emu->cur_thread->running_task;
|
||||
next_task = emu->cur_thread->task_stack;
|
||||
|
||||
/* Unless we're creating a task, register the switch */
|
||||
if(emu->cur_ev->header.value != 'c')
|
||||
|
Loading…
Reference in New Issue
Block a user