Support for nested tasks
This commit is contained in:
parent
ce9a68fc7e
commit
a8b1256375
7
chan.c
7
chan.c
@ -209,13 +209,6 @@ chan_set(struct ovni_chan *chan, int st)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
chan_enable_and_set(struct ovni_chan *chan, int st)
|
|
||||||
{
|
|
||||||
chan_enable(chan, 1);
|
|
||||||
chan_set(chan, st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
chan_push(struct ovni_chan *chan, int st)
|
chan_push(struct ovni_chan *chan, int st)
|
||||||
{
|
{
|
||||||
|
3
chan.h
3
chan.h
@ -56,9 +56,6 @@ chan_is_enabled(struct ovni_chan *chan);
|
|||||||
void
|
void
|
||||||
chan_set(struct ovni_chan *chan, int st);
|
chan_set(struct ovni_chan *chan, int st);
|
||||||
|
|
||||||
void
|
|
||||||
chan_enable_and_set(struct ovni_chan *chan, int st);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
chan_push(struct ovni_chan *chan, int st);
|
chan_push(struct ovni_chan *chan, int st);
|
||||||
|
|
||||||
|
6
emu.h
6
emu.h
@ -112,6 +112,10 @@ struct nosv_task {
|
|||||||
struct ovni_ethread *thread;
|
struct ovni_ethread *thread;
|
||||||
enum nosv_task_state state;
|
enum nosv_task_state state;
|
||||||
UT_hash_handle hh;
|
UT_hash_handle hh;
|
||||||
|
|
||||||
|
/* List handle for nested task support */
|
||||||
|
struct nosv_task *next;
|
||||||
|
struct nosv_task *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nosv_task_type {
|
struct nosv_task_type {
|
||||||
@ -284,6 +288,8 @@ struct ovni_ethread {
|
|||||||
|
|
||||||
/* nosv task */
|
/* nosv task */
|
||||||
struct nosv_task *task;
|
struct nosv_task *task;
|
||||||
|
/* 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];
|
||||||
|
84
emu_nosv.c
84
emu_nosv.c
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
|
#include "utlist.h"
|
||||||
|
|
||||||
#include "ovni.h"
|
#include "ovni.h"
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
@ -80,7 +81,7 @@ static void
|
|||||||
pre_task_create(struct ovni_emu *emu)
|
pre_task_create(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_task *task, *p = NULL;
|
struct nosv_task *task, *p = NULL;
|
||||||
|
|
||||||
task = calloc(1, sizeof(*task));
|
task = calloc(1, sizeof(*task));
|
||||||
|
|
||||||
if(task == NULL)
|
if(task == NULL)
|
||||||
@ -106,8 +107,6 @@ pre_task_create(struct ovni_emu *emu)
|
|||||||
/* Add the new task to the hash table */
|
/* Add the new task to the hash table */
|
||||||
HASH_ADD_INT(emu->cur_proc->tasks, id, task);
|
HASH_ADD_INT(emu->cur_proc->tasks, id, task);
|
||||||
|
|
||||||
emu->cur_task = task;
|
|
||||||
|
|
||||||
dbg("new task created id=%d\n", task->id);
|
dbg("new task created id=%d\n", task->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,9 +137,8 @@ pre_task_execute(struct ovni_emu *emu)
|
|||||||
|
|
||||||
task->state = TASK_ST_RUNNING;
|
task->state = TASK_ST_RUNNING;
|
||||||
task->thread = emu->cur_thread;
|
task->thread = emu->cur_thread;
|
||||||
emu->cur_thread->task = task;
|
DL_PREPEND(emu->cur_thread->task, task);
|
||||||
|
emu->cur_thread->running_task = task;
|
||||||
emu->cur_task = task;
|
|
||||||
|
|
||||||
dbg("task id=%d runs now\n", task->id);
|
dbg("task id=%d runs now\n", task->id);
|
||||||
}
|
}
|
||||||
@ -170,9 +168,9 @@ pre_task_pause(struct ovni_emu *emu)
|
|||||||
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");
|
||||||
|
|
||||||
task->state = TASK_ST_PAUSED;
|
emu->cur_thread->running_task = NULL;
|
||||||
|
|
||||||
emu->cur_task = task;
|
task->state = TASK_ST_PAUSED;
|
||||||
|
|
||||||
dbg("task id=%d pauses\n", task->id);
|
dbg("task id=%d pauses\n", task->id);
|
||||||
}
|
}
|
||||||
@ -202,9 +200,9 @@ pre_task_resume(struct ovni_emu *emu)
|
|||||||
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");
|
||||||
|
|
||||||
task->state = TASK_ST_RUNNING;
|
emu->cur_thread->running_task = task;
|
||||||
|
|
||||||
emu->cur_task = task;
|
task->state = TASK_ST_RUNNING;
|
||||||
|
|
||||||
dbg("task id=%d resumes\n", task->id);
|
dbg("task id=%d resumes\n", task->id);
|
||||||
}
|
}
|
||||||
@ -237,13 +235,25 @@ pre_task_end(struct ovni_emu *emu)
|
|||||||
|
|
||||||
task->state = TASK_ST_DEAD;
|
task->state = TASK_ST_DEAD;
|
||||||
task->thread = NULL;
|
task->thread = NULL;
|
||||||
emu->cur_thread->task = NULL;
|
DL_DELETE(emu->cur_thread->task, task);
|
||||||
|
emu->cur_thread->running_task = emu->cur_thread->task;
|
||||||
emu->cur_task = task;
|
|
||||||
|
|
||||||
dbg("task id=%d ends\n", task->id);
|
dbg("task id=%d ends\n", task->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pre_task_not_running(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
struct ovni_ethread *th;
|
||||||
|
th = emu->cur_thread;
|
||||||
|
|
||||||
|
chan_set(&th->chan[CHAN_NOSV_TASKID], 0);
|
||||||
|
chan_set(&th->chan[CHAN_NOSV_TYPEID], 0);
|
||||||
|
chan_set(&th->chan[CHAN_NOSV_APPID], 0);
|
||||||
|
|
||||||
|
chan_pop(&th->chan[CHAN_NOSV_SUBSYSTEM], ST_NOSV_TASK_RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pre_task_running(struct ovni_emu *emu, struct nosv_task *task)
|
pre_task_running(struct ovni_emu *emu, struct nosv_task *task)
|
||||||
{
|
{
|
||||||
@ -273,28 +283,35 @@ pre_task_running(struct ovni_emu *emu, struct nosv_task *task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pre_task_not_running(struct ovni_emu *emu)
|
pre_task_switch(struct ovni_emu *emu, struct nosv_task *prev_task, struct nosv_task *next_task)
|
||||||
{
|
{
|
||||||
struct ovni_ethread *th;
|
struct ovni_ethread *th;
|
||||||
|
struct ovni_eproc *proc;
|
||||||
|
|
||||||
|
assert(prev_task);
|
||||||
|
assert(next_task);
|
||||||
|
assert(prev_task != next_task);
|
||||||
|
|
||||||
th = emu->cur_thread;
|
th = emu->cur_thread;
|
||||||
|
proc = emu->cur_proc;
|
||||||
|
|
||||||
chan_set(&th->chan[CHAN_NOSV_TASKID], 0);
|
assert(next_task->id > 0);
|
||||||
chan_set(&th->chan[CHAN_NOSV_TYPEID], 0);
|
assert(next_task->type_id > 0);
|
||||||
chan_set(&th->chan[CHAN_NOSV_APPID], 0);
|
assert(proc->appid > 0);
|
||||||
|
|
||||||
if(emu->cur_loom->rank_enabled)
|
chan_set(&th->chan[CHAN_NOSV_TASKID], next_task->id);
|
||||||
chan_set(&th->chan[CHAN_NOSV_RANK], 0);
|
|
||||||
|
|
||||||
chan_pop(&th->chan[CHAN_NOSV_SUBSYSTEM], ST_NOSV_TASK_RUNNING);
|
if (prev_task->type_id != next_task->type_id)
|
||||||
|
chan_set(&th->chan[CHAN_NOSV_TYPEID], next_task->type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pre_task(struct ovni_emu *emu)
|
pre_task(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_task *task;
|
struct nosv_task *prev_task, *next_task;
|
||||||
|
|
||||||
task = emu->cur_task;
|
assert(emu->cur_thread);
|
||||||
|
prev_task = emu->cur_thread->running_task;
|
||||||
|
|
||||||
switch(emu->cur_ev->header.value)
|
switch(emu->cur_ev->header.value)
|
||||||
{
|
{
|
||||||
@ -307,19 +324,16 @@ pre_task(struct ovni_emu *emu)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(emu->cur_ev->header.value)
|
next_task = emu->cur_thread->running_task;
|
||||||
{
|
|
||||||
case 'x':
|
// Unless we're creating a task, register the switch
|
||||||
case 'r':
|
if (emu->cur_ev->header.value != 'c') {
|
||||||
pre_task_running(emu, task);
|
if(!next_task)
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
case 'e':
|
|
||||||
pre_task_not_running(emu);
|
pre_task_not_running(emu);
|
||||||
break;
|
else if(!prev_task)
|
||||||
case 'c':
|
pre_task_running(emu, next_task);
|
||||||
default:
|
else
|
||||||
break;
|
pre_task_switch(emu, prev_task, next_task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +364,7 @@ pre_type_create(struct ovni_emu *emu)
|
|||||||
err("A task type with id %d already exists\n", *typeid);
|
err("A task type with id %d already exists\n", *typeid);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
type = calloc(1, sizeof(*type));
|
type = calloc(1, sizeof(*type));
|
||||||
|
|
||||||
if(type == NULL)
|
if(type == NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user