Simbody  3.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
52 #include "SimTKcommon/Constants.h"
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 #if defined(_MSC_VER)
61  /* On Windows, the timespec struct is not defined. However, note that the
62  timespec struct is also defined in the pthread.h header on Windows, so the
63  guard symbols must match here to avoid a duplicate declaration. */
64  #ifndef HAVE_STRUCT_TIMESPEC
65  #define HAVE_STRUCT_TIMESPEC 1
66  struct timespec {
67  long tv_sec; // TODO: this should be time_t but must fix in pthreads too
68  long tv_nsec;
69  };
70  #endif /* HAVE_STRUCT_TIMESPEC */
71 
72  /* Posix nanosleep() sleeps the indicated number of nanoseconds and returns
73  0, or if it is interrupted early it returns how much time was left in
74  rem and returns EINTR. Ours is not interruptable so will always succeed and
75  return rem==0. It is OK if rem is NULL, but req==NULL or req<0 returns
76  EINVAL. A time of req==0 is allowed and our interpretation is that the
77  thread relinquishes its time slice to another ready-to-run thread if there
78  is one, otherwise returns immediately. This implementation rounds the
79  desired sleep time to the nearest millisecond. On a Linux system, this
80  requires including <time.h> (or <ctime>), which we already included
81  above. */
82  SimTK_SimTKCOMMON_EXPORT int nanosleep(const struct timespec* req, struct timespec* rem);
83 
84  /* Posix declares this handy function obsolete, but I don't think it is in
85  any danger of going away. It sleeps for the given number of microseconds.
86  However, using SimTK::sleepInNs() or SimTK::sleepInSec() is safer. */
87  typedef unsigned int useconds_t;
88  inline int usleep(useconds_t us) {
89  struct timespec req;
90  req.tv_sec = (long) (us / 1000000U);
91  req.tv_nsec = (long)((us % 1000000U)*1000U);
92  int status = nanosleep(&req,0);
93  return status ? -1 : 0;
94  }
95 #endif
96 
97 #if defined(_MSC_VER) || defined(__APPLE__)
98  // On Windows and OSX, the Posix clock_gettime function is missing.
99  typedef long clockid_t;
100 
101  /* These constants are the clock ids we support. All the varieties of
102  CLOCK_MONOTONIC are high resolution with no NTP adjustments. I measured
103  the resolutions on a single Windows 7 machine; hopefully they are typical
104  (resolution here means how often they are updated):
105  - MONOTONIC (counter): 0.001ms 1us
106  - REALTIME (time of day): 1ms 1000us
107  - CPUTIME (either): 20ms 20000us
108  These are slightly conservative resolutions so you should be able to
109  achieve them in practice. */
110  #define CLOCK_REALTIME 1 // time of day clock, from 1/1/1970
111  #define CLOCK_MONOTONIC 2 // counter from last boot time
112  #define CLOCK_MONOTONIC_HR 3 // "high resolution" (same)
113  #define CLOCK_MONOTONIC_RAW 4 // "not subject to NTP adjustments" (same)
114  #define CLOCK_THREAD_CPUTIME_ID 5 // current thread's cpu time (kernel+user)
115  #define CLOCK_PROCESS_CPUTIME_ID 6 // cumulative cpu time of all threads of
116  // this process, live or dead
117 
118  /* Returns zero if it succeeds (or if tp==NULL); otherwise EINVAL. On a
119  Linux system, this requires including <time.h> (or <ctime>) and linking
120  with -lrt to get the realtime library. */
121  SimTK_SimTKCOMMON_EXPORT int clock_gettime(clockid_t clock_id,
122  struct timespec *tp);
123 #endif
124 
125 
126 
127 namespace SimTK {
128 
155 inline long long timespecToNs(const timespec& ts)
156 { return (long long)ts.tv_sec*1000000000LL + (long long)ts.tv_nsec; }
157 
160 inline void nsToTimespec(const long long& ns, timespec& ts)
161 { ts.tv_sec = (long)(ns / 1000000000LL); // signed
162  if (ns >= 0) ts.tv_nsec = (long)( ns % 1000000000LL);
163  else ts.tv_nsec = -(long)((-ns) % 1000000000LL); }
164 
168 inline double nsToSec(const long long& ns)
169 { return (double)(ns*SimTK_NS_TO_S); }
170 
174 inline long long secToNs(const double& s)
175 { return (long long)(s*SimTK_S_TO_NS); }
197 inline double cpuTime()
198 { timespec ts;
199  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
200  return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
201 
208 inline double threadCpuTime()
209 { timespec ts;
210  clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
211  return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
242 inline long long realTimeInNs() {
243  timespec ts;
244  #ifdef CLOCK_MONOTONIC_RAW
245  clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
246  #else
247  clock_gettime(CLOCK_MONOTONIC, &ts);
248  #endif
249  return timespecToNs(ts);
250 }
251 
259 inline double realTime() {return nsToSec(realTimeInNs());}
260 
268 inline void sleepInNs(const long long& ns)
269 { timespec ts;
270  nsToTimespec(ns, ts);
271  nanosleep(&ts, 0); }
272 
280 inline void sleepInSec(const double& seconds) {sleepInNs(secToNs(seconds));}
283 } // namespace SimTK
284 
285 #endif // SimTK_SimTKCOMMON_TIMING_H_
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:202
long long secToNs(const double &s)
Given a signed time interval as a double precision floating point number of seconds, return the same time interval as a count of nanosecond ticks in a signed 64 bit integer.
Definition: Timing.h:174
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:197
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:160
double realTime()
Return current time on the high-resolution interval timer in seconds.
Definition: Timing.h:259
void sleepInNs(const long long &ns)
Sleep for the indicated number of nanoseconds, with the actual precision system dependent but intende...
Definition: Timing.h:268
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:155
High precision mathematical and physical constants.
void sleepInSec(const double &seconds)
Sleep for the indicated number of seconds, with the actual precision system dependent but intended to...
Definition: Timing.h:280
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:168
Mandatory first inclusion for any Simbody source or header file.
#define SimTK_NS_TO_S
Convert nanoseconds to seconds.
Definition: Constants.h:527
#define SimTK_S_TO_NS
Convert seconds to nanoseconds.
Definition: Constants.h:535
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:208
long long realTimeInNs()
Return current time on the high-resolution interval timer in nanoseconds, as a 64-bit integer count...
Definition: Timing.h:242