diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec29abb..27c5f2b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
-- nOS-V model version increased to 2.2.0.
+- nOS-V model version increased to 2.3.0.
+- Prevent accidental use of nOS-V traces without required events for the
+ breakdown model using the `nosv.can_breakdown` attribute.
### Added
diff --git a/doc/user/emulation/events.md b/doc/user/emulation/events.md
index ae3ad80..58d9fc2 100644
--- a/doc/user/emulation/events.md
+++ b/doc/user/emulation/events.md
@@ -1,7 +1,7 @@
# Emulator events
This is a exhaustive list of the events recognized by the emulator.
-Built on Jun 12 2024.
+Built on Jun 13 2024.
## Model nanos6
@@ -615,7 +615,7 @@ List of events for the model *tampi* with identifier **`T`** at version `1.0.0`:
## Model nosv
-List of events for the model *nosv* with identifier **`V`** at version `2.2.0`:
+List of events for the model *nosv* with identifier **`V`** at version `2.3.0`:
VTc(u32 taskid, u32 typeid)
- creates task %{taskid} with type %{typeid}
diff --git a/doc/user/emulation/versions.md b/doc/user/emulation/versions.md
index 617021c..d835257 100644
--- a/doc/user/emulation/versions.md
+++ b/doc/user/emulation/versions.md
@@ -39,6 +39,8 @@ Track changes in emulator model versions.
## nOS-V
+- nosv 2.3.0
+ - Add `nosv.can_breakdown` attribute to metadata for breakdown checks.
- nosv 2.2.0
- Add support for progress events `VP{pra}`.
- nosv 2.1.0
diff --git a/flake.nix b/flake.nix
index b4f1e95..07230fd 100644
--- a/flake.nix
+++ b/flake.nix
@@ -15,7 +15,7 @@
nosv = prev.nosv.override {
useGit = true;
gitBranch = "master";
- gitCommit = "af186f448d3b5675c107747f5c9237e7f4d31e4b";
+ gitCommit = "c668e3bbfae34cd9b8797811b29ae35361b267ca";
};
nanos6 = prev.nanos6.override {
useGit = true;
@@ -37,7 +37,8 @@
ovniFixed = prev.ovni.override {
useGit = true;
gitBranch = "master";
- gitCommit = "68fc8b0eba299c3a7fa3833ace2c94933a26749e";
+ # Includes ovni_attr_* API
+ gitCommit = "d1e8a62396ae92934c0b6e248d5f6ff921bef56f";
};
# Build with the current source
ovniLocal = prev.ovni.overrideAttrs (old: rec {
diff --git a/src/emu/nosv/breakdown.c b/src/emu/nosv/breakdown.c
index da23448..f3e6345 100644
--- a/src/emu/nosv/breakdown.c
+++ b/src/emu/nosv/breakdown.c
@@ -23,6 +23,7 @@
#include "recorder.h"
#include "sort.h"
#include "system.h"
+#include "thread.h"
#include "task.h"
#include "track.h"
#include "value.h"
@@ -48,6 +49,28 @@ create_cpu(struct bay *bay, struct nosv_breakdown_cpu *bcpu, int64_t gindex)
return 0;
}
+static int
+check_thread_metadata(struct thread *th)
+{
+ if (th->meta == NULL) {
+ err("thread has no metadata");
+ return -1;
+ }
+
+ JSON_Value *val = json_object_dotget_value(th->meta, "nosv.can_breakdown");
+ if (val == NULL) {
+ err("missing nosv.can_breakdown attribute");
+ return -1;
+ }
+
+ if (!json_value_get_boolean(val)) {
+ err("nosv.can_breakdown is false, missing events to enable breakdown");
+ return -1;
+ }
+
+ return 0;
+}
+
int
model_nosv_breakdown_create(struct emu *emu)
{
@@ -88,6 +111,13 @@ model_nosv_breakdown_create(struct emu *emu)
}
}
+ for (struct thread *th = emu->system.threads; th; th = th->gnext) {
+ if (check_thread_metadata(th) != 0) {
+ err("bad nosv metadata in thread: %s", th->id);
+ return -1;
+ }
+ }
+
return 0;
}
diff --git a/src/emu/nosv/setup.c b/src/emu/nosv/setup.c
index 4618cef..eb24731 100644
--- a/src/emu/nosv/setup.c
+++ b/src/emu/nosv/setup.c
@@ -82,7 +82,7 @@ static struct ev_decl model_evlist[] = {
struct model_spec model_nosv = {
.name = model_name,
- .version = "2.2.0",
+ .version = "2.3.0",
.evlist = model_evlist,
.model = model_id,
.create = model_nosv_create,
diff --git a/test/emu/nosv/instr_nosv.h b/test/emu/nosv/instr_nosv.h
index 14724a3..0b51488 100644
--- a/test/emu/nosv/instr_nosv.h
+++ b/test/emu/nosv/instr_nosv.h
@@ -12,6 +12,7 @@ static inline void
instr_nosv_init(void)
{
instr_require("nosv");
+ ovni_attr_set_boolean("nosv.can_breakdown", 1);
}
static inline uint32_t
diff --git a/test/rt/nodes/CMakeLists.txt b/test/rt/nodes/CMakeLists.txt
index b5931ca..5b6d4ab 100644
--- a/test/rt/nodes/CMakeLists.txt
+++ b/test/rt/nodes/CMakeLists.txt
@@ -64,8 +64,11 @@ nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-level-3 LEVEL 3 SORT)
nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-level-4 LEVEL 4 SORT)
# Same but with breakdown enabled
-nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-1 LEVEL 1 SORT BREAKDOWN)
-nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-2 LEVEL 2 SORT BREAKDOWN)
+nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-1 LEVEL 1 SORT BREAKDOWN
+ SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown")
+nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-2 LEVEL 2 SORT BREAKDOWN
+ SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown")
+# From level 3 up the breakdown can be enabled
nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-3 LEVEL 3 SORT BREAKDOWN)
nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-4 LEVEL 4 SORT BREAKDOWN)
diff --git a/test/rt/nosv/CMakeLists.txt b/test/rt/nosv/CMakeLists.txt
index 8cb9be5..5e785be 100644
--- a/test/rt/nosv/CMakeLists.txt
+++ b/test/rt/nosv/CMakeLists.txt
@@ -53,8 +53,12 @@ nosv_test(several-tasks.c SORT NAME several-tasks-level-3 LEVEL 3)
nosv_test(several-tasks.c SORT NAME several-tasks-level-4 LEVEL 4)
# Same but with breakdown enabled
-nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-0 LEVEL 0 BREAKDOWN)
-nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-1 LEVEL 1 BREAKDOWN)
-nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-2 LEVEL 2 BREAKDOWN)
+nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-0 LEVEL 0 BREAKDOWN
+ SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown")
+nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-1 LEVEL 1 BREAKDOWN
+ SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown")
+nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-2 LEVEL 2 BREAKDOWN
+ SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown")
+# From level 3 up the breakdown can be enabled
nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-3 LEVEL 3 BREAKDOWN)
nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN)