Files
hakmem/core/smallobject_cold_iface_v6.c
Moe Charm (CI) 1e04debb1b Phase v6-5: C5 extension for SmallObject Core v6
Extend v6 architecture to support C5 (129-256B) in addition to C6 (257-512B):

- SmallHeapCtxV6: Add tls_freelist_c5[32] and tls_count_c5 for C5 TLS cache
- smallsegment_v6_box.h: Add SMALL_V6_C5_CLASS_IDX (5) and C5_BLOCK_SIZE (256)
- smallobject_cold_iface_v6.c: Generalize refill_page for both C5 (256 blocks/page)
  and C6 (128 blocks/page)
- smallobject_core_v6.c: Add C5 fast path (alloc/free) with TLS batching

Performance (v6 C5 enabled):
- C5-heavy: 41.0M ops/s (-23% vs v6 OFF 53.6M) - needs optimization
- Mixed: 36.2M ops/s (-18% vs v6 OFF 44.0M) - functional baseline

Note: C5 route requires optimization in next phase to match v6-3 performance.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 15:50:14 +09:00

98 lines
2.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// smallobject_cold_iface_v6.c - SmallObject ColdIface v6 実装Phase v6-3
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "box/smallobject_cold_iface_v6.h"
#include "box/smallsegment_v6_box.h"
#ifndef likely
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
// Refill page for given class (C6 and C5 in v6-5)
SmallPageMetaV6* small_cold_v6_refill_page(uint32_t class_idx) {
// v6-5: Support C5 and C6
size_t block_size;
if (class_idx == SMALL_V6_C6_CLASS_IDX) {
block_size = SMALL_V6_C6_BLOCK_SIZE; // 512
} else if (class_idx == SMALL_V6_C5_CLASS_IDX) {
block_size = SMALL_V6_C5_BLOCK_SIZE; // 256
} else {
return NULL; // Unsupported class
}
// Get or acquire TLS segment
SmallSegmentV6* seg = small_segment_v6_acquire_for_thread();
if (unlikely(!seg)) {
return NULL;
}
// Find an available page (simple linear scan)
SmallPageMetaV6* page = NULL;
for (uint32_t i = 0; i < seg->num_pages; i++) {
if (seg->page_meta[i].capacity == 0) {
page = &seg->page_meta[i];
break;
}
}
if (unlikely(!page)) {
return NULL; // All pages in use
}
// Initialize page metadata
page->class_idx = (uint8_t)class_idx;
page->capacity = SMALL_PAGE_V6_SIZE / block_size; // C6: 128, C5: 256
page->used = 0;
page->flags = 0;
// Build freelist for the page
uintptr_t page_offset = (uintptr_t)page->page_idx * SMALL_PAGE_V6_SIZE;
uintptr_t page_base = seg->base + page_offset;
uint8_t* base = (uint8_t*)page_base;
// Build intrusive freelist (last to first for cache locality)
void* freelist = NULL;
for (int i = (int)page->capacity - 1; i >= 0; i--) {
uint8_t* block = base + ((size_t)i * block_size);
// Build freelist using BASE pointers
void* next = freelist;
memcpy(block, &next, sizeof(void*));
freelist = block;
}
page->free_list = freelist;
return page;
}
// Retire page (simple reset for v6-2)
void small_cold_v6_retire_page(SmallPageMetaV6* page) {
if (unlikely(!page)) {
return;
}
// v6-2: Simple reset (no actual deallocation)
page->free_list = NULL;
page->used = 0;
page->capacity = 0;
page->class_idx = 0;
page->flags = 0;
}
// Remote operations (dummy for v6-2, C6-heavy is mostly same-thread)
void small_cold_v6_remote_push(SmallPageMetaV6* page, void* ptr, uint32_t tid) {
(void)page;
(void)ptr;
(void)tid;
// Not implemented in v6-2
}
void small_cold_v6_remote_drain(SmallHeapCtxV6* ctx) {
(void)ctx;
// Not implemented in v6-2
}