Properly handle sleeps interrupted by receiving a message
authorArjen Baart <arjen@andromeda.nl>
Sat, 18 Jul 2020 08:21:40 +0000 (10:21 +0200)
committerArjen Baart <arjen@andromeda.nl>
Sat, 18 Jul 2020 08:21:40 +0000 (10:21 +0200)
.gitignore
doc/design.xml
doc/tachyon_class.svg [new file with mode: 0644]
src/Tachyon.cpp
src/Tachyon.h
test/Makefile.am
test/accellerate
test/accellerate_float
test/accellerate_multi [new file with mode: 0755]
test/timespec.cpp [new file with mode: 0644]

index b4dc9a3..00ba685 100644 (file)
@@ -1,2 +1,9 @@
 *.[oa]
 Makefile.in
+.*.swp
+autom4te.cache
+config.h.in
+aclocal.m4
+configure
+missing
+m4
index ee4c1c0..eb12e28 100644 (file)
@@ -80,7 +80,7 @@ while (std::cin &gt;&gt; report)
 
 </example>
 
-
+<svg src='time_graph.svg'/>
 
 <para>
 The virtual time is calculated by using an offset o and an acceleration factor a in a simple linear function:
@@ -94,6 +94,32 @@ The virtual time is calculated by using an offset o and an acceleration factor a
 T0 is the time at the moment of changing the accelleration.
 
 By default, the acceleration is 1.0 and the offset is 0, rendering the virtual time equal to the actual time.
+When the acceleration is unequal to 1.0, the virtual time starts to deviate from the actual time, i.e. run slower or faster.
+The difference or 'offset' will gruadually change as time progresses. At any point in time, Ta, the offset can be calculated with:
+
+<pre>
+  o' = Tv - Ta = (1 - a) * T0 - (1 - a) * Ta + o
+</pre>
+
+If the acceleration, a, is changed, the offset is recalculated to reflect the change in acceleration and
+T0 is set to the time at which the acceleration is changed.
+</para>
+
+<para>
+The nanosleep method will sleep for an interval of time, t<sub>s</sub>, in virtual time.
+This is a period of t<sub>s</sub> / a in actual time, unless the the accelleration or offset are changed during the sleep.
+If either of these parameters is changed, the time to sleep is recalculated from the moment of change to the
+moment the sleep period is supposed to end in virtual time.
+Receiving a message to change the accelleration or the virtual time interrupts a sleeping process.
+At that moment, the sleep will resume with a recalculated period in actual time.
+This is the diffrence bewteen at which the sleep ends and the current virtual time divided by the accelleration.
+</para>
+
+<para>
+The nanosleep method calculates the virtual time at which the sleep ends and call the sleep_until method to perform
+the actual sleep by suspending the process.
+Interruptions of the sleep are handled by recalculating the sleep period from the possibly changed parameters
+and resuming the sleep if needed.
 </para>
 
 <para>
@@ -126,7 +152,11 @@ Return the name of the IPC resource that can be used to control this object.
 </item>
 
 <item tag='time_t time(void)'>
-Return the virtual in second since the Epoch. See also time(2).
+Return the virtual in seconds since the Epoch. See also time(2).
+</item>
+
+<item tag='timespec gettime(void)'>
+Return the virtual in seconds and nanoseconds since the Epoch. See also clock_gettime(2).
 </item>
 
 <item tag='int nanosleep(struct timespec req)'>
diff --git a/doc/tachyon_class.svg b/doc/tachyon_class.svg
new file mode 100644 (file)
index 0000000..93e06c0
--- /dev/null
@@ -0,0 +1,577 @@
+<?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>
index da2af54..b9adaa4 100644 (file)
 
 #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;
@@ -33,17 +112,15 @@ Tachyon::Tachyon()
 
    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;
 
@@ -65,6 +142,26 @@ const char * Tachyon::name(void)
    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];
