Files
hakmem/core/front/tiny_first_page_cache.h

83 lines
3.1 KiB
C
Raw Normal View History

2025-12-13 19:19:42 +09:00
// tiny_first_page_cache.h
// Phase 3 C2 Patch 2: First Page Inline Cache
//
// Purpose: Cache current slab page pointer in TLS to avoid superslab metadata lookup
//
// Design:
// - TinyFirstPageCache struct: first_page_base + first_page_free_count
// - Per-class cache (C0-C7)
// - Fast-path check in free path (before superslab lookup)
// - Auto-invalidate on refill/retire
//
// Integration:
// - tiny_legacy_fallback_free_base(): Check cache hit before superslab lookup
// - Refill/retire: Update cache with new page info
#ifndef HAK_FRONT_TINY_FIRST_PAGE_CACHE_H
#define HAK_FRONT_TINY_FIRST_PAGE_CACHE_H
#include <stdint.h>
#include <stdbool.h>
#include "../hakmem_tiny_config.h" // For TINY_NUM_CLASSES
// ============================================================================
// First Page Cache Structure
// ============================================================================
typedef struct {
void* first_page_base; // Current page base pointer (avoid superslab lookup)
uint16_t first_page_free_count; // Free slots in current page (hint only)
} TinyFirstPageCache;
// ============================================================================
// External TLS Variable
// ============================================================================
extern __thread TinyFirstPageCache g_first_page_cache[TINY_NUM_CLASSES];
// ============================================================================
// First Page Cache API
// ============================================================================
/// Check if ptr is in cached first page (fast path hint)
/// @param class_idx: Size class (0-7)
/// @param ptr: Pointer to check (BASE pointer)
/// @param page_size: Page size for this class
/// @return: true if ptr is in cached page, false otherwise
__attribute__((always_inline))
static inline bool tiny_first_page_cache_hit(uint32_t class_idx, void* ptr, size_t page_size) {
if (class_idx >= TINY_NUM_CLASSES) return false;
void* base = g_first_page_cache[class_idx].first_page_base;
if (base == NULL) return false;
// Check if ptr is within [base, base + page_size)
uintptr_t ptr_addr = (uintptr_t)ptr;
uintptr_t base_addr = (uintptr_t)base;
return (ptr_addr >= base_addr) && (ptr_addr < base_addr + page_size);
}
/// Update first page cache (on refill)
/// @param class_idx: Size class (0-7)
/// @param base: New page base pointer
/// @param count: Free slots in page
__attribute__((always_inline))
static inline void tiny_first_page_cache_update(uint32_t class_idx, void* base, uint16_t count) {
if (class_idx >= TINY_NUM_CLASSES) return;
g_first_page_cache[class_idx].first_page_base = base;
g_first_page_cache[class_idx].first_page_free_count = count;
}
/// Invalidate first page cache (on retire or page full)
/// @param class_idx: Size class (0-7)
__attribute__((always_inline))
static inline void tiny_first_page_cache_invalidate(uint32_t class_idx) {
if (class_idx >= TINY_NUM_CLASSES) return;
g_first_page_cache[class_idx].first_page_base = NULL;
g_first_page_cache[class_idx].first_page_free_count = 0;
}
#endif // HAK_FRONT_TINY_FIRST_PAGE_CACHE_H