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