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 23namespace Scheduler { 24 25namespace Profiling { 26 27class Profiler { 28public: 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 45private: 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 87class Function { 88public: 89 inline Function(const char* functionName); 90 inline ~Function(); 91 92 inline void Exit(); 93 94private: 95 const char* fFunctionName; 96}; 97 98 99Function::Function(const char* functionName) 100 : 101 fFunctionName(functionName) 102{ 103 Profiler::Get()->EnterFunction(smp_get_current_cpu(), fFunctionName); 104} 105 106 107Function::~Function() 108{ 109 if (fFunctionName != NULL) 110 Exit(); 111} 112 113 114void 115Function::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