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): | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 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: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| ## 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. | ||||
| 
 | ||||
| [](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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user