diff --git a/src/emu/nanos6/breakdown.c b/src/emu/nanos6/breakdown.c index 26fa0d6..6d63da6 100644 --- a/src/emu/nanos6/breakdown.c +++ b/src/emu/nanos6/breakdown.c @@ -142,12 +142,12 @@ select_idle(struct mux *mux, struct value value, struct mux_input **input) { dbg("selecting tri output for value %s", value_str(value)); - if (value.type == VALUE_INT64 && value.i == ST_WORKER_IDLE) { - dbg("selecting input 1 (idle)"); - *input = mux_get_input(mux, 1); - } else { + if (value.type == VALUE_INT64 && value.i == ST_PROGRESSING) { dbg("selecting input 0 (tr)"); *input = mux_get_input(mux, 0); + } else { + dbg("selecting input 1 (idle)"); + *input = mux_get_input(mux, 1); } return 0; diff --git a/src/emu/nanos6/event.c b/src/emu/nanos6/event.c index 2fdaafc..c5b21d9 100644 --- a/src/emu/nanos6/event.c +++ b/src/emu/nanos6/event.c @@ -16,7 +16,7 @@ #include "thread.h" #include "value.h" -enum { PUSH = 1, POP = 2, IGN = 3 }; +enum { PUSH = 1, POP, SET, IGN }; #define CHSS CH_SUBSYSTEM #define CHTH CH_THREAD @@ -40,8 +40,9 @@ static const int ss_table[256][256][3] = { ['*'] = { CHSS, IGN, -1 }, }, ['P'] = { - ['r'] = { CH_IDLE, PUSH, ST_WORKER_IDLE }, - ['p'] = { CH_IDLE, POP, ST_WORKER_IDLE }, + ['p'] = { CH_IDLE, SET, ST_PROGRESSING }, + ['r'] = { CH_IDLE, SET, ST_RESTING }, + ['a'] = { CH_IDLE, SET, ST_ABSORBING }, }, ['C'] = { ['['] = { CHSS, PUSH, ST_TASK_CREATING }, @@ -123,6 +124,8 @@ simple(struct emu *emu) return chan_push(ch, value_int64(st)); } else if (action == POP) { return chan_pop(ch, value_int64(st)); + } else if (action == SET) { + return chan_set(ch, value_int64(st)); } else if (action == IGN) { return 0; /* do nothing */ } else { diff --git a/src/emu/nanos6/nanos6_priv.h b/src/emu/nanos6/nanos6_priv.h index 53d7436..a88e7a0 100644 --- a/src/emu/nanos6/nanos6_priv.h +++ b/src/emu/nanos6/nanos6_priv.h @@ -67,10 +67,11 @@ enum nanos6_thread_type { ST_TH_EXTERNAL = 4, }; -enum nanos6_worker_idle { +enum nanos6_progress { /* Can mix with subsystem values */ - ST_WORKER_IDLE = 100, - ST_WORKER_BUSY = 101, + ST_PROGRESSING = 100, + ST_RESTING, + ST_ABSORBING, }; struct nanos6_thread { diff --git a/src/emu/nanos6/setup.c b/src/emu/nanos6/setup.c index b602c0e..59c61ca 100644 --- a/src/emu/nanos6/setup.c +++ b/src/emu/nanos6/setup.c @@ -55,7 +55,6 @@ static const char *chan_name[CH_MAX] = { static const int chan_stack[CH_MAX] = { [CH_SUBSYSTEM] = 1, [CH_THREAD] = 1, - [CH_IDLE] = 1, }; static const int chan_dup[CH_MAX] = { @@ -127,8 +126,9 @@ static const struct pcf_value_label nanos6_thread_type[] = { }; static const struct pcf_value_label nanos6_worker_idle[] = { - { ST_WORKER_IDLE, "Idle" }, - { ST_WORKER_BUSY, "Busy" }, + { ST_PROGRESSING, "Progressing" }, + { ST_RESTING, "Resting" }, + { ST_ABSORBING, "Absorbing noise" }, { -1, NULL }, }; @@ -310,8 +310,8 @@ model_nanos6_connect(struct emu *emu) for (struct thread *th = emu->system.threads; th; th = th->gnext) { struct nanos6_thread *mth = EXT(th, model_id); struct chan *idle = &mth->m.ch[CH_IDLE]; - /* By default set all threads as Busy */ - if (chan_push(idle, value_int64(ST_WORKER_BUSY)) != 0) { + /* By default set all threads as Progressing */ + if (chan_set(idle, value_int64(ST_PROGRESSING)) != 0) { err("chan_push idle failed"); return -1; } @@ -320,8 +320,8 @@ model_nanos6_connect(struct emu *emu) for (struct cpu *cpu = emu->system.cpus; cpu; cpu = cpu->next) { struct nanos6_cpu *mcpu = EXT(cpu, model_id); struct mux *mux = &mcpu->m.track[CH_IDLE].mux; - /* Emit Idle when a CPU has no idle threads */ - mux_set_default(mux, value_int64(ST_WORKER_IDLE)); + /* Emit Resting when a CPU has no running threads */ + mux_set_default(mux, value_int64(ST_RESTING)); } memu->connected = 1; diff --git a/test/emu/nanos6/CMakeLists.txt b/test/emu/nanos6/CMakeLists.txt index dc2e1da..9f7c7dd 100644 --- a/test/emu/nanos6/CMakeLists.txt +++ b/test/emu/nanos6/CMakeLists.txt @@ -11,5 +11,5 @@ test_emu(ss-mismatch.c SHOULD_FAIL test_emu(delayed-connect-ss.c) test_emu(switch-same-type.c) test_emu(sponge.c) - +test_emu(sponge-breakdown.c BREAKDOWN) test_emu(breakdown-no-black.c BREAKDOWN) diff --git a/test/emu/nanos6/instr_nanos6.h b/test/emu/nanos6/instr_nanos6.h index 6c361c5..9a7c328 100644 --- a/test/emu/nanos6/instr_nanos6.h +++ b/test/emu/nanos6/instr_nanos6.h @@ -106,6 +106,10 @@ INSTR_0ARG(instr_nanos6_alloc_exit, "6MA") INSTR_0ARG(instr_nanos6_free_enter, "6Mf") INSTR_0ARG(instr_nanos6_free_exit, "6MF") +INSTR_0ARG(instr_nanos6_progressing, "6Pp") +INSTR_0ARG(instr_nanos6_resting, "6Pr") +INSTR_0ARG(instr_nanos6_absorbing, "6Pa") + static inline void instr_nanos6_task_create_and_execute(int32_t id, uint32_t typeid) { diff --git a/test/emu/nanos6/sponge-breakdown.c b/test/emu/nanos6/sponge-breakdown.c new file mode 100644 index 0000000..969f0d1 --- /dev/null +++ b/test/emu/nanos6/sponge-breakdown.c @@ -0,0 +1,57 @@ +/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#include +#include +#include "common.h" +#include "emu_prv.h" +#include "instr.h" +#include "instr_nanos6.h" +#include "nanos6/nanos6_priv.h" + +int +main(void) +{ + instr_start(0, 1); + + int type = PRV_NANOS6_BREAKDOWN; + FILE *f = fopen("match.sh", "w"); + if (f == NULL) + die("fopen failed:"); + + instr_nanos6_worker_loop_enter(); + + /* Enter sponge subsystem */ + instr_nanos6_sponge_enter(); + + /* Set state to Absorbing */ + instr_nanos6_absorbing(); + + /* Ensure the only row in breakdown is in absorbing */ + fprintf(f, "grep '1:%ld:%d:%d$' ovni/nanos6-breakdown.prv\n", + get_delta(), type, ST_ABSORBING); + + /* Set state to Resting */ + instr_nanos6_resting(); + + /* Ensure the only row in breakdown is in Resting */ + fprintf(f, "grep '1:%ld:%d:%d$' ovni/nanos6-breakdown.prv\n", + get_delta(), type, ST_RESTING); + + instr_nanos6_progressing(); + + /* Now the state must follow the subsystem, which should be + * sponge mode */ + fprintf(f, "grep '1:%ld:%d:%d$' ovni/nanos6-breakdown.prv\n", + get_delta(), type, ST_SPONGE); + + fclose(f); + + instr_nanos6_sponge_exit(); + + instr_nanos6_worker_loop_exit(); + + instr_end(); + + return 0; +}