93 lines
3.2 KiB
Objective-C
93 lines
3.2 KiB
Objective-C
#import "MMLoadAverageProvider.h"
|
|
#import <mach/mach.h>
|
|
#import <mach/processor_info.h>
|
|
#import <sys/sysctl.h>
|
|
#import <stdlib.h>
|
|
|
|
@implementation MMLoadAverageProvider
|
|
|
|
- (instancetype)init {
|
|
self = [super init];
|
|
return self;
|
|
}
|
|
|
|
- (MMTelemetryDomain)domain {
|
|
return MMTelemetryDomainSystem;
|
|
}
|
|
|
|
- (NSString *)providerIdentifier {
|
|
return @"com.i3omb.macmonitor.telemetry.system.load";
|
|
}
|
|
|
|
- (BOOL)isAvailable {
|
|
return YES;
|
|
}
|
|
|
|
+ (NSDictionary<NSString *, id> *)calculateLoadMetricsWithLoad1:(double)load1
|
|
load5:(double)load5
|
|
load15:(double)load15
|
|
taskCount:(int)taskCount
|
|
threadCount:(int)threadCount
|
|
cpuCount:(int)cpuCount
|
|
machFactor:(double)machFactor {
|
|
int safeCpus = cpuCount > 0 ? cpuCount : 1;
|
|
double norm1 = load1 / (double)safeCpus;
|
|
double norm5 = load5 / (double)safeCpus;
|
|
double norm15 = load15 / (double)safeCpus;
|
|
|
|
return @{
|
|
@"load1m": @(load1),
|
|
@"load5m": @(load5),
|
|
@"load15m": @(load15),
|
|
@"normalizedLoad1m": @(norm1),
|
|
@"normalizedLoad5m": @(norm5),
|
|
@"normalizedLoad15m": @(norm15),
|
|
@"taskCount": @(taskCount),
|
|
@"threadCount": @(threadCount),
|
|
@"logicalCpuCount": @(safeCpus),
|
|
@"machFactor": @(machFactor),
|
|
@"isOverloaded": @(norm1 > 1.0)
|
|
};
|
|
}
|
|
|
|
- (nullable NSDictionary<NSString *, id> *)sampleTelemetryWithError:(NSError **)error {
|
|
// 1. Get BSD load averages
|
|
double load[3] = {0.0, 0.0, 0.0};
|
|
int ret = getloadavg(load, 3);
|
|
if (ret <= 0) {
|
|
load[0] = 0.0;
|
|
load[1] = 0.0;
|
|
load[2] = 0.0;
|
|
}
|
|
|
|
// 2. Query Mach processor set for task & thread counts and mach factor
|
|
mach_port_t host = mach_host_self();
|
|
processor_set_name_port_t pset = MACH_PORT_NULL;
|
|
processor_set_load_info_data_t loadInfo = {0};
|
|
mach_msg_type_number_t count = PROCESSOR_SET_LOAD_INFO_COUNT;
|
|
|
|
kern_return_t kr = processor_set_default(host, &pset);
|
|
if (kr == KERN_SUCCESS && MACH_PORT_VALID(pset)) {
|
|
kr = processor_set_statistics(pset, PROCESSOR_SET_LOAD_INFO, (processor_set_info_t)&loadInfo, &count);
|
|
mach_port_deallocate(mach_task_self(), pset);
|
|
}
|
|
|
|
double machFactor = (double)loadInfo.mach_factor / (double)LOAD_SCALE;
|
|
|
|
// 3. Query logical CPU core count
|
|
int cpuCount = 1;
|
|
size_t size = sizeof(cpuCount);
|
|
sysctlbyname("hw.logicalcpu", &cpuCount, &size, NULL, 0);
|
|
if (cpuCount <= 0) cpuCount = 1;
|
|
|
|
return [MMLoadAverageProvider calculateLoadMetricsWithLoad1:load[0]
|
|
load5:load[1]
|
|
load15:load[2]
|
|
taskCount:loadInfo.task_count
|
|
threadCount:loadInfo.thread_count
|
|
cpuCount:cpuCount
|
|
machFactor:machFactor];
|
|
}
|
|
|
|
@end
|