Phase 21-1-B: Ring cache Alloc/Free 統合 - C2/C3 hot path integration
**統合内容**: - Alloc path (tiny_alloc_fast.inc.h): Ring pop → HeapV2/UltraHot/SLL fallback - Free path (tiny_free_fast_v2.inc.h): Ring push → HeapV2/SLL fallback - Lazy init: 最初の alloc/free 時に自動初期化(thread-safe) **設計**: - Lazy init パターン(ENV control と同様) - ring_cache_pop/push 内で slots == NULL チェック → ring_cache_init() 呼び出し - Include 構造: ファイルトップレベルに #include 追加(関数内 include 禁止) **Makefile 修正**: - TINY_BENCH_OBJS_BASE に core/front/tiny_ring_cache.o 追加 - Link エラー修正: 4箇所の object list に追加 **動作確認**: - Ring OFF (default): 83K ops/s (1K iterations) ✅ - Ring ON (HAKMEM_TINY_HOT_RING_ENABLE=1): 78K ops/s ✅ - クラッシュなし、正常動作確認 **次のステップ**: Phase 21-1-C (Refill/Cascade 実装)
This commit is contained in:
@ -130,6 +130,14 @@ static inline int ring_cascade_enabled(void) {
|
||||
return g_enable;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Init/Shutdown Forward Declarations (needed by pop/push)
|
||||
// ============================================================================
|
||||
|
||||
void ring_cache_init(void);
|
||||
void ring_cache_shutdown(void);
|
||||
void ring_cache_print_stats(void);
|
||||
|
||||
// ============================================================================
|
||||
// Ultra-Fast Pop/Push (1-2 instructions)
|
||||
// ============================================================================
|
||||
@ -137,8 +145,19 @@ static inline int ring_cascade_enabled(void) {
|
||||
// Pop from ring (alloc fast path)
|
||||
// Returns: BASE pointer (caller must convert to USER with +1)
|
||||
static inline void* ring_cache_pop(int class_idx) {
|
||||
// Fast path: Ring disabled or wrong class → return NULL immediately
|
||||
if (__builtin_expect(!ring_cache_enabled(), 0)) return NULL;
|
||||
if (__builtin_expect(class_idx != 2 && class_idx != 3, 0)) return NULL;
|
||||
|
||||
TinyRingCache* ring = (class_idx == 2) ? &g_ring_cache_c2 : &g_ring_cache_c3;
|
||||
|
||||
// Lazy init check (once per thread)
|
||||
if (__builtin_expect(ring->slots == NULL, 0)) {
|
||||
ring_cache_init(); // First call in this thread
|
||||
// Re-check after init (may fail if allocation failed)
|
||||
if (ring->slots == NULL) return NULL;
|
||||
}
|
||||
|
||||
// Empty check
|
||||
if (__builtin_expect(ring->head == ring->tail, 0)) {
|
||||
return NULL; // Empty
|
||||
@ -155,8 +174,19 @@ static inline void* ring_cache_pop(int class_idx) {
|
||||
// Input: BASE pointer (caller must pass BASE, not USER)
|
||||
// Returns: 1=SUCCESS, 0=FULL
|
||||
static inline int ring_cache_push(int class_idx, void* base) {
|
||||
// Fast path: Ring disabled or wrong class → return 0 (not handled)
|
||||
if (__builtin_expect(!ring_cache_enabled(), 0)) return 0;
|
||||
if (__builtin_expect(class_idx != 2 && class_idx != 3, 0)) return 0;
|
||||
|
||||
TinyRingCache* ring = (class_idx == 2) ? &g_ring_cache_c2 : &g_ring_cache_c3;
|
||||
|
||||
// Lazy init check (once per thread)
|
||||
if (__builtin_expect(ring->slots == NULL, 0)) {
|
||||
ring_cache_init(); // First call in this thread
|
||||
// Re-check after init (may fail if allocation failed)
|
||||
if (ring->slots == NULL) return 0;
|
||||
}
|
||||
|
||||
uint16_t next_tail = (ring->tail + 1) & ring->mask;
|
||||
|
||||
// Full check (leave 1 slot empty to distinguish full/empty)
|
||||
@ -178,12 +208,4 @@ static inline int ring_cache_push(int class_idx, void* base) {
|
||||
// Forward declaration (defined in tiny_ring_cache.c)
|
||||
int ring_refill_from_sll(int class_idx, int target_count);
|
||||
|
||||
// ============================================================================
|
||||
// Init/Shutdown (called from hakmem_tiny.c)
|
||||
// ============================================================================
|
||||
|
||||
void ring_cache_init(void);
|
||||
void ring_cache_shutdown(void);
|
||||
void ring_cache_print_stats(void);
|
||||
|
||||
#endif // HAK_FRONT_TINY_RING_CACHE_H
|
||||
|
||||
Reference in New Issue
Block a user