From f3425b5363b1c8eb6083494ead9074a4ab5c834b Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Thu, 11 Apr 2019 10:07:54 +0200
Subject: [PATCH] ENH: replace OSspecific clockValue with std::chrono version
 (#1278)

- aids with portability and maintenance (#1238)
---
 applications/test/OSspecific/Make/files       |   3 +
 .../test/{POSIX => OSspecific}/Make/options   |   0
 .../test/OSspecific/Test-OSspecific.C         |  59 ++++++++++
 applications/test/POSIX/Make/files            |   2 -
 applications/test/clock/Make/files            |   3 +
 applications/test/clock/Make/options          |   2 +
 .../Test-POSIX.C => clock/Test-clock.C}       |  84 +++++++++------
 src/OSspecific/POSIX/Make/files               |   2 -
 src/OpenFOAM/Make/files                       |   2 +
 src/OpenFOAM/global/clock/clock.C             |   1 +
 .../global}/clockTime/clockTime.C             |   0
 .../global}/clockTime/clockTime.H             |   1 +
 .../global}/clockValue/clockValue.C           | 102 +++++++-----------
 .../global}/clockValue/clockValue.H           |  28 +++--
 14 files changed, 173 insertions(+), 116 deletions(-)
 create mode 100644 applications/test/OSspecific/Make/files
 rename applications/test/{POSIX => OSspecific}/Make/options (100%)
 create mode 100644 applications/test/OSspecific/Test-OSspecific.C
 delete mode 100644 applications/test/POSIX/Make/files
 create mode 100644 applications/test/clock/Make/files
 create mode 100644 applications/test/clock/Make/options
 rename applications/test/{POSIX/Test-POSIX.C => clock/Test-clock.C} (67%)
 rename src/{OSspecific/POSIX => OpenFOAM/global}/clockTime/clockTime.C (100%)
 rename src/{OSspecific/POSIX => OpenFOAM/global}/clockTime/clockTime.H (99%)
 rename src/{OSspecific/POSIX => OpenFOAM/global}/clockValue/clockValue.C (65%)
 rename src/{OSspecific/POSIX => OpenFOAM/global}/clockValue/clockValue.H (83%)

diff --git a/applications/test/OSspecific/Make/files b/applications/test/OSspecific/Make/files
new file mode 100644
index 0000000000..b493846698
--- /dev/null
+++ b/applications/test/OSspecific/Make/files
@@ -0,0 +1,3 @@
+Test-OSspecific.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-OSspecific
diff --git a/applications/test/POSIX/Make/options b/applications/test/OSspecific/Make/options
similarity index 100%
rename from applications/test/POSIX/Make/options
rename to applications/test/OSspecific/Make/options
diff --git a/applications/test/OSspecific/Test-OSspecific.C b/applications/test/OSspecific/Test-OSspecific.C
new file mode 100644
index 0000000000..91e18644de
--- /dev/null
+++ b/applications/test/OSspecific/Test-OSspecific.C
@@ -0,0 +1,59 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2019 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Description
+    Report some basic os-specific values
+
+\*---------------------------------------------------------------------------*/
+
+#include "OSspecific.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    Info<< "Report some basic OS-specific values" << nl;
+
+    Info<< nl
+        << "host   : " << hostName() << nl
+        << "user   : " << userName() << nl
+        << "home   : " << home() << nl;
+
+    Info<< nl
+        << "cwd    : " << cwd() << nl
+        << "cwd -P : " << cwd(false) << nl
+        << "cwd -L : " << cwd(true) << nl;
+
+    Info<< nl
+        << "libs   : " << dlLoaded() << nl;
+
+    Info<< "\nEnd\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/POSIX/Make/files b/applications/test/POSIX/Make/files
deleted file mode 100644
index 491f2572f3..0000000000
--- a/applications/test/POSIX/Make/files
+++ /dev/null
@@ -1,2 +0,0 @@
-Test-POSIX.C
-EXE = $(FOAM_USER_APPBIN)/Test-POSIX
diff --git a/applications/test/clock/Make/files b/applications/test/clock/Make/files
new file mode 100644
index 0000000000..549cc0ca51
--- /dev/null
+++ b/applications/test/clock/Make/files
@@ -0,0 +1,3 @@
+Test-clock.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-clock
diff --git a/applications/test/clock/Make/options b/applications/test/clock/Make/options
new file mode 100644
index 0000000000..4e772fdf9d
--- /dev/null
+++ b/applications/test/clock/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/POSIX/Test-POSIX.C b/applications/test/clock/Test-clock.C
similarity index 67%
rename from applications/test/POSIX/Test-POSIX.C
rename to applications/test/clock/Test-clock.C
index d064e88c2f..c9ad63ff29 100644
--- a/applications/test/POSIX/Test-POSIX.C
+++ b/applications/test/clock/Test-clock.C
@@ -2,10 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2004-2010, 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
--------------------------------------------------------------------------------
-                            | Copyright (C) 2011 OpenFOAM Foundation
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,6 +22,7 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Description
+    Test some clock-related routines
 
 \*---------------------------------------------------------------------------*/
 
