1 /*****************************************************************************
2
3 ClockCycleCounter.hpp
4 Copyright (c) 2003 Laurent de Soras
5
6 Please complete the definitions according to your compiler/architecture.
7 It's not a big deal if it's not possible to get the clock count...
8
9 --- Legal stuff ---
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 2.1 of the License, or (at your option) any later version.
15
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
20
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
25 *Tab=3***********************************************************************/
26
27
28
29 #if defined (stopwatch_ClockCycleCounter_CURRENT_CODEHEADER)
30 #error Recursive inclusion of ClockCycleCounter code header.
31 #endif
32 #define stopwatch_ClockCycleCounter_CURRENT_CODEHEADER
33
34 #if ! defined (stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED)
35 #define stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED
36
37
38
39 /*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
40
41 #include "fnc.h"
42
43 #include <climits>
44
45
46
47 namespace stopwatch
48 {
49
50
51
52 /*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
53
54
55
56 /*
57 ==============================================================================
58 Name: start
59 Description:
60 Starts the counter.
61 Throws: Nothing
62 ==============================================================================
63 */
64
start()65 void ClockCycleCounter::start ()
66 {
67 _best_score = (static_cast <Int64> (1) << (sizeof (Int64) * CHAR_BIT - 2));
68 const Int64 start_clock = read_clock_counter ();
69 _start_time = start_clock;
70 _state = start_clock - _best_score;
71 }
72
73
74
75 /*
76 ==============================================================================
77 Name: stop_lap
78 Description:
79 Captures the current time and updates the smallest duration between two
80 consecutive calls to stop_lap() or the latest start().
81 start() must have been called at least once before calling this function.
82 Throws: Nothing
83 ==============================================================================
84 */
85
stop_lap()86 void ClockCycleCounter::stop_lap ()
87 {
88 const Int64 end_clock = read_clock_counter ();
89 _best_score = min (end_clock - _state, _best_score);
90 _state = end_clock;
91 }
92
93
94
95 /*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
96
97
98
99 /*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
100
101
102
read_clock_counter()103 Int64 ClockCycleCounter::read_clock_counter ()
104 {
105 register Int64 clock_cnt;
106
107 #if defined (_MSC_VER)
108
109 __asm
110 {
111 lea edi, clock_cnt
112 rdtsc
113 mov [edi ], eax
114 mov [edi + 4], edx
115 }
116
117 #elif defined (__GNUC__) && defined (__i386__)
118
119 __asm__ __volatile__ ("rdtsc" : "=A" (clock_cnt));
120
121 #elif (__MWERKS__) && defined (__POWERPC__)
122
123 asm
124 {
125 loop:
126 mftbu clock_cnt@hiword
127 mftb clock_cnt@loword
128 mftbu r5
129 cmpw clock_cnt@hiword,r5
130 bne loop
131 }
132
133 #endif
134
135 return (clock_cnt);
136 }
137
138
139
140 } // namespace stopwatch
141
142
143
144 #endif // stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED
145
146 #undef stopwatch_ClockCycleCounter_CURRENT_CODEHEADER
147
148
149
150 /*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
151