Skip to content

tls: add gc-aware pthread slots#1347

Merged
xushiwei merged 3 commits intogoplus:mainfrom
cpunion:feature/tls-gc
Oct 16, 2025
Merged

tls: add gc-aware pthread slots#1347
xushiwei merged 3 commits intogoplus:mainfrom
cpunion:feature/tls-gc

Conversation

@cpunion
Copy link
Collaborator

@cpunion cpunion commented Oct 15, 2025

Summary

  • introduce runtime/internal/clite/tls to provide pthread-based TLS handles that are GC-aware when building with BDWGC
  • add Boehm root registration helpers (AddRoots/RemoveRoots) and hook TLS slots into them on GC builds, with TLS-specific unit tests and stress coverage
  • harden TLS teardown (panic-safe destructors, pointer-arithmetic guards) and document the build-tag behaviour for TLS helpers
  • adjust SSA debug info generation to skip types that still carry type parameters so go/types sizing does not panic when TLS generics appear—and add targeted tests for hasTypeParam

Motivation

Loop defers keep their state in thread-local storage; because pthread TLS is invisible to BDWGC, the GC would reclaim defer nodes under heavy load. This PR adds a reusable TLS helper that registers each slot as a GC root, ensuring defer chains (and any other TLS-stored pointers) remain visible to the collector. When compiling without GC (-tags nogc), the helper falls back to plain pthread TLS.

The SSA change (hasTypeParam) is required because TLS handles introduce generic types that reach the debug-info builder. go/types' GC sizing asserts when asked for alignments of types that still contain type parameters. By detecting those shapes and skipping DI emission, we prevent crashes when generating debug info while keeping coverage via dedicated tests.

Testing

  • go test ./ssa -run TestHasTypeParam
  • cd runtime && ../llgo.sh test ./internal/clite/tls
  • cd runtime && ../llgo.sh test -tags=nogc ./internal/clite/tls

@gemini-code-assist
Copy link

Summary of Changes

Hello @cpunion, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the runtime's capabilities by introducing garbage collector-aware thread-local storage (TLS) using pthread slots. It provides a generic API for managing thread-local data, ensuring proper interaction with the Boehm-Demers-Weiser garbage collector by dynamically registering and deregistering TLS slots as GC roots. Concurrently, the Static Single Assignment (SSA) form's debug information generation has been refined to correctly handle generic types, preventing issues when generating debug metadata for parameterized types.

Highlights

  • GC-Aware Thread Local Storage (TLS): Introduced new functionality to manage thread-local storage (TLS) slots in a garbage collector-aware manner, specifically integrating with the Boehm-Demers-Weiser garbage collector (BDWGC).
  • BDWGC Root Management: Added AddRoots and RemoveRoots functions to the bdwgc package, allowing explicit registration and deregistration of memory ranges as GC roots.
  • Generic TLS Handle: A new tls package provides a generic Handle[T] type for managing TLS, offering methods for allocation, getting, setting, and clearing thread-local values, including support for custom destructors.
  • Conditional GC Integration: Implemented conditional compilation for TLS GC integration, with tls_gc.go handling root registration for GC-enabled builds and tls_nogc.go providing no-op functions for non-GC builds.
  • Generic Type Detection in SSA: Enhanced the SSA (Static Single Assignment) form's debug information builder with a hasTypeParam function to detect if a types.Type contains type parameters, allowing for appropriate handling of generic types during debug info generation.
  • Comprehensive Testing: Added extensive tests for both the new tls package, covering basic operations, thread isolation, destructor execution, and stress scenarios, and for the hasTypeParam function in ssa/di_test.go.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a GC-aware thread-local storage (TLS) implementation using pthread keys, which is a significant addition for managing thread-local data that may contain GC-managed pointers. The implementation is split across _gc and _nogc build-tagged files to correctly handle both scenarios. The accompanying tests are thorough, covering functionality, thread-safety, and resource cleanup.

Separately, this PR also includes a change in the SSA package to handle debug information generation for generic types by adding a hasTypeParam check. This seems to be an unrelated but useful fix.

My review found one high-severity issue in the TLS destructor logic where a panic in a user-provided destructor could lead to resource leaks and stale GC roots. I've provided a suggestion to make the cleanup more robust.

@xgopilot
Copy link
Contributor

xgopilot bot commented Oct 15, 2025

Code Review Summary

This PR introduces a well-architected TLS package with GC-aware pthread slot management. The implementation demonstrates solid engineering with good separation of concerns. However, critical memory safety issues must be addressed before merging.

Critical Issues 🚨

  • TOCTOU race condition in ensureSlot() causing potential memory leaks and use-after-free
  • Integer overflow risk in rootRange() pointer arithmetic
  • Panic handling missing in destructor could orphan GC roots

Documentation Gaps 📝

  • Missing package-level documentation
  • New BDWGC functions lack explanations
  • Build tag implications not documented

Positive Aspects ✅

  • Excellent build tag separation (gc/nogc)
  • Type-safe generic Handle API
  • Comprehensive test coverage including stress tests

Recommendation: Address critical memory safety issues before merge. See inline comments for specific fixes.

@codecov
Copy link

codecov bot commented Oct 15, 2025

Codecov Report

❌ Patch coverage is 91.02564% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.18%. Comparing base (dba7bd4) to head (00dd09c).
⚠️ Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
ssa/di.go 91.02% 5 Missing and 2 partials ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1347   +/-   ##
=======================================
  Coverage   90.18%   90.18%           
=======================================
  Files          43       43           
  Lines       12674    12752   +78     
=======================================
+ Hits        11430    11501   +71     
- Misses       1087     1092    +5     
- Partials      157      159    +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cpunion
Copy link
Collaborator Author

cpunion commented Oct 15, 2025

Thanks for the thorough pass! To the TOCTOU concern: pthread TLS slots are per-thread, and functions like ensureSlot run in a single-threaded context (the current thread only). That means there isn’t a window where another thread can sneak in: each thread owns its own pthread_key_t slot, so no cross-thread race is possible here. We’ll add a short comment in the code to make that assumption explicit and avoid future confusion.

Regarding the rest of your notes, we’ve:

  • Added overflow checks to rootRange before registering GC roots.
  • Documented AddRoots/RemoveRoots in the bdwgc wrapper.
  • Bumped stress coverage for TLS tests (more goroutines, lower per-thread load).

Let us know if you spot anything else. Thanks again!

@cpunion cpunion mentioned this pull request Oct 15, 2025
3 tasks
@xushiwei xushiwei merged commit 325e9a9 into goplus:main Oct 16, 2025
42 checks passed
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.

2 participants