/** * @file tiny_layout_box.h * @brief Box: Tiny Allocator Layout Definitions * * MISSION: Single source of truth for class size and header layout * * Current Design (Phase E1-CORRECT): * - All classes (0-7) have 1-byte header * - User pointer = base + 1 for ALL classes (0-7) * - Freed blocks store next pointers intrusively: * - C0/C7: next at base+0 (header overwritten while free) * - C1-C6: next at base+1 (header preserved while free) * - No external code should hardcode offsets; use this box API */ #ifndef TINY_LAYOUT_BOX_H #define TINY_LAYOUT_BOX_H #include #include "../hakmem_tiny_config.h" // For g_tiny_class_sizes and TINY_NUM_CLASSES // A/B Toggle: Headerless mode // ENV: HAKMEM_TINY_HEADERLESS=1 to enable // Default: 0 (Phase 1 compatible) #ifndef HAKMEM_TINY_HEADERLESS #define HAKMEM_TINY_HEADERLESS 0 #endif #include "../hakmem_build_flags.h" // Define all class-specific layout parameters // Current: Defined in g_tiny_class_sizes[8] in hakmem_tiny.c // This file makes them accessible via a unified Box API // Header size static inline size_t tiny_header_size(int class_idx) { #if HAKMEM_TINY_HEADERLESS (void)class_idx; return 0; #elif HAKMEM_TINY_HEADER_CLASSIDX (void)class_idx; return 1; #else (void)class_idx; return 0; #endif } // Legacy macro for backward compatibility (Phase 1) #define TINY_HEADER_SIZE 1 // Validation macros static inline int tiny_class_is_valid(int class_idx) { return class_idx >= 0 && class_idx < TINY_NUM_CLASSES; } static inline size_t tiny_class_stride(int class_idx) { // Use the extern global definition from hakmem_tiny_config.h // g_tiny_class_sizes is defined in core/hakmem_tiny_config_box.inc return tiny_class_is_valid(class_idx) ? g_tiny_class_sizes[class_idx] : 0; } // Calculate user pointer offset from base pointer // This logic centralizes the "User = Base + 1" vs "User = Base + 0" decision static inline size_t tiny_user_offset(int class_idx) { #if HAKMEM_TINY_HEADERLESS (void)class_idx; return 0; // Headerless: user = base #elif HAKMEM_TINY_HEADER_CLASSIDX (void)class_idx; // Phase E1-CORRECT: All classes have 1-byte header → user = base + 1 return 1u; #else (void)class_idx; return 0u; #endif } // Offset for storing the freelist next pointer inside a freed block. // This is distinct from tiny_user_offset(): // - User offset is always +1 in header mode. // - Next offset: // - C0: always 0 (16B, cannot fit header+next) // - C1-C6: always 1 (header-preserving) // - C7: 0 (default) or 1 (Phase 13 v1: header-preserving) static inline size_t tiny_nextptr_offset(int class_idx) { #if HAKMEM_TINY_HEADERLESS (void)class_idx; return 0; #elif HAKMEM_TINY_HEADER_CLASSIDX // Phase 13 v1: C7 preserve header gate // Bit pattern (default): C0=0, C1-C6=1, C7=0 → 0b01111110 = 0x7E // Bit pattern (C7 preserve): C0=0, C1-C7=1 → 0b11111110 = 0xFE unsigned int base_pattern = 0x7Eu; // default: C7 offset=0 // Phase 13 v1: Gate for C7 header-preserving layout if (class_idx == 7) { extern int tiny_c7_preserve_header_enabled(void); if (tiny_c7_preserve_header_enabled()) { base_pattern = 0xFEu; // C7 offset=1 (header-preserving) } } return (base_pattern >> ((unsigned)class_idx & 7u)) & 1u; #else (void)class_idx; return 0u; #endif } #endif // TINY_LAYOUT_BOX_H