libzmq master
The Intelligent Transport Layer

clock.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2010-2011 250bpm s.r.o.
00003     Copyright (c) 2010-2011 Other contributors as noted in the AUTHORS file
00004 
00005     This file is part of 0MQ.
00006 
00007     0MQ is free software; you can redistribute it and/or modify it under
00008     the terms of the GNU Lesser General Public License as published by
00009     the Free Software Foundation; either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     0MQ is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "clock.hpp"
00022 #include "platform.hpp"
00023 #include "likely.hpp"
00024 #include "config.hpp"
00025 #include "err.hpp"
00026 
00027 #include <stddef.h>
00028 
00029 #if defined _MSC_VER
00030 #include <intrin.h>
00031 #endif
00032 
00033 #if !defined ZMQ_HAVE_WINDOWS
00034 #include <sys/time.h>
00035 #endif
00036 
00037 zmq::clock_t::clock_t () :
00038     last_tsc (rdtsc ()),
00039     last_time (now_us () / 1000)
00040 {
00041 }
00042 
00043 zmq::clock_t::~clock_t ()
00044 {
00045 }
00046 
00047 uint64_t zmq::clock_t::now_us ()
00048 {
00049 #if defined ZMQ_HAVE_WINDOWS
00050 
00051     //  Get the high resolution counter's accuracy.
00052     LARGE_INTEGER ticksPerSecond;
00053     QueryPerformanceFrequency (&ticksPerSecond);
00054 
00055     //  What time is it?
00056     LARGE_INTEGER tick;
00057     QueryPerformanceCounter (&tick);
00058 
00059     //  Convert the tick number into the number of seconds
00060     //  since the system was started.
00061     double ticks_div = (double) (ticksPerSecond.QuadPart / 1000000);     
00062     return (uint64_t) (tick.QuadPart / ticks_div);
00063 
00064 #else
00065 
00066     //  Use POSIX gettimeofday function to get precise time.
00067     struct timeval tv;
00068     int rc = gettimeofday (&tv, NULL);
00069     errno_assert (rc == 0);
00070     return (tv.tv_sec * (uint64_t) 1000000 + tv.tv_usec);
00071 
00072 #endif
00073 }
00074 
00075 uint64_t zmq::clock_t::now_ms ()
00076 {
00077     uint64_t tsc = rdtsc ();
00078 
00079     //  If TSC is not supported, get precise time and chop off the microseconds.
00080     if (!tsc)
00081         return now_us () / 1000;
00082 
00083     //  If TSC haven't jumped back (in case of migration to a different
00084     //  CPU core) and if not too much time elapsed since last measurement,
00085     //  we can return cached time value.
00086     if (likely (tsc - last_tsc <= (clock_precision / 2) && tsc >= last_tsc))
00087         return last_time;
00088 
00089     last_tsc = tsc;
00090     last_time = now_us () / 1000;
00091     return last_time;
00092 }
00093 
00094 uint64_t zmq::clock_t::rdtsc ()
00095 {
00096 #if (defined _MSC_VER && (defined _M_IX86 || defined _M_X64))
00097     return __rdtsc ();
00098 #elif (defined __GNUC__ && (defined __i386__ || defined __x86_64__))
00099     uint32_t low, high;
00100     __asm__ volatile ("rdtsc" : "=a" (low), "=d" (high));
00101     return (uint64_t) high << 32 | low;
00102 #elif (defined __SUNPRO_CC && (__SUNPRO_CC >= 0x5100) && (defined __i386 || \
00103     defined __amd64 || defined __x86_64))
00104     union {
00105         uint64_t u64val;
00106         uint32_t u32val [2];
00107     } tsc;
00108     asm("rdtsc" : "=a" (tsc.u32val [0]), "=d" (tsc.u32val [1]));
00109     return tsc.u64val;
00110 #elif defined(__s390__)
00111     uint64_t tsc;
00112     asm("\tstck\t%0\n" : "=Q" (tsc) : : "cc");
00113     tsc >>= 12;     /* convert to microseconds just to be consistent */
00114     return(tsc);
00115 #else
00116     return 0;
00117 #endif
00118 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines