xref: /haiku/src/system/kernel/scheduler/scheduler_profiler.h (revision d0f2d8282f3f59a1af7fe2d340d2af0cb36a9b20)
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