jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
3.4KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Code derived from various headers from the Linux kernel
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. $Id: cycles.h,v 1.4.2.1 2006/06/20 14:44:00 letz Exp $
  16. */
  17. #ifndef __jack_cycles_h__
  18. #define __jack_cycles_h__
  19. /*
  20. * Standard way to access the cycle counter on i586+ CPUs.
  21. * Currently only used on SMP.
  22. *
  23. * If you really have a SMP machine with i486 chips or older,
  24. * compile for that, and this will just always return zero.
  25. * That's ok, it just means that the nicer scheduling heuristics
  26. * won't work for you.
  27. *
  28. * We only use the low 32 bits, and we'd simply better make sure
  29. * that we reschedule before that wraps. Scheduling at least every
  30. * four billion cycles just basically sounds like a good idea,
  31. * regardless of how fast the machine is.
  32. */
  33. #ifdef __linux__
  34. #ifdef __x86_64__
  35. typedef unsigned long cycles_t;
  36. extern cycles_t cacheflush_time;
  37. static inline unsigned long get_cycles(void)
  38. {
  39. unsigned int hi, lo;
  40. __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
  41. return (((unsigned long)hi)<<32) | ((unsigned long)lo);
  42. }
  43. #endif /* __x86_64__ */
  44. #ifdef __sparc_v9__
  45. /* rd is V9 only */
  46. static inline unsigned long long get_cycles(void)
  47. {
  48. unsigned long long res;
  49. __asm__ __volatile__("rd %%tick, %0" : "=r"(res));
  50. return res;
  51. }
  52. #endif /* __sparc_v9__ */
  53. #ifdef __PPC__
  54. /* PowerPC */
  55. #define CPU_FTR_601 0x00000100
  56. typedef unsigned long cycles_t;
  57. /* For the "cycle" counter we use the timebase lower half. */
  58. extern cycles_t cacheflush_time;
  59. static inline cycles_t get_cycles(void)
  60. {
  61. cycles_t ret = 0;
  62. __asm__ __volatile__(
  63. "98: mftb %0\n"
  64. "99:\n"
  65. ".section __ftr_fixup,\"a\"\n"
  66. " .long %1\n"
  67. " .long 0\n"
  68. " .long 98b\n"
  69. " .long 99b\n"
  70. ".previous"
  71. : "=r" (ret) : "i" (CPU_FTR_601));
  72. return ret;
  73. }
  74. #endif /* __PPC__ */
  75. #ifdef __i386__
  76. typedef unsigned long long cycles_t;
  77. extern cycles_t cacheflush_time;
  78. #define rdtscll(val) \
  79. __asm__ __volatile__("rdtsc" : "=A" (val))
  80. static inline cycles_t get_cycles (void)
  81. {
  82. unsigned long long ret;
  83. rdtscll(ret);
  84. return ret;
  85. }
  86. #endif /* __i386__ */
  87. /* everything else but x86, amd64, sparcv9 or ppc */
  88. #if !defined (__PPC__) && !defined (__x86_64__) && !defined (__i386__) && !defined (__sparc_v9__)
  89. #warning No suitable get_cycles() implementation. Returning 0 instead
  90. typedef unsigned long long cycles_t;
  91. static inline cycles_t get_cycles(void)
  92. {
  93. return 0;
  94. }
  95. #endif /* everything else but x86, amd64, sparcv9 or ppc */
  96. #endif /* __linux__ */
  97. #if defined(__FreeBSD_kernel__)
  98. #warning No suitable get_cycles() implementation. Returning 0 instead
  99. typedef unsigned long long cycles_t;
  100. static inline cycles_t get_cycles(void)
  101. {
  102. return 0;
  103. }
  104. #endif /* __FreeBSD_kernel__ */
  105. #endif /* __jack_cycles_h__ */