Skip to content

runtime: use hchan-style channel queues#2030

Open
zhouguangyuan0718 wants to merge 1 commit into
xgo-dev:mainfrom
zhouguangyuan0718:codex/hchan-channel-queues
Open

runtime: use hchan-style channel queues#2030
zhouguangyuan0718 wants to merge 1 commit into
xgo-dev:mainfrom
zhouguangyuan0718:codex/hchan-channel-queues

Conversation

@zhouguangyuan0718

@zhouguangyuan0718 zhouguangyuan0718 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Rework llgo channels around hchan-style state: buffered ring metadata plus explicit send and receive wait queues.
  • Replace the old single pending recv/select state with per-waiter queue nodes, so multiple goroutines and select cases can wait on the same channel safely.
  • Implement select waiters with a shared select state and one-shot claim, so only one case can win while the losing waiters are removed from their channel queues.
  • Lock all distinct channels in address order for blocking select registration to avoid multi-channel lock-order deadlocks.
  • Preserve closed-channel semantics: receive drains buffered values then returns zero/ok=false, send panics, and close wakes recv/send waiters without leaving the channel locked.

Design Notes

  • Chan now tracks qcount/dataqsiz/buf/recvx/sendx plus sendq and recvq.
  • Blocking send/recv first try the fast path under the channel mutex. If not ready, they enqueue a chanWaiter and sleep on a condvar.
  • Waiter/select completion is represented by one waitStatus state machine instead of separate done, recvOK, panicOnWake, and claimed booleans.
  • waitClaimed keeps select two-phase completion safe: a case can reserve the select result before copying data, and only the final status wakes the select goroutine.
  • Unbuffered rendezvous copies directly between sender and receiver waiters.
  • Buffered receive pulls from the ring buffer and then admits one queued sender into the freed slot.
  • Blocking select first tries a non-blocking pass. If no case is ready, it sorts/dedups channels, locks them, retries under locks, enqueues waiters, unlocks, and sleeps on the shared selectState.
  • The inline channel list uses [selectInlineChanCount]*Chan and spills to a slice when a select references more distinct channels.

Tests

  • /opt/data/tmp/llgo-pr-split/llgo-channel test -timeout=180s ./test -run 'Test(ClosedChannelSendPanicDoesNotKeepChannelLocked|SelectDuplicateChannelDoesNotDeadlock|ConcurrentSelectProposeReplyStress)' -count=1

Added Coverage

  • closed-channel send panic does not leave the channel unusable
  • duplicate-channel select does not deadlock
  • concurrent select request/reply stress makes progress

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@zhouguangyuan0718 zhouguangyuan0718 force-pushed the codex/hchan-channel-queues branch 3 times, most recently from 297fbdb to 90e6402 Compare July 7, 2026 12:12
@zhouguangyuan0718 zhouguangyuan0718 changed the title [codex] runtime: use hchan-style channel queues runtime: use hchan-style channel queues Jul 7, 2026
@zhouguangyuan0718 zhouguangyuan0718 marked this pull request as ready for review July 7, 2026 14:56
@zhouguangyuan0718 zhouguangyuan0718 force-pushed the codex/hchan-channel-queues branch from 90e6402 to 5130dae Compare July 7, 2026 15:26
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