1 /*
2  * cycles.h - measures CPU cycles using architecture specific extensions.
3  *
4  * Currently only setup for the pentuim using the RDTSC instruction
5  *
6  * Copyright (c) 1998 Phil Maker <pjm@gnu.org>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $Id: cycles.h,v 1.1.1.1 1999/09/12 03:26:50 pjm Exp $
31  */
32 
33 #ifndef _cycles_h_
34 #define _cycles_h_ 1
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 #include <nana-config.h>
41 
42 #if HAVE_CYCLES
43 
44 #if HAVE_RDTSC /* enabled by configure --enable-rdtsc instruction */
45 
46 /*
47  * Pentium RDTSC instruction -
48  *
49  * 0. 64 bit counter running at clock speed so
50  *    (2^64)/(1000*1000*1000*60*60*24*365) = 584 years @ 1GHz
51  * 1. reset to 0 on power on (is it)
52  * 2. on pentium or later CPUs
53  */
54 
55 typedef unsigned long long CYCLES;
56 
57 #define cycles() \
58 ({ \
59      CYCLES __t; \
60      asm volatile ("rdtsc ; movl %%edx,%1; movl %%eax,%0" \
61 	 : "=m" (__t), "=m" (*(((char *)&__t) + 4)) \
62 	 : /* no input */ \
63 	 : "eax", "edx", "cc", "memory" \
64        ); \
65     __t; \
66 })
67 
68 #endif /* HAVE_RDTSC */
69 
70 /*
71  * Calibration routines which should be available for all platforms
72  *
73  * cycles_per_second(t,n) - performs n measurements using a spin loop
74  *    using the now() function to wait for t or more seconds. It returns
75  *    the max number of cycles per second that it measures. As a side
76  *    effect (gasp) it also sets the values return by cycles_per_second_min()
77  *    and cycles_per_second_max().
78  *
79  * Notes:
80  *
81  *    1. each call to cycles_per_second() resets our min/max values.
82  *    2. overflows are always possible if t gets too large.
83  *
84  */
85 
86 CYCLES cycles_per_second(double t, int n);
87 CYCLES cycles_per_second_min();
88 CYCLES cycles_per_second_max();
89 
90 /*
91  * cycles_diff - returns the time in second between two cycle measurement
92  *
93  * Note: start <= stop
94  *       stop - start should be representable in a double.
95  * !No overflow detection
96  */
97 
98 double cycles_diff(CYCLES start, CYCLES stop);
99 
100 #endif /* HAVE_CYCLES */
101 #ifdef _cplusplus
102 };
103 #endif
104 
105 #endif /* _cycles_h_ */
106 
107