using static UnmanagedMMU.SegmentedPool; namespace UnmanagedMMU.Diagnostics { /// /// Static helper class for generating diagnostics and suggestions for SegmentedPool. /// Separates report generation logic from the pool implementation. /// public static class SegmentedPoolDiagnostics { /// /// Generates a formatted report string including suggestions. /// public static string GenerateReport(PoolState state) { string status = state.BaseAligned ? "OK" : "FAIL"; string segmentStatus = $"{state.ActiveSegmentCount} active, {state.FreeSegmentCount} free"; double efficiency = (state.TotalUsed + state.PaddingBytes) > 0 ? (100.0 * state.TotalUsed / (state.TotalUsed + state.PaddingBytes)) : 100.0; string efficiencyLabel = GetEfficiencyLabel(efficiency, state.SegmentAlignment); string suggestionLine = state.Suggestion; if (!string.IsNullOrEmpty(suggestionLine)) { suggestionLine = $"\n {suggestionLine}"; } return $"=== SegmentedPool Diagnostics ===\n" + $" Configuration\n" + $" Segment Alignment: {state.SegmentAlignment} bytes (Min Base Alignment)\n" + $" Segment Size: {FormatBytes(state.SegmentSize)}\n" + $" Segment Summary\n" + $" Total Segments: {state.TotalSegmentCount} ({segmentStatus})\n" + $" Potential Savings: {FormatBytes(state.PotentialSavings)} (via Trim())\n" + $" Current Segment\n" + $" Base Address: 0x{(nuint)state.CurrentBase:x}\n" + $" Offset: {state.CurrentOffset} bytes\n" + $" Base Alignment: {status} (To {state.SegmentAlignment} bytes)\n" + $" Memory Statistics\n" + $" Total Reserved: {FormatBytes(state.TotalReserved)}\n" + $" Total Used: {FormatBytes(state.TotalUsed)}\n" + $" Efficiency: {efficiency:F0}% ({efficiencyLabel})\n" + $" Padding Overhead: {FormatBytes(state.PaddingBytes)}\n" + $" Allocation Breakdown\n" + $" Data Bytes: {FormatBytes(state.TotalUsed)}\n" + $" Alignment Padding: {FormatBytes(state.PaddingBytes)}\n" + $" Total Segment Space: {FormatBytes(state.CurrentOffset)}\n" + $" Action Required:{suggestionLine}"; } private static string GetEfficiencyLabel(double efficiency, nuint segmentAlignment) { int threshold = segmentAlignment switch { 8 => 50, 16 => 60, 32 => 75, 64 => 85, _ => 90 }; if (efficiency >= 100) return "Perfect"; if (efficiency >= threshold) return "Good"; return "High Overhead"; } private static string FormatBytes(nuint bytes) { if (bytes >= 1073741824) return $"{bytes / 1073741824} GiB"; if (bytes >= 1048576) return $"{bytes / 1048576} MiB"; if (bytes >= 1024) return $"{bytes / 1024} KiB"; return $"{bytes} B"; } /// /// Generates actionable suggestions based on pool metrics. /// Comprehensive coverage of all pool states. /// public static string GenerateSuggestions(PoolState state, DiagnosticConfig config) { // === CRITICAL ISSUES === // 1. Base alignment broken (should never happen) if (!state.BaseAligned) { return "CRITICAL: Segment base not aligned to configured boundary. This indicates a memory management bug."; } // === HIGH PRIORITY === // 2. Pool exhausted (Next alloc blocks) if (state.FreeSegmentCount == 0) { return "INFO: No free segments available. Next allocation will block. Call Reset() to recycle segments or increase initialSegments."; } // 3. Significant Memory Waste (Trim Opportunity) if (state.PotentialSavings > 0) { double wasteRatio = (double)state.PotentialSavings / state.TotalReserved; if (wasteRatio > 0.50) { return $"ACTION: {state.FreeSegmentCount - 16} excess segments can be freed. Calling Trim() will recover {FormatBytes(state.PotentialSavings)} ({(wasteRatio * 100):F0}% of reserved memory)."; } if (state.PotentialSavings > 1024 * 1024) { return $"ACTION: Excess free segments ({state.FreeSegmentCount}). Calling Trim() will recover {FormatBytes(state.PotentialSavings)}. Current usage: {FormatBytes(state.TotalUsed)} of {FormatBytes(state.TotalReserved)}. Efficiency: {(state.TotalUsed / state.TotalReserved) * 100:F0}%."; } } // 4. Efficiency Issues (Alignment Mismatch) double efficiency = (state.TotalUsed + state.PaddingBytes) > 0 ? (100.0 * state.TotalUsed / (state.TotalUsed + state.PaddingBytes)) : 100.0; int threshold = state.SegmentAlignment switch { 8 => 50, 16 => 60, 32 => 75, 64 => 85, _ => 90 }; if (efficiency < threshold) { if (state.SegmentAlignment <= 32) { return $"Suggestion: Current alignment ({state.SegmentAlignment}B) is low. Increase to 32B for better efficiency."; } else { return $"Suggestion: Verify allocation alignment matches segment base ({state.SegmentAlignment}B). Efficiency is {efficiency:F0}%."; } } // 5. Segment Nearly Full if (config.SegmentSize > 0 && state.CurrentOffset > config.SegmentSize * 0.90) { return "INFO: Current segment nearly full. Consider Reset() to reuse this segment instead of allocating a new one."; } // === LOW PRIORITY / OPTIONAL === // 6. Low Utilization (Memory Bloat) if (state.TotalReserved > 16 * 1024 * 1024) { double usageRatio = (double)state.TotalUsed / state.TotalReserved; if (usageRatio < 0.10) { return $"INFO: Low memory utilization ({usageRatio:P0}). Consider Reset() or Trim() to reduce footprint."; } } return "Pool operating normally."; } } /// /// Configuration details passed to diagnostics for context-aware suggestions. /// public readonly struct DiagnosticConfig { public nuint SegmentSize { get; init; } public nuint TotalReserved { get; init; } } }