Add developer documentation
This commit is contained in:
parent
de8439c55b
commit
5741cc383f
63
doc/dev/channels.md
Normal file
63
doc/dev/channels.md
Normal file
@ -0,0 +1,63 @@
|
||||
# Channels
|
||||
|
||||
As the emulation progresses, information is written in the PRV trace to record
|
||||
the new states. The emulator has specific mechanism to handle the output of new
|
||||
states in the PRV trace via channels. A channel stores a value that represents
|
||||
an state at a given point in time and typically corresponds to the value that
|
||||
will be observed in the Paraver timeline.
|
||||
|
||||
!!! Note
|
||||
|
||||
The emulator receives input *events* and performs *state*
|
||||
transitions which are written into the Paraver trace.
|
||||
|
||||
Channels become dirty when a new value is written to them. No other
|
||||
modifications are allowed by default until the channel is flushed by calling
|
||||
`chan_flush()`. This behavior can be controlled with the `CHAN_DIRTY_WRITE`
|
||||
property. By default, a duplicated value cannot be written into a channel,
|
||||
unless the `CHAN_DUPLICATES` property is set.
|
||||
|
||||
A channel has an unique name used to identify the channel when debugging and
|
||||
also to create derived channels. The name can be set following the printf style
|
||||
when calling `chan_init()`.
|
||||
|
||||
## Types
|
||||
|
||||
There are two types of channels, **single** and **stack**. The type single only
|
||||
stores one value which is updated by `chan_set()`. The stack type allows the
|
||||
channel to record multiple values in a stack by using `chan_push()` and
|
||||
`chan_pop()`. The value of the channels is the topmost in the stack (the last
|
||||
pushed).
|
||||
|
||||
Notice that the `chan_pop()` function uses the same value being pop()'ed as
|
||||
argument. The function checks that the stack contains the expected value,
|
||||
forcing the emulator to always receive a matching pair of push and pop values.
|
||||
|
||||
After the channel initialization, the value of the channels is null. A channel
|
||||
with an empty stack also returns the value null when being read.
|
||||
|
||||
## Data value
|
||||
|
||||
The data type of a channel is handled by the `value` structure. This structure
|
||||
can store a null value, a 64 bit integer or a double. Any data type can be
|
||||
written to a channel and multiple data types can be stored in the stack.
|
||||
|
||||
!!! Note
|
||||
|
||||
For now only null and int64 types are allowed when the channel is connected
|
||||
to a Paraver trace.
|
||||
|
||||
## Properties
|
||||
|
||||
Channels have properties that can be set by `chan_prop_set()`. Setting the
|
||||
`CHAN_DIRTY_WRITE` property to true allows a channel to modify its value while
|
||||
being in the dirty state. The `CHAN_DUPLICATES` property determines is a channel
|
||||
can write the same value to the channel twice.
|
||||
|
||||
## Callback
|
||||
|
||||
A unique function can be set to each channel which will be called once a channel
|
||||
becomes dirty with `chan_set_dirty_cb()`. This callback will be called before
|
||||
`chan_set()`, `chan_push()` or `chan_pop()` returns. The [patch
|
||||
bay](../patchbay) uses this callback to detect when a channel is modified an run
|
||||
other callbacks.
|
26
doc/dev/extend.md
Normal file
26
doc/dev/extend.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Extend
|
||||
|
||||
The extend mechanism allows a structure to be extended by a model. It works by
|
||||
placing an array of pointers indexed by the model identifier (char) inside the
|
||||
structure. Most of the structures of the emulator have a `ext` member, allowing
|
||||
them to be extended.
|
||||
|
||||
Models are forbidden to access information from other models than their own.
|
||||
|
||||
The function `void extend_set(struct extend *ext, int id, void *ctx)` stores the
|
||||
ctx pointer inside the extend structure for the model with the given id.
|
||||
|
||||
Use `void *extend_get(struct extend *ext, int id)` to retrieve its value.
|
||||
|
||||
A helper macro `EXT(st, m)` directly attempts to find the member `ext` in the
|
||||
structure st, and return the pointer of the model `m`.
|
||||
|
||||
Here is an example where Nanos6 stores its own CPU information:
|
||||
|
||||
struct cpu *syscpu;
|
||||
struct nanos6_cpu *cpu;
|
||||
|
||||
extend_set(&syscpu->ext, '6', cpu);
|
||||
|
||||
cpu = extend_get(&syscpu->ext, '6');
|
||||
cpu = EXT(syscpu, '6'); /* same */
|
BIN
doc/dev/fig/bay.jpg
Normal file
BIN
doc/dev/fig/bay.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 952 KiB |
BIN
doc/dev/fig/mux.pdf
Normal file
BIN
doc/dev/fig/mux.pdf
Normal file
Binary file not shown.
634
doc/dev/fig/mux.svg
Normal file
634
doc/dev/fig/mux.svg
Normal file
@ -0,0 +1,634 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="269.875mm"
|
||||
height="166.6875mm"
|
||||
viewBox="0 0 269.875 166.6875"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="mux.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#999999"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.069618"
|
||||
inkscape:cx="553.00116"
|
||||
inkscape:cy="329.08945"
|
||||
inkscape:window-width="1914"
|
||||
inkscape:window-height="1025"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid132"
|
||||
spacingx="0.26458333"
|
||||
spacingy="0.26458333"
|
||||
empspacing="10"
|
||||
originx="-5.2916665"
|
||||
originy="-7.9375" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker1653"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto-start-reverse"
|
||||
inkscape:stockid="Arrow1L"
|
||||
markerWidth="8.75"
|
||||
markerHeight="5"
|
||||
viewBox="0 0 8.75 5"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always"
|
||||
preserveAspectRatio="xMidYMid">
|
||||
<path
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path1651"
|
||||
transform="scale(-0.5)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-5.2916665,-7.9375)">
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect3087"
|
||||
width="68.791656"
|
||||
height="26.458332"
|
||||
x="195.79167"
|
||||
y="127.00001"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect2797"
|
||||
width="68.791656"
|
||||
height="26.458332"
|
||||
x="195.79167"
|
||||
y="47.625"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<path
|
||||
style="fill:#cccccc;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 58.208333,21.166667 15.875,5.291667 V 47.625 l -15.875,5.291667 z"
|
||||
id="path299" />
|
||||
<path
|
||||
style="fill:#cccccc;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 127,26.458333 142.875,31.75 V 74.083332 L 127,79.374999 Z"
|
||||
id="path409"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 7.9374999,37.041666 41.0104161,10e-7 h 9.260417"
|
||||
id="path1649"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583;fill:#0000ff"
|
||||
x="29.095898"
|
||||
y="35.174423"
|
||||
id="text2523"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;stroke-width:0.264583;fill:#0000ff"
|
||||
x="29.095898"
|
||||
y="35.174423"
|
||||
id="tspan2527">nanos6.thread0.subsystem</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 66.145833,68.791666 V 59.53125 50.270833"
|
||||
id="path2581" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="66.183037"
|
||||
y="72.489632"
|
||||
id="text2593"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="66.183037"
|
||||
y="72.489632"
|
||||
id="tspan2591">thread0.state</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="61.100502"
|
||||
y="38.325821"
|
||||
id="text2597"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2595"
|
||||
style="stroke-width:0.264583"
|
||||
x="61.100502"
|
||||
y="38.325821">mux0</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 74.083333,37.041667 H 96.572917 127"
|
||||
id="path2605"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583;-inkscape-font-specification:'sans-serif Italic';font-weight:normal;font-style:italic;font-stretch:normal;font-variant:normal"
|
||||
x="100.5334"
|
||||
y="35.174423"
|
||||
id="text2638"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;stroke-width:0.264583;-inkscape-font-specification:'sans-serif Italic';font-family:sans-serif;font-weight:normal;font-style:italic;font-stretch:normal;font-variant:normal"
|
||||
x="100.5334"
|
||||
y="35.174423"
|
||||
id="tspan2636">nanos6.thread0.subsystem.run</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 109.80208,42.333333 h 7.9375 H 127"
|
||||
id="path2695"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 109.80208,47.624999 h 7.9375 H 127"
|
||||
id="path2701"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 109.80208,52.916666 h 7.9375 H 127"
|
||||
id="path2705"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 109.80208,58.208333 h 7.9375 H 127"
|
||||
id="path2715"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 109.80208,63.499999 h 7.9375 H 127"
|
||||
id="path2717"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 109.80208,68.791666 h 7.9375 H 127"
|
||||
id="path2719"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 142.875,52.916666 h 22.48959 30.42708"
|
||||
id="path2725"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="134.98779"
|
||||
y="90.697647"
|
||||
id="text2729"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="134.98779"
|
||||
y="90.697647"
|
||||
id="tspan2727">cpu0.th_running</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 134.9375,87.312499 v -5.291667 l 0,-5.291666"
|
||||
id="path2731"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="129.93782"
|
||||
y="54.177567"
|
||||
id="text2735"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2733"
|
||||
style="stroke-width:0.264583"
|
||||
x="129.93782"
|
||||
y="54.177567">mux1</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.06519"
|
||||
y="53.858898"
|
||||
id="text2801"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2799"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.06519"
|
||||
y="53.858898">cpu0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.11082"
|
||||
y="59.127312"
|
||||
id="text2805"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2803"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.11082"
|
||||
y="59.127312">cpu1</tspan></text>
|
||||
<rect
|
||||
style="fill:#00ffff;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect2807"
|
||||
width="18.520834"
|
||||
height="5.2916665"
|
||||
x="222.25"
|
||||
y="50.270832"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 185.20833,58.208333 5.29167,0 5.29166,0"
|
||||
id="path2967"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 185.20833,63.499999 5.29167,0 5.29166,0"
|
||||
id="path2969"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 185.20833,68.791666 5.29167,0 5.29166,0"
|
||||
id="path2971"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.06517"
|
||||
y="64.44223"
|
||||
id="text2975"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2973"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.06517"
|
||||
y="64.44223">cpu2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.11081"
|
||||
y="69.710648"
|
||||
id="text2979"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2977"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="202.11081"
|
||||
y="69.710648">cpu3</tspan></text>
|
||||
<path
|
||||
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 216.95833,50.270833 V 71.437499"
|
||||
id="path3079" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 31.75,37.041666 v 47.625 47.625004"
|
||||
id="path3083"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 74.083332,132.29167 h 63.499998 l 58.20834,-1e-5"
|
||||
id="path3085"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41937"
|
||||
y="133.2339"
|
||||
id="text3091"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3089"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41937"
|
||||
y="133.2339">thread0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.46501"
|
||||
y="138.50232"
|
||||
id="text3095"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3093"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.46501"
|
||||
y="138.50232">thread1</tspan></text>
|
||||
<rect
|
||||
style="fill:#00ffff;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect3097"
|
||||
width="29.104164"
|
||||
height="5.2916698"
|
||||
x="222.25"
|
||||
y="129.64583"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41936"
|
||||
y="143.81723"
|
||||
id="text3109"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3107"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41936"
|
||||
y="143.81723">thread2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.465"
|
||||
y="149.08565"
|
||||
id="text3113"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3111"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.465"
|
||||
y="149.08565">thread3</tspan></text>
|
||||
<path
|
||||
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 216.95833,129.64583 v 21.16666"
|
||||
id="path3115" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="196.27194"
|
||||
y="45.757755"
|
||||
id="text3121"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3119"
|
||||
style="font-size:2.82222px;stroke-width:0.264583"
|
||||
x="196.27194"
|
||||
y="45.757755">CPU: Nanos6 subsystem of the RUNNING thread</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="195.91916"
|
||||
y="125.13276"
|
||||
id="text3125"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3123"
|
||||
style="font-size:2.82222px;stroke-width:0.264583"
|
||||
x="195.91916"
|
||||
y="125.13276">Thread: Nanos6 subsystem of the ACTIVE thread</tspan></text>
|
||||
<path
|
||||
style="fill:#cccccc;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 58.208333,116.41667 15.875,5.29167 v 21.16667 l -15.875,5.29166 z"
|
||||
id="path3197" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="m 66.145833,164.04167 v -9.26041 -9.26042"
|
||||
id="path3199" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="66.183037"
|
||||
y="167.73962"
|
||||
id="text3203"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="66.183037"
|
||||
y="167.73962"
|
||||
id="tspan3201">thread0.state</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="61.100502"
|
||||
y="133.57582"
|
||||
id="text3207"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3205"
|
||||
style="stroke-width:0.264583"
|
||||
x="61.100502"
|
||||
y="133.57582">mux2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
|
||||
x="100.44865"
|
||||
y="130.42442"
|
||||
id="text3211"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';text-align:center;text-anchor:middle;stroke-width:0.264583"
|
||||
x="100.44865"
|
||||
y="130.42442"
|
||||
id="tspan3209">nanos6.thread0.subsystem.act</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 31.75,132.29167 H 47.624999 58.208333"
|
||||
id="path3213"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<rect
|
||||
style="fill:#4d4d4d;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect3875"
|
||||
width="68.791656"
|
||||
height="26.458332"
|
||||
x="195.79167"
|
||||
y="87.3125"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41937"
|
||||
y="93.546394"
|
||||
id="text3879"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3877"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41937"
|
||||
y="93.546394">thread0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.46501"
|
||||
y="98.814812"
|
||||
id="text3883"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3881"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.46501"
|
||||
y="98.814812">thread1</tspan></text>
|
||||
<rect
|
||||
style="fill:#00d400;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect3885"
|
||||
width="29.104164"
|
||||
height="5.2916698"
|
||||
x="222.25"
|
||||
y="89.958321"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41936"
|
||||
y="104.12972"
|
||||
id="text3897"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3895"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.41936"
|
||||
y="104.12972">thread2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3.52777px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.465"
|
||||
y="109.39815"
|
||||
id="text3901"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3899"
|
||||
style="fill:#ffffff;stroke-width:0.264583"
|
||||
x="199.465"
|
||||
y="109.39815">thread3</tspan></text>
|
||||
<path
|
||||
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 216.95832,89.958318 V 111.12498"
|
||||
id="path3903" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="195.91916"
|
||||
y="85.445251"
|
||||
id="text3909"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3907"
|
||||
style="font-size:2.82222px;stroke-width:0.264583"
|
||||
x="195.91916"
|
||||
y="85.445251">Thread: Thread state</tspan></text>
|
||||
<rect
|
||||
style="fill:#ffcc00;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect3911"
|
||||
width="10.583326"
|
||||
height="5.2916679"
|
||||
x="240.77083"
|
||||
y="89.958336"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="93.656296"
|
||||
id="text4019"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="93.656296"
|
||||
id="tspan4017">thread0.state</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="98.947968"
|
||||
id="text4023"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="98.947968"
|
||||
id="tspan4021">thread1.state</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 185.20833,97.895832 H 190.5 195.79166"
|
||||
id="path4025"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 185.20833,103.1875 H 190.5 195.79166"
|
||||
id="path4027"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 185.20833,108.47917 H 190.5 195.79166"
|
||||
id="path4029"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 185.20833,92.604166 H 190.5 195.79166"
|
||||
id="path4031"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 185.20833,142.875 H 190.5 195.79166"
|
||||
id="path4033"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 185.20833,148.16667 H 190.5 195.79166"
|
||||
id="path4035"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-mid:url(#marker1653)"
|
||||
d="M 185.20833,137.58333 H 190.5 195.79166"
|
||||
id="path4039"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="104.23963"
|
||||
id="text4043"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="104.23963"
|
||||
id="tspan4041">thread2.state</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="109.5313"
|
||||
id="text4047"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;fill:#aa0000;stroke-width:0.264583"
|
||||
x="174.6622"
|
||||
y="109.5313"
|
||||
id="tspan4045">thread3.state</tspan></text>
|
||||
<rect
|
||||
style="fill:#d40000;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect4158"
|
||||
width="5.2916636"
|
||||
height="5.2916675"
|
||||
x="246.0625"
|
||||
y="50.270832"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<rect
|
||||
style="fill:#d40000;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect4212"
|
||||
width="5.2916636"
|
||||
height="5.2916675"
|
||||
x="246.0625"
|
||||
y="145.52083"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<rect
|
||||
style="fill:#00d400;stroke-width:0.4;stroke-dasharray:none"
|
||||
id="rect4214"
|
||||
width="5.2916636"
|
||||
height="5.2916656"
|
||||
x="246.0625"
|
||||
y="105.83334"
|
||||
rx="1.4210855e-14"
|
||||
ry="7.1054274e-15" />
|
||||
<path
|
||||
style="fill:#ff0000;stroke:#ff0000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:0.80000001,0.40000001;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 251.35416,39.6875 V 169.33333"
|
||||
id="path3425" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:2.82222px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583;-inkscape-font-specification:'sans-serif Italic';font-weight:normal;font-style:italic;font-stretch:normal;font-variant:normal"
|
||||
x="166.67923"
|
||||
y="51.049423"
|
||||
id="text4270"><tspan
|
||||
sodipodi:role="line"
|
||||
style="font-size:2.82222px;text-align:center;text-anchor:middle;stroke-width:0.264583;-inkscape-font-specification:'sans-serif Italic';font-family:sans-serif;font-weight:normal;font-style:italic;font-stretch:normal;font-variant:normal"
|
||||
x="166.67923"
|
||||
y="51.049423"
|
||||
id="tspan4268">nanos6.cpu0.subsystem.run</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 27 KiB |
@ -1,4 +1,4 @@
|
||||
# Developer guide
|
||||
# Developer guidelines
|
||||
|
||||
To contribute to the ovni project, please read carefully this guide and
|
||||
follow the guidelines to have your contribution accepted in the project.
|
48
doc/dev/model.md
Normal file
48
doc/dev/model.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Model
|
||||
|
||||
The emulator is designed to support multiple models simultaneously. Each model
|
||||
must be implemented by following the `model_spec` interface, which defines the
|
||||
functions that will be called by the emulation when that model is enabled.
|
||||
|
||||
Each model must have a unique character that identifies the model, and will be
|
||||
used to filter the events in the MCV (model, category, value) tuple of the
|
||||
input event.
|
||||
|
||||
Unless otherwise stated, all model functions return 0 on success or -1 on error.
|
||||
|
||||
## Probe
|
||||
|
||||
The probe function determines if the model should be enabled or not, based on
|
||||
the information read from the metadata of the traces. No events are available
|
||||
yet. Returns -1 on error, 0 if the model must be enabled or 1 if not.
|
||||
|
||||
If the model is not enabled, no other function will be called.
|
||||
|
||||
## Create
|
||||
|
||||
The create function is called for each enabled model to allow them to allocate
|
||||
all the required structures to perform the emulation using the
|
||||
[extend](../extend) mechanism. All the required channels must be created and
|
||||
registered in the patch bay in this function, so other models can found them in
|
||||
the next stage.
|
||||
|
||||
## Connect
|
||||
|
||||
In the connect function, the channels and multiplexers are connected, as all the
|
||||
channels of all models have already been registered in the patch bay. The
|
||||
channels must also be connected to the output traces to record the states.
|
||||
|
||||
## Event
|
||||
|
||||
The event function is called only if the processed input event matches the model
|
||||
character. The function must return 0 on success or -1 on error. If an error
|
||||
is returned, the emulator will print some information about the current event and
|
||||
proceed to call the last stage so the traces can be closed and flushed to disk
|
||||
before stopping the emulation process.
|
||||
|
||||
## Finish
|
||||
|
||||
This function is called when there are no more events to be processed or when
|
||||
the emulator has encountered a problem processing on event and needs to abort
|
||||
the emulation process. The output traces must be closed to write all the buffers
|
||||
into disk. Additional allocated structures may now be freed.
|
47
doc/dev/mux.md
Normal file
47
doc/dev/mux.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Mux
|
||||
|
||||
The emulator provides a mechanism to interconnect [channels](../channels) in a
|
||||
similar way as an [analog
|
||||
multiplexer](https://en.wikipedia.org/wiki/Multiplexer) by using the `mux`
|
||||
module.
|
||||
|
||||
Multiplexers or muxers have one output channel, one select channel and a
|
||||
variable number of input channels (including zero). Each input channel is
|
||||
registered in the multiplexer by using a key with a given value. In the normal
|
||||
operation of a mux, the value of the select channel is used to find an input
|
||||
with a matching key. When there is no match, the output value is set to null.
|
||||
|
||||
Multiplexers can be configured to execute a custom select function, which will
|
||||
take the value of the select channel and determine which input should be
|
||||
selected. This allows a multiplexer to act as a filter too.
|
||||
|
||||
## Tracking
|
||||
|
||||
The typical use of multiplexers is to implement the tracking modes of channels.
|
||||
As an example, the following diagram shows three multiplexers used to implement
|
||||
the subsystem view of [Nanos6](../nanos6):
|
||||
|
||||
![Patch bay](fig/mux.svg)
|
||||
|
||||
The first mux0 uses the thread state channel to filter the value of the
|
||||
subsystem channel and only pass it to the output when the thread is in the
|
||||
Running state (green). Then the filtered subsystem channel is connected to an
|
||||
input of a second mux (mux1) which selects the current input of the thread
|
||||
running in the CPU0. The output *nanos6.cpu.subsystem.run* is then connected to
|
||||
the Paraver timeline in the row corresponding to the CPU0, which shows the
|
||||
subsystem of the currently running thread.
|
||||
|
||||
The Nanos6 subsystem channel is also connected to the mux2, which forwards the
|
||||
value to the output only when the thread state is Active. The output is directly
|
||||
connected to the Paraver row assigned to that thread. This channels shows the
|
||||
subsystem of the thread by only when is active (not paused nor dead). You can
|
||||
see that the subsystem is shown in the thread0 at the current time (red dotted
|
||||
line) when in the CPU0 the subsystem has been hidden when the thread stops being
|
||||
in the Running state (yellow).
|
||||
|
||||
Multiplexers allow models to interact with each other in a controlled way. In
|
||||
the example, the blue channel (*nanos6.thread0.subsystem*) is directly modified by
|
||||
the Nanos6 model when a new event is received. While the red channels are
|
||||
controled by the ovni model. The rest of the channels are automatically updated
|
||||
in the propagation phase of the [bay](../patchbay) allowing the ovni model to
|
||||
modify the Nanos6 Paraver view of the subsystems.
|
23
doc/dev/paraver.md
Normal file
23
doc/dev/paraver.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Paraver trace
|
||||
|
||||
Paraver traces are handled by the top level module `pvt` (Paraver trace), which
|
||||
in turn uses the `prv`, `pcf` and `prf` to control the trace events, type
|
||||
definitions and row names (in that order).
|
||||
|
||||
Traces must be initialized with the number of rows and a name by calling
|
||||
`pvt_open()`.
|
||||
|
||||
The emulation time must be updated with `pvt_advance()` prior to emitting any
|
||||
event, so they get the update clock in the trace.
|
||||
|
||||
## Connecting channels
|
||||
|
||||
A channel can be connected to each row in a trace with `prv_register()`, so the
|
||||
new values of the channel get written in the trace. Only null and int64 data
|
||||
values are supported for now.
|
||||
|
||||
Duplicated values cause an error by default, unless the channel is registered
|
||||
with the flag `PRV_DUP`.
|
||||
|
||||
The emission phase is controlled by the [patch bay](../patchbay) and runs all
|
||||
the emit callbacks at once for all dirty channels.
|
39
doc/dev/patchbay.md
Normal file
39
doc/dev/patchbay.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Patch bay
|
||||
|
||||
The patch bay (or simply bay) allows [channels](../channels/) to be registered
|
||||
with their name so they are visible to all parts of the emulator and provides a
|
||||
way to run callbacks when the channels update their values.
|
||||
|
||||
The name follows from the [patch bay](https://en.wikipedia.org/wiki/Patch_panel)
|
||||
used to connect audio channels:
|
||||
|
||||
![Patch bay](fig/bay.jpg)
|
||||
|
||||
## Registering channels
|
||||
|
||||
Channels are registered with `bay_register()`, using the channel name as a
|
||||
unique identifier. It is an error to register multiple channels with the same
|
||||
name.
|
||||
|
||||
The register step sets the channel callback function, so the bay can detect
|
||||
which channel become dirty and act upon them.
|
||||
|
||||
## Callbacks
|
||||
|
||||
After registering a channel in the bay, multiple callbacks can be registered
|
||||
with `bay_add_cb()` and will be called in same order they were added.
|
||||
|
||||
The callbacks are executed in the propagation phase, when `bay_propagate()` is
|
||||
called. There are two types of callbacks: *dirty* and *emit*.
|
||||
|
||||
All dirty callbacks are called first, for all the channels that are dirty.
|
||||
Executing the dirty callbacks may cause other channels to become dirty too,
|
||||
which will be added to the list of dirty channels. Channels that are already
|
||||
dirty cannot be modified, so we prevent an infinite updating loop.
|
||||
|
||||
Then the emit callbacks are called for each dirty channel in the same way. The
|
||||
emit callbacks are generally used to write the values of the channels in the
|
||||
output traces. These callbacks cannot cause any new channel to become dirty.
|
||||
|
||||
Finally, all channels are flushed by calling `chan_flush()`, clearing the dirty
|
||||
flag and leaving them ready for the next input event.
|
@ -1,170 +0,0 @@
|
||||
# Channels
|
||||
|
||||
As the emulation progresses, information is written in the PRV trace to
|
||||
record the new states. The emulator has specific mechanism to handle the
|
||||
output of new states in the PRV trace via channels. A channel stores an
|
||||
integer that represents an state at a given point in time and
|
||||
corresponds to the value that will be observed in the Paraver timeline.
|
||||
|
||||
!!! Note
|
||||
|
||||
In general, the emulator receives events, then performs a state
|
||||
transition and the new state (or states) are written into the
|
||||
PRV file.
|
||||
|
||||
There are two classes of channels: CPU and thread channels. Both CPU and
|
||||
threads have the same fixed number of channels, given by the enumeration
|
||||
`enum chan`.
|
||||
|
||||
For example the `CHAN_OVNI_STATE` of the thread stores the execution
|
||||
state of the thread (running, paused ...). Whereas, the CPU channel
|
||||
`CHAN_OVNI_NRTHREADS` records how many running threads a given CPU has.
|
||||
|
||||
The channels are used in the following way:
|
||||
|
||||
- In the "pre" phase, the emulator modifies the state of the emulator
|
||||
based on the new event. The channels are then updated accordingly in
|
||||
this phase, for example when a thread goes from running to paused it
|
||||
must update the `CHAN_OVNI_STATE` channel of the thread by also the
|
||||
`CHAN_OVNI_NRTHREADS` channel of the CPU.
|
||||
|
||||
- In the "emit" phase, the emulator calls the `chan_emit()` method on
|
||||
those channels that have been modified. Those have the dirty attribute
|
||||
set to 1.
|
||||
|
||||
- The optional "post" phase is used to perform some operations before
|
||||
the next event is loaded, but is not commonly used.
|
||||
|
||||
Then the emulator then loads the next event and repeats the process
|
||||
again.
|
||||
|
||||
## Disabling and enabling channels
|
||||
|
||||
Some channels provide information that only makes sense in some
|
||||
conditions. For example, the CPU channel `CHAN_OVNI_TID` tracks the TID
|
||||
of the thread currently running in the CPU. When there is no thread
|
||||
running or there are multiple threads running in the same CPU, this
|
||||
channel cannot output valid information.
|
||||
|
||||
For those cases, the channels can be enabled or disabled as to only
|
||||
provide information when it is necessary. When a channel is disabled, it
|
||||
will emit the value stored in `badst` which by default is set to 0.
|
||||
|
||||
Notice that if a channel was in a given state A, and was disabled, it
|
||||
must emit the new state is 0. When the channel is enabled again, it will
|
||||
emit again the state A.
|
||||
|
||||
## Thread tracking channels
|
||||
|
||||
Regarding thread channels, there are two common conditions that cause
|
||||
the channels to become disabled. When the thread is no longer running,
|
||||
and then the thread is not active.
|
||||
|
||||
For those cases, the thread channels can be configured to automatically
|
||||
be enabled or disabled, following the execution state of the thread. The
|
||||
tracking mode specifies how the tracking must be done:
|
||||
|
||||
- `CHAN_TRACK_NONE`: nothing to track
|
||||
- `CHAN_TRACK_RUNNING_TH`: enable the channel only if the thread is
|
||||
running
|
||||
- `CHAN_TRACK_ACTIVE_TH`: enable the channel only if the thread is
|
||||
running, cooling or warming.
|
||||
|
||||
This mechanism removes the complexity of detecting when a thread stops
|
||||
running, to update a channel of a given module. As the thread state
|
||||
changes as handled by the `emu_ovni.c` module only.
|
||||
|
||||
## CPU tracking channels
|
||||
|
||||
Similarly, CPU channels can also be configured to track the execution
|
||||
state of the threads. They become disabled when the tracking condition
|
||||
is not met, but also copy the state of the tracking thread channel.
|
||||
|
||||
They share the same tracking modes, but their behavior is slightly
|
||||
different:
|
||||
|
||||
In the case of tracking the running thread, if the CPU has more than one
|
||||
thread running, the channel will always output the error state
|
||||
`ST_TOO_MANY_TH`.
|
||||
|
||||
If is has no threads running, will be disabled and emit a 0 state by
|
||||
default.
|
||||
|
||||
Otherwise, it will emit the same value as the running thread. If the
|
||||
thread channel is disabled, it will emit a `ST_BAD` error state.
|
||||
|
||||
Regarding the active thread tracking mode, the CPU channels behave
|
||||
similarly, but with the active threads instead of running ones.
|
||||
|
||||
The CPU tracking mechanism simplify the process of updating CPU
|
||||
channels, as the modules don't need to worry about the execution model.
|
||||
Only the channels need to be configured to follow the proper execution
|
||||
state.
|
||||
|
||||
## Channel state modes
|
||||
|
||||
The channels can be updated in three ways:
|
||||
|
||||
1. A fixed state can be set to the channel using `chan_set()`, which
|
||||
overrides the previous state.
|
||||
|
||||
2. The new state can be stored in a stack with `chan_push()` and
|
||||
`chan_pop()`, to remember the history of the previous states. The
|
||||
emitted event will be the one on the top.
|
||||
|
||||
3. Using a punctual event.
|
||||
|
||||
Setting the channel state is commonly used to track quantities such as
|
||||
the number of threads running per CPU. While the stack mode is commonly
|
||||
used to track functions or sections of code delimited with enter and
|
||||
exit events, which can call an return to the previous state.
|
||||
|
||||
An example program may be instrumented like this:
|
||||
|
||||
int bar() {
|
||||
instr("Xb[");
|
||||
...
|
||||
instr("Xb]");
|
||||
}
|
||||
|
||||
int foo() {
|
||||
instr("Xf[");
|
||||
bar();
|
||||
instr("Xf]");
|
||||
}
|
||||
|
||||
Then, in the emulator, when processing the events `Xf[` and `Xf]`, we
|
||||
could track of the state as follows:
|
||||
|
||||
int hook_pre_foo(struct ovni_chan *chan, int value) {
|
||||
switch(value) {
|
||||
case '[': chan_push(chan, 2); break;
|
||||
case ']': chan_pop(chan, 2); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
int hook_pre_bar(struct ovni_chan *chan, int value) {
|
||||
switch(value) {
|
||||
case '[': chan_push(chan, 1); break;
|
||||
case ']': chan_pop(chan, 1); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
The channel will emit the following sequence of states: 0, 1, 2, 1, 0.
|
||||
|
||||
Notice that the `chan_pop()` function uses the same state being pop()'ed
|
||||
as argument. The function checks that the stack contains the expected
|
||||
state, forcing the emulator to always receive a matching pair of enter
|
||||
and exit events.
|
||||
|
||||
## Punctual events
|
||||
|
||||
There are some conditions that are better mapped to events rather than
|
||||
to state transitions. For those cases, the channels provide punctual
|
||||
events which are emitted as a state than only has 1 ns of duration.
|
||||
|
||||
When a channel is configured to emit a punctual event with `chan_ev()`,
|
||||
it will first output the new state at the current time minus 1 ns, then
|
||||
restore the previous channel state and emit it at the current time.
|
@ -10,7 +10,7 @@ happened on the hardware. It consists of CPUs which can execute multiple threads
|
||||
at the same time.
|
||||
|
||||
The emulator uses several models to identify how the resources are being
|
||||
used. The following diagram despicts the resource, process and task
|
||||
used. The following diagram depicts the resource, process and task
|
||||
model.
|
||||
|
||||
[![Model](fig/model.svg)](fig/model.svg)
|
||||
@ -34,11 +34,11 @@ the problem. No effort is made to let the emulator recover from an
|
||||
inconsistency.
|
||||
|
||||
The emulator critical path is kept as simple as possible, so the
|
||||
processing of events can keep the disk writting as the bottleneck.
|
||||
processing of events can keep the disk writing as the bottleneck.
|
||||
|
||||
The linter mode enables more tests which are disabled from the default
|
||||
The lint mode enables more tests which are disabled from the default
|
||||
mode to prevent costly operations running in the emulator by default.
|
||||
The linter tests are enabled when running the ovni testsuite.
|
||||
The lint tests are enabled when running the ovni testsuite.
|
||||
|
||||
## Emulation models
|
||||
|
||||
|
@ -202,4 +202,4 @@ multiple times by varying the arguments with the task for clause, which breaks
|
||||
the emulation model.
|
||||
|
||||
The task for is currently only shown in the subsystem view, but it doesn't
|
||||
appear as running any task in the the other views.
|
||||
appear as running any task in the other views.
|
||||
|
@ -32,6 +32,11 @@ nav:
|
||||
- emulation/nosv.md
|
||||
- emulation/nanos6.md
|
||||
- emulation/events.md
|
||||
- emulation/channels.md
|
||||
- 'Developer guide':
|
||||
- developer-guide/index.md
|
||||
- dev/index.md
|
||||
- dev/channels.md
|
||||
- dev/patchbay.md
|
||||
- dev/mux.md
|
||||
- dev/paraver.md
|
||||
- dev/model.md
|
||||
- dev/extend.md
|
||||
|
Loading…
Reference in New Issue
Block a user