Repository navigation
feat(c/pthread): restore native thread APIs and layouts - #46
MeteorsLiu wants to merge 6 commits into
Conversation
9addf11 to
cc6e25e
Compare
|
Merge order: #45 → #51 → #48 → #49 → #44 → #47 → #46 → #50 → #52. Each draft changes one folder only. This refresh regenerates native APIs without omitting functions merely to preserve handwritten entry points. Existing compatibility APIs remain available; colliding native names use the The combined prerequisite snapshot passes These PRs remain draft for review. Documented generator/ABI failures and previously approved |
There was a problem hiding this comment.
Summary
This PR replaces the hand-written pthread/sync type stubs with ABI-exact, llcppg-generated native bindings for linux/amd64 and darwin/arm64, plus supporting types (Iovec, SchedParam, mach port, SigsetT), while keeping a cgo/placeholder fallback for other POSIX targets.
I verified the mechanics:
go build ./c/...passes on linux/amd64.- All linux/amd64 struct sizes match the glibc C ABI exactly (
Mutex40,Cond48,RWLock56,Attr56,Sem/Barrier32, attrs 4/8,Key/Spinlock4). - The darwin/arm64
pthreadpackage type-checks cleanly (go vet), including theThread/OverrideTreceiver methods — these compile becauseThread/OverrideTare aliases to pointer types, which Go permits as method receivers. - Build-tag coverage for
Attr/Keyand the sync types is complete and non-overlapping across all!windowstargets.
Overall this is a solid, correct improvement for the two validated targets. The findings below are mostly generated-code quality/portability items; none block merge.
Portability: a function is free on linux but a method on darwin
pthread_detach, pthread_kill, pthread_getschedparam, and pthread_setschedparam are generated as free functions on linux/amd64 but as Thread methods on darwin/arm64. Cross-platform code cannot call these uniformly (pthread.Detach(t) vs t.Detach()). If portability across the validated targets is a goal, consider unifying the receiver vs. free-function form in the generator. (See inline comment.)
Generated placeholder names leak into the public darwin API
The darwin bindings expose _llcppg_param1, _llcppg_param2, … in exported signatures and in JitWriteCallbackT, and the retained Doxygen @param __attr / @param __pthread blocks reference names that became the receiver. The linux bindings keep meaningful names. Regenerating with real parameter names would improve godoc and cross-platform consistency. (See inline comment.)
Minor documentation artifacts
c/signal/types_darwin_arm64.go—// [???] signal setplaceholder (the linux counterpart reads "A set of signals…").c/pthread/sync/libc_darwin_arm64.go— stray// this should go in limits.h>carried verbatim ontoSEM_VALUE_MAX.
Fallback types stay smaller than the real C ABI (pre-existing, non-validated targets)
c/pthread/types_other.go keeps the 24-byte placeholder Attr and 4-byte Key for non-validated POSIX targets (e.g. darwin/amd64, linux/arm64). The real pthread_attr_t is 56–64 bytes and darwin's pthread_key_t is 8 bytes, so calling the Attr/Key methods there would let libc write past the Go allocation. This predates the PR, which actually fixes it for the two validated targets; worth tracking for the fallback path. (The sync fallback avoids this by using cgo C.pthread_* types.) (See inline comment.)
Note (pre-existing, outside this diff)
sync.go's (*MutexAttr).Init / (*CondAttr).Init / (*RWLockAttr).Init each take an extra *Attr parameter beyond the receiver even though pthread_*attr_init take a single pointer. Not touched by this PR, flagged only for awareness.
Findings without inline locations
c/signal/types_darwin_arm64.go:13:// [???] signal setis a generator placeholder left in the doc comment. The linux counterpart (c/signal/types_linux_amd64.go) documents this as "A set of signals to be blocked, unblocked, or waited for." Worth cleaning up before this becomes the darwin baseline.c/pthread/sync/libc_darwin_arm64.go:94: Stray editorial note carried verbatim from the macOSsemaphore.hheader (// this should go in limits.h>, including the dangling>). It's meaningless as godoc forSEM_VALUE_MAXand should be dropped or replaced.
| } | ||
|
|
||
| // llgo:link Thread.Detach C.pthread_detach | ||
| func (self Thread) Detach() c.Int { |
There was a problem hiding this comment.
Cross-platform inconsistency: pthread_detach is a Thread method here, but a free function on linux/amd64 (func Detach(__th Thread) in libc_linux_amd64.go:113). The same split applies to pthread_kill, pthread_getschedparam, and pthread_setschedparam. Code written against one target won't compile on the other — consider unifying the receiver vs. free-function form in the generator.
| } | ||
|
|
||
| //go:linkname Equal C.pthread_equal | ||
| func Equal(_llcppg_param1 Thread, _llcppg_param2 Thread) c.Int |
There was a problem hiding this comment.
Generated placeholder parameter names (_llcppg_param1, _llcppg_param2) leak into the exported API throughout this darwin file (and into JitWriteCallbackT). The linux bindings use meaningful names (__threadid, __signo, …). Regenerating with real parameter names would improve godoc and keep the two targets consistent.
| import "github.com/goplus/lib/c" | ||
|
|
||
| // Attr represents POSIX thread attributes. | ||
| type Attr struct { |
There was a problem hiding this comment.
On non-validated POSIX targets (e.g. darwin/amd64, linux/arm64 glibc) this placeholder Attr is 24 bytes and Key (line 14) is 4 bytes, but the real pthread_attr_t is 56–64 bytes and darwin's pthread_key_t is 8 bytes. The Attr/Key methods declared in pthread.go would then let libc write past the Go allocation. This is pre-existing and is fixed for the two validated targets by this PR — noting it so the fallback path is tracked. (The sync fallback avoids this by using cgo C.pthread_* types.)
Generate native pthread APIs and layouts while preserving existing entry-point names where compatible.
The implementation includes:
AttrandKeylayouts on the three supported targets.CreateandJoinGC behavior, with direct C calls available asNativeCreateandNativeJoin; keep other targets’ existing declarations.nogcon all three targets.The native APIs share the established names while retaining the separate GC entry points.