Simbody  3.4 (development)
Timing.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_TIMING_H_
00002 #define SimTK_SimTKCOMMON_TIMING_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK 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/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2010-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00051 #include "SimTKcommon/internal/common.h"
00052 #include "SimTKcommon/Constants.h"
00053 
00054 // This header is needed on Mac and Linux for some or all of the Posix time 
00055 // functions and the timespec struct. We include it on Windows also for 
00056 // uniform cross-platform behavior, since there are many other useful time-
00057 // date-handling symbols declared here on all platforms.
00058 #include <ctime>
00059 
00060 #if defined(_MSC_VER)
00061     /* On Windows, the timespec struct is not defined. However, note that the 
00062     timespec struct is also defined in the pthread.h header on Windows, so the 
00063     guard symbols must match here to avoid a duplicate declaration. */
00064     #ifndef HAVE_STRUCT_TIMESPEC
00065     #define HAVE_STRUCT_TIMESPEC 1
00066     struct timespec {
00067             long tv_sec;  // TODO: this should be time_t but must fix in pthreads too
00068             long tv_nsec;
00069     };
00070     #endif /* HAVE_STRUCT_TIMESPEC */
00071 
00072     /* Posix nanosleep() sleeps the indicated number of nanoseconds and returns
00073     0, or if it is interrupted early it returns how much time was left in 
00074     rem and returns EINTR. Ours is not interruptable so will always succeed and
00075     return rem==0. It is OK if rem is NULL, but req==NULL or req<0 returns 
00076     EINVAL. A time of req==0 is allowed and our interpretation is that the 
00077     thread relinquishes its time slice to another ready-to-run thread if there
00078     is one, otherwise returns immediately. This implementation rounds the 
00079     desired sleep time to the nearest millisecond. On a Linux system, this 
00080     requires including <time.h> (or <ctime>), which we already included 
00081     above. */
00082     SimTK_SimTKCOMMON_EXPORT int nanosleep(const struct timespec* req, struct timespec* rem);
00083 
00084     /* Posix declares this handy function obsolete, but I don't think it is in
00085     any danger of going away. It sleeps for the given number of microseconds.
00086     However, using SimTK::sleepInNs() or SimTK::sleepInSec() is safer. */
00087     typedef unsigned int useconds_t;
00088     inline int usleep(useconds_t us) {
00089         struct timespec req;
00090         req.tv_sec  = (long) (us / 1000000U);
00091         req.tv_nsec = (long)((us % 1000000U)*1000U);
00092         int status = nanosleep(&req,0);
00093         return status ? -1 : 0;
00094     }
00095 #endif
00096 
00097 #if defined(_MSC_VER) || defined(__APPLE__)
00098     // On Windows and OSX, the Posix clock_gettime function is missing.
00099     typedef long clockid_t;
00100 
00101     /* These constants are the clock ids we support. All the varieties of 
00102     CLOCK_MONOTONIC are high resolution with no NTP adjustments. I measured 
00103     the resolutions on a single Windows 7 machine; hopefully they are typical
00104     (resolution here means how often they are updated):
00105       - MONOTONIC (counter):    0.001ms      1us
00106       - REALTIME (time of day):    1ms    1000us
00107       - CPUTIME (either):         20ms   20000us
00108     These are slightly conservative resolutions so you should be able to 
00109     achieve them in practice. */
00110     #define CLOCK_REALTIME           1 // time of day clock, from 1/1/1970
00111     #define CLOCK_MONOTONIC          2 // counter from last boot time
00112     #define CLOCK_MONOTONIC_HR       3 // "high resolution" (same)
00113     #define CLOCK_MONOTONIC_RAW      4 // "not subject to NTP adjustments" (same)
00114     #define CLOCK_THREAD_CPUTIME_ID  5 // current thread's cpu time (kernel+user)
00115     #define CLOCK_PROCESS_CPUTIME_ID 6 // cumulative cpu time of all threads of
00116                                        //   this process, live or dead
00117 
00118     /* Returns zero if it succeeds (or if tp==NULL); otherwise EINVAL. On a 
00119     Linux system, this requires including <time.h> (or <ctime>) and linking 
00120     with -lrt to get the realtime library. */
00121     SimTK_SimTKCOMMON_EXPORT int clock_gettime(clockid_t clock_id, 
00122                                                struct timespec *tp); 
00123 #endif
00124 
00125 
00126 
00127 namespace SimTK {
00128 
00155 inline long long timespecToNs(const timespec& ts)
00156 {   return (long long)ts.tv_sec*1000000000LL + (long long)ts.tv_nsec; }
00157 
00160 inline void nsToTimespec(const long long& ns, timespec& ts) 
00161 {   ts.tv_sec  = (long)(ns / 1000000000LL); // signed
00162     if (ns >= 0) ts.tv_nsec =  (long)(  ns  % 1000000000LL);
00163     else         ts.tv_nsec = -(long)((-ns) % 1000000000LL); }
00164 
00168 inline double nsToSec(const long long& ns) 
00169 {   return (double)(ns*SimTK_NS_TO_S); }
00170 
00174 inline long long secToNs(const double& s) 
00175 {   return (long long)(s*SimTK_S_TO_NS); }
00197 inline double cpuTime() 
00198 {   timespec ts;
00199     clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
00200     return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
00201 
00208 inline double threadCpuTime() 
00209 {   timespec ts;
00210     clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
00211     return (double)(timespecToNs(ts)*SimTK_NS_TO_S); }
00242 inline long long realTimeInNs() {
00243     timespec ts;
00244     #ifdef CLOCK_MONOTONIC_RAW
00245         clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
00246     #else
00247         clock_gettime(CLOCK_MONOTONIC, &ts);
00248     #endif
00249     return timespecToNs(ts);
00250 }
00251 
00259 inline double realTime() {return nsToSec(realTimeInNs());}
00260 
00268 inline void sleepInNs(const long long& ns) 
00269 {   timespec ts;
00270     nsToTimespec(ns, ts);
00271     nanosleep(&ts, 0); }
00272 
00280 inline void sleepInSec(const double& seconds) {sleepInNs(secToNs(seconds));}
00283 } // namespace SimTK
00284 
00285 #endif // SimTK_SimTKCOMMON_TIMING_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines