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
|
/* FIXME: Use a table with registrable pointers to custom data
|
||||||
* structures */
|
* structures */
|
||||||
|
|
||||||
/* nosv task */
|
/* nOS-V stack of tasks: points to the runnable task. */
|
||||||
struct nosv_task *task;
|
struct nosv_task *task_stack;
|
||||||
/* nosv effective task, which is what is currently executing */
|
|
||||||
struct nosv_task *running_task;
|
|
||||||
|
|
||||||
/* Channels are used to output the emulator state in PRV */
|
/* Channels are used to output the emulator state in PRV */
|
||||||
struct ovni_chan chan[CHAN_MAX];
|
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
|
static void
|
||||||
pre_task_execute(struct ovni_emu *emu)
|
pre_task_execute(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_task *task;
|
struct nosv_task *task, *top;
|
||||||
int taskid;
|
int taskid;
|
||||||
|
|
||||||
|
top = emu->cur_thread->task_stack;
|
||||||
taskid = emu->cur_ev->payload.i32[0];
|
taskid = emu->cur_ev->payload.i32[0];
|
||||||
|
|
||||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
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)
|
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||||
die("thread state is not running\n");
|
die("thread state is not running\n");
|
||||||
|
|
||||||
if(emu->cur_thread->task != NULL)
|
if(top == task)
|
||||||
die("thread already has a task\n");
|
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->state = TASK_ST_RUNNING;
|
||||||
task->thread = emu->cur_thread;
|
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);
|
dbg("task id=%d runs now\n", task->id);
|
||||||
}
|
}
|
||||||
@ -146,9 +150,10 @@ pre_task_execute(struct ovni_emu *emu)
|
|||||||
static void
|
static void
|
||||||
pre_task_pause(struct ovni_emu *emu)
|
pre_task_pause(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_task *task;
|
struct nosv_task *task, *top;
|
||||||
int taskid;
|
int taskid;
|
||||||
|
|
||||||
|
top = emu->cur_thread->task_stack;
|
||||||
taskid = emu->cur_ev->payload.i32[0];
|
taskid = emu->cur_ev->payload.i32[0];
|
||||||
|
|
||||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
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)
|
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||||
die("thread state is not running\n");
|
die("thread state is not running\n");
|
||||||
|
|
||||||
if(emu->cur_thread->task != task)
|
if(top != task)
|
||||||
die("thread has assigned a different task\n");
|
die("thread has assigned a different task\n");
|
||||||
|
|
||||||
if(emu->cur_thread != task->thread)
|
if(emu->cur_thread != task->thread)
|
||||||
die("task is assigned to a different thread\n");
|
die("task is assigned to a different thread\n");
|
||||||
|
|
||||||
emu->cur_thread->running_task = NULL;
|
|
||||||
|
|
||||||
task->state = TASK_ST_PAUSED;
|
task->state = TASK_ST_PAUSED;
|
||||||
|
|
||||||
dbg("task id=%d pauses\n", task->id);
|
dbg("task id=%d pauses\n", task->id);
|
||||||
@ -178,9 +181,10 @@ pre_task_pause(struct ovni_emu *emu)
|
|||||||
static void
|
static void
|
||||||
pre_task_resume(struct ovni_emu *emu)
|
pre_task_resume(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_task *task;
|
struct nosv_task *task, *top;
|
||||||
int taskid;
|
int taskid;
|
||||||
|
|
||||||
|
top = emu->cur_thread->task_stack;
|
||||||
taskid = emu->cur_ev->payload.i32[0];
|
taskid = emu->cur_ev->payload.i32[0];
|
||||||
|
|
||||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
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)
|
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||||
die("thread is not running\n");
|
die("thread is not running\n");
|
||||||
|
|
||||||
if(emu->cur_thread->task != task)
|
if(top != task)
|
||||||
die("thread has assigned a different task\n");
|
die("thread has assigned a different task\n");
|
||||||
|
|
||||||
if(emu->cur_thread != task->thread)
|
if(emu->cur_thread != task->thread)
|
||||||
die("task is assigned to a different thread\n");
|
die("task is assigned to a different thread\n");
|
||||||
|
|
||||||
emu->cur_thread->running_task = task;
|
|
||||||
|
|
||||||
task->state = TASK_ST_RUNNING;
|
task->state = TASK_ST_RUNNING;
|
||||||
|
|
||||||
dbg("task id=%d resumes\n", task->id);
|
dbg("task id=%d resumes\n", task->id);
|
||||||
@ -211,9 +213,10 @@ pre_task_resume(struct ovni_emu *emu)
|
|||||||
static void
|
static void
|
||||||
pre_task_end(struct ovni_emu *emu)
|
pre_task_end(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_task *task;
|
struct nosv_task *task, *top;
|
||||||
int taskid;
|
int taskid;
|
||||||
|
|
||||||
|
top = emu->cur_thread->task_stack;
|
||||||
taskid = emu->cur_ev->payload.i32[0];
|
taskid = emu->cur_ev->payload.i32[0];
|
||||||
|
|
||||||
HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task);
|
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)
|
if(emu->cur_thread->state != TH_ST_RUNNING)
|
||||||
die("thread is not running\n");
|
die("thread is not running\n");
|
||||||
|
|
||||||
if(emu->cur_thread->task != task)
|
if(top != task)
|
||||||
die("thread has assigned a different task\n");
|
die("thread has assigned a different task\n");
|
||||||
|
|
||||||
if(emu->cur_thread != task->thread)
|
if(emu->cur_thread != task->thread)
|
||||||
@ -235,8 +238,8 @@ pre_task_end(struct ovni_emu *emu)
|
|||||||
|
|
||||||
task->state = TASK_ST_DEAD;
|
task->state = TASK_ST_DEAD;
|
||||||
task->thread = NULL;
|
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);
|
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;
|
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)
|
switch(emu->cur_ev->header.value)
|
||||||
{
|
{
|
||||||
@ -333,7 +336,7 @@ pre_task(struct ovni_emu *emu)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
next_task = emu->cur_thread->running_task;
|
next_task = emu->cur_thread->task_stack;
|
||||||
|
|
||||||
/* Unless we're creating a task, register the switch */
|
/* Unless we're creating a task, register the switch */
|
||||||
if(emu->cur_ev->header.value != 'c')
|
if(emu->cur_ev->header.value != 'c')
|
||||||
|
Loading…
Reference in New Issue
Block a user