Skip to content

runtime: store goroutine state behind pthread-key getg#2090

Open
cpunion wants to merge 1 commit into
xgo-dev:mainfrom
cpunion:codex/runtime-g-state-gls
Open

runtime: store goroutine state behind pthread-key getg#2090
cpunion wants to merge 1 commit into
xgo-dev:mainfrom
cpunion:codex/runtime-g-state-gls

Conversation

@cpunion

@cpunion cpunion commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Problem

LLGo keeps goroutine-owned runtime state in several pthread-backed locations:

  • the active defer chain has its own pthread key;
  • panic/recover and Goexit use additional pthread keys;
  • main-goroutine detection uses a pthread identity comparison.

That splits one goroutine's state across unrelated lifetime mechanisms and makes each new field add more key management.

Change

Introduce one runtime g and one getg path:

type g struct {
	defer_ *Defer
	panic_ unsafe.Pointer
	goexit bool
	isMain bool
}

Hosted LLGo targets store *g behind one pthread key. getg lazily allocates a zeroed GC root, installs it with pthread_setspecific, and reuses it for defer, panic/recover, Goexit, and main state. The pthread-key destructor releases an outstanding panic value and the GC root.

Host builds and currently single-context bare-metal targets use the same g API with an ordinary global fallback.

This PR does not add compiler directives, locality metadata, package-block storage, or C-library constructor changes. It changes eight files and has an independent diff of +369/-73.

Relation to #2079

This PR and #2079 are independent and can merge in either order.

The current head deliberately uses pthread keys so it can be reviewed and merged without the larger TLS/GLS compiler change.

Runtime cost

Apple M4 Max, macOS arm64, Go 1.26.5, LLVM 19.1.7, real LLGo, five adjacent benchmark runs:

Path Result
getg through one pthread key median 1.853 ns/op; range 1.797-2.131 ns/op

The benchmark reports 0 B/op, 0 allocs/op on the hot path. Allocation occurs once when a pthread first acquires its g.

Validation

Tests were serialized with GOMAXPROCS=2, GOMEMLIMIT=8GiB, and -p=1.

  • macOS arm64, Go 1.26.5: runtime host compilation and real-LLGo test/llgoext pass.
  • Ubuntu arm64, Go 1.26.5, LLVM 19.1.7: the same compiler/runtime tests pass in a container limited to 8 GiB, 2 CPU, no swap, and 512 PIDs.
  • Integration coverage verifies stable getg within one goroutine, distinct state across concurrently live goroutines, defer-head isolation, and Set/Get/Clear transitions.
  • No existing test is skipped or ignored.

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch 2 times, most recently from b543675 to 57ae899 Compare July 15, 2026 00:48
@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch from 57ae899 to b651488 Compare July 15, 2026 08:54
@cpunion
cpunion marked this pull request as ready for review July 15, 2026 10:22
@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch 2 times, most recently from 63fe488 to 56564e7 Compare July 15, 2026 20:52
@cpunion cpunion changed the title runtime: store goroutine state in //llgo:gls [Based on #2079] runtime: store goroutine state in //llgo:gls Jul 16, 2026
@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch 3 times, most recently from 353c562 to e363bbe Compare July 18, 2026 23:20
@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch 2 times, most recently from a309b55 to 34387d1 Compare July 20, 2026 04:24
@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch from 34387d1 to 3434b3c Compare July 23, 2026 09:31
@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch from 3434b3c to 59a616e Compare July 23, 2026 10:42
@cpunion
cpunion force-pushed the codex/runtime-g-state-gls branch from 59a616e to 87ba303 Compare July 24, 2026 03:29
@cpunion cpunion changed the title [Based on #2079] runtime: store goroutine state in //llgo:gls runtime: store goroutine state behind pthread-key getg Jul 24, 2026
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.

1 participant