Simbody

Timing.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_TIMING_H_
00002 #define SimTK_SimTKCOMMON_TIMING_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK Simbody(tm)                         *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2010 Stanford University and the Authors.           *
00013  * Authors: Peter Eastman                                                     *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00059 #include "SimTKcommon/internal/common.h"
00060 #include "SimTKcommon/Constants.h"
00061 
00062 // This header is needed on Mac and Linux for some or all of the Posix time 
00063 // functions and the timespec struct. We include it on Windows also for 
00064 // uniform cross-platform behavior, since there are many other useful time-
00065 // date-handling symbols declared here on all platforms.
00066 #include <ctime>
00067 
00068 #if defined(_MSC_VER)
00069     /* On Windows, the timespec struct is not defined. However, note that the 
00070     timespec struct is also defined in the pthread.h header on Windows, so the 
00071     guard symbols must match here to avoid a duplicate declaration. */
00072     #ifndef HAVE_STRUCT_TIMESPEC
00073     #define HAVE_STRUCT_TIMESPEC 1
00074     struct timespec {
00075             long tv_sec;  // TODO: this should be time_t but must fix in pthreads too
00076             long tv_nsec;
00077     };
00078     #endif /* HAVE_STRUCT_TIMESPEC */
00079 
00080     /* Posix nanosleep() sleeps the indicated number of nanoseconds and returns
00081     0, or if it is interrupted early it returns how much time was left in 
00082     rem and returns EINTR. Ours is not interruptable so will always succeed and
00083     return rem==0. It is OK if rem is NULL, but req==NULL or req<0 returns 
00084     EINVAL. A time of req==0 is allowed and our interpretation is that the 
00085     thread relinquishes its time slice to another ready-to-run thread if there
00086     is one, otherwise returns immediately. This implementation rounds the 
00087     desired sleep time to the nearest millisecond. On a Linux system, this 
00088     requires including <time.h> (or <ctime>), which we already included 
00089     above. */
00090     SimTK_SimTKCOMMON_EXPORT int nanosleep(const struct timespec* req, struct timespec* rem);
00091 
00092     /* Posix declares this handy function obsolete, but I don't think it is in
00093     any danger of going away. It sleeps for the given number of microseconds.
00094     However, using SimTK::sleepInNs() or SimTK::sleepInSec() is safer. */
00095     typedef unsigned int useconds_t;
00096     inline int usleep(useconds_t us) {
00097         struct timespec req;
00098         req.tv_sec  = (long) (us / 1000000U);
00099         req.tv_nsec = (long)((us % 1000000U)*1000U);
00100         int status = nanosleep(&req,0);
00101         return status ? -1 : 0;
00102     }
00103 #endif
00104 
00105 #if defined(_MSC_VER) || defined(__APPLE__)
00106     // On Windows and OSX, the Posix clock_gettime function is missing.
00107     typedef long clockid_t;
00108 
00109     /* These constants are the clock ids we support. All the varieties of 
00110     CLOCK_MONOTONIC are high resolution with no NTP adjustments. I measured 
00111     the resolutions on a single Windows 7 machine; hopefully they are typical
00112     (resolution here means how often they are updated):
00113       - MONOTONIC (counter):    0.001ms      1us
00114       - REALTIME (time of day):    1ms    1000us
00115       - CPUTIME (either):         20ms   20000us
00116     These are slightly conservative resolutions so you should be able to 
00117     achieve them in practice. */
00118     #define CLOCK_REALTIME           1 // time of day clock, from 1/1/1970
00119     #define CLOCK_MONOTONIC          2 // counter from last boot time
00120     #define CLOCK_MONOTONIC_HR       3 // "high resolution" (same)
00121     #define CLOCK_MONOTONIC_RAW      4 // "not subject to NTP adjustments" (same)
00122     #define CLOCK_THREAD_CPUTIME_ID  5 // current thread's cpu time (kernel+user)
00123     #define CLOCK_PROCESS_CPUTIME_ID 6 // cumulative cpu time of all threads of
00124                                        //   this process, live or dead
00125 
00126     /* Returns zero if it succeeds (or if tp==NULL); otherwise EINVAL. On a 
00127     Linux system, this requires including <time.h> (or <ctime>) and linking 
00128     with -lrt to get the realtime library. */
00129     SimTK_SimTKCOMMON_EXPORT int clock_gettime(clockid_t clock_id, 
00130                                                struct timespec *tp); 
00131 #endif
00132 
00133 
00134 
00135 namespace SimTK {
00136 
00163 inline long long timespecToNs(const timespec& ts)
00164 {   return (long long)ts.tv_sec*1000000000LL + (long long)ts.tv_nsec; }
00165 
00168 inline void nsToTimespec(const long long& ns, timespec& ts) 
00169 {   ts.tv_sec  = (long)(ns / 1000000000LL); // signed
00170     if (ns >= 0) ts.tv_nsec =  (long)(  ns  % 1000000000LL);
00171     else         ts.tv_nsec = -(long)((-ns) % 1000000000LL); }
00172 
00176 inline double nsToSec(const long long& ns) 
00177 {   return (double)(ns*SimTK_NS_TO_S); }
00178 
00182 inline long long secToNs(const double& s) 
00183 {   return (long long)(s*SimTK_S_TO_NS); }
00205 inline double cpuTime() 
00206 {   timespec ts;
00207     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
00208     return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
00209 
00216 inline double threadCpuTime() 
00217 {   timespec ts;
00218     clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
00219     return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
00250 inline long long realTimeInNs() {
00251     timespec ts;
00252     #ifdef CLOCK_MONOTONIC_RAW
00253         clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
00254     #else
00255         clock_gettime(CLOCK_MONOTONIC, &ts);
00256     #endif
00257     return timespecToNs(ts);
00258 }
00259 
00267 inline double realTime() {return nsToSec(realTimeInNs());}
00268 
00276 inline void sleepInNs(const long long& ns) 
00277 {   timespec ts;
00278     nsToTimespec(ns, ts);
00279     nanosleep(&ts, 0); }
00280 
00288 inline void sleepInSec(const double& seconds) {sleepInNs(secToNs(seconds));}
00291 } // namespace SimTK
00292 
00293 #endif // SimTK_SimTKCOMMON_TIMING_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines