Rewrote the comments in the libraries under 'includes' in English (excluding those inside folders)

This commit is contained in:
2026-07-29 23:34:36 +08:00
parent 3633be1995
commit a2cc28a6ab
54 changed files with 7091 additions and 899 deletions

View File

@@ -6,21 +6,21 @@ import viperio
import stdio
# ============================================================
# memhub - 统一内存管理库
# MemManager (多态基类, vtable)
# ├─ MemPool (arena bump 分配器, 不支持单个 free)
# ├─ MemSlab (定长块池, 支持 alloc/free 位图跟踪)
# └─ MemBuddy (伙伴系统, 支持 alloc/free/realloc 合并)
# 所有子类通过 vtable 覆盖 alloc/free/reset, 可用 MemManager 指针多态调用
# memhub - Unified memory management library
# MemManager (polymorphic base class, vtable)
# ├─ MemPool (arena bump allocator, no support for individual free)
# ├─ MemSlab (fixed-size block pool, alloc/free tracked via bitmap)
# └─ MemBuddy (buddy system, supports alloc/free/realloc with coalescing)
# All subclasses override alloc/free/reset via vtable, invokable polymorphically through MemManager pointer
# ============================================================
MEMHUB_ALIGN: t.CDefine = 8
# MemSlab 位图常量
# MemSlab bitmap constants
MEMSLAB_MIN_BLOCK: t.CDefine = 16
MEMSLAB_BITMAP_BYTES: t.CDefine = 256
# MemBuddy 伙伴系统常量
# MemBuddy buddy constants
MEMBUDDY_MIN_BLOCK: t.CDefine = 32
MEMBUDDY_MAX_ORDERS: t.CDefine = 32
MEMBUDDY_HEADER_SIZE: t.CDefine = 8
@@ -48,35 +48,35 @@ def _block_size_at_order(order: t.CInt) -> t.CSizeT:
# ============================================================
# MemManager - 多态基类
# @t.CVTable 显式标记, 确保跨模块导入时也被识别为 vtable 类
# (HandlesImports 只通过装饰器检测 IsCVTable, 不像同模块自动推断)
# MemManager - Polymorphic base class
# @t.CVTable explicit annotation to ensure recognition as vtable class during cross-module imports
# (HandlesImports only detects IsCVTable via decorator; automatic inference is unavailable across modules)
# ============================================================
@t.CVTable
class MemManager:
__provides__: list[str] = ['__memmgr__']
base: t.CVoid | t.CPtr # 内存区起始地址
size: t.CSizeT # 内存区总大小
base: t.CVoid | t.CPtr # Starting address of memory region
size: t.CSizeT # Total size of memory region
def __init__(self, base: t.CVoid | t.CPtr, size: t.CSizeT):
self.base = base
self.size = size
# === 虚函数 (子类覆盖) ===
# === Virtual functions (overridden by subclasses) ===
def alloc(self, size: t.CSizeT) -> t.CVoid | t.CPtr:
# 默认: 不支持分配
# Default: allocation not supported
return None
def free(self, ptr: t.CVoid | t.CPtr) -> t.CInt:
# 默认: 无操作
# Default: no operation
return 0
def reset(self) -> t.CInt:
# 默认: 无操作
# Default: no operation
return 0
# === 具体方法 (调用虚函数, 自动多态分派) ===
# === Concrete methods (invoke virtual functions for automatic polymorphic dispatch) ===
def calloc(self, count: t.CSizeT, size: t.CSizeT) -> t.CVoid | t.CPtr:
total: t.CSizeT = count * size
@@ -94,7 +94,7 @@ class MemManager:
new_ptr: t.CVoid | t.CPtr = self.alloc(new_size)
if new_ptr is None:
return ptr
# 基类无法追踪旧分配大小, 不复制数据; 子类可覆盖以保留数据
# Base class cannot track original allocation size; data will not be copied. Subclasses may override to preserve data
self.free(ptr)
return new_ptr
@@ -117,12 +117,12 @@ class MemManager:
# ============================================================
# MemPool - arena bump 分配器
# 不支持单个 free, reset 一次性回收全部
# MemPool - Arena bump allocator
# Individual free operations are unsupported; reset reclaims all memory at once
# ============================================================
class MemPool(MemManager):
offset: t.CSizeT # bump 游标
high_water: t.CSizeT # 峰值水位
offset: t.CSizeT # Bump pointer offset
high_water: t.CSizeT # High-water mark
def __init__(self, base: t.CVoid | t.CPtr, size: t.CSizeT):
self.base = base
@@ -141,7 +141,7 @@ class MemPool(MemManager):
return ptr
def free(self, ptr: t.CVoid | t.CPtr) -> t.CInt:
# bump 分配器不支持单个 free
# Bump allocator does not support individual free operations
return 1
def reset(self) -> t.CInt:
@@ -151,18 +151,18 @@ class MemPool(MemManager):
# ============================================================
# MemSlab - 定长块池
# arena 开头存位图, 后续区域按 block_size 切分, 空闲链管理
# MemSlab - Fixed-size block pool
# Bitmap stored at the start of arena; subsequent area split into block_size units managed by free list
# ============================================================
class MemSlab(MemManager):
block_size: t.CSizeT # 每块大小 (对齐后)
block_count: t.CSizeT # 总块数
used_count: t.CSizeT # 已用块数
free_list: t.CVoid | t.CPtr # 空闲链头
alloc_map: t.CUInt8T | t.CPtr # 分配位图 (位于 arena 开头)
alloc_map_size: t.CSizeT # 位图字节数
usable: t.CVoid | t.CPtr # 可用块区起始 (跳过位图)
usable_size: t.CSizeT # 可用块区大小
block_size: t.CSizeT # Block size (aligned)
block_count: t.CSizeT # Total block count
used_count: t.CSizeT # Used block count
free_list: t.CVoid | t.CPtr # Free list head
alloc_map: t.CUInt8T | t.CPtr # Allocation bitmap (at start of arena)
alloc_map_size: t.CSizeT # Bitmap byte count
usable: t.CVoid | t.CPtr # Usable block area start (after bitmap)
usable_size: t.CSizeT # Usable block area size
def __init__(self, base: t.CVoid | t.CPtr, size: t.CSizeT, block_size: t.CSizeT):
self.base = base
@@ -190,7 +190,7 @@ class MemSlab(MemManager):
self.usable_size = size - map_bytes
self.block_size = bs
# 清零位图
# Clear bitmap
idx: t.CSizeT = 0
while idx < map_bytes:
self.alloc_map[idx] = 0
@@ -199,7 +199,7 @@ class MemSlab(MemManager):
self.block_count = self.usable_size / bs
if self.block_count == 0: return
# 构建空闲链: 每块首 8 字节存下一块指针
# Construct free list: the first 8 bytes of each block store pointer to next block
self.free_list = None
i: t.CSizeT = 0
while i < self.block_count:
@@ -209,7 +209,7 @@ class MemSlab(MemManager):
i += 1
def alloc(self, size: t.CSizeT) -> t.CVoid | t.CPtr:
# slab 模式: 仅当请求 <= block_size 时分配一块
# Slab mode: allocate one block only if requested size <= block_size
if self.free_list is None: return None
if size > self.block_size: return None
block: t.CVoid | t.CPtr = self.free_list
@@ -250,20 +250,20 @@ class MemSlab(MemManager):
# ============================================================
# MemBuddy - 伙伴系统分配器
# arena 开头存空闲链头数组, 后续区域按 2 的幂管理
# 线程安全 (自旋锁), 支持合并
# MemBuddy - Buddy system allocator
# Free list head array stored at arena start; subsequent memory managed in power-of-two sized blocks
# Thread-safe (spinlock enabled), supports block coalescing
# ============================================================
class MemBuddy(MemManager):
# 覆盖父类 __provides__MemBuddy 同时提供 __mbuddy__ __memmgr__
# 使 with MemBuddy(...) 上下文内的 __requires__=['__mbuddy__'] 类(如 _str
# 能通过 _find_provider 自动注入
# Override parent __provides__: MemBuddy provides both __mbuddy__ and __memmgr__.
# Within `with MemBuddy(...)` context, classes (e.g. _str) with __requires__=['__mbuddy__']
# can be automatically injected via _find_provider
__provides__: list[str] = ['__mbuddy__', '__memmgr__']
max_order: t.CInt # 最大阶数
free_lists: t.CUInt64T | t.CPtr # 空闲链头数组 (位于 arena 开头)
lock_val: t.CVolatile | t.CInt # 自旋锁
usable: t.CVoid | t.CPtr # 可用区起始 (跳过 free_lists)
usable_size: t.CSizeT # 可用区大小 (2 的幂)
max_order: t.CInt # Maximum order
free_lists: t.CUInt64T | t.CPtr # Free list head array (located at arena start)
lock_val: t.CVolatile | t.CInt # Spinlock
usable: t.CVoid | t.CPtr # Start of usable memory region (skips free_lists)
usable_size: t.CSizeT # Size of usable memory (power of two)
def __init__(self, base: t.CVoid | t.CPtr, size: t.CSizeT):
self.base = base
@@ -278,7 +278,7 @@ class MemBuddy(MemManager):
fl_bytes: t.CSizeT = (MEMBUDDY_MAX_ORDERS + 1) * 8
self.free_lists = base
# 初始化所有空闲链头为 0
# Initialize all free list heads to be 0
i: t.CInt
for i in range(MEMBUDDY_MAX_ORDERS + 1):
self.free_lists[i] = 0
@@ -308,10 +308,10 @@ class MemBuddy(MemManager):
bs = bs << 1
self.max_order += 1
# 整个可用区作为 max_order 阶空闲块
# Entire usable memory region as a max_order free block
self._fl_push(self.max_order, self.usable)
# === 空闲链操作 ===
# === Free list operations ===
def _fl_push(self, order: t.CInt, block: t.CVoid | t.CPtr):
old_head: t.CUInt64T = self.free_lists[order]
@@ -347,7 +347,7 @@ class MemBuddy(MemManager):
cur = t.CVoid(c.Deref(t.CUInt64T(cur, t.CPtr)), t.CPtr)
return 0
# === 伙伴系统核心 ===
# === Buddy system core ===
def _buddy_of(self, block: t.CVoid | t.CPtr, order: t.CInt) -> t.CVoid | t.CPtr:
offset: t.CSizeT = t.CUInt64T(block) - t.CUInt64T(self.usable)
@@ -406,16 +406,16 @@ class MemBuddy(MemManager):
if order > self.max_order: return 0
return 1
# === ===
# === Spinlock ===
def _lock(self):
def _lock(self): # can use the spinlock library for decoupling
while atom.__atomic_test_and_set(c.Addr(self.lock_val), atom.ATOMIC_ACQUIRE):
pass
def _unlock(self):
atom.__atomic_clear(c.Addr(self.lock_val), atom.ATOMIC_RELEASE)
# === 虚函数覆盖 ===
# === Virtual function overrides ===
def alloc(self, size: t.CSizeT) -> t.CVoid | t.CPtr:
self._lock()
@@ -430,7 +430,7 @@ class MemBuddy(MemManager):
c.DerefAs(block, t.CVoid(t.CUInt64T((order << 1) | 1), t.CPtr))
result = t.CVoid(t.CUInt64T(block) + MEMBUDDY_HEADER_SIZE, t.CPtr)
if result is None:
# 分配失败: 打印内存使用情况
# Allocation failure: print memory usage statistics
fb: t.CSizeT = self.free_bytes()
ub: t.CSizeT = self.usable_size - fb
stdio.printf("[MEM-FAIL] alloc(%zu) failed: total=%zu used=%zu free=%zu free_blocks=%zu\n",
@@ -460,7 +460,7 @@ class MemBuddy(MemManager):
self._fl_push(self.max_order, self.usable)
return 1
# realloc 覆盖: 伙伴系统从块头读取旧阶数, 无需 old_size
# realloc override: buddy system reads original order from block header; old_size is not required
def realloc(self, ptr: t.CVoid | t.CPtr, new_size: t.CSizeT) -> t.CVoid | t.CPtr:
if ptr is None:
return self.alloc(new_size)
@@ -486,19 +486,19 @@ class MemBuddy(MemManager):
self.free(ptr)
return new_ptr
# === 状态查询 ===
# === Status Queries ===
@property
def mem_size(self) -> t.CSizeT:
# 可用区总大小2 的幂),分配上限为 mem_size - MEMBUDDY_HEADER_SIZE
# Total usable region size (power of two). Maximum allocatable size = mem_size - MEMBUDDY_HEADER_SIZE
return self.usable_size
def stats(self) -> t.CSizeT:
# 返回可用区总大小,用于状态统计
# Return total usable region size, for status statistics
return self.usable_size
def free_count(self) -> t.CSizeT:
# 统计所有阶数空闲链中的块总数
# Count total blocks in all order lists for status statistics
count: t.CSizeT = 0
i: t.CInt
for i in range(MEMBUDDY_MAX_ORDERS + 1):
@@ -510,7 +510,7 @@ class MemBuddy(MemManager):
return count
def free_bytes(self) -> t.CSizeT:
# 统计所有空闲块的总字节数
# Count total bytes in all free blocks for status statistics
total: t.CSizeT = 0
i: t.CInt
for i in range(MEMBUDDY_MAX_ORDERS + 1):
@@ -522,11 +522,11 @@ class MemBuddy(MemManager):
return total
def used_bytes(self) -> t.CSizeT:
# 已使用字节数 = 可用区总大小 - 空闲字节数
# Used bytes = total usable region size - free bytes in all free blocks
return self.usable_size - self.free_bytes()
def dump_stats(self, label: t.CChar | t.CPtr):
# 打印内存使用统计
# Print memory usage statistics
fb: t.CSizeT = self.free_bytes()
ub: t.CSizeT = self.usable_size - fb
stdio.printf("[MEM] %s: total=%zu used=%zu (%zu%%) free=%zu free_blocks=%zu\n",
@@ -535,7 +535,7 @@ class MemBuddy(MemManager):
fb, self.free_count())
def self_check(self) -> t.CInt:
# 验证伙伴分配器内部一致性,返回 0=OK非 0=损坏
# Validate buddy allocator internal consistency, return 0=OK, non-0=damage
if self.usable is None:
return 0
i: t.CInt
@@ -543,12 +543,12 @@ class MemBuddy(MemManager):
head_val: t.CUInt64T = self.free_lists[i]
cur: t.CVoid | t.CPtr = t.CVoid(head_val, t.CPtr)
while t.CUInt64T(cur) != 0:
# 检查指针在可用区内
# Check pointer is in usable region range
if t.CUInt64T(cur) < t.CUInt64T(self.usable):
return 1
if t.CUInt64T(cur) >= t.CUInt64T(self.usable) + self.usable_size:
return 2
# 检查对齐order i 的块必须按 _block_size_at_order(i) 对齐
# Check alignment: order i blocks must be aligned to size _block_size_at_order(i)
offset: t.CSizeT = t.CUInt64T(cur) - t.CUInt64T(self.usable)
bs: t.CSizeT = _block_size_at_order(i)
if offset % bs != 0: