diff --git a/c/pthread/sync/_pthd/pthd.c b/c/pthread/sync/_pthd/pthd.c new file mode 100644 index 00000000..453bbe4d --- /dev/null +++ b/c/pthread/sync/_pthd/pthd.c @@ -0,0 +1,6 @@ +#include + +pthread_once_t llgoSyncOnceInitVal() { + pthread_once_t initVal = PTHREAD_ONCE_INIT; + return initVal; +} diff --git a/c/pthread/sync/llgo_autogen.lla b/c/pthread/sync/llgo_autogen.lla new file mode 100644 index 00000000..e1b6d0eb Binary files /dev/null and b/c/pthread/sync/llgo_autogen.lla differ diff --git a/c/pthread/sync/sync.go b/c/pthread/sync/sync.go new file mode 100644 index 00000000..2ddf2ee9 --- /dev/null +++ b/c/pthread/sync/sync.go @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sync + +// #include +import "C" + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" +) + +const ( + LLGoFiles = "_pthd/pthd.c" + LLGoPackage = "link" +) + +type Once C.pthread_once_t + +//go:linkname onceInitVal C.llgoSyncOnceInitVal +func onceInitVal() Once + +var OnceInit = onceInitVal() + +// llgo:link (*Once).Do C.pthread_once +func (o *Once) Do(f func()) c.Int { return 0 } diff --git a/cl/_testlibc/once/in.go b/cl/_testlibc/once/in.go new file mode 100644 index 00000000..e7247122 --- /dev/null +++ b/cl/_testlibc/once/in.go @@ -0,0 +1,19 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/pthread/sync" +) + +var once sync.Once = sync.OnceInit + +func f() { + once.Do(func() { + c.Printf(c.Str("Do once\n")) + }) +} + +func main() { + f() + f() +} diff --git a/cl/_testlibc/once/out.ll b/cl/_testlibc/once/out.ll new file mode 100644 index 00000000..05ffcbc4 --- /dev/null +++ b/cl/_testlibc/once/out.ll @@ -0,0 +1,55 @@ +; ModuleID = 'main' +source_filename = "main" + +%"github.com/goplus/llgo/c/pthread/sync.Once" = type { i64, [8 x i8] } + +@"main.init$guard" = global i1 false, align 1 +@main.once = global %"github.com/goplus/llgo/c/pthread/sync.Once" zeroinitializer, align 8 +@"github.com/goplus/llgo/c/pthread/sync.OnceInit" = external global %"github.com/goplus/llgo/c/pthread/sync.Once", align 8 +@__llgo_argc = global i32 0, align 4 +@__llgo_argv = global ptr null, align 8 +@0 = private unnamed_addr constant [9 x i8] c"Do once\0A\00", align 1 + +define void @main.f() { +_llgo_0: + %0 = call i32 @pthread_once(ptr @main.once, ptr @"main.f$1") + ret void +} + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + %1 = load %"github.com/goplus/llgo/c/pthread/sync.Once", ptr @"github.com/goplus/llgo/c/pthread/sync.OnceInit", align 4 + store %"github.com/goplus/llgo/c/pthread/sync.Once" %1, ptr @main.once, align 4 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define i32 @main(i32 %0, ptr %1) { +_llgo_0: + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + call void @main.f() + call void @main.f() + ret i32 0 +} + +declare i32 @pthread_once(ptr, ptr) + +define void @"main.f$1"() { +_llgo_0: + %0 = call i32 (ptr, ...) @printf(ptr @0) + ret void +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare i32 @printf(ptr, ...) diff --git a/internal/build/build.go b/internal/build/build.go index d115f7c6..e1ed2f73 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -597,7 +597,7 @@ func llgoPkgLinkFiles(pkg *packages.Package, llFile string, procFile func(linkFi // files = "file1; file2; ..." func clFiles(files string, pkg *packages.Package, procFile func(linkFile string), verbose bool) { - dir := filepath.Dir(pkg.CompiledGoFiles[0]) + dir := filepath.Dir(pkg.GoFiles[0]) expFile := pkg.ExportFile for _, file := range strings.Split(files, ";") { cFile := filepath.Join(dir, strings.TrimSpace(file))