@@ -91,18 +188,53 @@ time_t Tachyon::time(void)
 {
 }
 
+// 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)
@@ -110,6 +242,11 @@ 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;
@@ -117,7 +254,44 @@ int Tachyon::nanosleep(float req)
    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)
@@ -126,6 +300,14 @@ 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.
index 04eb354..c073506 100644 (file)
@@ -10,8 +10,8 @@ class Tachyon
    char      queue_name[255];
    mqd_t     msg_queue;
 
-   time_t    offset;
-   time_t    T0;
+   timespec  offset;
+   timespec  T0;
 
    double    accelleration;
 
@@ -23,13 +23,23 @@ public:
    ~Tachyon();
    const char * name(void);
 
+   void expect_message(void);
    void receive_message(void);
 
-   time_t time(void);
+   time_t   time(void);
+   timespec gettime(void);
+
    int nanosleep(struct timespec req);
    int nanosleep(float req);
+   int sleep_until(timespec ends_at);
 
    void settime(time_t sec);
    void accellerate(double factor);
 };
 
+//  Operations on timespec structures
+
+timespec operator + (timespec a, timespec b);
+timespec operator - (timespec a, timespec b);
+
+bool operator < (timespec a, timespec b);
index d5e36d4..6801cf9 100644 (file)
@@ -1,12 +1,13 @@
-TESTS = create sleep accellerate sleep_float accellerate_float
+TESTS = create timespec sleep accellerate accellerate_multi sleep_float accellerate_float
 
 AM_CPPFLAGS = -I../src
 LDADD = ../src/.libs/libTachyon.la -lrt -lm
 
-check_PROGRAMS = create sleep sleep_float
+check_PROGRAMS = create timespec sleep sleep_float
 
 
 create_SOURCES       = create.cpp
+timespec_SOURCES     = timespec.cpp
 sleep_SOURCES        = sleep.cpp
 sleep_float_SOURCES  = sleep_float.cpp
 
index 537d329..f20aabb 100755 (executable)
@@ -1,5 +1,7 @@
 #!/bin/bash
-
+#
+#  Test accellerating the virtual time once
+#
 set -m
 
 PATH=../src:$PATH
@@ -13,9 +15,11 @@ fg
 END_TIME=`date +%s`
 duration=$(($END_TIME - $START_TIME))
 echo "Elapsed time is $duration"
-if [[ $duration -eq 15 ]] || [[ $duration -eq 14 ]]
+cat sleep.tmp
+
+if [[ $duration -eq 5 ]] || [[ $duration -eq 6 ]]
 then
-   echo "Elapsed time within 15 seconds"
+   echo "Elapsed time within 6 seconds"
    exit 0
 fi
 echo "Elapsed time $duration seconds is unexpected."
index f41e818..8ff7325 100755 (executable)
@@ -13,9 +13,11 @@ fg
 END_TIME=`date +%s`
 duration=$(($END_TIME - $START_TIME))
 echo "Elapsed time is $duration"
-if [[ $duration -eq 6 ]] || [[ $duration -eq 5 ]]
+cat sleep.tmp
+
+if [[ $duration -eq 1 ]] || [[ $duration -eq 2 ]]
 then
-   echo "Elapsed time within 7 seconds"
+   echo "Elapsed time within 2 seconds"
    exit 0
 fi
 echo "Elapsed time $duration seconds is unexpected."
