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 bigtime_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 99 Function::Function(const char* functionName) 100 : 101 fFunctionName(functionName) 102 { 103 Profiler::Get()->EnterFunction(smp_get_current_cpu(), fFunctionName); 104 } 105 106 107 Function::~Function() 108 { 109 if (fFunctionName != NULL) 110 Exit(); 111 } 112 113 114 void 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