Simbody 3.7
Loading...
Searching...
No Matches
Timing.h
Go to the documentation of this file.
1#ifndef SimTK_SimTKCOMMON_TIMING_H_
2#define SimTK_SimTKCOMMON_TIMING_H_
3
4/* -------------------------------------------------------------------------- *
5 * Simbody(tm): SimTKcommon *
6 * -------------------------------------------------------------------------- *
7 * This is part of the SimTK biosimulation toolkit originating from *
8 * Simbios, the NIH National Center for Physics-Based Simulation of *
9 * Biological Structures at Stanford, funded under the NIH Roadmap for *
10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11 * *
12 * Portions copyright (c) 2010-12 Stanford University and the Authors. *
13 * Authors: Michael Sherman *
14 * Contributors: *
15 * *
16 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17 * not use this file except in compliance with the License. You may obtain a *
18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19 * *
20 * Unless required by applicable law or agreed to in writing, software *
21 * distributed under the License is distributed on an "AS IS" BASIS, *
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 * See the License for the specific language governing permissions and *
24 * limitations under the License. *
25 * -------------------------------------------------------------------------- */
26
53
54// This header is needed on Mac and Linux for some or all of the Posix time
55// functions and the timespec struct. We include it on Windows also for
56// uniform cross-platform behavior, since there are many other useful time-
57// date-handling symbols declared here on all platforms.
58#include <ctime>
59
60
61// macOS (OSX) 10.12 introduced support for clock_gettime().
62// The following logic is based on documentation in /usr/local/Availability.h
63// and from this site:
64// https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Using/using.html.
65// This website also recommends using Availability.h over the similarly-helpful
66// AvailabilityMacros.h.
67#if defined(__APPLE__)
68 #include <Availability.h>
69#endif
70// We'll use the following macros throughout Timing.(h|cpp).
71// "MAX_ALLOWED" is the version of the OSX SDK used when building.
72// "MIN_REQUIRED" is the "DEPLOYMENT_TARGET": earliest version on which the
73// binaries should run.
74// One can use the 10.12 SDK to deploy to earlier releases, like 10.11. The SDK
75// version determines if we need to declare clock_gettime() (e.g., developer is
76// using an SDK older than 10.12), and the deployment target determines if we
77// cannot expect the user's system to contain an implementation of
78// clock_gettime() (e.g., user may be running an on OS older than 10.12).
79// We need both of these macros because developers may only have the 10.12 SDK,
80// but may want to use it to deploy to machines running 10.11. In such a case,
81// we cannot declare clock_gettime() ourselves (the SDK does it), but we must
82// still define it.
83// The number 101200 identifies macOS version 10.12. The explicit version
84// number must be used instead of a macro like __MAC_10_12 because pre-10.12
85// systems won't have __MAC_10_12 defined.
86#if defined(__APPLE__) && __MAC_OS_X_VERSION_MAX_ALLOWED < 101200
87 // SDK is older than 10.12.
88 #define SimTK_IS_APPLE_AND_MUST_DECLARE_CLOCK_GETTIME 1
89#else
90 #define SimTK_IS_APPLE_AND_MUST_DECLARE_CLOCK_GETTIME 0
91#endif
92
93#if defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200
94 // user's OS may be pre-10.12.
95 #define SimTK_IS_APPLE_AND_MUST_DEFINE_CLOCK_GETTIME 1
96#else
97 #define SimTK_IS_APPLE_AND_MUST_DEFINE_CLOCK_GETTIME 0
98#endif
99
100
101
102#if defined(_MSC_VER)
103 /* Posix nanosleep() sleeps the indicated number of nanoseconds and returns
104 0, or if it is interrupted early it returns how much time was left in
105 rem and returns EINTR. Ours is not interruptable so will always succeed and
106 return rem==0. It is OK if rem is NULL, but req==NULL or req<0 returns
107 EINVAL. A time of req==0 is allowed and our interpretation is that the
108 thread relinquishes its time slice to another ready-to-run thread if there
109 is one, otherwise returns immediately. This implementation rounds the
110 desired sleep time to the nearest millisecond. On a Linux system, this
111 requires including <time.h> (or <ctime>), which we already included
112 above. */
113 SimTK_SimTKCOMMON_EXPORT int nanosleep(const struct timespec* req, struct timespec* rem);
114
115 /* Posix declares this handy function obsolete, but I don't think it is in
116 any danger of going away. It sleeps for the given number of microseconds.
117 However, using SimTK::sleepInNs() or SimTK::sleepInSec() is safer. */
118 typedef unsigned int useconds_t;
119 inline int usleep(useconds_t us) {
120 struct timespec req;
121 req.tv_sec = (long) (us / 1000000U);
122 req.tv_nsec = (long)((us % 1000000U)*1000U);
123 int status = nanosleep(&req,0);
124 return status ? -1 : 0;
125 }
126#endif
127
128#if defined(_MSC_VER) || SimTK_IS_APPLE_AND_MUST_DECLARE_CLOCK_GETTIME
129 // On Windows and OSX < 10.12, the Posix clock_gettime function is missing.
130 typedef long clockid_t;
131
132 /* These constants are the clock ids we support. All the varieties of
133 CLOCK_MONOTONIC are high resolution with no NTP adjustments. I measured
134 the resolutions on a single Windows 7 machine; hopefully they are typical
135 (resolution here means how often they are updated):
136 - MONOTONIC (counter): 0.001ms 1us
137 - REALTIME (time of day): 1ms 1000us
138 - CPUTIME (either): 20ms 20000us
139 These are slightly conservative resolutions so you should be able to
140 achieve them in practice. */
141 #define CLOCK_REALTIME 1 // time of day clock, from 1/1/1970
142 #define CLOCK_MONOTONIC 2 // counter from last boot time
143 #define CLOCK_MONOTONIC_HR 3 // "high resolution" (same)
144 #define CLOCK_MONOTONIC_RAW 4 // "not subject to NTP adjustments" (same)
145 #define CLOCK_THREAD_CPUTIME_ID 5 // current thread's cpu time (kernel+user)
146 #define CLOCK_PROCESS_CPUTIME_ID 6 // cumulative cpu time of all threads of
147 // this process, live or dead
148
149 /* Returns zero if it succeeds (or if tp==NULL); otherwise EINVAL. On a
150 Linux system, this requires including <time.h> (or <ctime>) and linking
151 with -lrt to get the realtime library. */
152 SimTK_SimTKCOMMON_EXPORT int clock_gettime(clockid_t clock_id,
153 struct timespec *tp);
154#endif
155
156
157
158namespace SimTK {
159
186inline long long timespecToNs(const timespec& ts)
187{ return (long long)ts.tv_sec*1000000000LL + (long long)ts.tv_nsec; }
188
191inline void nsToTimespec(const long long& ns, timespec& ts)
192{ ts.tv_sec = (long)(ns / 1000000000LL); // signed
193 if (ns >= 0) ts.tv_nsec = (long)( ns % 1000000000LL);
194 else ts.tv_nsec = -(long)((-ns) % 1000000000LL); }
195
199inline double nsToSec(const long long& ns)
200{ return (double)(ns*SimTK_NS_TO_S); }
201
205inline long long secToNs(const double& s)
206{ return (long long)(s*SimTK_S_TO_NS); }
228inline double cpuTime()
229{ timespec ts;
230 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
231 return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
232
239inline double threadCpuTime()
240{ timespec ts;
241 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
242 return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
273inline long long realTimeInNs() {
274 timespec ts;
275 #ifdef CLOCK_MONOTONIC_RAW
276 clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
277 #else
278 clock_gettime(CLOCK_MONOTONIC, &ts);
279 #endif
280 return timespecToNs(ts);
281}
282
290inline double realTime() {return nsToSec(realTimeInNs());}
291
299inline void sleepInNs(const long long& ns)
300{ timespec ts;
301 nsToTimespec(ns, ts);
302 nanosleep(&ts, 0); }
303
311inline void sleepInSec(const double& seconds) {sleepInNs(secToNs(seconds));}
314} // namespace SimTK
315
316#endif // SimTK_SimTKCOMMON_TIMING_H_
High precision mathematical and physical constants.
Mandatory first inclusion for any Simbody source or header file.
#define SimTK_SimTKCOMMON_EXPORT
Definition SimTKcommon/include/SimTKcommon/internal/common.h:224
double threadCpuTime()
Return the total CPU time in seconds (both kernel and user time) that has been used so far by the cur...
Definition Timing.h:239
double cpuTime()
Return the cumulative CPU time in seconds (both kernel and user time) that has been used so far by an...
Definition Timing.h:228
void sleepInSec(const double &seconds)
Sleep for the indicated number of seconds, with the actual precision system dependent but intended to...
Definition Timing.h:311
double realTime()
Return current time on the high-resolution interval timer in seconds.
Definition Timing.h:290
long long realTimeInNs()
Return current time on the high-resolution interval timer in nanoseconds, as a 64-bit integer count.
Definition Timing.h:273
void sleepInNs(const long long &ns)
Sleep for the indicated number of nanoseconds, with the actual precision system dependent but intende...
Definition Timing.h:299
long long secToNs(const double &s)
Given a signed time interval as a double precision floating point number of seconds,...
Definition Timing.h:205
void nsToTimespec(const long long &ns, timespec &ts)
Given a signed number of nanoseconds, convert that into seconds and leftover nanoseconds in a timespe...
Definition Timing.h:191
double nsToSec(const long long &ns)
Given a count of nanosecond ticks as a signed 64 bit integer, return the same time interval as a doub...
Definition Timing.h:199
long long timespecToNs(const timespec &ts)
Convert a time stored in a timespec struct to the equivalent number of nanoseconds (as a signed quant...
Definition Timing.h:186
#define SimTK_S_TO_NS
Convert seconds to nanoseconds.
Definition Constants.h:535
#define SimTK_NS_TO_S
Convert nanoseconds to seconds.
Definition Constants.h:527
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition Assembler.h:37