From 8e66091dd215c268e483ee73129453440d5a33bf Mon Sep 17 00:00:00 2001 From: Aofei Sheng Date: Thu, 15 Aug 2024 18:40:17 +0800 Subject: [PATCH] gc: fix missing pthread registration causing unknown thread error - Use `GC_pthread_create` instead of `pthread_create` when GC is enabled. --- c/pthread/_pthread/pthread_gc.c | 11 +++++++++++ c/pthread/_pthread/pthread_nogc.c | 9 +++++++++ c/pthread/pthread.go | 8 ++------ c/pthread/pthread_gc.go | 25 +++++++++++++++++++++++++ c/pthread/pthread_nogc.go | 25 +++++++++++++++++++++++++ cl/_testgo/goroutine/out.ll | 4 ++-- ssa/goroutine.go | 2 +- 7 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 c/pthread/_pthread/pthread_gc.c create mode 100644 c/pthread/_pthread/pthread_nogc.c create mode 100644 c/pthread/pthread_gc.go create mode 100644 c/pthread/pthread_nogc.go diff --git a/c/pthread/_pthread/pthread_gc.c b/c/pthread/_pthread/pthread_gc.c new file mode 100644 index 00000000..79e2427e --- /dev/null +++ b/c/pthread/_pthread/pthread_gc.c @@ -0,0 +1,11 @@ +#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/pthread_nogc.c b/c/pthread/_pthread/pthread_nogc.c new file mode 100644 index 00000000..fd352eea --- /dev/null +++ b/c/pthread/_pthread/pthread_nogc.c @@ -0,0 +1,9 @@ +#include + +int llgoPthreadCreate(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { + return pthread_create(thread, attr, start_routine, arg); +} + +int llgoPthreadJoin(pthread_t thread, void **retval) { + return pthread_join(thread, retval); +} diff --git a/c/pthread/pthread.go b/c/pthread/pthread.go index 3f5a95aa..49ac2877 100644 --- a/c/pthread/pthread.go +++ b/c/pthread/pthread.go @@ -22,10 +22,6 @@ import ( "github.com/goplus/llgo/c" ) -const ( - LLGoPackage = "decl" -) - func __noop__() c.Int { return 0 } @@ -65,7 +61,7 @@ type Thread = *aThread // // See https://man7.org/linux/man-pages/man3/pthread_create.3.html // -//go:linkname Create C.pthread_create +//go:linkname Create C.llgoPthreadCreate func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int // The pthread_join() function waits for the thread specified by @@ -86,7 +82,7 @@ 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.pthread_join +//go:linkname Join C.llgoPthreadJoin func Join(thread Thread, retval *c.Pointer) c.Int // The pthread_exit() function terminates the calling thread and diff --git a/c/pthread/pthread_gc.go b/c/pthread/pthread_gc.go new file mode 100644 index 00000000..c3d79f6c --- /dev/null +++ b/c/pthread/pthread_gc.go @@ -0,0 +1,25 @@ +//go:build !nogc +// +build !nogc + +/* + * 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 pthread + +const ( + LLGoFiles = "$(pkg-config --cflags bdw-gc): _pthread/pthread_gc.c" + LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc" +) diff --git a/c/pthread/pthread_nogc.go b/c/pthread/pthread_nogc.go new file mode 100644 index 00000000..bbf3549e --- /dev/null +++ b/c/pthread/pthread_nogc.go @@ -0,0 +1,25 @@ +//go:build nogc +// +build nogc + +/* + * 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 pthread + +const ( + LLGoFiles = "_pthread/pthread_nogc.c" + LLGoPackage = "link" +) diff --git a/cl/_testgo/goroutine/out.ll b/cl/_testgo/goroutine/out.ll index ef8f5b75..410ca1a0 100644 --- a/cl/_testgo/goroutine/out.ll +++ b/cl/_testgo/goroutine/out.ll @@ -51,7 +51,7 @@ _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 @pthread_create(ptr %16, ptr null, ptr @"main._llgo_routine$1", ptr %13) + %17 = call i32 @llgoPthreadCreate(ptr %16, ptr null, ptr @"main._llgo_routine$1", ptr %13) br label %_llgo_3 _llgo_1: ; preds = %_llgo_3 @@ -104,7 +104,7 @@ _llgo_0: declare void @free(ptr) -declare i32 @pthread_create(ptr, ptr, ptr, ptr) +declare i32 @llgoPthreadCreate(ptr, ptr, ptr, ptr) declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") diff --git a/ssa/goroutine.go b/ssa/goroutine.go index d2bf3787..293f6115 100644 --- a/ssa/goroutine.go +++ b/ssa/goroutine.go @@ -51,7 +51,7 @@ func (p Program) tyPthreadCreate() *types.Signature { } func (b Builder) pthreadCreate(pp, attr, routine, arg Expr) Expr { - fn := b.Pkg.cFunc("pthread_create", b.Prog.tyPthreadCreate()) + fn := b.Pkg.cFunc("llgoPthreadCreate", b.Prog.tyPthreadCreate()) return b.Call(fn, pp, attr, routine, arg) }