Files
hakmem/core/tiny_box_geometry.h
Moe Charm (CI) 25d963a4aa Code Cleanup: Remove false positives, redundant validations, and reduce verbose logging
Following the C7 stride upgrade fix (commit 23c0d9541), this commit performs
comprehensive cleanup to improve code quality and reduce debug noise.

## Changes

### 1. Disable False Positive Checks (tiny_nextptr.h)
- **Disabled**: NXT_MISALIGN validation block with `#if 0`
- **Reason**: Produces false positives due to slab base offsets (2048, 65536)
  not being stride-aligned, causing all blocks to appear "misaligned"
- **TODO**: Reimplement to check stride DISTANCE between consecutive blocks
  instead of absolute alignment to stride boundaries

### 2. Remove Redundant Geometry Validations

**hakmem_tiny_refill_p0.inc.h (P0 batch refill)**
- Removed 25-line CARVE_GEOMETRY_FIX validation block
- Replaced with NOTE explaining redundancy
- **Reason**: Stride table is now correct in tiny_block_stride_for_class(),
  defense-in-depth validation adds overhead without benefit

**ss_legacy_backend_box.c (legacy backend)**
- Removed 18-line LEGACY_FIX_GEOMETRY validation block
- Replaced with NOTE explaining redundancy
- **Reason**: Shared_pool validates geometry at acquisition time

### 3. Reduce Verbose Logging

**hakmem_shared_pool.c (sp_fix_geometry_if_needed)**
- Made SP_FIX_GEOMETRY logging conditional on `!HAKMEM_BUILD_RELEASE`
- **Reason**: Geometry fixes are expected during stride upgrades,
  no need to log in release builds

### 4. Verification
- Build:  Successful (LTO warnings expected)
- Test:  10K iterations (1.87M ops/s, no crashes)
- NXT_MISALIGN false positives:  Eliminated

## Files Modified
- core/tiny_nextptr.h - Disabled false positive NXT_MISALIGN check
- core/hakmem_tiny_refill_p0.inc.h - Removed redundant CARVE validation
- core/box/ss_legacy_backend_box.c - Removed redundant LEGACY validation
- core/hakmem_shared_pool.c - Made SP_FIX_GEOMETRY logging debug-only

## Impact
- **Code clarity**: Removed 43 lines of redundant validation code
- **Debug noise**: Reduced false positive diagnostics
- **Performance**: Eliminated overhead from redundant geometry checks
- **Maintainability**: Single source of truth for geometry validation

🧹 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 23:00:24 +09:00

178 lines
6.3 KiB
C

