Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"math"
"reflect"
"runtime"
"sync"
"unsafe"

"github.com/ebitengine/purego/internal/strings"
Expand All @@ -22,10 +21,6 @@ const (
align8ByteSize = 8 // 8-byte alignment boundary
)

var thePool = sync.Pool{New: func() any {
return new(syscall15Args)
}}

// RegisterLibFunc is a wrapper around RegisterFunc that uses the C function returned from Dlsym(handle, name).
// It panics if it can't find the name symbol.
func RegisterLibFunc(fptr any, handle uintptr, name string) {
Expand Down Expand Up @@ -310,8 +305,7 @@ func RegisterFunc(fptr any, cfn uintptr) {
keepAlive = addValue(v, keepAlive, addInt, addFloat, addStack, &numInts, &numFloats, &numStack)
}

syscall := thePool.Get().(*syscall15Args)
defer thePool.Put(syscall)
syscall := &syscall15Args{}

if runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x" {
syscall.Set(cfn, sysargs[:], floats[:], 0)
Expand All @@ -321,7 +315,6 @@ func RegisterFunc(fptr any, cfn uintptr) {
syscall.Set(cfn, sysargs[:], floats[:], arm64_r8)
runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall))
} else {
*syscall = syscall15Args{}
// This is a fallback for Windows amd64, 386, and arm. Note this may not support floats
syscall.a1, syscall.a2, _ = syscall_syscall15X(cfn, sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4],
sysargs[5], sysargs[6], sysargs[7], sysargs[8], sysargs[9], sysargs[10], sysargs[11],
Expand Down
35 changes: 35 additions & 0 deletions func_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"runtime"
"strings"
"sync"
"testing"
"unsafe"

Expand All @@ -35,6 +36,40 @@ func getSystemLibrary() (string, error) {
}
}

func TestRegisterFunc_ConcurrentPointerReturn(t *testing.T) {
library, err := getSystemLibrary()
if err != nil {
t.Fatalf("couldn't get system library: %s", err)
}
libc, err := load.OpenLibrary(library)
if err != nil {
t.Fatalf("failed to dlopen: %s", err)
}

var alloc func(uint64) *byte
var free func(*byte)
purego.RegisterLibFunc(&alloc, libc, "malloc")
purego.RegisterLibFunc(&free, libc, "free")

var wg sync.WaitGroup

for i := 0; i < runtime.NumCPU(); i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 0; j < 400_000; j++ {
ptr := alloc(5)
if ptr == nil {
continue
}
free(ptr)
}
}(i)
}

Comment on lines +54 to +69
wg.Wait()
}

func TestRegisterFunc(t *testing.T) {
library, err := getSystemLibrary()
if err != nil {
Expand Down
5 changes: 1 addition & 4 deletions syscall_sysv.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ import (
var syscall15XABI0 uintptr

func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
args := thePool.Get().(*syscall15Args)
defer thePool.Put(args)

*args = syscall15Args{
args := &syscall15Args{
fn: fn,
a1: a1, a2: a2, a3: a3, a4: a4, a5: a5, a6: a6, a7: a7, a8: a8,
a9: a9, a10: a10, a11: a11, a12: a12, a13: a13, a14: a14, a15: a15,
Expand Down
Loading