@@ -31,57 +30,72 @@ Description
 #include "clock.H"
 #include "clockTime.H"
 #include "cpuTime.H"
+#include "clockValue.H"
 
 using namespace Foam;
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// Main program:
 
-int main(int argc, char *argv[])
+template<class ClockValue>
+void testEpoch()
 {
-    Info<<"cwd() " << cwd() << nl;
-    Info<<"cwd(-P) " << cwd(false) << nl;
-    Info<<"cwd(-L) " << cwd(true) << nl;
+    Info<< nl << "Test epoch" << nl;
 
-    Info<<"rmDir" << nl;
-    rmDir("hmm");
+    ClockValue now(true);
 
-    {
-        Foam::clock sysClock();
+    Info<< "epoch = " << now.str() << "  # day-hh:mm::ss" << nl
+        << "epoch = " << now << nl;
+}
 
-        Info<< "clock: date "  << clock::date() << nl
-            << "clock: time "  << clock::clockTime() << nl
-            << "clock: iso  "  << clock::dateTime() << nl;
-    }
 
-    Info<< "since epoch = " << clockValue::now().str() << nl;
+template<class ClockValue>
+void testElapsed()
+{
+    Info<< nl << "Test elapsed" << nl;
 
-    {
-        clockValue a;
+    ClockValue a;
 
-        Info<< "clockValue() " << a << nl;
-        a.update();
-        Info<< "updated " << a << nl;
+    Info<< "clockValue() " << a << nl;
+    a.update();
+    Info<< "updated " << a << nl;
 
-        Info<< "sleep 4..." << endl;
-        sleep(4);
+    Info<< "sleep 4..." << endl;
+    sleep(4);
 
-        a.update();
-        Info<< " = " << a.seconds() << nl;
+    a.update();
+    Info<< " = " << a.seconds() << nl;
 
-        Info<< "sleep 2..." << endl;
-        sleep(2);
+    Info<< "sleep 2..." << endl;
+    sleep(2);
 
-        Info<< "elapsed = " << a.elapsed() << nl;
-        Info<< "elapsed = " << a.elapsed().seconds() << nl;
-        Info<< "elapsed = " << a.elapsed().str() << nl;
+    Info<< "elapsed = " << a.elapsed() << nl
+        << "elapsed = " << a.elapsed().seconds() << nl
+        << "elapsed = " << a.elapsed().str() << nl;
 
-        clockValue b = clockValue::now();
+    ClockValue b(true);
 
-        Info<< "(" << b << " - " << a << ") = " << (b - a) << nl;
-        Info<< "(" << b << " + " << a << ") = " << (b + a) << nl;
+    Info<< "(" << b << " - " << a << ") = " << (b - a) << nl;
+    Info<< "(" << b << " + " << a << ") = " << (b + a) << nl;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    {
+        Foam::clock sysClock();
+
+        Info<< "clock: date "  << clock::date() << nl
+            << "clock: time "  << clock::clockTime() << nl
+            << "clock: iso  "  << clock::dateTime() << nl;
     }
 
+    testEpoch<clockValue>();
+
+    testElapsed<clockValue>();
+
+
     {
         clockTime clk;
 
diff --git a/src/OSspecific/POSIX/Make/files b/src/OSspecific/POSIX/Make/files
index 1f91738212..7ce5e03c60 100644
--- a/src/OSspecific/POSIX/Make/files
+++ b/src/OSspecific/POSIX/Make/files
@@ -1,5 +1,3 @@
-clockTime/clockTime.C
-clockValue/clockValue.C
 cpuInfo/cpuInfo.C
 cpuTime/cpuTime.C
 memInfo/memInfo.C
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 0e7ae03ba7..5a35b70613 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -4,6 +4,8 @@ global/global.Cver
 global/argList/argList.C
 global/argList/argListHelp.C
 global/clock/clock.C
+global/clockTime/clockTime.C
+global/clockValue/clockValue.C
 global/profiling/profiling.C
 global/profiling/profilingInformation.C
 global/profiling/profilingSysInfo.C
diff --git a/src/OpenFOAM/global/clock/clock.C b/src/OpenFOAM/global/clock/clock.C
index 822118d90e..b5c2c971ac 100644
--- a/src/OpenFOAM/global/clock/clock.C
+++ b/src/OpenFOAM/global/clock/clock.C
@@ -75,6 +75,7 @@ std::string Foam::clock::dateTime()
     return os.str();
 }
 
+
 std::string Foam::clock::date()
 {
     time_t t = getTime();
diff --git a/src/OSspecific/POSIX/clockTime/clockTime.C b/src/OpenFOAM/global/clockTime/clockTime.C
similarity index 100%
rename from src/OSspecific/POSIX/clockTime/clockTime.C
rename to src/OpenFOAM/global/clockTime/clockTime.C
diff --git a/src/OSspecific/POSIX/clockTime/clockTime.H b/src/OpenFOAM/global/clockTime/clockTime.H
similarity index 99%
rename from src/OSspecific/POSIX/clockTime/clockTime.H
rename to src/OpenFOAM/global/clockTime/clockTime.H
index 91aaa033ab..556efa5763 100644
--- a/src/OSspecific/POSIX/clockTime/clockTime.H
+++ b/src/OpenFOAM/global/clockTime/clockTime.H
@@ -62,6 +62,7 @@ class clockTime
         //- Last time when elapsedTime or timeIncrement was called
         mutable value_type last_;
 
+
 public:
 
     // Constructors
diff --git a/src/OSspecific/POSIX/clockValue/clockValue.C b/src/OpenFOAM/global/clockValue/clockValue.C
similarity index 65%
rename from src/OSspecific/POSIX/clockValue/clockValue.C
rename to src/OpenFOAM/global/clockValue/clockValue.C
index 7e1447d978..0fff3629a4 100644
--- a/src/OSspecific/POSIX/clockValue/clockValue.C
+++ b/src/OpenFOAM/global/clockValue/clockValue.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -25,40 +25,32 @@ License
 
 #include "clockValue.H"
 #include "IOstreams.H"
-#include <sys/time.h>
+
 #include <sstream>
 #include <iomanip>
 
-// * * * * * * * * * * * * * * * * Local Data  * * * * * * * * * * * * * * * //
-
-namespace
-{
-
-    constexpr int factorMicro = (1000000);  //!< From usec to sec
-    constexpr int factorMicro2 = (500000);  //!< Rounding usec to sec
-    constexpr int factorHundred = (10000);  //!< From usec to 0.01 sec
-
-} // End anonymous namespace
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::clockValue::clockValue()
 :
-    clockValue(false)
+    value_(value_type::zero())
+{}
+
+
+Foam::clockValue::clockValue(const value_type& value)
+:
+    value_(value)
 {}
 
 
 Foam::clockValue::clockValue(bool useNow)
+:
+    value_(value_type::zero())
 {
     if (useNow)
     {
         update();
     }
-    else
-    {
-        clear();
-    }
 }
 
 
@@ -66,14 +58,13 @@ Foam::clockValue::clockValue(bool useNow)
 
 void Foam::clockValue::clear()
 {
-    value_.tv_sec  = 0;
-    value_.tv_usec = 0;
+    value_ = value_type::zero();
 }
 
 
 void Foam::clockValue::update()
 {
-    gettimeofday(&value_, 0);
+    value_ = std::chrono::high_resolution_clock::now().time_since_epoch();
 }
 
 
@@ -85,13 +76,7 @@ Foam::clockValue Foam::clockValue::elapsed() const
 
 long Foam::clockValue::seconds() const
 {
-    long sec = value_.tv_sec;
-    if (sec > 0 && value_.tv_usec > factorMicro2)
-    {
-        ++sec;
-    }
-
-    return sec;
+    return std::chrono::duration_cast<std::chrono::seconds>(value_).count();
 }
 
 
@@ -99,23 +84,24 @@ std::string Foam::clockValue::str() const
 {
     std::ostringstream os;
 
-    const unsigned long ss = value_.tv_sec;
+    // seconds
+    const unsigned long ss =
+         std::chrono::duration_cast<std::chrono::seconds>(value_).count();
 
     // days
     const auto dd = (ss / 86400);
 
-    if (dd) os << dd << '-';
-
     // hours
     const int hh = ((ss / 3600) % 24);
 
+    if (dd) os << dd << '-';
+
     if (dd || hh)
     {
         os  << std::setw(2) << std::setfill('0')
             << hh << ':';
     }
 
-
     // minutes
     os  << std::setw(2) << std::setfill('0')
         << ((ss / 60) % 60) << ':';
@@ -124,12 +110,16 @@ std::string Foam::clockValue::str() const
     os  << std::setw(2) << std::setfill('0')
         << (ss % 60);
 
-    // 1/100th seconds. As none or 2 decimal places
-    const int hundredths = (value_.tv_sec % factorHundred);
+    // milliseconds. As none or 3 decimal places
+    const long ms =
+    (
+        std::chrono::duration_cast<std::chrono::milliseconds>(value_).count()
+      - (ss * 1000)
+    );
 
-    if (hundredths)
+    if (ms > 0)
     {
-        os  << '.' << std::setw(2) << std::setfill('0') << hundredths;
+        os  << '.' << std::setw(3) << std::setfill('0') << ms;
     }
 
     return os.str();
@@ -140,38 +130,24 @@ std::string Foam::clockValue::str() const
 
 Foam::clockValue::operator double () const
 {
-    return (value_.tv_sec + 1e-6*value_.tv_usec);
+    return
+    (
+        (double(value_.count()) * value_type::period::num)
+      / value_type::period::den
+    );
 }
 
 
 Foam::clockValue& Foam::clockValue::operator-=(const clockValue& rhs)
 {
-    const value_type& b = rhs.value_;
-
-    value_.tv_sec -= b.tv_sec;
-
-    if (value_.tv_usec < b.tv_usec)
-    {
-        --(value_.tv_sec);
-        value_.tv_usec += factorMicro;
-    }
-
-    value_.tv_usec -= b.tv_usec;
-
+    value_ -= rhs.value_;
     return *this;
 }
 
 
 Foam::clockValue& Foam::clockValue::operator+=(const clockValue& rhs)
 {
-    const value_type& b = rhs.value_;
-
-    // Microseconds first
-    value_.tv_usec += b.tv_usec;
-
-    value_.tv_sec  += b.tv_sec + (value_.tv_usec / factorMicro);
-    value_.tv_usec %= factorMicro;
-
+    value_ += rhs.value_;
     return *this;
 }
 
@@ -180,19 +156,13 @@ Foam::clockValue& Foam::clockValue::operator+=(const clockValue& rhs)
 
 Foam::clockValue Foam::operator-(const clockValue& a, const clockValue& b)
 {
-    clockValue result(a);
-    result -= b;
-
-    return result;
+    return clockValue(a.value() - b.value());
 }
 
 
 Foam::clockValue Foam::operator+(const clockValue& a, const clockValue& b)
 {
-    clockValue result(a);
-    result += b;
-
-    return result;
+    return clockValue(a.value() + b.value());
 }
 
 
diff --git a/src/OSspecific/POSIX/clockValue/clockValue.H b/src/OpenFOAM/global/clockValue/clockValue.H
similarity index 83%
rename from src/OSspecific/POSIX/clockValue/clockValue.H
rename to src/OpenFOAM/global/clockValue/clockValue.H
index 0109af083b..206967fe02 100644
--- a/src/OSspecific/POSIX/clockValue/clockValue.H
+++ b/src/OpenFOAM/global/clockValue/clockValue.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -25,8 +25,7 @@ Class
     Foam::clockValue
 
 Description
-    Access to clock value (approx. 2 microsecond resolution) with
-    some and basic operations.
+    Access to high-resolution clock value with some basic operations.
 
 SourceFiles
     clockValue.C
@@ -36,11 +35,8 @@ SourceFiles
 #ifndef clockValue_H
 #define clockValue_H
 
+#include <chrono>
 #include <string>
-#include <sys/types.h>
-#ifdef darwin
-    #include <sys/time.h>
-#endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -56,19 +52,23 @@ class clockValue
     // Private Data
 
         //- Time structure used
-        typedef struct timeval value_type;
+        typedef std::chrono::high_resolution_clock::duration value_type;
 
         value_type value_;
 
+
 public:
 
     // Constructors
 
-        //- Construct null, zero initialized
+        //- Construct zero initialized
         clockValue();
 
+        //- Construct from duration with the same clock base
+        explicit clockValue(const value_type& value);
+
         //- Construct zero initialized or with current time
-        clockValue(bool useNow);
+        explicit clockValue(bool useNow);
 
 
     // Factory Methods
@@ -82,6 +82,12 @@ public:
 
     // Member Functions
 
+        //- Return the value
+        inline const value_type& value() const
+        {
+            return value_;
+        }
+
         //- Reset to zero
         void clear();
 
@@ -100,7 +106,7 @@ public:
 
     // Operators
 
-        //- Conversion operator to seconds
+        //- Conversion operator to seconds in floating point
         operator double() const;
 
         //- Subtract time value
-- 
GitLab