Files
llgo/c/bdwgc/_test/bdwgc.go
2024-07-09 01:33:48 +08:00

102 lines
2.2 KiB
Go

package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/bdwgc"
"github.com/goplus/llgo/c/bdwgc/_test/testing"
)
// ------ Test malloc ------
func TestMalloc(t *testing.T) {
pn := (*int)(bdwgc.Malloc(unsafe.Sizeof(int(0))))
*pn = 1 << 30
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
pl := (*int64)(bdwgc.Realloc(c.Pointer(pn), unsafe.Sizeof(int64(0))))
*pl = 1 << 60
c.Printf(c.Str("value: %lld, %llx, %p, %p\n"), *pl, *pl, pl, &pl)
bdwgc.Free(c.Pointer(pl))
}
// ------ Test finalizer ------
const (
RETURN_VALUE_FREED = 1 << 31
)
var called uint = 0
func setReturnValueFreed(pobj c.Pointer, clientData c.Pointer) {
called |= RETURN_VALUE_FREED
c.Printf(c.Str("called: %x\n"), called)
}
func setLoopValueFreed(pobj c.Pointer, clientData c.Pointer) {
pmask := (*uint)(clientData)
called |= *pmask
c.Printf(c.Str("called: %x\n"), called)
}
func isCalled(mask uint) bool {
return called&mask != 0
}
func returnValue() *int {
pn := bdwgc.Malloc(unsafe.Sizeof(int(0)))
bdwgc.RegisterFinalizer(pn, setReturnValueFreed, nil, nil, nil)
return (*int)(pn)
}
func callFunc() {
pn := returnValue()
*pn = 1 << 30
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
bdwgc.Gcollect()
check(!isCalled(RETURN_VALUE_FREED), c.Str("finalizer should not be called"))
}
func loop() {
for i := 0; i < 5; i++ {
p := bdwgc.Malloc(unsafe.Sizeof(int(0)))
pn := (*int)(p)
*pn = i
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
pflag := (*uint)(c.Malloc(unsafe.Sizeof(uint(0))))
*pflag = 1 << i
bdwgc.RegisterFinalizer(p, setLoopValueFreed, c.Pointer(pflag), nil, nil)
bdwgc.Gcollect()
check(!isCalled(1<<i), c.Str("finalizer should not be called"))
for j := 0; j < i; j++ {
check(isCalled(1<<j), c.Str("finalizers of previous objects should be called"))
}
}
}
// Clear stack to avoid reference
func clearStack() {
p := c.Alloca(128)
c.Memset(p, 0, 128)
}
func check(b bool, msg *c.Char) {
if !b {
c.Printf(c.Str("check failed: %s\n"), msg)
panic("check failed")
}
}
func TestFinalizer(t *testing.T) {
bdwgc.Init()
callFunc()
clearStack()
bdwgc.Gcollect()
check(isCalled(RETURN_VALUE_FREED), c.Str("finalizer should be called"))
loop()
}