Update subsystem on nested tasks
Also check the return value of update_task_channels().
This commit is contained in:
parent
10de4c8f09
commit
e22e6a21e0
@ -76,31 +76,31 @@ static int
|
|||||||
chan_task_stopped(struct emu *emu)
|
chan_task_stopped(struct emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||||
|
struct chan *ch = th->m.ch;
|
||||||
|
|
||||||
struct value null = value_null();
|
struct value null = value_null();
|
||||||
if (chan_set(&th->m.ch[CH_TASKID], null) != 0) {
|
if (chan_set(&ch[CH_TASKID], null) != 0) {
|
||||||
err("chan_set taskid failed");
|
err("chan_set taskid failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (chan_set(&th->m.ch[CH_TYPE], null) != 0) {
|
if (chan_set(&ch[CH_TYPE], null) != 0) {
|
||||||
err("chan_set type failed");
|
err("chan_set type failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (chan_set(&th->m.ch[CH_APPID], null) != 0) {
|
if (chan_set(&ch[CH_APPID], null) != 0) {
|
||||||
err("chan_set appid failed");
|
err("chan_set appid failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proc *proc = emu->proc;
|
struct proc *proc = emu->proc;
|
||||||
if (proc->rank >= 0) {
|
if (proc->rank >= 0) {
|
||||||
if (chan_set(&th->m.ch[CH_RANK], null) != 0) {
|
if (chan_set(&ch[CH_RANK], null) != 0) {
|
||||||
err("chan_set rank failed");
|
err("chan_set rank failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Do we need this transition? */
|
if (chan_pop(&ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
|
||||||
if (chan_pop(&th->m.ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
|
|
||||||
err("chan_pop subsystem failed");
|
err("chan_pop subsystem failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -156,10 +156,10 @@ chan_task_running(struct emu *emu, struct task *task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
chan_task_switch(struct emu *emu,
|
chan_task_switch(struct emu *emu, struct task *prev, struct task *next, char tr)
|
||||||
struct task *prev, struct task *next)
|
|
||||||
{
|
{
|
||||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||||
|
struct chan *ch = th->m.ch;
|
||||||
|
|
||||||
if (!prev || !next) {
|
if (!prev || !next) {
|
||||||
err("cannot switch to or from a NULL task");
|
err("cannot switch to or from a NULL task");
|
||||||
@ -188,18 +188,32 @@ chan_task_switch(struct emu *emu,
|
|||||||
|
|
||||||
/* No need to change the rank or app ID as we will switch
|
/* No need to change the rank or app ID as we will switch
|
||||||
* to tasks from same thread */
|
* to tasks from same thread */
|
||||||
if (chan_set(&th->m.ch[CH_TASKID], value_int64(next->id)) != 0) {
|
if (chan_set(&ch[CH_TASKID], value_int64(next->id)) != 0) {
|
||||||
err("chan_set taskid failed");
|
err("chan_set taskid failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: test when switching to another task with the same type. We
|
/* TODO: test when switching to another task with the same type. We
|
||||||
* should emit the same type state value as previous task. */
|
* should emit the same type state value as previous task. */
|
||||||
if (chan_set(&th->m.ch[CH_TYPE], value_int64(next->type->gid)) != 0) {
|
if (chan_set(&ch[CH_TYPE], value_int64(next->type->gid)) != 0) {
|
||||||
err("chan_set type failed");
|
err("chan_set type failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the subsystem depending if we are pushing (X) or
|
||||||
|
* poping (E) a task from the stack */
|
||||||
|
if (tr == 'X') {
|
||||||
|
if (chan_push(&ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
|
||||||
|
err("chan_push subsystem failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (tr == 'E') {
|
||||||
|
if (chan_pop(&ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
|
||||||
|
err("chan_pop subsystem failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,8 +289,7 @@ expand_transition_value(struct emu *emu, int was_running, int runs_now, char *tr
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
update_task_channels(struct emu *emu,
|
update_task_channels(struct emu *emu, char tr, struct task *prev, struct task *next)
|
||||||
char tr, struct task *prev, struct task *next)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
switch (tr) {
|
switch (tr) {
|
||||||
@ -291,7 +304,7 @@ update_task_channels(struct emu *emu,
|
|||||||
/* Additional nested transitions */
|
/* Additional nested transitions */
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'E':
|
case 'E':
|
||||||
ret = chan_task_switch(emu, prev, next);
|
ret = chan_task_switch(emu, prev, next, tr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err("unexpected transition value %c", tr);
|
err("unexpected transition value %c", tr);
|
||||||
@ -307,8 +320,22 @@ update_task_channels(struct emu *emu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
enforce_task_rules(struct emu *emu, char tr, struct task *next)
|
enforce_task_rules(struct emu *emu, char tr, struct task_stack *stack, struct task *next)
|
||||||
{
|
{
|
||||||
|
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||||
|
struct value ss;
|
||||||
|
if (chan_read(&th->m.ch[CH_SUBSYSTEM], &ss) != 0) {
|
||||||
|
err("chan_read failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is no task in the stack, the subsystem must not be
|
||||||
|
* running a task */
|
||||||
|
if (stack->top == NULL && ss.type == VALUE_INT64 && ss.i == ST_TASK_RUNNING) {
|
||||||
|
err("task stack empty but subsystem is Task running");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (tr != 'x' && tr != 'X')
|
if (tr != 'x' && tr != 'X')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -320,17 +347,9 @@ enforce_task_rules(struct emu *emu, char tr, struct task *next)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
|
||||||
struct value ss;
|
|
||||||
if (chan_read(&th->m.ch[CH_SUBSYSTEM], &ss) != 0) {
|
|
||||||
err("chan_read failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ss.type == VALUE_INT64 && ss.i != ST_TASK_RUNNING) {
|
if (ss.type == VALUE_INT64 && ss.i != ST_TASK_RUNNING) {
|
||||||
err("wrong subsystem state on task begin");
|
err("wrong subsystem state on task begin");
|
||||||
//return -1;
|
return -1;
|
||||||
return 0; // FIXME
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -352,18 +371,21 @@ update_task(struct emu *emu)
|
|||||||
|
|
||||||
struct task *next = task_get_running(stack);
|
struct task *next = task_get_running(stack);
|
||||||
|
|
||||||
|
char tr;
|
||||||
int was_running = (prev != NULL);
|
int was_running = (prev != NULL);
|
||||||
int runs_now = (next != NULL);
|
int runs_now = (next != NULL);
|
||||||
char tr;
|
|
||||||
if (expand_transition_value(emu, was_running, runs_now, &tr) != 0) {
|
if (expand_transition_value(emu, was_running, runs_now, &tr) != 0) {
|
||||||
err("expand_transition_value failed");
|
err("expand_transition_value failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the task related channels now */
|
/* Update the task related channels now */
|
||||||
update_task_channels(emu, tr, prev, next);
|
if (update_task_channels(emu, tr, prev, next) != 0) {
|
||||||
|
err("update_task_channels failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (enforce_task_rules(emu, tr, next) != 0) {
|
if (enforce_task_rules(emu, tr, stack, next) != 0) {
|
||||||
err("enforce_task_rules failed");
|
err("enforce_task_rules failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,11 @@ static const int chan_stack[CH_MAX] = {
|
|||||||
[CH_SUBSYSTEM] = 1,
|
[CH_SUBSYSTEM] = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const int chan_dup[CH_MAX] = {
|
||||||
|
[CH_APPID] = 1,
|
||||||
|
[CH_TYPE] = 1,
|
||||||
|
};
|
||||||
|
|
||||||
/* ----------------- pvt ------------------ */
|
/* ----------------- pvt ------------------ */
|
||||||
|
|
||||||
static const int pvt_type[] = {
|
static const int pvt_type[] = {
|
||||||
@ -101,6 +106,7 @@ static const struct model_chan_spec th_chan = {
|
|||||||
.prefix = model_name,
|
.prefix = model_name,
|
||||||
.ch_names = chan_name,
|
.ch_names = chan_name,
|
||||||
.ch_stack = chan_stack,
|
.ch_stack = chan_stack,
|
||||||
|
.ch_dup = chan_dup,
|
||||||
.pvt = &pvt_spec,
|
.pvt = &pvt_spec,
|
||||||
.track = th_track,
|
.track = th_track,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user