1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     dbg_Instrument.h
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 46347 $
14  *---------------------------------------------------------------------------*/
15 /* Please see man pages for details
16 
17 
18 
19 
20 */
21 
22 #ifndef DBG_INSTRUMENT_H_
23 #define DBG_INSTRUMENT_H_
24 
25 #ifdef __cplusplus
26 
27 namespace nn {
28 namespace dbg {
29 namespace CTR {
30 
31     enum InstrumentType
32     {
33         TRACE_STACK   = (0<<0), // Stack mode
34         TRACE_LOG     = (1<<0), // Log mode
35         RECORD_TICK   = (1<<1), // Also record tick
36         RING_BUFFER   = (1<<2)  // Ring buffer
37     };
38 
39     //================================================================
40     // Record measurement 1
41     //================================================================
42     // When also record tick
43     struct RecordForLogWithTick
44     {
45         u32 mAddress; //Use least significant bit in 0==in, 1==out
46         u32 mCall;
47         s64 mTick;
48     };
49 
50     // When not recording tick
51     struct RecordForLog
52     {
53         u32 mAddress;
54         u32 mCall;
55     };
56 
57     //================================================================
58     // Measurement class
59     //================================================================
60     /* Please see man pages for details
61 
62     */
63     class Instrument
64     {
65         friend class Statistics;
66     public:
Instrument()67         Instrument() : mIsAvailable(false)
68         {
69         }
70         /* Please see man pages for details
71 
72         */
73         void Initialize( void* buffer, size_t bufferSize, s32 type=TRACE_STACK );
74         /* Please see man pages for details
75 
76         */
77         void Finalize( void );
78 
79         /* Please see man pages for details
80 
81         */
82         void Dump( void );
83         /* Please see man pages for details
84 
85         */
86         void Clear( void );
87 
88         /* Please see man pages for details
89 
90         */
91         void Enable( void );
92         /* Please see man pages for details
93 
94         */
95         void Disable( void );
96 
97         /* Please see man pages for details
98 
99         */
100         static void SetLogFunction( void (*logFunc)( const char*, ... ) );
101 
102         /* Please see man pages for details
103 
104         */
GetRecordSize(void)105         inline size_t GetRecordSize(void)
106         {
107             return (mType & RECORD_TICK)? sizeof(RecordForLogWithTick): sizeof(RecordForLog);
108         }
IsRingBuffer(void)109         inline bool IsRingBuffer(void)
110         {
111             return (mType & RING_BUFFER);
112         }
IsRecordTick(void)113         inline bool IsRecordTick(void)
114         {
115             return (mType & RECORD_TICK);
116         }
IsTraceLog(void)117         inline bool IsTraceLog(void)
118         {
119             return (mType & TRACE_LOG);
120         }
121 
GetBufferCount(void)122         inline int GetBufferCount(void)
123         {
124             return mBufferCount;
125         }
GetEntryCount(void)126         inline int GetEntryCount(void)
127         {
128             return mCount;
129         }
130 
131         // for internal
132         static Instrument* SearchInfo( bit32 threadId );
133         void EntryFunc( void *func_address, void *call_site );
134         void ExitFunc( void *func_address, void *call_site );
135 
136     private:
137         static void AddToList( Instrument* pInfo );
138         static void DeleteFromList( Instrument* pInfo );
139         bool  IsBottom_BufferPtr( void* p );
140         void* Inc_BufferPtr( void* p );
141         void* Dec_BufferPtr( void* p );
142 
143         bit32 mThreadId;
144         int   mCount;
145 
146         void* mBufferTop;
147         void* mBufferBottom;
148         int   mBufferSize;
149 
150         void* mBufferOrigin;
151         void* mBufferPtr;
152 
153         int   mBufferCount;
154 
155         Instrument* mNext;
156 
157         s32   mType;
158         bool  mIsAvailable;
159         NN_PADDING3;
160     };
161 
162     //================================================================
163     // 1 item of the total
164     //================================================================
165     struct StatisticsRecord
166     {
167         u32  mAddress;
168         int  mEntryCount;
169         int  mTickCount;
170         NN_PADDING4;
171         s64  mTickStart;
172         s64  mTickSum;
173     };
174 
175     //================================================================
176     // Totals
177     //================================================================
178     /* Please see man pages for details
179 
180     */
181     class Statistics
182     {
183     public:
184         /* Please see man pages for details
185 
186         */
187         void Initialize( void* buffer=NULL, size_t bufferSize=0 );
188         /* Please see man pages for details
189 
190         */
191         void Collect( Instrument* info, bool isClear=true );
192 
193         /* Please see man pages for details
194 
195         */
196         void Dump( bool isArrangeTick=true );
197         /* Please see man pages for details
198 
199         */
200         void Clear(void);
201 
202         /* Please see man pages for details
203 
204         */
205         static void SetLogFunction( void (*logFunc)( const char*, ... ) );
206 
207         /* Please see man pages for details
208 
209         */
GetIgnoredLines(void)210         int GetIgnoredLines(void)
211         {
212             return mIgnoredLines;
213         }
214 
215     private:
216         StatisticsRecord*  mBuffer;
217         size_t mBufferSize;
218         void*  mBufferBottom;
219 
220         int    mIgnoredLines;
221     };
222 
223 } // namespace CTR
224 } // namespace dbg
225 } // namespace nn
226 
227 #endif // __cplusplus
228 
229 #define NN_DBG_TRACE_STACK      (nn::dbg::CTR::TRACE_STACK)
230 #define NN_DBG_TRACE_LOG        (nn::dbg::CTR::TRACE_LOG)
231 #define NN_DBG_RECORD_TICK      (nn::dbg::CTR::RECORD_TICK)
232 #define NN_DBG_RING_BUFFER      (nn::dbg::CTR::RING_BUFFER)
233 
234 //================================================================================
235 // Call function for GCC format measurements
236 //================================================================================
237 #ifdef __cplusplus
238 extern "C"{
239 #endif
240 
241 NN_WEAK_SYMBOL void __cyg_profile_func_enter( void *func_address, void *call_site )
242     __attribute__ ((no_instrument_function));
243 
244 NN_WEAK_SYMBOL void __cyg_profile_func_exit ( void *func_address, void *call_site )
245     __attribute__ ((no_instrument_function));
246 
247 #ifdef __cplusplus
248 }
249 #endif
250 
251 #endif  // DBG_INSTRUMENT_H_
252 
253