Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2001 Paul Davis 00003 Code derived from various headers from the Linux kernel 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 00019 $Id: cycles.h,v 1.4.2.1 2006/06/20 14:44:00 letz Exp $ 00020 */ 00021 00022 #ifndef __jack_cycles_h__ 00023 #define __jack_cycles_h__ 00024 00025 /* 00026 * Standard way to access the cycle counter on i586+ CPUs. 00027 * Currently only used on SMP. 00028 * 00029 * If you really have a SMP machine with i486 chips or older, 00030 * compile for that, and this will just always return zero. 00031 * That's ok, it just means that the nicer scheduling heuristics 00032 * won't work for you. 00033 * 00034 * We only use the low 32 bits, and we'd simply better make sure 00035 * that we reschedule before that wraps. Scheduling at least every 00036 * four billion cycles just basically sounds like a good idea, 00037 * regardless of how fast the machine is. 00038 */ 00039 00040 #ifdef __linux__ 00041 00042 #ifdef __x86_64__ 00043 00044 typedef unsigned long cycles_t; 00045 extern cycles_t cacheflush_time; 00046 00047 static inline unsigned long get_cycles(void) 00048 { 00049 unsigned int hi, lo; 00050 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 00051 return (((unsigned long)hi)<<32) | ((unsigned long)lo); 00052 } 00053 00054 #endif /* __x86_64__ */ 00055 00056 #ifdef __sparc_v9__ 00057 /* rd is V9 only */ 00058 static inline unsigned long long get_cycles(void) 00059 { 00060 unsigned long long res; 00061 __asm__ __volatile__("rd %%tick, %0" : "=r"(res)); 00062 return res; 00063 } 00064 #endif /* __sparc_v9__ */ 00065 00066 #ifdef __PPC__ 00067 00068 /* PowerPC */ 00069 00070 #define CPU_FTR_601 0x00000100 00071 00072 typedef unsigned long cycles_t; 00073 00074 /* For the "cycle" counter we use the timebase lower half. */ 00075 00076 extern cycles_t cacheflush_time; 00077 00078 static inline cycles_t get_cycles(void) 00079 { 00080 cycles_t ret = 0; 00081 00082 __asm__ __volatile__( 00083 "98: mftb %0\n" 00084 "99:\n" 00085 ".section __ftr_fixup,\"a\"\n" 00086 " .long %1\n" 00087 " .long 0\n" 00088 " .long 98b\n" 00089 " .long 99b\n" 00090 ".previous" 00091 : "=r" (ret) : "i" (CPU_FTR_601)); 00092 return ret; 00093 } 00094 00095 #endif /* __PPC__ */ 00096 00097 #ifdef __i386__ 00098 00099 typedef unsigned long long cycles_t; 00100 00101 extern cycles_t cacheflush_time; 00102 00103 #define rdtscll(val) \ 00104 __asm__ __volatile__("rdtsc" : "=A" (val)) 00105 00106 static inline cycles_t get_cycles (void) 00107 { 00108 unsigned long long ret; 00109 00110 rdtscll(ret); 00111 return ret; 00112 } 00113 00114 #endif /* __i386__ */ 00115 00116 /* everything else but x86, amd64, sparcv9 or ppc */ 00117 #if !defined (__PPC__) && !defined (__x86_64__) && !defined (__i386__) && !defined (__sparc_v9__) 00118 00119 #warning No suitable get_cycles() implementation. Returning 0 instead 00120 00121 typedef unsigned long long cycles_t; 00122 00123 static inline cycles_t get_cycles(void) 00124 { 00125 return 0; 00126 } 00127 00128 #endif /* everything else but x86, amd64, sparcv9 or ppc */ 00129 00130 #endif /* __linux__ */ 00131 00132 00133 #if defined(__FreeBSD_kernel__) 00134 00135 #warning No suitable get_cycles() implementation. Returning 0 instead 00136 00137 typedef unsigned long long cycles_t; 00138 00139 static inline cycles_t get_cycles(void) 00140 { 00141 return 0; 00142 } 00143 00144 #endif /* __FreeBSD_kernel__ */ 00145 00146 00147 #endif /* __jack_cycles_h__ */