Heap Allocator

Module: cbase.allocator_protocol.c_heap_allocator

In-process heap allocator with free-list reuse and auto-growing pages. Backed by malloc / free and managed through a page-list structure. Thread-safety is achieved via an optional global mutex.

class cbase.allocator_protocol.c_heap_allocator.HeapAllocator

Bases: object

__init__(*args, **kwargs)
active_page
Type:

HeapMemoryPage | None

allocated()
Return type:

Generator[HeapMemoryBlock]

autopage_alignment
Type:

int

autopage_capacity
Type:

int

autopage_capacity_max
Type:

int

calloc(size, with_lock=True)
Parameters:
Return type:

HeapMemoryBlock

extend(capacity=0, with_lock=True)
Parameters:
Return type:

HeapMemoryPage

free(buffer, with_lock=True)
Parameters:
Return type:

None

free_list()
Return type:

Generator[HeapMemoryBlock]

mapped_pages
Type:

int

owner
Type:

bool

pages()
Return type:

Generator[HeapMemoryPage]

reclaim(with_lock=True)
Parameters:

with_lock (bool)

Return type:

None

request(size, with_lock=True, scan_all_pages=True)
Parameters:
Return type:

HeapMemoryBlock

class cbase.allocator_protocol.c_heap_allocator.HeapMemoryBlock

Bases: MemoryBlock

address
Type:

str | None

buffer
Type:

memoryview

capacity
Type:

int

next_allocated
Type:

HeapMemoryBlock | None

next_free
Type:

HeapMemoryBlock | None

parent_page
Type:

HeapMemoryPage | None

size
Type:

int

class cbase.allocator_protocol.c_heap_allocator.HeapMemoryPage

Bases: object

address
Type:

str | None

allocated()
Return type:

Generator[HeapMemoryBlock]

allocator
Type:

HeapAllocator | None

capacity
Type:

int

classmethod from_buffer(buffer_addr)
Return type:

HeapMemoryPage

occupied
Type:

int

reclaim()
Return type:

None

cbase.allocator_protocol.c_heap_allocator.__reduce_cython__(self)
cbase.allocator_protocol.c_heap_allocator.__setstate_cython__(self, __pyx_state)

Module Singleton

from cbase.allocator_protocol.c_heap_allocator import ALLOCATOR

ALLOCATOR is a module-level HeapAllocator instance that serves as the global heap backend for the allocator protocol.

Compile-Time Constants

Auto-page sizing:

from cbase.allocator_protocol.c_heap_allocator import (
    DEFAULT_AUTOPAGE_CAPACITY,    # 64 KiB — first/auto page size
    MAX_AUTOPAGE_CAPACITY,         # 16 MiB — maximum page size
    DEFAULT_AUTOPAGE_ALIGNMENT,    # 4 KiB — page alignment
)

Size-binned free-list tuning (added in v0.1.9):

from cbase.allocator_protocol.c_heap_allocator import (
    EXACT_BIN_COUNT,              # 8192 — exact 8-byte-granular bins (≤ 64 KiB)
    LARGE_BIN_COUNT,              # 9 — pow2-class bins (> 64 KiB)
    BIN_COUNT,                    # 8202 — total bin count (EXACT + LARGE + 1)
    PAGE_EXTEND_MAX,              # 128 MiB — max auto-page extension
    PAGE_FIT_TO_REQUEST,          # 0 — when 1, page fits request instead of pow2 scaling
    EXACT_BIN_PROBE_COUNT,        # 2 — exact bins to probe on miss before page path
)

Bin-computation helpers (static inline C functions exposed to Cython):

from cbase.allocator_protocol.c_heap_allocator import (
    c_heap_block_ceil_log2,       # ceil(log2(v)) for bin indexing
    c_heap_block_bin,             # bin index for a given block capacity
)

Usage Examples

Direct allocator usage:

from cbase.allocator_protocol.c_heap_allocator import HeapAllocator

alloc = HeapAllocator()

# Extend with a default-sized page
page = alloc.extend()

# Allocate zeroed memory (auto-extends as needed)
block = alloc.calloc(1024)
buf = block.buffer  # memoryview of the payload

# Free a block
alloc.free(block)

# Reclaim freed space
alloc.reclaim()

Iterating pages and blocks:

# All pages, newest-first
for page in alloc.pages():
    print(f"Page {page.address}: {page.occupied}/{page.capacity}")

# All allocated blocks
for block in alloc.allocated():
    print(f"Block {block.address}: {block.size} bytes")

Tuning auto-page parameters:

alloc.autopage_capacity = 128 * 1024       # 128 KiB
alloc.autopage_capacity_max = 64 * 1024 * 1024  # 64 MiB
alloc.autopage_alignment = 4096            # 4 KiB

Thread Safety

All methods accept a with_lock parameter (default True). Set to False when the caller already holds the lock or when the allocator is used from a single thread.