1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #ifndef _PROFILER_GET_TICK_H_
10 #define _PROFILER_GET_TICK_H_
11 
12 #if USE_XPROF_STATS
13 #include <ctime>
14 
15 /*
16  * Ensure that any changes here are synchronised with SQUID_CHECK_FUNCTIONAL_CPU_PROFILER
17  */
18 
19 #if !_SQUID_SOLARIS_
20 typedef int64_t  hrtime_t;
21 #endif
22 
23 #if defined(__GNUC__) && ( defined(__i386) || defined(__i386__) )
24 static inline hrtime_t
get_tick(void)25 get_tick(void)
26 {
27     hrtime_t regs;
28 
29     asm volatile ("rdtsc":"=A" (regs));
30     return regs;
31     /* We need return value, we rely on CC to optimise out needless subf calls */
32     /* Note that "rdtsc" is relatively slow OP and stalls the CPU pipes, so use it wisely */
33 }
34 
35 #elif defined(__GNUC__) && ( defined(__x86_64) || defined(__x86_64__) )
36 static inline hrtime_t
get_tick(void)37 get_tick(void)
38 {
39     uint32_t lo, hi;
40     // Based on an example in Wikipedia
41     /* We cannot use "=A", since this would use %rax on x86_64 */
42     asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
43     return (hrtime_t)hi << 32 | lo;
44 }
45 
46 #elif defined(__GNUC__) && defined(__alpha)
47 static inline hrtime_t
get_tick(void)48 get_tick(void)
49 {
50     hrtime_t regs;
51 
52     asm volatile ("rpcc %0" : "=r" (regs));
53     return regs;
54 }
55 
56 #elif defined(_M_IX86) && defined(_MSC_VER) /* x86 platform on Microsoft C Compiler ONLY */
57 static __inline hrtime_t
get_tick(void)58 get_tick(void)
59 {
60     hrtime_t regs;
61 
62     __asm {
63         cpuid
64         rdtsc
65         mov eax,DWORD PTR regs[0]
66         mov edx,DWORD PTR regs[4]
67     }
68     return regs;
69 }
70 
71 #elif defined(HAVE_CLOCK_GETTIME_NSEC_NP) && defined(CLOCK_MONOTONIC_RAW)
72 
73 static inline hrtime_t
get_tick()74 get_tick()
75 {
76     return clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW);
77 }
78 
79 #else
80 /* This CPU is unsupported. Short-circuit, no profiling here */
81 // #error for configure tests to prevent library construction
82 #error This CPU is unsupported. No profiling available here.
83 #endif
84 
85 #endif /* USE_XPROF_STATS */
86 #endif /* _PROFILING_H_ */
87 
88