cl: compileFuncDecl/funcName fix; patch library: sync

This commit is contained in:
xushiwei
2024-06-17 18:32:58 +08:00
parent bec29f99e6
commit 98f3e45c0a
6 changed files with 76 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
#include <pthread.h>
pthread_once_t llgoSyncOnceInitVal() {
pthread_once_t initVal = PTHREAD_ONCE_INIT;
return initVal;
}
// -----------------------------------------------------------------------------
pthread_once_t llgoSyncOnceInitVal = PTHREAD_ONCE_INIT;
// -----------------------------------------------------------------------------

View File

@@ -30,12 +30,15 @@ const (
LLGoPackage = "link"
)
// -----------------------------------------------------------------------------
// Once is an object that will perform exactly one action.
type Once C.pthread_once_t
//go:linkname onceInitVal C.llgoSyncOnceInitVal
func onceInitVal() Once
var OnceInit = onceInitVal()
//go:linkname OnceInit llgoSyncOnceInitVal
var OnceInit Once
// llgo:link (*Once).Do C.pthread_once
func (o *Once) Do(f func()) c.Int { return 0 }
// -----------------------------------------------------------------------------

18
cl/_testlibgo/sync/in.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import (
"sync"
)
var once sync.Once
func f(s string) {
once.Do(func() {
println(s)
})
}
func main() {
f("Do once")
f("Do twice")
}

View File

@@ -279,6 +279,9 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
}
b.EndBuild()
})
for _, af := range f.AnonFuncs {
p.compileFuncDecl(pkg, af)
}
}
return fn, nil, goFunc
}

View File

@@ -336,8 +336,14 @@ func typesFuncName(pkgPath string, fn *types.Func) (fullName, inPkgName string)
// - func: pkg.name
// - method: pkg.(T).name, pkg.(*T).name
func funcName(pkg *types.Package, fn *ssa.Function) string {
sig := fn.Signature
return llssa.FuncName(pkg, fn.Name(), sig.Recv())
var recv *types.Var
parent := fn.Parent()
if parent != nil { // closure in method
recv = parent.Signature.Recv()
} else {
recv = fn.Signature.Recv()
}
return llssa.FuncName(pkg, fn.Name(), recv)
}
func checkCgo(fnName string) bool {

View File

@@ -18,5 +18,39 @@ package sync
// llgo:skipall
import (
_ "unsafe"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/pthread"
"github.com/goplus/llgo/c/pthread/sync"
)
const (
LLGoPackage = "link"
)
// -----------------------------------------------------------------------------
var onceParam pthread.Key
func init() {
onceParam.Create(nil)
}
type Once sync.Once
func (o *Once) Do(f func()) {
ptr := c.Malloc(unsafe.Sizeof(f))
*(*func())(ptr) = f
onceParam.Set(ptr)
if *(*c.Long)(unsafe.Pointer(o)) == 0 { // try init
*(*sync.Once)(o) = sync.OnceInit
}
(*sync.Once)(o).Do(func() {
ptr := onceParam.Get()
(*(*func())(ptr))()
c.Free(ptr)
})
}
// -----------------------------------------------------------------------------