/** * @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 is 0 for C0/C7 (cannot preserve header while free), else 1. static inline size_t tiny_nextptr_offset(int class_idx) { #if HAKMEM_TINY_HEADERLESS (void)class_idx; return 0; #elif HAKMEM_TINY_HEADER_CLASSIDX // Bit pattern: C0=0, C1-C6=1, C7=0 → 0b01111110 = 0x7E return (0x7Eu >> ((unsigned)class_idx & 7u)) & 1u; #else (void)class_idx; return 0u; #endif } #endif // TINY_LAYOUT_BOX_H