xref: /haiku/src/system/kernel/scheduler/scheduler_profiler.h (revision 96dcc73b39cc68a59c276a35690f8af1886214ef)
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 
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 			bigtime_t		fEntryTime;
59 			bigtime_t		fOthersTime;
60 	};
61 
62 			uint32			_FunctionCount() const;
63 			void			_Dump(uint32 count);
64 
65 			FunctionData*	_FindFunction(const char* function);
66 
67 			template<typename Type, Type FunctionData::*Member>
68 	static	int				_CompareFunctions(const void* a, const void* b);
69 
70 			template<typename Type, Type FunctionData::*Member>
71 	static	int				_CompareFunctionsPerCall(const void* a,
72 								const void* b);
73 
74 			const uint32	kMaxFunctionEntries;
75 			const uint32	kMaxFunctionStackEntries;
76 
77 			FunctionEntry*	fFunctionStacks[SMP_MAX_CPUS];
78 			uint32			fFunctionStackPointers[SMP_MAX_CPUS];
79 
80 			FunctionData*	fFunctionData;
81 			spinlock		fFunctionLock;
82 
83 			status_t		fStatus;
84 };
85 
86 class Function {
87 public:
88 	inline					Function(const char* functionName);
89 	inline					~Function();
90 
91 	inline	void			Exit();
92 
93 private:
94 			const char*		fFunctionName;
95 };
96 
97 
98 Function::Function(const char* functionName)
99 	:
100 	fFunctionName(functionName)
101 {
102 	Profiler::Get()->EnterFunction(smp_get_current_cpu(), fFunctionName);
103 }
104 
105 
106 Function::~Function()
107 {
108 	if (fFunctionName != NULL)
109 		Exit();
110 }
111 
112 
113 void
114 Function::Exit()
115 {
116 	Profiler::Get()->ExitFunction(smp_get_current_cpu(), fFunctionName);
117 	fFunctionName = NULL;
118 }
119 
120 
121 }	// namespace Profiling
122 
123 }	// namespace Scheduler
124 
125 
126 #else	// SCHEDULER_PROFILING
127 
128 #define SCHEDULER_ENTER_FUNCTION()	(void)0
129 #define SCHEDULER_EXIT_FUNCTION()	(void)0
130 
131 #endif	// !SCHEDULER_PROFILING
132 
133 
134 #endif	// KERNEL_SCHEDULER_PROFILER_H
135 
136