• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aio-libs / multidict / 36250672783
87%

Build:
DEFAULT BRANCH: master
Ran 26 Sep 2026 03:05PM UTC
Jobs 1
Files 44
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

26 Sep 2026 03:04PM UTC coverage: 87.109%. Remained the same
36250672783

push

github

web-flow
Keep one thread-local version counter on free-threaded builds (#1599)

<!-- Thank you for your contribution! -->

## What do these changes do?

#1587 gave each thread a batch of versions in two thread-local
variables, `version_next` and `version_end`. Under the default TLS model
every access to a thread-local in a shared object goes through
`__tls_get_addr()`, and GCC recomputes the address rather than keep it
in a register, so each mutation made two such calls where it used to
make one `lock xadd`. On a single thread that cost about 34 instructions
per mutation.

A single `version_last` now does the job. A batch never hands out its
own base, a multiple of `VERSION_BATCH`, so reaching one means the batch
is spent, and starting the variable at `VERSION_BATCH - 1` makes the
first call refill. One `++version_last` reads and advances it, which is
one TLS lookup. Versions stay unique and increasing within a thread, the
same guarantees as before. The GIL build and the pure-Python
implementation are unaffected.

Instructions per operation, free-threaded 3.14.7t (Callgrind,
`benchmarks/callgrind_driver.py`):

| operation | `MultiDict` | `CIMultiDict` |
|---|---:|---:|
| `ctor_items` | 73,543 -> 70,308 (-4.4%) | 85,771 -> 82,536 (-3.8%) |
| `ctor_small` | 7,529 -> 7,175 (-4.7%) | 8,717 -> 8,363 (-4.1%) |
| `setitem_replace` | 527 -> 511 (-3.0%) | 584 -> 568 (-2.7%) |
| `setitem_insert` | 634 -> 617 (-2.6%) | 690 -> 674 (-2.4%) |
| `delitem` | 425 -> 409 (-3.8%) | 482 -> 466 (-3.3%) |
| `pop` | 565 -> 549 (-2.9%) | 622 -> 606 (-2.6%) |

## Are there changes in behavior for the user?

No.

## Is it a substantial burden for the maintainers to support this?

No, it is smaller than what it replaces.

## Related issue number

N/A

## Checklist

- [x] I think the code is well written
- [x] Unit tests for the changes exist (the existing
`test_version_thread_safety` checks uniqueness across 16 threads and
crosses many batch boundaries)
- [x] Documentation reflects the ... (continued)

781 of 1562 branches covered (50.0%)

Branch coverage included in aggregate %.

8213 of 8763 relevant lines covered (93.72%)

1.87 hits per line

Jobs
ID Job ID Ran Files Coverage
1 MyPy - 36250672783.1 26 Sep 2026 03:05PM UTC 88
87.11
GitHub Action Run
Source Files on build 36250672783
  • Tree
  • List 44
  • Changed 2
  • Source Changed 0
  • Coverage Changed 2
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #36250672783
  • b5d40539 on github
  • Prev Build on master (#36228053380)
  • Next Build on master (#36250920366)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc