--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="297mm"
+ height="210mm"
+ viewBox="0 0 297 210"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="tachyon_class.svg">
+ <defs
+ id="defs2" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.98994949"
+ inkscape:cx="518.70929"
+ inkscape:cy="431.60921"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1163"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-87)">
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 236.93444,164.56796 180.2733,182.20774"
+ id="path4571"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4629"
+ inkscape:connection-end="#g4699" />
+ <g
+ id="g4539"
+ transform="translate(-8.8198944,13.630746)">
+ <text
+ id="text4495"
+ y="132.62924"
+ x="40.090427"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.62924"
+ x="40.090427"
+ id="tspan4493"
+ sodipodi:role="line">queue_name</tspan></text>
+ <rect
+ y="129.16928"
+ x="26.206951"
+ height="5.5835876"
+ width="31.508732"
+ id="rect4501"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.29407194;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ <g
+ id="g4544"
+ transform="translate(43.297664)">
+ <text
+ id="text4499"
+ y="132.62924"
+ x="75.370003"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.62924"
+ x="75.370003"
+ id="tspan4497"
+ sodipodi:role="line">msg_queue</tspan></text>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.29407194;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4503"
+ width="31.508732"
+ height="5.5835876"
+ x="63.624683"
+ y="128.90201" />
+ </g>
+ <g
+ id="g4529"
+ transform="translate(34.745039,-4.8108515)">
+ <text
+ id="text4491"
+ y="109.10953"
+ x="83.92263"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="109.10953"
+ x="83.92263"
+ id="tspan4489"
+ sodipodi:role="line">~Tachyon</tspan></text>
+ <ellipse
+ ry="6.0135641"
+ rx="23.118814"
+ cy="107.63954"
+ cx="86.996239"
+ id="path4511"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ <g
+ id="g4534"
+ transform="translate(-130.6948,-17.907058)">
+ <ellipse
+ ry="6.0135641"
+ rx="23.118814"
+ cy="131.96107"
+ cx="157.02086"
+ id="ellipse4515"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text4519"
+ y="132.89651"
+ x="153.67996"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.89651"
+ x="153.67996"
+ id="tspan4517"
+ sodipodi:role="line">name</tspan></text>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 27.623526,120.05799 4.914586,22.74204"
+ id="path4546"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4534"
+ inkscape:connection-end="#g4539" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 68.554641,101.49234 35.383318,142.80003"
+ id="path4548"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4524"
+ inkscape:connection-end="#g4539" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 121.93615,108.84194 0.65009,20.06007"
+ id="path4554"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4529"
+ inkscape:connection-end="#g4544" />
+ <g
+ id="g4524"
+ transform="translate(31.003265,-4.543582)">
+ <text
+ id="text4487"
+ y="107.50591"
+ x="37.685001"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#060000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#060000;fill-opacity:1;stroke-width:0.26458332px"
+ y="107.50591"
+ x="37.685001"
+ id="tspan4485"
+ sodipodi:role="line">Tachyon</tspan></text>
+ <ellipse
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="ellipse4513"
+ cx="37.551376"
+ cy="106.03593"
+ rx="23.118814"
+ ry="6.0135641" />
+ </g>
+ <g
+ transform="translate(-76.43909,22.450641)"
+ id="g4581">
+ <ellipse
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="ellipse4575"
+ cx="157.02086"
+ cy="131.96107"
+ rx="23.118814"
+ ry="6.0135641" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="153.67996"
+ y="132.89651"
+ id="text4579"><tspan
+ sodipodi:role="line"
+ id="tspan4577"
+ x="153.67996"
+ y="132.89651"
+ style="stroke-width:0.26458332px">message_notification</tspan></text>
+ </g>
+ <g
+ id="g4589"
+ transform="translate(-34.745043,44.366741)">
+ <ellipse
+ ry="6.0135641"
+ rx="23.118814"
+ cy="131.96107"
+ cx="157.02086"
+ id="ellipse4583"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text4587"
+ y="132.89651"
+ x="153.67996"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.89651"
+ x="153.67996"
+ id="tspan4585"
+ sodipodi:role="line">expect_message</tspan></text>
+ </g>
+ <g
+ transform="translate(-91.673453,45.16855)"
+ id="g4597">
+ <ellipse
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="ellipse4591"
+ cx="157.02086"
+ cy="131.96107"
+ rx="23.118814"
+ ry="6.0135641" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="153.67996"
+ y="132.89651"
+ id="text4595"><tspan
+ sodipodi:role="line"
+ id="tspan4593"
+ x="153.67996"
+ y="132.89651"
+ style="stroke-width:0.26458332px">receive_message</tspan></text>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 72.798163,107.40372 45.234127,63.01272"
+ id="path4599"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4524"
+ inkscape:connection-end="#g4589" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 80.581769,154.41172 -15.234363,22.7179"
+ id="path4601"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4581"
+ inkscape:connection-end="#g4597" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 90.835237,159.80136 21.187113,11.13681"
+ id="path4603"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4581"
+ inkscape:connection-end="#g4589" />
+ <g
+ id="g4611"
+ transform="translate(-89.802566,76.973624)">
+ <ellipse
+ ry="6.0135641"
+ rx="23.118814"
+ cy="131.96107"
+ cx="157.02086"
+ id="ellipse4605"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text4609"
+ y="132.89651"
+ x="153.67996"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.89651"
+ x="153.67996"
+ id="tspan4607"
+ sodipodi:role="line">accellerate</tspan></text>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 65.701099,183.1424 66.8646,202.92192"
+ id="path4613"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4597"
+ inkscape:connection-end="#g4611" />
+ <g
+ transform="translate(19.77794,-30.201457)"
+ id="g4621">
+ <ellipse
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="ellipse4615"
+ cx="157.02086"
+ cy="131.96107"
+ rx="23.118814"
+ ry="6.0135641" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="153.67996"
+ y="132.89651"
+ id="text4619"><tspan
+ sodipodi:role="line"
+ id="tspan4617"
+ x="153.67996"
+ y="132.89651"
+ style="stroke-width:0.26458332px">nanosleep</tspan></text>
+ </g>
+ <g
+ id="g4577">
+ <g
+ transform="translate(79.913584,32.606881)"
+ id="g4629">
+ <ellipse
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="ellipse4623"
+ cx="157.02086"
+ cy="131.96107"
+ rx="23.118814"
+ ry="6.0135641" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="153.67996"
+ y="132.89651"
+ id="text4627"><tspan
+ sodipodi:role="line"
+ id="tspan4625"
+ x="153.67996"
+ y="132.89651"
+ style="stroke-width:0.26458332px">sleep_until</tspan></text>
+ </g>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 182.38577,107.5949 48.9617,51.13778"
+ id="path4631"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4621"
+ inkscape:connection-end="#g4629" />
+ <g
+ transform="translate(15.583288,106.98589)"
+ id="g4639">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="75.370003"
+ y="132.62924"
+ id="text4635"><tspan
+ sodipodi:role="line"
+ id="tspan4633"
+ x="75.370003"
+ y="132.62924"
+ style="stroke-width:0.26458332px">accelleration</tspan></text>
+ <rect
+ y="128.90201"
+ x="63.624683"
+ height="5.5835876"
+ width="31.508732"
+ id="rect4637"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.29407194;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot4641"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:13.33333333px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:sans-serif;font-stretch:normal;font-variant:normal;text-anchor:middle;text-align:center;writing-mode:lr;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal"><flowRegion
+ id="flowRegion4643"><rect
+ id="rect4645"
+ width="57.523754"
+ height="16.1075"
+ x="598.06525"
+ y="445.25311" /></flowRegion><flowPara
+ id="flowPara4647" /></flowRoot> <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 72.669091,214.77862 92.358348,235.8879"
+ id="path4649"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4611"
+ inkscape:connection-end="#g4639" />
+ <g
+ id="g4659"
+ transform="translate(95.94976,108.24416)">
+ <text
+ id="text4655"
+ y="132.62924"
+ x="75.370003"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.62924"
+ x="75.370003"
+ id="tspan4653"
+ sodipodi:role="line">offset</tspan></text>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.29407194;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4657"
+ width="31.508732"
+ height="5.5835876"
+ x="63.624683"
+ y="128.90201" />
+ </g>
+ <g
+ transform="translate(56.66114,107.17508)"
+ id="g4667">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="75.370003"
+ y="132.62924"
+ id="text4663"><tspan
+ sodipodi:role="line"
+ id="tspan4661"
+ x="75.370003"
+ y="132.62924"
+ style="stroke-width:0.26458332px">T0</tspan></text>
+ <rect
+ y="128.90201"
+ x="63.624683"
+ height="5.5835876"
+ width="31.508732"
+ id="rect4665"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.29407194;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot4669"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:13.33333333px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:sans-serif;font-stretch:normal;font-variant:normal;text-anchor:middle;text-align:center;writing-mode:lr;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal"><flowRegion
+ id="flowRegion4671"><rect
+ id="rect4673"
+ width="37.320702"
+ height="18.127804"
+ x="712.21246"
+ y="507.88257" /></flowRegion><flowPara
+ id="flowPara4675" /></flowRoot> <g
+ transform="translate(70.291886,-25.657875)"
+ id="g4683">
+ <ellipse
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="ellipse4677"
+ cx="157.02086"
+ cy="131.96107"
+ rx="23.118814"
+ ry="6.0135641" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="153.67996"
+ y="132.89651"
+ id="text4681"><tspan
+ sodipodi:role="line"
+ id="tspan4679"
+ x="153.67996"
+ y="132.89651"
+ style="stroke-width:0.26458332px">time</tspan></text>
+ </g>
+ <g
+ id="g4691"
+ transform="translate(110.91685,-13.630747)">
+ <ellipse
+ ry="6.0135641"
+ rx="23.118814"
+ cy="131.96107"
+ cx="157.02086"
+ id="ellipse4685"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text4689"
+ y="132.89651"
+ x="153.67996"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.89651"
+ x="153.67996"
+ id="tspan4687"
+ sodipodi:role="line">settime</tspan></text>
+ </g>
+ <g
+ id="g4587">
+ <g
+ id="g4699"
+ transform="translate(23.252444,50.246669)">
+ <ellipse
+ ry="6.0135641"
+ rx="23.118814"
+ cy="131.96107"
+ cx="157.02086"
+ id="ellipse4693"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.26499999;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text4697"
+ y="132.89651"
+ x="153.67996"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.26458332px"
+ y="132.89651"
+ x="153.67996"
+ id="tspan4695"
+ sodipodi:role="line">gettime</tspan></text>
+ </g>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 177.0585,107.77277 2.9551,68.42182"
+ id="path4569"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4621"
+ inkscape:connection-end="#g4699" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 180.2733,182.20774 99.179841,235.8879"
+ id="path4579"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4699"
+ inkscape:connection-end="#g4639" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 180.2733,182.20774 -4.70538,54.93843"
+ id="path4581"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4699"
+ inkscape:connection-end="#g4659" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 79.084058,214.09573 50.537492,21.98136"
+ id="path4589"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4611"
+ inkscape:connection-end="#g4667" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 180.2733,182.20774 -42.05367,53.86935"
+ id="path4591"
+ inkscape:connector-type="polyline"
+ inkscape:connector-curvature="0"
+ inkscape:connection-start="#g4587"
+ inkscape:connection-end="#g4667" />
+ </g>
+</svg>
#include <sys/types.h>
#include <unistd.h>
+#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
+#include <errno.h>
#include "Tachyon.h"
const int MAX_MESSAGE_SIZE=100;
-static void message_notification(union sigval note)
+/*
+ Functions to calculate timespec structures
+*/
+
+// Calculate a + b
+timespec timespec_add(timespec a, timespec b)
+{
+ timespec sum;
+
+ sum.tv_sec = a.tv_sec + b.tv_sec;
+ sum.tv_nsec = a.tv_nsec + b.tv_nsec;
+
+ if (sum.tv_nsec >= 1000000000)
+ {
+ sum.tv_sec++;
+ sum.tv_nsec -= 1000000000;
+ }
+
+ return sum;
+}
+
+timespec operator + (timespec a, timespec b)
+{
+ return timespec_add(a, b);
+}
+
+// Calculate a - b
+timespec timespec_subtract(timespec a, timespec b)
{
- Tachyon *tp = (Tachyon *) note.sival_ptr;
+ timespec dif;
+
+ dif.tv_sec = a.tv_sec - b.tv_sec;
+ dif.tv_nsec = a.tv_nsec - b.tv_nsec;
+ if (dif.tv_nsec < 0 && dif.tv_sec > 0)
+ {
+ dif.tv_sec--;
+ dif.tv_nsec += 1000000000;
+ }
+ if (dif.tv_nsec > 0 && dif.tv_sec < 0)
+ {
+ dif.tv_sec++;
+ dif.tv_nsec -= 1000000000;
+ }
+
+ return dif;
+}
+
+timespec operator - (timespec a, timespec b)
+{
+ return timespec_subtract(a, b);
+}
+
+// Compare a and b. Return < 0 if a < b
+int timespec_compare(timespec a, timespec b)
+{
+ int cmp = 0;
+
+ if (a.tv_sec == b.tv_sec)
+ {
+ cmp = a.tv_nsec - b.tv_nsec;
+ }
+ else
+ {
+ cmp = a.tv_sec - b.tv_sec;
+ }
+
+ return cmp;
+}
+
+bool operator < (timespec a, timespec b)
+{
+ return timespec_compare(a, b) < 0;
+}
+
+static void message_notification(int signum, siginfo_t *si, void *notused)
+{
+ Tachyon *tp = (Tachyon *) si->si_value.sival_ptr;
tp->receive_message();
+ tp->expect_message();
}
Tachyon::Tachyon()
{
- offset = 0;
- T0 = 0;
+ offset.tv_sec = 0;
+ offset.tv_nsec = 0;
+ clock_gettime(CLOCK_REALTIME, &T0);
accelleration = 1.0;
struct mq_attr queue_attributes;
struct sigevent sev;
+ struct sigaction act;
sprintf(queue_name, "/Tachyon.%d", getpid());
queue_attributes.mq_maxmsg = 2;
msg_queue = mq_open(queue_name, O_CREAT | O_RDONLY, S_IRWXU, &queue_attributes);
- sev.sigev_notify = SIGEV_THREAD;
- sev.sigev_notify_function = message_notification;
- sev.sigev_notify_attributes = NULL;
- sev.sigev_value.sival_ptr = this;
- mq_notify(msg_queue, &sev);
+ // Setup the signal handler for message arrival
+ expect_message();
}
Tachyon::Tachyon(const char *name)
{
- offset = 0;
- T0 = 0;
+ offset.tv_sec = 0;
+ offset.tv_nsec = 0;
+ clock_gettime(CLOCK_REALTIME, &T0);
accelleration = 1.0;
return queue_name;
}
+// Prepare notification and signal handling for ther next message
+
+void Tachyon::expect_message(void)
+{
+ struct sigevent sev;
+ struct sigaction act;
+
+ // Setup the signal handler for message arrival
+
+ act.sa_sigaction = message_notification;
+ act.sa_flags = SA_SIGINFO;
+ sigaction(SIGUSR1, &act, NULL);
+
+ sev.sigev_notify = SIGEV_SIGNAL;
+ sev.sigev_signo = SIGUSR1;
+ sev.sigev_notify_attributes = NULL;
+ sev.sigev_value.sival_ptr = this;
+ mq_notify(msg_queue, &sev);
+}
+
void Tachyon::receive_message(void)
{
char message[MAX_MESSAGE_SIZE];
{
}
+// calculate the currect virtual time
+
+timespec Tachyon::gettime(void)
+{
+ timespec actual_time;
+ timespec virtual_time;
+ timespec difference;
+
+ double seconds;
+ double nanoseconds;
+ double overflow;
+
+ clock_gettime(CLOCK_REALTIME, &actual_time);
+ //printf(" Actual time: %d,%d, T0 = %d,%d\n", actual_time.tv_sec, actual_time.tv_nsec, T0.tv_sec, T0.tv_nsec);
+
+ // Tvirtual = T0 + acc * (Tactual - T0) + offset
+
+ difference = timespec_subtract(actual_time, T0);
+ //printf(" Ta - T0 = %d,%d\n", difference.tv_sec, difference.tv_nsec);
+
+ seconds = difference.tv_sec * accelleration;
+ nanoseconds = difference.tv_nsec * accelleration;
+ overflow = trunc(nanoseconds * 1.0e-9);
+ seconds += overflow;
+ nanoseconds -= overflow * 1.0e9;
+
+ difference.tv_sec = trunc(seconds);
+ difference.tv_nsec = trunc(nanoseconds);
+ //printf(" a * (Ta - T0) = %d,%d\n", difference.tv_sec, difference.tv_nsec);
+
+ virtual_time = timespec_add(T0, difference);
+ virtual_time = timespec_add(virtual_time, offset);
+
+ return virtual_time;
+}
+
int Tachyon::nanosleep(struct timespec req)
{
double seconds;
double nanoseconds;
+ int sleep_return;
- seconds = req.tv_sec / accelleration;
- nanoseconds = req.tv_nsec / accelleration;
- nanoseconds += (seconds - trunc(seconds)) * 1.0e9;
- req.tv_sec = trunc(seconds);
- req.tv_nsec = trunc(nanoseconds);
+ timespec virt_time;
- ::nanosleep(&req, NULL);
+ virt_time = gettime();
+
+ return sleep_until(timespec_add(virt_time, req));
}
int Tachyon::nanosleep(float req)
double seconds;
double nanoseconds;
struct timespec req_t;
+ int sleep_return;
+
+ timespec virt_time;
+
+ virt_time = gettime();
seconds = req / accelleration;
nanoseconds = (seconds - trunc(seconds)) * 1.0e9;
req_t.tv_sec = trunc(seconds);
req_t.tv_nsec = trunc(nanoseconds);
- ::nanosleep(&req_t, NULL);
+ return sleep_until(virt_time + req_t);
+}
+
+int Tachyon::sleep_until(timespec ends_at)
+{
+ double seconds;
+ double nanoseconds;
+ int sleep_return;
+ bool error;
+
+ timespec virt_time;
+ timespec remaining;
+
+ virt_time = gettime();
+ while (!error && virt_time < ends_at)
+ {
+ timespec period;
+
+ period = ends_at - virt_time;
+ //printf("Tv = %d,%d. sleep end at %d,%d\n", virt_time.tv_sec, virt_time.tv_nsec, ends_at.tv_sec, ends_at.tv_nsec);
+ //printf("Virtual period = %d,%d\n", period.tv_sec, period.tv_nsec);
+
+ seconds = period.tv_sec / accelleration;
+ nanoseconds = period.tv_nsec / accelleration;
+ nanoseconds += (seconds - trunc(seconds)) * 1.0e9;
+ period.tv_sec = trunc(seconds);
+ period.tv_nsec = trunc(nanoseconds);
+
+ //printf("Sleeping for : %d,%d\n", period.tv_sec, period.tv_nsec);
+ errno = 0;
+ sleep_return = ::nanosleep(&period, &remaining);
+ //printf("nanosleep returns %d, error = %s\n", sleep_return, strerror(errno));
+
+ error = sleep_return == -1 && errno != EINTR;
+ virt_time = gettime();
+ }
+
+ return sleep_return;
}
void Tachyon::settime(time_t sec)
void Tachyon::accellerate(double factor)
{
+ timespec actual_time, virtual_time;
+
+ clock_gettime(CLOCK_REALTIME, &actual_time);
+ virtual_time = gettime();
+
+ T0 = actual_time;
+ offset = virtual_time - actual_time;
+
accelleration = factor;
// send to the Tachyon object in another process.