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 __sparc_v9__ 00067 /* rd is V9 only */ 00068 static inline unsigned long long get_cycles(void) 00069 { 00070 unsigned long long res; 00071 __asm__ __volatile__("rd %%tick, %0" : "=r"(res)); 00072 return res; 00073 } 00074 #endif 00075 00076 #ifdef __PPC__ 00077 00078 /* PowerPC */ 00079 00080 #define CPU_FTR_601 0x00000100 00081 00082 typedef unsigned long cycles_t; 00083 00084 /* For the "cycle" counter we use the timebase lower half. */ 00085 00086 extern cycles_t cacheflush_time; 00087 00088 static inline cycles_t get_cycles(void) 00089 { 00090 cycles_t ret = 0; 00091 00092 __asm__ __volatile__( 00093 "98: mftb %0\n" 00094 "99:\n" 00095 ".section __ftr_fixup,\"a\"\n" 00096 " .long %1\n" 00097 " .long 0\n" 00098 " .long 98b\n" 00099 " .long 99b\n" 00100 ".previous" 00101 : "=r" (ret) : "i" (CPU_FTR_601)); 00102 return ret; 00103 } 00104 00105 #endif /* __PPC__ */ 00106 00107 #ifdef __i386__ 00108 00109 typedef unsigned long long cycles_t; 00110 00111 extern cycles_t cacheflush_time; 00112 00113 #define rdtscll(val) \ 00114 __asm__ __volatile__("rdtsc" : "=A" (val)) 00115 00116 static inline cycles_t get_cycles (void) 00117 { 00118 unsigned long long ret; 00119 00120 rdtscll(ret); 00121 return ret; 00122 } 00123 00124 #endif /* __i386__ */ 00125 00126 /* everything else but x86, amd64, sparcv9 or ppc */ 00127 #if !defined (__PPC__) && !defined (__x86_64__) && !defined (__i386__) && !defined (__sparc_v9__) 00128 00129 #warning No suitable get_cycles() implementation. Returning 0 instead 00130 00131 typedef unsigned long long cycles_t; 00132 00133 static inline cycles_t get_cycles(void) 00134 { 00135 return 0; 00136 } 00137 00138 #endif /* everything else but x86, amd64, sparcv9 or ppc */ 00139 00140 #endif /* __linux__ */ 00141 00142 00143 #if defined(__FreeBSD_kernel__) 00144 00145 #warning No suitable get_cycles() implementation. Returning 0 instead 00146 00147 typedef unsigned long long cycles_t; 00148 00149 static inline cycles_t get_cycles(void) 00150 { 00151 return 0; 00152 } 00153 00154 #endif /* __FreeBSD_kernel__ */ 00155 00156 00157 #endif /* __jack_cycles_h__ */