Add nosv.can_breakdown attribute check

The nosv.can_breakdown attribute states if enough events for the
breakdown model of nOS-V are enabled at runtime. It is used to ensure
that breakdown traces have the progress events enabled along with others
required for proper visualization of traces.

The emulator will panic when the level is not enough, instead of relying
on users to always remember to enable the correct level.
This commit is contained in:
Rodrigo Arias 2024-06-13 09:53:42 +02:00
parent d1e8a62396
commit 247ea7e7c3
9 changed files with 54 additions and 11 deletions

View File

@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### 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 ### Added

View File

@ -1,7 +1,7 @@
# Emulator events # Emulator events
This is a exhaustive list of the events recognized by the emulator. This is a exhaustive list of the events recognized by the emulator.
Built on Jun 12 2024. Built on Jun 13 2024.
## Model nanos6 ## Model nanos6
@ -615,7 +615,7 @@ List of events for the model *tampi* with identifier **`T`** at version `1.0.0`:
## Model nosv ## 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`:
<dl> <dl>
<dt><a id="VTc" href="#VTc"><pre>VTc(u32 taskid, u32 typeid)</pre></a></dt> <dt><a id="VTc" href="#VTc"><pre>VTc(u32 taskid, u32 typeid)</pre></a></dt>
<dd>creates task %{taskid} with type %{typeid}</dd> <dd>creates task %{taskid} with type %{typeid}</dd>

View File

@ -39,6 +39,8 @@ Track changes in emulator model versions.
## nOS-V ## nOS-V
- nosv 2.3.0
- Add `nosv.can_breakdown` attribute to metadata for breakdown checks.
- nosv 2.2.0 - nosv 2.2.0
- Add support for progress events `VP{pra}`. - Add support for progress events `VP{pra}`.
- nosv 2.1.0 - nosv 2.1.0

View File

@ -15,7 +15,7 @@
nosv = prev.nosv.override { nosv = prev.nosv.override {
useGit = true; useGit = true;
gitBranch = "master"; gitBranch = "master";
gitCommit = "af186f448d3b5675c107747f5c9237e7f4d31e4b"; gitCommit = "c668e3bbfae34cd9b8797811b29ae35361b267ca";
}; };
nanos6 = prev.nanos6.override { nanos6 = prev.nanos6.override {
useGit = true; useGit = true;
@ -37,7 +37,8 @@
ovniFixed = prev.ovni.override { ovniFixed = prev.ovni.override {
useGit = true; useGit = true;
gitBranch = "master"; gitBranch = "master";
gitCommit = "68fc8b0eba299c3a7fa3833ace2c94933a26749e"; # Includes ovni_attr_* API
gitCommit = "d1e8a62396ae92934c0b6e248d5f6ff921bef56f";
}; };
# Build with the current source # Build with the current source
ovniLocal = prev.ovni.overrideAttrs (old: rec { ovniLocal = prev.ovni.overrideAttrs (old: rec {

View File

@ -23,6 +23,7 @@
#include "recorder.h" #include "recorder.h"
#include "sort.h" #include "sort.h"
#include "system.h" #include "system.h"
#include "thread.h"
#include "task.h" #include "task.h"
#include "track.h" #include "track.h"
#include "value.h" #include "value.h"
@ -48,6 +49,28 @@ create_cpu(struct bay *bay, struct nosv_breakdown_cpu *bcpu, int64_t gindex)
return 0; 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 int
model_nosv_breakdown_create(struct emu *emu) 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; return 0;
} }

View File

@ -82,7 +82,7 @@ static struct ev_decl model_evlist[] = {
struct model_spec model_nosv = { struct model_spec model_nosv = {
.name = model_name, .name = model_name,
.version = "2.2.0", .version = "2.3.0",
.evlist = model_evlist, .evlist = model_evlist,
.model = model_id, .model = model_id,
.create = model_nosv_create, .create = model_nosv_create,

View File

@ -12,6 +12,7 @@ static inline void
instr_nosv_init(void) instr_nosv_init(void)
{ {
instr_require("nosv"); instr_require("nosv");
ovni_attr_set_boolean("nosv.can_breakdown", 1);
} }
static inline uint32_t static inline uint32_t

View File

@ -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) nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-level-4 LEVEL 4 SORT)
# Same but with breakdown enabled # 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-1 LEVEL 1 SORT 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")
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-3 LEVEL 3 SORT BREAKDOWN)
nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-4 LEVEL 4 SORT BREAKDOWN) nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-4 LEVEL 4 SORT BREAKDOWN)

View File

@ -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) nosv_test(several-tasks.c SORT NAME several-tasks-level-4 LEVEL 4)
# Same but with breakdown enabled # 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-0 LEVEL 0 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) 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-3 LEVEL 3 BREAKDOWN)
nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN) nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN)