1 #ifndef _CPU_USAGE_MAC_H_ 2 #define _CPU_USAGE_MAC_H_ 3 4 #include <sys/resource.h> 5 6 #include <mach/mach.h> 7 #include <mach/processor_info.h> 8 #include <mach/mach_host.h> 9 10 11 class ESCpuUsage 12 { 13 Base::CTimer m_Timer; 14 fp8 m_LastCPUCheckTime; 15 16 fp8 m_LastESTime; 17 18 processor_info_array_t m_lastProcessorInfo; 19 mach_msg_type_number_t m_lastNumProcessorInfo; 20 21 22 public: ESCpuUsage()23 ESCpuUsage(): m_LastCPUCheckTime(0) 24 { 25 m_Timer.Reset(); 26 m_LastCPUCheckTime = m_Timer.Time(); 27 28 struct rusage r_usage; 29 if (!getrusage(RUSAGE_SELF, &r_usage)) { 30 31 m_LastESTime = (fp8)r_usage.ru_utime.tv_sec + (fp8)r_usage.ru_utime.tv_usec * 1e-6; 32 33 m_LastESTime += (fp8)r_usage.ru_stime.tv_sec + (fp8)r_usage.ru_stime.tv_usec * 1e-6; 34 35 } 36 37 processor_info_array_t processorInfo; 38 mach_msg_type_number_t numProcessorInfo; 39 natural_t numProcessors = 0U; 40 41 kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numProcessors, &processorInfo, &numProcessorInfo); 42 if(err == KERN_SUCCESS) 43 { 44 m_lastProcessorInfo = processorInfo; 45 m_lastNumProcessorInfo = numProcessorInfo; 46 } 47 else 48 { 49 m_lastProcessorInfo = NULL; 50 m_lastNumProcessorInfo = 0; 51 } 52 53 } 54 ~ESCpuUsage()55 virtual ~ESCpuUsage() 56 { 57 if(m_lastProcessorInfo) 58 { 59 size_t lastProcessorInfoSize = sizeof(integer_t) * m_lastNumProcessorInfo; 60 vm_deallocate(mach_task_self(), (vm_address_t)m_lastProcessorInfo, lastProcessorInfoSize); 61 } 62 } 63 GetCpuUsage(int & _total,int & _es)64 bool GetCpuUsage(int &_total, int &_es) 65 { 66 struct rusage r_usage; 67 68 fp8 newtime = m_Timer.Time(); 69 70 fp8 period = newtime - m_LastCPUCheckTime; 71 if (period > 0.) 72 { 73 if (!getrusage(RUSAGE_SELF, &r_usage)) 74 { 75 76 fp8 utime = (fp8)r_usage.ru_utime.tv_sec + (fp8)r_usage.ru_utime.tv_usec * 1e-6; 77 78 utime += (fp8)r_usage.ru_stime.tv_sec + (fp8)r_usage.ru_stime.tv_usec * 1e-6; 79 80 _es = int ( ( utime - m_LastESTime ) * 100. / period ); 81 82 m_LastESTime = utime; 83 } 84 85 processor_info_array_t processorInfo; 86 mach_msg_type_number_t numProcessorInfo; 87 natural_t numProcessors = 0U; 88 89 kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numProcessors, &processorInfo, &numProcessorInfo); 90 if(err == KERN_SUCCESS) 91 { 92 float accInUse = 0.0f, accTotal = 0.0f; 93 94 for(unsigned i = 0U; i < numProcessors; ++i) 95 { 96 float inUse, total; 97 98 if(m_lastProcessorInfo) 99 { 100 inUse = ( 101 (processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] - m_lastProcessorInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER]) 102 + (processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] - m_lastProcessorInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM]) 103 + (processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE] - m_lastProcessorInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE]) 104 ); 105 106 total = inUse + (processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE] - m_lastProcessorInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE]); 107 } else { 108 inUse = processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] + processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] + processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE]; 109 total = inUse + processorInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE]; 110 } 111 112 accInUse += inUse; 113 accTotal += total; 114 } 115 116 _total = static_cast<int>((fp8)accInUse * 100. / (fp8)accTotal); 117 118 _es /= numProcessors; 119 120 if(m_lastProcessorInfo) 121 { 122 size_t lastProcessorInfoSize = sizeof(integer_t) * m_lastNumProcessorInfo; 123 vm_deallocate(mach_task_self(), (vm_address_t)m_lastProcessorInfo, lastProcessorInfoSize); 124 } 125 126 m_lastProcessorInfo = processorInfo; 127 m_lastNumProcessorInfo = numProcessorInfo; 128 } 129 } 130 else 131 { 132 _es = 0; 133 _total = 0; 134 } 135 136 _es = ::Base::Math::Clamped(_es, 0, 100); 137 _total = ::Base::Math::Clamped(_total, 0, 100); 138 139 m_LastCPUCheckTime = newtime; 140 141 return true; 142 } 143 144 }; 145 146 #endif 147