From 50837d61735c7e5c32317bed89659b699cb94a34 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Mon, 23 Oct 2023 15:24:31 +0200 Subject: [PATCH] Port Nanos6 model to tasks with bodies For now we still allow Nanos6 to use the relaxed nest model, so a nested task can begin the execution without the parent being paused. --- src/emu/nanos6/event.c | 40 ++++++++++++++++++++-------------- src/emu/nanos6/setup.c | 6 ----- test/emu/nanos6/CMakeLists.txt | 9 +++----- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/emu/nanos6/event.c b/src/emu/nanos6/event.c index 5223b1e..f7bf3d3 100644 --- a/src/emu/nanos6/event.c +++ b/src/emu/nanos6/event.c @@ -224,11 +224,6 @@ chan_task_switch(struct emu *emu, return -1; } - if (prev->thread != next->thread) { - err("cannot switch to a task of another thread"); - return -1; - } - if (chan_set(&th->m.ch[CH_TASKID], value_int64(next->id)) != 0) { err("chan_set taskid failed"); return -1; @@ -271,19 +266,22 @@ update_task_state(struct emu *emu) return -1; } + /* Nanos6 doesn't have parallel tasks */ + uint32_t body_id = 1; + int ret = 0; switch (emu->ev->v) { case 'x': - ret = task_execute(stack, task); + ret = task_execute(stack, task, body_id); break; case 'e': - ret = task_end(stack, task); + ret = task_end(stack, task, body_id); break; case 'p': - ret = task_pause(stack, task); + ret = task_pause(stack, task, body_id); break; case 'r': - ret = task_resume(stack, task); + ret = task_resume(stack, task, body_id); break; default: err("unexpected Nanos6 task event"); @@ -352,7 +350,7 @@ update_task_channels(struct emu *emu, } static int -enforce_task_rules(struct emu *emu, char tr, struct task *next) +enforce_task_rules(struct emu *emu, char tr, struct body *bnext) { if (tr != 'x' && tr != 'X') return 0; @@ -360,8 +358,9 @@ enforce_task_rules(struct emu *emu, char tr, struct task *next) /* If a task has just entered the running state, it must show * the running task body subsystem */ - if (next->state != TASK_ST_RUNNING) { - err("task not in running state on begin"); + if (body_get_state(bnext) != BODY_ST_RUNNING) { + err("task body %u not in running state on begin", + body_get_id(bnext)); return -1; } @@ -407,7 +406,8 @@ update_task(struct emu *emu) struct nanos6_thread *th = EXT(emu->thread, '6'); struct task_stack *stack = &th->task_stack; - struct task *prev = task_get_running(stack); + struct body *bprev = task_get_running(stack); + struct task *prev = bprev == NULL ? NULL : body_get_task(bprev); /* Update the emulator state, but don't modify the channels */ if (update_task_state(emu) != 0) { @@ -415,7 +415,8 @@ update_task(struct emu *emu) return -1; } - struct task *next = task_get_running(stack); + struct body *bnext = task_get_running(stack); + struct task *next = bnext == NULL ? NULL : body_get_task(bnext); /* Update the subsystem channel */ if (update_task_ss_channel(emu, emu->ev->v) != 0) { @@ -437,7 +438,7 @@ update_task(struct emu *emu) return -1; } - if (enforce_task_rules(emu, tr, next) != 0) { + if (enforce_task_rules(emu, tr, bnext) != 0) { err("enforce_task_rules failed"); return -1; } @@ -459,7 +460,14 @@ create_task(struct emu *emu) struct nanos6_proc *proc = EXT(emu->proc, '6'); struct task_info *info = &proc->task_info; - if (task_create(info, type_id, task_id) != 0) { + /* Only allow pausing the tasks, no parallel or resurrect */ + int flags = TASK_FLAG_PAUSE; + + /* TODO: Nanos6 still submits inline tasks without pausing the previous + * task, so we relax the model to allow this for now. */ + flags |= TASK_FLAG_RELAX_NESTING; + + if (task_create(info, type_id, task_id, flags) != 0) { err("task_create failed"); return -1; } diff --git a/src/emu/nanos6/setup.c b/src/emu/nanos6/setup.c index 0cbb4ea..b524bd3 100644 --- a/src/emu/nanos6/setup.c +++ b/src/emu/nanos6/setup.c @@ -297,12 +297,6 @@ model_nanos6_create(struct emu *emu) return -1; } - /* Init task stack thread pointer */ - for (struct thread *t = sys->threads; t; t = t->gnext) { - struct nanos6_thread *th = EXT(t, model_id); - th->task_stack.thread = t; - } - for (struct proc *p = sys->procs; p; p = p->gnext) { if (init_proc(p) != 0) { err("init_proc failed"); diff --git a/test/emu/nanos6/CMakeLists.txt b/test/emu/nanos6/CMakeLists.txt index 80fac0b..7c55773 100644 --- a/test/emu/nanos6/CMakeLists.txt +++ b/test/emu/nanos6/CMakeLists.txt @@ -3,7 +3,7 @@ test_emu(nested-tasks.c) test_emu(nested-tasks-bad.c SHOULD_FAIL - REGEX "cannot execute task 1: state is not created") + REGEX "body_execute: body 1 state must be Created but is Running") test_emu(task-types.c MP) test_emu(blocking.c MP) test_emu(ss-mismatch.c SHOULD_FAIL @@ -13,8 +13,5 @@ test_emu(switch-same-type.c) test_emu(sponge.c) test_emu(sponge-breakdown.c BREAKDOWN) test_emu(breakdown-no-black.c BREAKDOWN) - -# FIXME: Disabled to support the taskiter in NODES until we have more detailed -# task states instrumentation. -test_emu(rerun-task-bad.c DISABLED SHOULD_FAIL - REGEX "task_execute: cannot execute task [0-9]\\+: state is not created") +test_emu(rerun-task-bad.c SHOULD_FAIL + REGEX "body_execute: body 1 cannot resurrect")