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
 *.[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>
 
 
 </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:
 
 <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.
 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>
 </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)'>
 </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)'>
 </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 <sys/types.h>
 #include <unistd.h>
+#include <signal.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <math.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;
 
 
 #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->receive_message();
+   tp->expect_message();
 }
 
 Tachyon::Tachyon()
 {
 }
 
 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;
 
    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;
 
    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);
 
 
    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)
 {
 }
 
 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;
 
 
    accelleration = 1.0;
 
@@ -65,6 +142,26 @@ const char * Tachyon::name(void)
    return queue_name;
 }
 
    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];
 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 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)
 }
 
 int Tachyon::nanosleep(float req)
@@ -110,6 +242,11 @@ int Tachyon::nanosleep(float req)
    double seconds;
    double nanoseconds;
    struct timespec req_t;
    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;
 
    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);
 
    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::settime(time_t sec)
@@ -126,6 +300,14 @@ void Tachyon::settime(time_t sec)
 
 void Tachyon::accellerate(double factor)
 {
 
 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.
    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;
 
    char      queue_name[255];
    mqd_t     msg_queue;
 
-   time_t    offset;
-   time_t    T0;
+   timespec  offset;
+   timespec  T0;
 
    double    accelleration;
 
 
    double    accelleration;
 
@@ -23,13 +23,23 @@ public:
    ~Tachyon();
    const char * name(void);
 
    ~Tachyon();
    const char * name(void);
 
+   void expect_message(void);
    void receive_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 nanosleep(struct timespec req);
    int nanosleep(float req);
+   int sleep_until(timespec ends_at);
 
    void settime(time_t sec);
    void accellerate(double factor);
 };
 
 
    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
 
 
 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
 
 
 create_SOURCES       = create.cpp
+timespec_SOURCES     = timespec.cpp
 sleep_SOURCES        = sleep.cpp
 sleep_float_SOURCES  = sleep_float.cpp
 
 sleep_SOURCES        = sleep.cpp
 sleep_float_SOURCES  = sleep_float.cpp
 
index 537d329..f20aabb 100755 (executable)
@@ -1,5 +1,7 @@
 #!/bin/bash
 #!/bin/bash
-
+#
+#  Test accellerating the virtual time once
+#
 set -m
 
 PATH=../src:$PATH
 set -m
 
 PATH=../src:$PATH
@@ -13,9 +15,11 @@ fg
 END_TIME=`date +%s`
 duration=$(($END_TIME - $START_TIME))
 echo "Elapsed time is $duration"
 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
 then
-   echo "Elapsed time within 15 seconds"
+   echo "Elapsed time within 6 seconds"
    exit 0
 fi
 echo "Elapsed time $duration seconds is unexpected."
    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"
 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
 then
-   echo "Elapsed time within 7 seconds"
+   echo "Elapsed time within 2 seconds"
    exit 0
 fi
 echo "Elapsed time $duration seconds is unexpected."
    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));
+
+}