// tiny_box_geometry.h - Box 3: Geometry & Capacity Calculator
// Purpose: Centralize stride/capacity/base calculations for Tiny allocator
//
// Box Theory Responsibility:
// - Calculate block stride (size + header) with C7 (headerless) handling
// - Calculate slab capacity (usable bytes / stride)
// - Calculate slab base address with Slab 0 offset handling
// - Provide single source of truth for geometry calculations
//
// This Box eliminates code duplication and makes C7 special cases explicit.
#ifndef TINY_BOX_GEOMETRY_H
#define TINY_BOX_GEOMETRY_H
#include <stdint.h>
#include <stddef.h>
#include <stdio.h> // guard logging helpers
#include "hakmem_tiny_superslab_constants.h"
#include "hakmem_tiny_config.h" // For g_tiny_class_sizes declaration
// ============================================================================
// Box 3 API: Geometry Calculations (Single Source of Truth)
// ============================================================================
/**
* Calculate block stride for a given class
*
* Phase E1-CORRECT: ALL classes have 1-byte header (unified box structure)
*
* @param class_idx Class index (0-7)
* @return Block stride in bytes (total block size)
*
* Box Structure: [Header 1B][User Data N-1B] = N bytes total
* - g_tiny_class_sizes[cls] = total block size (stride) = N
* - usable data = N - 1 (implicit)
* - All classes follow same structure (no C7 special case!)
*/
static inline size_t tiny_stride_for_class(int class_idx) {
#if HAKMEM_TINY_HEADER_CLASSIDX
// Phase E1-CORRECT: g_tiny_class_sizes stores TOTAL size (stride)
// ALL classes have 1-byte header, so usable = stride - 1
return g_tiny_class_sizes[class_idx];
#else
// No headers: stride = usable size
return g_tiny_class_sizes[class_idx];
#endif
}
/**
* Calculate slab capacity (number of blocks that fit in usable space)
*
* @param slab_idx Slab index within SuperSlab (0 for first slab, 1+ for others)
* @param stride Block stride in bytes (from tiny_stride_for_class)
* @return Number of blocks that fit in this slab
*
* Slab 0 has reduced usable space (SUPERSLAB_SLAB0_USABLE_SIZE)
* Slabs 1+ have full usable space (SUPERSLAB_SLAB_USABLE_SIZE)
*/
static inline uint16_t tiny_capacity_for_slab(int slab_idx, size_t stride) {
size_t usable = (slab_idx == 0)
? SUPERSLAB_SLAB0_USABLE_SIZE
: SUPERSLAB_SLAB_USABLE_SIZE;
return (uint16_t)(usable / stride);
}
/**
* Get slab base address (accounts for SUPERSLAB_SLAB0_DATA_OFFSET)
*
* @param ss SuperSlab pointer
* @param slab_idx Slab index within SuperSlab
* @return Pointer to first usable byte in this slab
*
* Slab 0 has an offset (SUPERSLAB_SLAB0_DATA_OFFSET) due to SuperSlab metadata
* Slabs 1+ start at slab_idx * SLAB_SIZE
*/
static inline uint8_t* tiny_slab_base_for_geometry(struct SuperSlab* ss, int slab_idx) {
uint8_t* base = (uint8_t*)ss + (slab_idx * SLAB_SIZE);
// Slab 0 offset: sizeof(SuperSlab)=1088, aligned to next 1024-boundary=2048
if (slab_idx == 0) base += SUPERSLAB_SLAB0_DATA_OFFSET;
return base;
}
/**
* Calculate usable bytes for a given slab
*
* @param slab_idx Slab index within SuperSlab
* @return Usable bytes in this slab
*/
static inline size_t tiny_usable_bytes_for_slab(int slab_idx) {
return (slab_idx == 0)
? SUPERSLAB_SLAB0_USABLE_SIZE
: SUPERSLAB_SLAB_USABLE_SIZE;
}
/**
* Calculate block address within a slab (linear allocation)
*
* @param base Slab base address (from tiny_slab_base_for_geometry)
* @param index Block index (0-based)
* @param stride Block stride (from tiny_stride_for_class)
* @return Pointer to block at given index
*/
static inline void* tiny_block_at_index(uint8_t* base, uint16_t index, size_t stride) {
return (void*)(base + ((size_t)index * stride));
}
/**
* Validate that a linear carve operation stays within slab bounds
*
* @param slab_idx Slab index
* @param carved Current carved count
* @param stride Block stride
* @param reserve Number of blocks to reserve
* @return 1 if operation is safe, 0 if it would exceed bounds
*/
static inline int tiny_carve_guard(int slab_idx,
uint16_t carved,
size_t stride,
uint32_t reserve) {
size_t usable = tiny_usable_bytes_for_slab(slab_idx);
size_t needed = ((size_t)carved + (size_t)reserve) * stride;
return needed <= usable;
}
// ============================================================================
// Box 3 Debug Helpers (fail-fast validation)
// ============================================================================
/**
* Debug helper: verbose carve guard with diagnostics
*
* @param stage Debug stage name
* @param class_idx Class index
* @param slab_idx Slab index
* @param carved Current carved count
* @param used Current used count
* @param capacity Slab capacity
* @param stride Block stride
* @param reserve Blocks to reserve
* @return 1 if safe, 0 if would exceed bounds (with stderr logging)
*/
static inline int tiny_carve_guard_verbose(const char* stage,
int class_idx,
int slab_idx,
uint16_t carved,
uint16_t used,
uint16_t capacity,
size_t stride,
uint32_t reserve) {
#if HAKMEM_BUILD_RELEASE
(void)stage; (void)class_idx; (void)slab_idx;
(void)carved; (void)used; (void)capacity;
return tiny_carve_guard(slab_idx, carved, stride, reserve);
#else
size_t usable = tiny_usable_bytes_for_slab(slab_idx);
size_t needed = ((size_t)carved + (size_t)reserve) * stride;
if (__builtin_expect(needed > usable, 0)) {
fprintf(stderr,
"[LINEAR_GUARD] stage=%s cls=%d slab=%d carved=%u used=%u cap=%u "
"stride=%zu reserve=%u needed=%zu usable=%zu\n",
stage ? stage : "carve",
class_idx,
slab_idx,
carved,
used,
capacity,
stride,
reserve,
needed,
usable);
return 0;
}
return 1;
#endif
}
#endif // TINY_BOX_GEOMETRY_H