Jack2
1.9.7
|
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 __x86_64__ 00041 00042 typedef unsigned long cycles_t; 00043 extern cycles_t cacheflush_time; 00044 00045 static inline unsigned long get_cycles(void) 00046 { 00047 unsigned int hi, lo; 00048 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 00049 return (((unsigned long)hi)<<32) | ((unsigned long)lo); 00050 } 00051 00052 #endif /* __x86_64__ */ 00053 00054 #ifdef __sparc_v9__ 00055 /* rd is V9 only */ 00056 static inline unsigned long long get_cycles(void) 00057 { 00058 unsigned long long res; 00059 __asm__ __volatile__("rd %%tick, %0" : "=r"(res)); 00060 return res; 00061 } 00062 #endif /* __sparc_v9__ */ 00063 00064 #ifdef __PPC__ 00065 00066 /* PowerPC */ 00067 00068 #define CPU_FTR_601 0x00000100 00069 00070 typedef unsigned long cycles_t; 00071 00072 /* For the "cycle" counter we use the timebase lower half. */ 00073 00074 extern cycles_t cacheflush_time; 00075 00076 static inline cycles_t get_cycles(void) 00077 { 00078 cycles_t ret = 0; 00079 00080 __asm__ __volatile__( 00081 "98: mftb %0\n" 00082 "99:\n" 00083 ".section __ftr_fixup,\"a\"\n" 00084 " .long %1\n" 00085 " .long 0\n" 00086 " .long 98b\n" 00087 " .long 99b\n" 00088 ".previous" 00089 : "=r" (ret) : "i" (CPU_FTR_601)); 00090 return ret; 00091 } 00092 00093 #endif /* __PPC__ */ 00094 00095 #ifdef __i386__ 00096 00097 typedef unsigned long long cycles_t; 00098 00099 extern cycles_t cacheflush_time; 00100 00101 #define rdtscll(val) \ 00102 __asm__ __volatile__("rdtsc" : "=A" (val)) 00103 00104 static inline cycles_t get_cycles (void) 00105 { 00106 unsigned long long ret; 00107 00108 rdtscll(ret); 00109 return ret; 00110 } 00111 00112 #endif /* __i386__ */ 00113 00114 /* everything else but x86, amd64, sparcv9 or ppc */ 00115 #if !defined (__PPC__) && !defined (__x86_64__) && !defined (__i386__) && !defined (__sparc_v9__) 00116 00117 #warning No suitable get_cycles() implementation. Returning 0 instead 00118 00119 typedef unsigned long long cycles_t; 00120 00121 static inline cycles_t get_cycles(void) 00122 { 00123 return 0; 00124 } 00125 00126 #endif /* everything else but x86, amd64, sparcv9 or ppc */ 00127 00128 00129 #endif /* __jack_cycles_h__ */