Skip to content
Open
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
8 changes: 1 addition & 7 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(syscallArgs)
}}

// 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 @@ -323,13 +318,12 @@ func RegisterFunc(fptr any, cfn uintptr) {
var syscall *syscallArgs
if runtime.GOOS == "windows" && runtime.GOARCH != "arm64" {
// Windows amd64, 386, and arm use syscall.SyscallN.
syscall = thePool.Get().(*syscallArgs)
syscall = &syscallArgs{}
syscall.a1, syscall.a2, _ = syscall_syscallN(cfn, sysargs[:numStack]...)
syscall.f1 = syscall.a2 // on amd64 a2 stores the float return. On 32bit platforms floats aren't support
} else {
syscall = syscall_SyscallN(cfn, sysargs[:], floats[:], arm64_r8)
}
defer thePool.Put(syscall)
if ty.NumOut() == 0 {
return nil
}
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++ {
Comment on lines +54 to +60
ptr := alloc(5)
if ptr == nil {
continue
}
free(ptr)
}
Comment on lines +49 to +66
}(i)
}

wg.Wait()
}

func TestRegisterFunc(t *testing.T) {
library, err := getSystemLibrary()
if err != nil {
Expand Down
4 changes: 1 addition & 3 deletions syscall.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ type syscallArgs struct {
}

func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs {
s := thePool.Get().(*syscallArgs)
*s = syscallArgs{
s := &syscallArgs{
fn: fn,
a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3],
a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7],
Expand Down Expand Up @@ -79,6 +78,5 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) {
var floats [maxArgs]uintptr
copy(floats[:], tmp[:])
s := syscall_SyscallN(fn, tmp[:], floats[:], 0)
defer thePool.Put(s)
return s.a1, s.a2, s.a3
}
4 changes: 1 addition & 3 deletions syscall_32bit.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ type syscallArgs struct {
}

func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs {
s := thePool.Get().(*syscallArgs)
*s = syscallArgs{
s := &syscallArgs{
fn: fn,
a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3],
a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7],
Expand Down Expand Up @@ -81,6 +80,5 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) {
var floats [16]uintptr
copy(floats[:], tmp[:16])
s := syscall_SyscallN(fn, tmp[:], floats[:], 0)
defer thePool.Put(s)
return s.a1, s.a2, s.a3
}
4 changes: 1 addition & 3 deletions syscall_ppc64le.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ type syscallArgs struct {
}

func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs {
s := thePool.Get().(*syscallArgs)
*s = syscallArgs{
s := &syscallArgs{
fn: fn,
a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3],
a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7],
Expand Down Expand Up @@ -67,6 +66,5 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) {
var floats [maxArgs]uintptr
copy(floats[:], tmp[:])
s := syscall_SyscallN(fn, tmp[:], floats[:], 0)
defer thePool.Put(s)
return s.a1, s.a2, s.a3
}
Loading