Skip to content

purego: remove pooling of syscall#452

Merged
TotallyGamerJet merged 2 commits into
ebitengine:mainfrom
TotallyGamerJet:#451_memory_race
May 24, 2026
Merged

purego: remove pooling of syscall#452
TotallyGamerJet merged 2 commits into
ebitengine:mainfrom
TotallyGamerJet:#451_memory_race

Conversation

@TotallyGamerJet
Copy link
Copy Markdown
Collaborator

What issue is this addressing?

Closes #451

What type of issue is this addressing?

Bug

What this PR does | solves

This removes the pool which was occasionally causing issues. Unfortunately this does increase the memory cost of each call

Copy link
Copy Markdown
Member

@hajimehoshi hajimehoshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

My understanding is, introducing a pool broke some invariations for nosplit functions: is that correct?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the shared sync.Pool used for *syscallArgs during FFI calls, addressing a concurrency regression where concurrent calls could observe corrupted/swapped return values (issue #451). The change trades reduced allocations for correctness by ensuring each call uses a distinct syscallArgs instance.

Changes:

  • Remove sync.Pool-backed reuse of *syscallArgs and allocate fresh syscallArgs per call path.
  • Update syscall dispatch implementations (syscall.go, syscall_32bit.go, syscall_ppc64le.go) to no longer Get/Put pooled structs.
  • Add a new concurrent malloc/free test intended to exercise the pointer-return path under contention.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
func.go Removes global sync.Pool and stops pooling *syscallArgs in RegisterFunc call paths.
syscall.go Stops pooling in SyscallN path by allocating a fresh syscallArgs.
syscall_32bit.go Same as above for 32-bit/arm builds.
syscall_ppc64le.go Same as above for ppc64le build path.
func_test.go Adds a new concurrency test invoking malloc/free across goroutines.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread func_test.go Outdated
Comment thread func_test.go
Comment on lines +49 to +66
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)
}
Comment thread func_test.go
Comment on lines +54 to +60
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++ {
@hajimehoshi
Copy link
Copy Markdown
Member

Still LGTM (it's up to you to address on the Codex suggestions)

@TotallyGamerJet
Copy link
Copy Markdown
Collaborator Author

I don't think it's necessary to make those changes

@hajimehoshi
Copy link
Copy Markdown
Member

hajimehoshi commented May 24, 2026

Sure. Let's merge this then.

@TotallyGamerJet
Copy link
Copy Markdown
Collaborator Author

@hajimehoshi still waiting on approval

Copy link
Copy Markdown
Member

@hajimehoshi hajimehoshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (Sorry I think I have already approved)

@TotallyGamerJet TotallyGamerJet merged commit 11272d2 into ebitengine:main May 24, 2026
42 checks passed
hajimehoshi added a commit that referenced this pull request May 24, 2026
(cherry picked from commit 11272d2)

Co-authored-by: TotallyGamerJet <TotallyGamerJet@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

func.go: Concurrent calls swap return-value pointers (sync.Pool of *syscall15Args, regressed in #282)

3 participants