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