Add developer documentation

This commit is contained in:
Rodrigo Arias 2023-02-14 16:38:43 +01:00 committed by Rodrigo Arias Mallo
parent de8439c55b
commit 5741cc383f
14 changed files with 893 additions and 178 deletions

63
doc/dev/channels.md Normal file
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

BIN
doc/dev/fig/mux.pdf Normal file

Binary file not shown.

634
doc/dev/fig/mux.svg Normal file
View 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

View File

@ -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
View 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
View 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
View 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
View 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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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