diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt --- a/flang/runtime/CMakeLists.txt +++ b/flang/runtime/CMakeLists.txt @@ -66,6 +66,7 @@ stop.cpp sum.cpp terminator.cpp + time-intrinsic.cpp tools.cpp transformational.cpp type-code.cpp diff --git a/flang/runtime/time-intrinsic.cpp b/flang/runtime/time-intrinsic.cpp new file mode 100644 --- /dev/null +++ b/flang/runtime/time-intrinsic.cpp @@ -0,0 +1,32 @@ +//===-- runtime/time-intrinsic.cpp ----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Implements time-related intrinsic subroutines. + +#include "time-intrinsic.h" + +#include + +namespace Fortran::runtime { +extern "C" { + +// CPU_TIME (Fortran 2018 16.9.57) +double RTNAME(CpuTime)() { + // This is part of the c++ standard, so it should at least exist everywhere. + // It probably does not have the best resolution, so we prefer other + // platform-specific alternatives if they exist. + std::clock_t timestamp{std::clock()}; + if (timestamp != std::clock_t{-1}) { + return static_cast(timestamp) / CLOCKS_PER_SEC; + } + + // Return some negative value to represent failure. + return -1.0; +} +} // extern "C" +} // namespace Fortran::runtime diff --git a/flang/unittests/RuntimeGTest/CMakeLists.txt b/flang/unittests/RuntimeGTest/CMakeLists.txt --- a/flang/unittests/RuntimeGTest/CMakeLists.txt +++ b/flang/unittests/RuntimeGTest/CMakeLists.txt @@ -11,6 +11,7 @@ Random.cpp Reduction.cpp RuntimeCrashTest.cpp + Time.cpp Transformational.cpp ) diff --git a/flang/unittests/RuntimeGTest/Time.cpp b/flang/unittests/RuntimeGTest/Time.cpp new file mode 100644 --- /dev/null +++ b/flang/unittests/RuntimeGTest/Time.cpp @@ -0,0 +1,35 @@ +//===-- flang/unittests/RuntimeGTest/Time.cpp -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "../../runtime/time-intrinsic.h" + +using namespace Fortran::runtime; + +volatile int x = 0; + +void LookBusy() { + // We're trying to track actual processor time, so sleeping is not an option. + // Doing some writes to a volatile variable should do the trick. + for (int i = 0; i < (1 << 8); ++i) { + x = i; + } +} + +TEST(TimeIntrinsics, CpuTime) { + // We can't really test that we get the "right" result for CPU_TIME, but we + // can have a smoke test to see that we get something reasonable on the + // platforms where we expect to support it. + double start = RTNAME(CpuTime)(); + LookBusy(); + double end = RTNAME(CpuTime)(); + + ASSERT_GE(start, 0.0); + ASSERT_GT(end, 0.0); + ASSERT_GT(end, start); +}