diff --git a/c/pthread/_wrap/pthread_gc.c b/c/pthread/_wrap/pthread_gc.c deleted file mode 100644 index 79e2427e..00000000 --- a/c/pthread/_wrap/pthread_gc.c +++ /dev/null @@ -1,11 +0,0 @@ -#define GC_THREADS -#include -#include - -int llgoPthreadCreate(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - return GC_pthread_create(thread, attr, start_routine, arg); -} - -int llgoPthreadJoin(pthread_t thread, void **retval) { - return GC_pthread_join(thread, retval); -} diff --git a/c/pthread/pthread.go b/c/pthread/pthread.go index eb72d6f8..8fb1c48f 100644 --- a/c/pthread/pthread.go +++ b/c/pthread/pthread.go @@ -32,6 +32,9 @@ type aThread struct { Unused [8]byte } +//llgo:type C +type RoutineFunc func(c.Pointer) c.Pointer + // Thread represents a POSIX thread. type Thread = *aThread diff --git a/c/pthread/pthread_gc.go b/c/pthread/pthread_gc.go index 28b4e87b..1150e1a8 100644 --- a/c/pthread/pthread_gc.go +++ b/c/pthread/pthread_gc.go @@ -26,7 +26,6 @@ import ( ) const ( - LLGoFiles = "$(pkg-config --cflags bdw-gc): _wrap/pthread_gc.c" LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc" ) @@ -56,8 +55,8 @@ const ( // // See https://man7.org/linux/man-pages/man3/pthread_create.3.html // -//go:linkname Create C.llgoPthreadCreate -func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int +//go:linkname Create C.GC_pthread_create +func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int // The pthread_join() function waits for the thread specified by // thread to terminate. If that thread has already terminated, then @@ -77,5 +76,5 @@ func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg // // See https://man7.org/linux/man-pages/man3/pthread_join.3.html // -//go:linkname Join C.llgoPthreadJoin +//go:linkname Join C.GC_pthread_join func Join(thread Thread, retval *c.Pointer) c.Int diff --git a/c/pthread/pthread_nogc.go b/c/pthread/pthread_nogc.go index 9e1da640..97a6d216 100644 --- a/c/pthread/pthread_nogc.go +++ b/c/pthread/pthread_nogc.go @@ -56,7 +56,7 @@ const ( // See https://man7.org/linux/man-pages/man3/pthread_create.3.html // //go:linkname Create C.pthread_create -func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int +func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int // The pthread_join() function waits for the thread specified by // thread to terminate. If that thread has already terminated, then diff --git a/cl/_testgo/goroutine/out.ll b/cl/_testgo/goroutine/out.ll index 410ca1a0..97c5f0f9 100644 --- a/cl/_testgo/goroutine/out.ll +++ b/cl/_testgo/goroutine/out.ll @@ -2,6 +2,7 @@ source_filename = "main" %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } +%"github.com/goplus/llgo/c/pthread.RoutineFunc" = type { ptr, ptr } @"main.init$guard" = global i1 false, align 1 @__llgo_argc = global i32 0, align 4 @@ -51,25 +52,31 @@ _llgo_0: %15 = getelementptr inbounds { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" }, ptr %13, i32 0, i32 1 store %"github.com/goplus/llgo/internal/runtime.String" %12, ptr %15, align 8 %16 = alloca i8, i64 8, align 1 - %17 = call i32 @llgoPthreadCreate(ptr %16, ptr null, ptr @"main._llgo_routine$1", ptr %13) + %17 = alloca %"github.com/goplus/llgo/c/pthread.RoutineFunc", align 8 + %18 = getelementptr inbounds %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr %17, i32 0, i32 0 + store ptr @"__llgo_stub.main._llgo_routine$1", ptr %18, align 8 + %19 = getelementptr inbounds %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr %17, i32 0, i32 1 + store ptr null, ptr %19, align 8 + %20 = load %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr %17, align 8 + %21 = call i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr %16, ptr null, %"github.com/goplus/llgo/c/pthread.RoutineFunc" %20, ptr %13) br label %_llgo_3 _llgo_1: ; preds = %_llgo_3 - %18 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 0 - store ptr @1, ptr %19, align 8 - %20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 1 - store i64 1, ptr %20, align 4 - %21 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %18, align 8 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %21) + %22 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 0 + store ptr @1, ptr %23, align 8 + %24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 1 + store i64 1, ptr %24, align 4 + %25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %22, align 8 + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %25) br label %_llgo_3 _llgo_2: ; preds = %_llgo_3 ret i32 0 _llgo_3: ; preds = %_llgo_1, %_llgo_0 - %22 = load i1, ptr %2, align 1 - br i1 %22, label %_llgo_2, label %_llgo_1 + %26 = load i1, ptr %2, align 1 + br i1 %26, label %_llgo_2, label %_llgo_1 } define void @"main.main$1"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) { @@ -104,7 +111,13 @@ _llgo_0: declare void @free(ptr) -declare i32 @llgoPthreadCreate(ptr, ptr, ptr, ptr) +declare i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr, ptr, %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr) + +define linkonce ptr @"__llgo_stub.main._llgo_routine$1"(ptr %0, ptr %1) { +_llgo_0: + %2 = tail call ptr @"main._llgo_routine$1"(ptr %1) + ret ptr %2 +} declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") diff --git a/internal/runtime/z_thread.go b/internal/runtime/z_thread.go new file mode 100644 index 00000000..72d8687b --- /dev/null +++ b/internal/runtime/z_thread.go @@ -0,0 +1,28 @@ +/* + * 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 runtime + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/pthread" +) + +func CreateThread(th *pthread.Thread, attr *pthread.Attr, routine pthread.RoutineFunc, arg c.Pointer) c.Int { + return pthread.Create(th, attr, routine, arg) +} diff --git a/ssa/goroutine.go b/ssa/goroutine.go index 293f6115..10aed50a 100644 --- a/ssa/goroutine.go +++ b/ssa/goroutine.go @@ -36,22 +36,8 @@ func (p Program) tyRoutine() *types.Signature { return p.routineTy } -// func(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int -func (p Program) tyPthreadCreate() *types.Signature { - if p.createThdTy == nil { - paramPPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtrPtr().raw.Type) - paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type) - paramRoutine := types.NewParam(token.NoPos, nil, "", p.tyRoutine()) - paramCInt := types.NewParam(token.NoPos, nil, "", p.CInt().raw.Type) - params := types.NewTuple(paramPPtr, paramPtr, paramRoutine, paramPtr) - results := types.NewTuple(paramCInt) - p.createThdTy = types.NewSignatureType(nil, nil, nil, params, results, false) - } - return p.createThdTy -} - func (b Builder) pthreadCreate(pp, attr, routine, arg Expr) Expr { - fn := b.Pkg.cFunc("llgoPthreadCreate", b.Prog.tyPthreadCreate()) + fn := b.Pkg.rtFunc("CreateThread") return b.Call(fn, pp, attr, routine, arg) } diff --git a/ssa/package.go b/ssa/package.go index ceb10af0..2e9d6da4 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -183,7 +183,6 @@ type aProgram struct { freeTy *types.Signature createKeyTy *types.Signature - createThdTy *types.Signature getSpecTy *types.Signature setSpecTy *types.Signature routineTy *types.Signature