123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- /* $Id:$ */
- /*
- * Copyright (c) 2008-2010 Aaron Turner.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright owners nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- * Read TimeStamp Counter (RDTSC)
- * http://www-unix.mcs.anl.gov/~kazutomo/rdtsc.html
- * I'm not really sure what the license is, but I'll assume Kazutomo Yoshii is
- * cool with me using it since he published it on his website.
- * Should also check out: http://www.fftw.org/cycle.h
- */
- #ifndef __RDTSC_H__
- #define __RDTSC_H__
- u_int64_t rdtsc_calibrate(u_int32_t mhz);
- #if defined(__i386__)
- #define HAVE_RDTSC 1
- static inline u_int64_t
- rdtsc(void)
- {
- u_int64_t x;
- __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
- return x;
- }
- #elif defined(__x86_64__)
- #define HAVE_RDTSC 1
- static inline u_int64_t
- rdtsc(void)
- {
- unsigned hi, lo;
- __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
- return ( (u_int64_t)lo)|( ((u_int64_t)hi)<<32 );
- }
- #elif defined(__powerpc__)
- #define HAVE_RDTSC 1
- static inline u_int64_t
- rdtsc(void)
- {
- u_int64_t result=0;
- u_int32_t upper, lower,tmp;
- __asm__ volatile(
- "0: \n"
- "\tmftbu %0 \n"
- "\tmftb %1 \n"
- "\tmftbu %2 \n"
- "\tcmpw %2,%0 \n"
- "\tbne 0b \n"
- : "=r"(upper),"=r"(lower),"=r"(tmp)
- );
- result = upper;
- result = result<<32;
- result = result|lower;
- return(result);
- }
- #else
- /* do not HAVE_RDTSC for your platform */
- #endif
- /* only define rdtsc_sleep() if we have rdtsc() */
- #ifdef HAVE_RDTSC
- /*
- * sleeps for sleep time, using the rdtsc counter for accuracy
- * you need to call rdtsc_calibrate() BEFORE this or you'll sleep for
- * an additional .1 sec the very first time you call it.
- */
- static inline void
- rdtsc_sleep(const struct timespec sleep)
- {
- u_int64_t sleep_until;
- u_int64_t now = 0;
- static u_int64_t clicks_per_usec = 0;
- sleep_until = rdtsc();
- clicks_per_usec = clicks_per_usec > 0 ? clicks_per_usec : rdtsc_calibrate(0);
-
- sleep_until += clicks_per_usec * TIMESPEC_TO_MICROSEC(&sleep);
-
- while (now < sleep_until)
- now = rdtsc();
- }
- #endif
- #endif /* __RDTSC_H__ */
|