diff --git a/test/accellerate_multi b/test/accellerate_multi
new file mode 100755 (executable)
index 0000000..9e999b3
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+#  Test accellerating the virtual time multiple times
+#
+set -m
+
+PATH=../src:$PATH
+
+START_TIME=`date +%s`
+./sleep >sleep.tmp &
+sleep 1
+read a b c TACHYON_NAME <sleep.tmp
+tachyon -a 3 $TACHYON_NAME
+sleep 14
+tachyon -a 10 $TACHYON_NAME
+fg
+END_TIME=`date +%s`
+duration=$(($END_TIME - $START_TIME))
+echo "Elapsed time is $duration"
+cat sleep.tmp
+
+if [[ $duration -eq 20 ]] || [[ $duration -eq 21 ]]
+then
+   echo "Elapsed time within 21 seconds"
+   exit 0
+fi
+echo "Elapsed time $duration seconds is unexpected."
+exit 1
diff --git a/test/timespec.cpp b/test/timespec.cpp
new file mode 100644 (file)
index 0000000..db6452e
--- /dev/null
@@ -0,0 +1,86 @@
+#include <iostream>
+#include "Tachyon.h"
+#include "assert.h"
+
+/*   test timespec operators  */
+
+bool operator_test(timespec a, timespec b, timespec exp_add, timespec exp_sub, bool exp_lt)
+{
+   bool ok;
+
+   ok = true;
+
+   timespec add = a + b;
+   timespec sub = a - b;
+   bool     lt  = a < b;
+
+   std::cout << a.tv_sec << "." << a.tv_nsec << " + " << b.tv_sec << "." << b.tv_nsec;
+   std::cout << " = " << add.tv_sec << "." << add.tv_nsec <<  "\n";
+   std::cout << a.tv_sec << "." << a.tv_nsec << " - " << b.tv_sec << "." << b.tv_nsec;
+   std::cout << " = " << sub.tv_sec << "." << sub.tv_nsec <<  "\n";
+   std::cout << a.tv_sec << "." << a.tv_nsec << " < " << b.tv_sec << "." << b.tv_nsec;
+   std::cout << " = " << lt <<  "\n\n";
+   std::cout.flush();
+
+   ok = ok && add.tv_sec == exp_add.tv_sec && add.tv_nsec == exp_add.tv_nsec;
+   ok = ok && sub.tv_sec == exp_sub.tv_sec && sub.tv_nsec == exp_sub.tv_nsec;
+   ok = ok && lt == exp_lt;
+
+   return ok;
+}
+
+int main()
+{
+   timespec t_add, t_sub;   // The expected values
+
+   timespec ts0, ts1;
+
+   ts0.tv_sec = 10;
+   ts0.tv_nsec = 600000000;
+   ts1.tv_sec = 2;
+   ts1.tv_nsec = 500000000;
+
+   t_add.tv_sec  = 13;
+   t_add.tv_nsec = 100000000;
+   t_sub.tv_sec  = 8;
+   t_sub.tv_nsec = 100000000;
+
+   assert(operator_test(ts0, ts1, t_add, t_sub, false));
+
+   t_sub.tv_sec  = -8;
+   t_sub.tv_nsec = -100000000;
+   assert(operator_test(ts1, ts0, t_add, t_sub, true));
+
+   timespec ts3, ts4;
+
+   ts3.tv_sec = 10;
+   ts3.tv_nsec = 600000000;
+   ts4.tv_sec = 2;
+   ts4.tv_nsec = 700000000;
+
+   t_add.tv_sec  = 13;
+   t_add.tv_nsec = 300000000;
+   t_sub.tv_sec  = 7;
+   t_sub.tv_nsec = 900000000;
+   assert(operator_test(ts3, ts4, t_add, t_sub, false));
+
+   t_sub.tv_sec  = -7;
+   t_sub.tv_nsec = -900000000;
+   assert(operator_test(ts4, ts3, t_add, t_sub, true));
+
+
+
+   timespec ts6, ts7;
+
+   ts6.tv_sec = 10;
+   ts6.tv_nsec = 600000000;
+   ts7.tv_sec = 10;
+   ts7.tv_nsec = 600000999;
+
+   t_add.tv_sec  = 21;
+   t_add.tv_nsec = 200000999;
+   t_sub.tv_sec  = 0;
+   t_sub.tv_nsec = -999;
+   assert(operator_test(ts6, ts7, t_add, t_sub, true));
+
+}