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 | To contribute to the ovni project, please read carefully this guide and | ||||||
| follow the guidelines to have your contribution accepted in the project. | 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. | at the same time. | ||||||
| 
 | 
 | ||||||
| The emulator uses several models to identify how the resources are being | 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. | inconsistency. | ||||||
| 
 | 
 | ||||||
| The emulator critical path is kept as simple as possible, so the | 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. | 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 | ## Emulation models | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -202,4 +202,4 @@ multiple times by varying the arguments with the task for clause, which breaks | |||||||
| the emulation model. | the emulation model. | ||||||
| 
 | 
 | ||||||
| The task for is currently only shown in the subsystem view, but it doesn't | 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/nosv.md | ||||||
|     - emulation/nanos6.md |     - emulation/nanos6.md | ||||||
|     - emulation/events.md |     - emulation/events.md | ||||||
|     - emulation/channels.md |  | ||||||
|   - 'Developer guide': |   - '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