1 /*
2 * Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef KERNEL_SCHEDULER_PROFILER_H
6 #define KERNEL_SCHEDULER_PROFILER_H
7
8
9 #include <smp.h>
10
11
12 //#define SCHEDULER_PROFILING
13 #ifdef SCHEDULER_PROFILING
14
15
16 #define SCHEDULER_ENTER_FUNCTION() \
17 Scheduler::Profiling::Function schedulerProfiler(__PRETTY_FUNCTION__)
18
19 #define SCHEDULER_EXIT_FUNCTION() \
20 schedulerProfiler.Exit()
21
22
23 namespace Scheduler {
24
25 namespace Profiling {
26
27 class Profiler {
28 public:
29 Profiler();
30
31 void EnterFunction(int32 cpu, const char* function);
32 void ExitFunction(int32 cpu, const char* function);
33
34 void DumpCalled(uint32 count);
35 void DumpTimeInclusive(uint32 count);
36 void DumpTimeExclusive(uint32 count);
37 void DumpTimeInclusivePerCall(uint32 count);
38 void DumpTimeExclusivePerCall(uint32 count);
39
GetStatus()40 status_t GetStatus() const { return fStatus; }
41
42 static Profiler* Get();
43 static void Initialize();
44
45 private:
46 struct FunctionData {
47 const char* fFunction;
48
49 uint32 fCalled;
50
51 bigtime_t fTimeInclusive;
52 bigtime_t fTimeExclusive;
53 };
54
55 struct FunctionEntry {
56 FunctionData* fFunction;
57
58 nanotime_t fEntryTime;
59 nanotime_t fOthersTime;
60 nanotime_t fProfilerTime;
61 };
62
63 uint32 _FunctionCount() const;
64 void _Dump(uint32 count);
65
66 FunctionData* _FindFunction(const char* function);
67
68 template<typename Type, Type FunctionData::*Member>
69 static int _CompareFunctions(const void* a, const void* b);
70
71 template<typename Type, Type FunctionData::*Member>
72 static int _CompareFunctionsPerCall(const void* a,
73 const void* b);
74
75 const uint32 kMaxFunctionEntries;
76 const uint32 kMaxFunctionStackEntries;
77
78 FunctionEntry* fFunctionStacks[SMP_MAX_CPUS];
79 uint32 fFunctionStackPointers[SMP_MAX_CPUS];
80
81 FunctionData* fFunctionData;
82 spinlock fFunctionLock;
83
84 status_t fStatus;
85 };
86
87 class Function {
88 public:
89 inline Function(const char* functionName);
90 inline ~Function();
91
92 inline void Exit();
93
94 private:
95 const char* fFunctionName;
96 };
97
98
Function(const char * functionName)99 Function::Function(const char* functionName)
100 :
101 fFunctionName(functionName)
102 {
103 Profiler::Get()->EnterFunction(smp_get_current_cpu(), fFunctionName);
104 }
105
106
~Function()107 Function::~Function()
108 {
109 if (fFunctionName != NULL)
110 Exit();
111 }
112
113
114 void
Exit()115 Function::Exit()
116 {
117 Profiler::Get()->ExitFunction(smp_get_current_cpu(), fFunctionName);
118 fFunctionName = NULL;
119 }
120
121
122 } // namespace Profiling
123
124 } // namespace Scheduler
125
126
127 #else // SCHEDULER_PROFILING
128
129 #define SCHEDULER_ENTER_FUNCTION() (void)0
130 #define SCHEDULER_EXIT_FUNCTION() (void)0
131
132 #endif // !SCHEDULER_PROFILING
133
134
135 #endif // KERNEL_SCHEDULER_PROFILER_H
136
137