Always emit task body when running a task
The emulator now enforces that the subsystem state is task body when a task begins, either a new task or a nested one.
This commit is contained in:
parent
2db1a8a841
commit
8cab61bc62
70
emu_nanos6.c
70
emu_nanos6.c
@ -78,7 +78,31 @@ hook_init_nanos6(struct ovni_emu *emu)
|
|||||||
/* --------------------------- pre ------------------------------- */
|
/* --------------------------- pre ------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chan_task_stopped(struct ovni_emu *emu, char tr)
|
update_ss_channel(struct ovni_emu *emu, int tr)
|
||||||
|
{
|
||||||
|
struct ovni_ethread *th = emu->cur_thread;
|
||||||
|
struct ovni_chan *chan = &th->chan[CHAN_NANOS6_SUBSYSTEM];
|
||||||
|
|
||||||
|
switch(tr)
|
||||||
|
{
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
chan_push(chan, ST_NANOS6_TASK_BODY);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
chan_pop(chan, ST_NANOS6_TASK_BODY);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'p':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
edie(emu, "unexpected transition value %c\n", tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chan_task_stopped(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct ovni_ethread *th;
|
struct ovni_ethread *th;
|
||||||
th = emu->cur_thread;
|
th = emu->cur_thread;
|
||||||
@ -88,14 +112,10 @@ chan_task_stopped(struct ovni_emu *emu, char tr)
|
|||||||
|
|
||||||
if(emu->cur_loom->rank_enabled)
|
if(emu->cur_loom->rank_enabled)
|
||||||
chan_set(&th->chan[CHAN_NANOS6_RANK], 0);
|
chan_set(&th->chan[CHAN_NANOS6_RANK], 0);
|
||||||
|
|
||||||
/* Only exit the task body when finishing */
|
|
||||||
if(tr == 'e')
|
|
||||||
chan_pop(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_TASK_BODY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chan_task_running(struct ovni_emu *emu, struct task *task, char tr)
|
chan_task_running(struct ovni_emu *emu, struct task *task)
|
||||||
{
|
{
|
||||||
struct ovni_ethread *th;
|
struct ovni_ethread *th;
|
||||||
struct ovni_eproc *proc;
|
struct ovni_eproc *proc;
|
||||||
@ -117,10 +137,6 @@ chan_task_running(struct ovni_emu *emu, struct task *task, char tr)
|
|||||||
|
|
||||||
if(emu->cur_loom->rank_enabled)
|
if(emu->cur_loom->rank_enabled)
|
||||||
chan_set(&th->chan[CHAN_NANOS6_RANK], proc->rank + 1);
|
chan_set(&th->chan[CHAN_NANOS6_RANK], proc->rank + 1);
|
||||||
|
|
||||||
/* Only enter the body of the task when we begin the execution */
|
|
||||||
if(tr == 'x')
|
|
||||||
chan_push(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_TASK_BODY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -212,11 +228,11 @@ update_task_channels(struct ovni_emu *emu,
|
|||||||
{
|
{
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'r':
|
case 'r':
|
||||||
chan_task_running(emu, next, tr);
|
chan_task_running(emu, next);
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'p':
|
case 'p':
|
||||||
chan_task_stopped(emu, tr);
|
chan_task_stopped(emu);
|
||||||
break;
|
break;
|
||||||
/* Additional nested transitions */
|
/* Additional nested transitions */
|
||||||
case 'X':
|
case 'X':
|
||||||
@ -228,6 +244,29 @@ update_task_channels(struct ovni_emu *emu,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enforce_task_rules(struct ovni_emu *emu,
|
||||||
|
char tr, struct task *prev, struct task *next)
|
||||||
|
|
||||||
|
{
|
||||||
|
UNUSED(prev);
|
||||||
|
|
||||||
|
/* If a task has just entered the running state, it must show
|
||||||
|
* the running task body subsystem */
|
||||||
|
if(tr == 'x' || tr == 'X')
|
||||||
|
{
|
||||||
|
if(next->state != TASK_ST_RUNNING)
|
||||||
|
edie(emu, "a Nanos6 task starts running but not in the running state\n");
|
||||||
|
|
||||||
|
struct ovni_ethread *th = emu->cur_thread;
|
||||||
|
struct ovni_chan *sschan = &th->chan[CHAN_NANOS6_SUBSYSTEM];
|
||||||
|
int st = chan_get_st(sschan);
|
||||||
|
|
||||||
|
if(st != ST_NANOS6_TASK_BODY)
|
||||||
|
edie(emu, "a Nanos6 task starts running but not in the \"running body\" subsystem state\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_task(struct ovni_emu *emu)
|
update_task(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
@ -245,8 +284,13 @@ update_task(struct ovni_emu *emu)
|
|||||||
int runs_now = (next != NULL);
|
int runs_now = (next != NULL);
|
||||||
char tr = expand_transition_value(emu, was_running, runs_now);
|
char tr = expand_transition_value(emu, was_running, runs_now);
|
||||||
|
|
||||||
/* Update the channels now */
|
/* Update the task related channels now */
|
||||||
update_task_channels(emu, tr, prev, next);
|
update_task_channels(emu, tr, prev, next);
|
||||||
|
|
||||||
|
/* Update the subsystem channel */
|
||||||
|
update_ss_channel(emu, tr);
|
||||||
|
|
||||||
|
enforce_task_rules(emu, tr, prev, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -16,3 +16,4 @@ nanos6_rt_test(simple-task.c)
|
|||||||
nanos6_rt_test(nested-task.c)
|
nanos6_rt_test(nested-task.c)
|
||||||
nanos6_rt_test(several-tasks.c)
|
nanos6_rt_test(several-tasks.c)
|
||||||
nanos6_rt_test(sched-add.c)
|
nanos6_rt_test(sched-add.c)
|
||||||
|
nanos6_rt_test(if0.c)
|
||||||
|
11
test/rt/nanos6/if0.c
Normal file
11
test/rt/nanos6/if0.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
#pragma oss task if(0)
|
||||||
|
{
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user