-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[flang-rt] Runtime implementation of extended intrinsic function SECNDS() #152021
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
68a1a81
716f82d
8bbe4eb
5f671e7
9c53878
80b61ed
26b1265
78a8d07
2f3a274
9940825
7268c8c
812760f
205818e
5945264
5cdb74d
599713e
4ae3cd3
fdd310a
1cf3a46
aa3d3d4
0603b56
fb75bee
27ddc47
a61d035
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ | |
| #include "flang-rt/runtime/stat.h" | ||
| #include "flang-rt/runtime/terminator.h" | ||
| #include "flang-rt/runtime/tools.h" | ||
| #include "flang/Runtime/extensions.h" | ||
| #include <cerrno> | ||
| #include <cstdlib> | ||
| #include <limits> | ||
|
|
@@ -309,6 +310,12 @@ std::int32_t RTNAME(Hostnm)( | |
| return status; | ||
| } | ||
|
|
||
| float RTNAME(Secnds)(float *refTime, const char *sourceFile, int line) { | ||
|
||
| Terminator terminator{sourceFile, line}; | ||
| RUNTIME_CHECK(terminator, refTime != nullptr); | ||
| return FORTRAN_PROCEDURE_NAME(secnds)(refTime); | ||
| } | ||
|
|
||
| std::int32_t RTNAME(PutEnv)( | ||
| const char *str, size_t str_length, const char *sourceFile, int line) { | ||
| Terminator terminator{sourceFile, line}; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -303,6 +303,47 @@ void FORTRAN_PROCEDURE_NAME(qsort)(int *array, int *len, int *isize, | |
| // PERROR(STRING) | ||
| void RTNAME(Perror)(const char *str) { perror(str); } | ||
|
|
||
| // GNU extension function SECNDS(refTime) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is ready for review. I did some testing with multiple threads. Test program: Output: |
||
| float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime) { | ||
eugeneepshteyn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| constexpr float FAIL_SECNDS{-1.0f}; // Failure code for this function | ||
| // Failure code for time functions that return std::time_t | ||
| constexpr time_t FAIL_TIME{std::time_t{-1}}; | ||
|
||
| if (!refTime) { | ||
| return FAIL_SECNDS; | ||
| } | ||
| std::time_t now{std::time(nullptr)}; | ||
| if (now == FAIL_TIME) { | ||
| return FAIL_SECNDS; | ||
| } | ||
| // In float result, we can only precisely store 2^24 seconds, which | ||
| // comes out to about 194 days. Thus, need to pick a starting point. | ||
| // Given the description of this function, midnight of the current | ||
| // day is the best starting point. | ||
| static time_t startingPoint{0}; | ||
|
||
| if (!startingPoint) { | ||
| struct tm timeInfo; | ||
| #ifdef _WIN32 | ||
| if (localtime_s(&timeInfo, &now)) { | ||
| return FAIL_SECNDS; | ||
| } | ||
| #else | ||
| if (!localtime_r(&now, &timeInfo)) { | ||
| return FAIL_SECNDS; | ||
| } | ||
| #endif | ||
| // Back to midnight | ||
| timeInfo.tm_hour = 0; | ||
| timeInfo.tm_min = 0; | ||
| timeInfo.tm_sec = 0; | ||
| startingPoint = std::mktime(&timeInfo); | ||
| if (startingPoint == FAIL_TIME) { | ||
| return FAIL_SECNDS; | ||
| } | ||
| } | ||
| double diffStartingPoint{std::difftime(now, startingPoint)}; | ||
| return static_cast<float>(diffStartingPoint) - *refTime; | ||
| } | ||
|
|
||
| // GNU extension function TIME() | ||
| std::int64_t RTNAME(time)() { return time(nullptr); } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a risk that lowering will emit a call with a null dummy argument pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lowering, probably not. So just not have this
Secndswrapper at all? Have lowering go directly tosecnds_?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are other examples in lowering that work in that way, sure. Otherwise, a trivial wrapper is okay.