139 lines
4.1 KiB
Python
139 lines
4.1 KiB
Python
import stdio
|
||
import t, c
|
||
import memhub
|
||
import stdlib
|
||
import string
|
||
|
||
|
||
# ============================================================
|
||
# memhub_test - 内存管理库测试
|
||
#
|
||
# 测试 MemPool/MemBuddy 的 alloc/free/reset/realloc,
|
||
# 以及 MemManager 多态虚分派(通过 __vtable__ 调用子类方法)。
|
||
# ============================================================
|
||
|
||
|
||
def memhub_test() -> int:
|
||
stdio.printf("memhub: === Test Start ===\n")
|
||
|
||
# === Test 1: MemPool (bump allocator) ===
|
||
# MemPool 是 arena bump 分配器,不支持单个 free,reset 一次性回收
|
||
stdio.printf("memhub: === Test 1: MemPool ===\n")
|
||
|
||
arena1: bytes = stdlib.malloc(4096)
|
||
if arena1 is None:
|
||
stdio.printf("[FAIL] malloc arena1\n")
|
||
return 1
|
||
|
||
pool: memhub.MemPool | t.CPtr = memhub.MemPool(arena1, 4096)
|
||
|
||
p1: bytes = pool.alloc(64)
|
||
if p1 is None:
|
||
stdio.printf("[FAIL] MemPool.alloc(64)\n")
|
||
return 1
|
||
|
||
p2: bytes = pool.alloc(128)
|
||
if p2 is None:
|
||
stdio.printf("[FAIL] MemPool.alloc(128)\n")
|
||
return 1
|
||
|
||
stdio.printf("memhub: MemPool alloc ok\n")
|
||
|
||
# 写入验证
|
||
string.memset(p1, 66, 64)
|
||
if p1[0] != 66:
|
||
stdio.printf("[FAIL] MemPool write/read p1[0]=%d\n", p1[0])
|
||
return 1
|
||
|
||
# reset 后可以重新分配
|
||
pool.reset()
|
||
p3: bytes = pool.alloc(64)
|
||
if p3 is None:
|
||
stdio.printf("[FAIL] MemPool.alloc after reset\n")
|
||
return 1
|
||
stdio.printf("memhub: MemPool reset ok\n")
|
||
|
||
# === Test 2: MemBuddy (buddy system) ===
|
||
# MemBuddy 是伙伴系统,支持 alloc/free/realloc 合并
|
||
stdio.printf("memhub: === Test 2: MemBuddy ===\n")
|
||
|
||
arena2: bytes = stdlib.malloc(65536)
|
||
if arena2 is None:
|
||
stdio.printf("[FAIL] malloc arena2\n")
|
||
return 1
|
||
|
||
buddy: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena2, 65536)
|
||
|
||
b1: bytes = buddy.alloc(64)
|
||
if b1 is None:
|
||
stdio.printf("[FAIL] MemBuddy.alloc(64)\n")
|
||
return 1
|
||
|
||
b2: bytes = buddy.alloc(256)
|
||
if b2 is None:
|
||
stdio.printf("[FAIL] MemBuddy.alloc(256)\n")
|
||
return 1
|
||
stdio.printf("memhub: MemBuddy alloc ok\n")
|
||
|
||
# 写入验证
|
||
string.memset(b1, 85, 64)
|
||
if b1[0] != 85:
|
||
stdio.printf("[FAIL] MemBuddy write/read b1[0]=%d\n", b1[0])
|
||
return 1
|
||
|
||
# free b1 后重新 alloc,应能回收内存
|
||
buddy.free(b1)
|
||
b3: bytes = buddy.alloc(64)
|
||
if b3 is None:
|
||
stdio.printf("[FAIL] MemBuddy.alloc after free\n")
|
||
return 1
|
||
stdio.printf("memhub: MemBuddy free/alloc ok\n")
|
||
|
||
# === Test 3: MemBuddy realloc ===
|
||
# realloc 扩展内存,验证数据保持
|
||
stdio.printf("memhub: === Test 3: MemBuddy realloc ===\n")
|
||
|
||
b4: bytes = buddy.alloc(32)
|
||
if b4 is None:
|
||
stdio.printf("[FAIL] MemBuddy.alloc(32) for realloc\n")
|
||
return 1
|
||
string.memset(b4, 171, 32)
|
||
|
||
# realloc 到更大(32 -> 128)
|
||
b4_new: bytes = buddy.realloc(b4, 32, 128)
|
||
if b4_new is None:
|
||
stdio.printf("[FAIL] MemBuddy.realloc\n")
|
||
return 1
|
||
|
||
# 验证数据保持(前32字节应保持 171=0xAB)
|
||
# 注意:b4_new[0] 是 i8(有符号),0xAB=-85,需 & 255 转无符号再比较
|
||
if (b4_new[0] & 255) != 171:
|
||
stdio.printf("[FAIL] MemBuddy.realloc data lost b4_new[0]=%d\n", b4_new[0])
|
||
return 1
|
||
stdio.printf("memhub: MemBuddy realloc ok\n")
|
||
|
||
# === Test 4: Polymorphism (MemManager virtual dispatch) ===
|
||
# 用 MemManager 指针调用 MemBuddy 的 alloc,验证虚分派
|
||
stdio.printf("memhub: === Test 4: Polymorphism ===\n")
|
||
|
||
mgr: memhub.MemManager | t.CPtr = (memhub.MemManager | t.CPtr)(buddy)
|
||
if mgr is None:
|
||
stdio.printf("[FAIL] MemManager cast\n")
|
||
return 1
|
||
|
||
# 通过 MemManager 指针调用 alloc(虚分派到 MemBuddy.alloc)
|
||
b5: bytes = mgr.alloc(64)
|
||
if b5 is None:
|
||
stdio.printf("[FAIL] MemManager.alloc (virtual dispatch)\n")
|
||
return 1
|
||
|
||
# 验证写入正常
|
||
string.memset(b5, 99, 64)
|
||
if b5[0] != 99:
|
||
stdio.printf("[FAIL] MemManager.alloc write/read\n")
|
||
return 1
|
||
stdio.printf("memhub: Polymorphism ok\n")
|
||
|
||
stdio.printf("memhub: === All Tests Passed ===\n")
|
||
return 0
|