11 KiB
11 KiB
MacMonitor: System Architecture & Technical Specifications
This document details the architectural principles, data flow models, memory safety invariants, and subsystem implementation specifics for MacMonitor.
1. Architectural Principles & Constraints
1.1 Target Platform Invariants
- Instruction Set Architecture: Intel
x86_64. - Target OS: macOS 14.0 (Sonoma) or newer.
- Language Stack:
- Presentation & ViewModels: Modern Swift 5.9+ with SwiftUI,
@Observable, and Swift Charts. - Telemetry & Kernel Layer: Objective-C & C interfaces directly communicating with Mach, IOKit, BSD sysctl, CoreAudio, and DisplayServices.
- Presentation & ViewModels: Modern Swift 5.9+ with SwiftUI,
- Hybrid Bridge: Bridging Header (
MacMonitor-Bridging-Header.h) providing strict separation of concerns and zero overhead between C structures and Swift value types.
2. Unidirectional Data Flow & Concurrency Model
flowchart TD
subgraph KernelSpace ["Kernel / Driver Space"]
SMC_DEV["AppleSMC Driver"]
MACH_KERN["Mach Kernel Task/Host"]
BSD_SYS["BSD Sysctl & libproc"]
IOK_DRV["IOBlockStorage & IOAccelerator"]
end
subgraph TelemetryLayer ["Low-Level Telemetry Engine (Serial GCD Queue)"]
DISPATCH["dispatch_source_t Timer<br/>(com.i3omb.macmonitor.telemetry · QOS_CLASS_UTILITY)"]
PROV1["MMAppleSMCClient"]
PROV2["MMCPUUsageProvider"]
PROV3["MMMemoryProvider"]
PROV4["MMProcessCollector"]
BATCH["Snapshot Dictionary / DTO Aggregator"]
end
subgraph PresentationLayer ["UI & State Layer (@MainActor)"]
STORE["SystemTelemetryStore (@Observable)"]
ALERTS["AlertEngine (Rule Evaluator)"]
VIEWS["SwiftUI Dashboard / Popover / Charts (60 FPS)"]
end
SMC_DEV <-->|"IOConnectCallStructMethod"| PROV1
MACH_KERN -->|"host_processor_info / host_statistics64"| PROV2
BSD_SYS -->|"sysctl / proc_listpids"| PROV3
BSD_SYS --> PROV4
IOK_DRV -->|"IORegistryEntryCreateCFProperties"| BATCH
DISPATCH -->|"Trigger Tick (1s/2s)"| PROV1 & PROV2 & PROV3 & PROV4
PROV1 & PROV2 & PROV3 & PROV4 --> BATCH
BATCH -->|"Async Dispatch (Snapshot Copy)"| STORE
STORE -->|"Evaluate Rules"| ALERTS
STORE -->|"Declarative Bindings"| VIEWS
2.1 Threading & QoS Architecture
- Background Polling Queue:
All hardware and kernel polling operations execute on a dedicated serial queue:
Configured with quality-of-service
dispatch_queue_t queue = dispatch_queue_create("com.i3omb.macmonitor.telemetry", DISPATCH_QUEUE_SERIAL);QOS_CLASS_UTILITYto prevent thermal or CPU contention with foreground user processes. - Deterministic Sampling Timer:
Driven by a Grand Central Dispatch timer source (
dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, ...)). Timer coalescing leeway is set to 10% of the sample period to conserve battery on MacBooks while maintaining timing accuracy. - Main Actor State Ingestion:
Snapshots are unmarshaled into immutable,
SendableSwift structures and dispatched asynchronously to@MainActor:Task { @MainActor in self.store.digest(snapshot: batch) } - Mach Virtual Memory Management Invariant:
Calls returning kernel-allocated memory arrays (such as
host_processor_infoorprocessor_cpu_load_info) must explicitly deallocate their previous memory pointers usingvm_deallocate(mach_task_self(), ...)in the subsequent sampling pass to prevent progressive heap bloat.
3. Subsystem Implementation Specifications
3.1 Apple System Management Controller (AppleSMC)
- Service Name:
AppleSMC - IOKit Connection: Initiated using
IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("AppleSMC"))andIOServiceOpen(service, mach_task_self(), 0, &connect). - Selector:
kSMCHandleYPCEvent(Index 2) dispatched viaIOConnectCallStructMethod.
SMC Data Types & Decoding Algorithms
| Data Type | FourCC | Byte Length | Encoding Scheme | Decoding Formula |
|---|---|---|---|---|
sp78 |
0x73703738 |
2 | Signed 8.8 Fixed-Point | tempC = ((int16_t)(b[0] << 8 | b[1])) / 256.0 |
fpe2 |
0x66706532 |
2 | Unsigned 14.2 Fixed-Point | rpm = ((uint16_t)(b[0] << 8 | b[1])) / 4.0 |
ui8 |
0x75693820 |
1 | Unsigned 8-bit Integer | val = (uint8_t)b[0] |
ui16 |
0x75693136 |
2 | Unsigned 16-bit Big-Endian | val = (uint16_t)(b[0] << 8 | b[1]) |
ui32 |
0x75693332 |
4 | Unsigned 32-bit Big-Endian | val = (uint32_t)(b[0] << 24 | ... | b[3]) |
flt |
0x666c7420 |
4 | IEEE 754 32-bit Float | memcpy(&val, b, 4) |
Intel SMC Key Catalog
- Fans:
FNum(Total count),F0Ac/F1Ac(Current RPM),F0Mn/F1Mn(Min RPM),F0Mx/F1Mx(Max RPM),F0Tg/F1Tg(Target RPM),F0ID/F1ID(Fan name). - CPU Thermals:
TC0P(Package proximity),TC0D(Die),TCXC(PECI),TC0C–TC15C(Individual core DTS). - Chassis Thermals:
TPCD(PCH Die),Th0H–Th2H(Heatsinks),TM0P–TM3P(Memory DIMMs),TA0P/TA1P(Chassis Ambient),Tp0P(Power Supply),TTLD(Thunderbolt). - Electrical & RAPL:
PSTR/PDTR(System Total Watts),PCPR/PCTR(CPU Package Watts via Intel RAPL),PG0R(GPU Watts),VC0C(Core Voltage),IC0C(Core Current).
3.2 Host CPU & Kernel Scheduling Telemetry
- Per-Core Tick Counting:
Executed via
host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, ...). Deltas between ticks determine normalized CPU percentages:\Delta \text{ticks} = \Delta \text{user} + \Delta \text{system} + \Delta \text{idle} + \Delta \text{nice}\text{Core \%} = \frac{\Delta \text{user} + \Delta \text{system} + \Delta \text{nice}}{\Delta \text{ticks}} \times 100\% - Kernel Context Switches & Syscalls:
Polled via BSD sysctl node statistics:
vm.stats.sys.v_swtchvm.stats.sys.v_syscallvm.stats.sys.v_intrvm_statistics64.faults(Page faults) Rates are computed against elapsed nanoseconds measured usingmach_absolute_time()andmach_timebase_info().
- Unix Load Averages:
Queried via standard BSD
getloadavg(double load[], 3)and normalized against[NSProcessInfo processInfo].activeProcessorCount.
3.3 Virtual Memory & Pressure Subsystem
- RAM Calculation Strategy:
Direct query of
host_statistics64(mach_host_self(), HOST_VM_INFO64, ...)multiplied byvm_kernel_page_size.- App Memory:
(\text{internal\_count} - \text{purgeable\_count}) \times \text{page\_size} - Wired Memory:
\text{wire\_count} \times \text{page\_size} - Compressed Memory:
\text{compressor\_page\_count} \times \text{page\_size} - Cached Files:
(\text{external\_page\_count} + \text{purgeable\_count}) \times \text{page\_size} - Free Memory:
\text{free\_count} \times \text{page\_size}
- App Memory:
- Swap Statistics:
sysctlbyname("vm.swapusage", &swap, ...)reportingxsu_total,xsu_avail, andxsu_used. - Memory Pressure Monitoring:
Dedicated GCD dispatch source:
dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, queue);
3.4 Storage & Disk I/O Engine
- Volume Capacity & APFS Snapshots:
Queried via
NSFileManager.defaultManager.mountedVolumeURLsIncludingResourceValuesForKeys:. UtilizesNSURLVolumeAvailableCapacityForImportantUsageKeyandNSURLVolumeAvailableCapacityForOpportunisticUsageKeyto properly calculate usable storage space without showing local APFS snapshots as consumed capacity. - Real-Time Disk Throughput (IOPS & MB/s):
Matches
IOBlockStorageDriverin IOKit registry. ExtractsIOBlockStorageDriverStatistics:Bytes (Read)andBytes (Write)Operations (Read)andOperations (Write)Deltas over elapsed time yield read/write throughput (MB/s) and IOPS.
3.5 High-Performance Process Explorer
- Enumeration:
proc_listpids(PROC_ALL_PIDS, 0, pids, byteSize)to retrieve active PIDs. - Resource Attribution:
proc_pidinfo(pid, PROC_PIDTASKINFO, ...)yieldspti_total_user,pti_total_system,pti_resident_size, andpti_threadnum.- Differential CPU calculation tracks elapsed nanoseconds vs elapsed CPU time per process.
- Static Metadata Caching:
Executable paths (
proc_pidpath) and application icons (NSWorkspace.iconForFile:) are cached in an internal hash map keyed by PID to eliminate file system traversal overhead during 1 Hz polling loops. Dead PIDs are pruned on each iteration. - Drill-Down Inspector:
- Threads:
proc_pidinfo(..., PROC_PIDLISTTHREADS)+PROC_PIDTHREADINFO. - File Descriptors:
proc_pidinfo(..., PROC_PIDLISTFDS)+proc_pidfdinfo(..., PROC_PIDFDVNODEPATHINFO). - Sockets:
proc_pidfdinfo(..., PROC_PIDFDSOCKETINFO).
- Threads:
3.6 GPU & Graphics Telemetry
- IOKit Accelerator Service: Matches
IOAcceleratornodes in the IORegistry. - Performance Properties: Inspects
PerformanceStatisticsdictionary:Device Utilization %GPU Core Clock HzvramUsedBytes/vramFreeBytesTemperature(C)
- Multi-GPU Architecture: Handles both Intel integrated graphics (Intel Iris/UHD) and discrete AMD Radeon Pro GPUs on 15"/16" MacBook Pros. Correctly accommodates AMD GPU power-down states when automatic graphics switching is idle.
3.7 Network Bandwidth & Protocol Control Blocks
- 64-Bit Network Traffic Counters:
Avoids 32-bit integer rollover on high-throughput connections by querying BSD routing tables via
sysctlwithNET_RT_IFLIST2and decodingstruct if_data64(ifi_ibytes,ifi_obytes,ifi_ipackets,ifi_opackets). - Socket Table Inspection:
Scans active TCP/UDP Protocol Control Blocks via
net.inet.tcp.pcblist_nandnet.inet.udp.pcblist_n, parsingxinpcb_nto extract local/foreign addresses and connection states.
3.8 Display & Screen Brightness
- Dynamic Framework Linking:
To safely access screen brightness across built-in MacBook screens and Apple external displays, private
DisplayServices.frameworksymbols (DisplayServicesGetBrightness,DisplayServicesSetBrightness) are loaded dynamically viadlopen/dlsym. - Display Configurations:
CoreGraphics APIs (
CGGetActiveDisplayList,CGDisplayCopyDisplayMode) provide active screen resolution, refresh rate (Hz), and built-in panel identification.
3.9 Time-Series Visualization (Swift Charts Engine)
- Ring Buffer Design:
Fixed-capacity circular ring buffers (
RingBuffer<T>) maintain rolling samples (60s, 5m, 15m, 1h). Appending isO(1)with zero runtime dynamic memory reallocations. - Swift Charts Integration:
Renders using Apple's declarative
Chart,LineMark, and gradientAreaMarkcomponents, backed by Metal rasterization.
3.10 Intelligence & Alert Rules Engine
- Architecture: Synchronous post-sampling evaluation engine (
AlertEngine). - Notification Throttle & Cooldown: Each alert identifier maintains a cooldown timestamp. Notifications for persistent abnormal conditions (e.g. CPU temperature > 95°C) are capped at a maximum of 1 alert per 10–15 minutes until normalized, preventing notification floods.
- Delivery Channel: Native
UNUserNotificationCenterwith critical priority sounds for fan stalls and hardware emergencies.