-
Notifications
You must be signed in to change notification settings - Fork 911
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
net: enable native golang linux networking #4498
base: dev
Are you sure you want to change the base?
Changes from all commits
ce1520d
5f07a43
bdb93fe
9c6020a
3215051
d698225
10221bb
c40115c
d3abf3c
f5ea847
5c8d4f6
673d901
5f0f0aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright 2024 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
//go:build linux | ||
|
||
package runtime | ||
|
||
// For debugging purposes this is used for all target architectures, but this is only valid for linux systems. | ||
// TODO: add linux specific build tags | ||
type pollDesc struct { | ||
runtimeCtx uintptr | ||
} | ||
|
||
func (pd *pollDesc) wait(mode int, isFile bool) error { | ||
return nil | ||
} | ||
|
||
const ( | ||
pollNoError = 0 // no error | ||
pollErrClosing = 1 // descriptor is closed | ||
pollErrTimeout = 2 // I/O timeout | ||
pollErrNotPollable = 3 // general error polling descriptor | ||
) | ||
|
||
//go:linkname poll_runtime_pollReset internal/poll.runtime_pollReset | ||
func poll_runtime_pollReset(pd *pollDesc, mode int) int { | ||
// println("poll_runtime_pollReset not implemented", pd, mode) | ||
return pollNoError | ||
} | ||
|
||
//go:linkname poll_runtime_pollWait internal/poll.runtime_pollWait | ||
func poll_runtime_pollWait(pd *pollDesc, mode int) int { | ||
// println("poll_runtime_pollWait not implemented", pd, mode) | ||
return pollNoError | ||
} | ||
|
||
//go:linkname poll_runtime_pollSetDeadline internal/poll.runtime_pollSetDeadline | ||
func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) { | ||
// println("poll_runtime_pollSetDeadline not implemented", pd, d, mode) | ||
} | ||
|
||
//go:linkname poll_runtime_pollOpen internal/poll.runtime_pollOpen | ||
func poll_runtime_pollOpen(fd uintptr) (*pollDesc, int) { | ||
// println("poll_runtime_pollOpen not implemented", fd) | ||
return &pollDesc{runtimeCtx: uintptr(0x1337)}, pollNoError | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright 2024 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
//go:build !linux | ||
|
||
package runtime | ||
|
||
const ( | ||
pollNoError = 0 // no error | ||
pollErrClosing = 1 // descriptor is closed | ||
pollErrTimeout = 2 // I/O timeout | ||
pollErrNotPollable = 3 // general error polling descriptor | ||
) | ||
|
||
// Network poller descriptor. | ||
// | ||
// No heap pointers. | ||
// For linux to call create Fds with a pollDesc, it needs a ctxRuntime pointer, so use the original pollDesc struct. | ||
// On linux we have a heap. | ||
type pollDesc struct{} | ||
|
||
//go:linkname poll_runtime_pollReset internal/poll.runtime_pollReset | ||
func poll_runtime_pollReset(pd *pollDesc, mode int) int { | ||
println("poll_runtime_pollReset not implemented", pd, mode) | ||
return pollErrClosing | ||
} | ||
|
||
//go:linkname poll_runtime_pollWait internal/poll.runtime_pollWait | ||
func poll_runtime_pollWait(pd *pollDesc, mode int) int { | ||
println("poll_runtime_pollWait not implemented", pd, mode) | ||
return pollErrClosing | ||
} | ||
|
||
//go:linkname poll_runtime_pollSetDeadline internal/poll.runtime_pollSetDeadline | ||
func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) { | ||
println("poll_runtime_pollSetDeadline not implemented", pd, d, mode) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,20 +4,21 @@ package runtime | |
|
||
//go:linkname poll_runtime_pollServerInit internal/poll.runtime_pollServerInit | ||
func poll_runtime_pollServerInit() { | ||
panic("todo: runtime_pollServerInit") | ||
// fmt.Printf("poll_runtime_pollServerInit not implemented, skipping panic\n") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you put in debugging code, please remove it before sending in a PR. It makes the diff bigger and more work to review. |
||
} | ||
|
||
//go:linkname poll_runtime_pollOpen internal/poll.runtime_pollOpen | ||
func poll_runtime_pollOpen(fd uintptr) (uintptr, int) { | ||
panic("todo: runtime_pollOpen") | ||
} | ||
// //go:linkname poll_runtime_pollOpen internal/poll.runtime_pollOpen | ||
// func poll_runtime_pollOpen(fd uintptr) (uintptr, int) { | ||
// // fmt.Printf("poll_runtime_pollOpen not implemented, skipping panic\n") | ||
// return 0, 0 | ||
// } | ||
|
||
//go:linkname poll_runtime_pollClose internal/poll.runtime_pollClose | ||
func poll_runtime_pollClose(ctx uintptr) { | ||
panic("todo: runtime_pollClose") | ||
// fmt.Printf("poll_runtime_pollClose not implemented, skipping panic\n") | ||
} | ||
|
||
//go:linkname poll_runtime_pollUnblock internal/poll.runtime_pollUnblock | ||
func poll_runtime_pollUnblock(ctx uintptr) { | ||
panic("todo: runtime_pollUnblock") | ||
// fmt.Printf("poll_runtime_pollUnblock not implemented, skipping panic\n") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,72 @@ | ||
// Copyright 2009 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package runtime | ||
|
||
import ( | ||
"sync/atomic" | ||
"unsafe" | ||
) | ||
|
||
// This file contains stub implementations for internal/poll. | ||
// The official golang implementation states: | ||
// | ||
// "That is, don't think of these as semaphores. | ||
// Think of them as a way to implement sleep and wakeup | ||
// such that every sleep is paired with a single wakeup, | ||
// even if, due to races, the wakeup happens before the sleep." | ||
Comment on lines
+15
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, that's useful to know. So they're not really semaphores but something like it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
// | ||
// This is an experimental and probably incomplete implementation of the | ||
// semaphore system, tailed to the network use case. That means, that it does not | ||
// implement the modularity that the semacquire/semacquire1 implementation model | ||
// offers, which in fact is emitted here entirely. | ||
// This means we assume the following constant settings from the golang standard | ||
// library: lifo=false,profile=semaBlock,skipframe=0,reason=waitReasonSemaquire | ||
|
||
type semaRoot struct { | ||
nwait atomic.Uint32 | ||
} | ||
|
||
var semtable semTable | ||
|
||
// Prime to not correlate with any user patterns. | ||
const semTabSize = 251 | ||
|
||
type semTable [semTabSize]struct { | ||
root semaRoot | ||
pad [64 - unsafe.Sizeof(semaRoot{})]byte // only 64 x86_64, make this variable | ||
} | ||
|
||
func (t *semTable) rootFor(addr *uint32) *semaRoot { | ||
return &t[(uintptr(unsafe.Pointer(addr))>>3)%semTabSize].root | ||
} | ||
Comment on lines
+36
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain what this is doing, and what it's for? |
||
|
||
//go:linkname semacquire internal/poll.runtime_Semacquire | ||
func semacquire(sema *uint32) { | ||
panic("todo: semacquire") | ||
if cansemacquire(sema) { | ||
return | ||
} | ||
Comment on lines
+47
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't look like a complete implementation? |
||
} | ||
|
||
// Copied from src/runtime/sema.go | ||
func cansemacquire(addr *uint32) bool { | ||
for { | ||
v := atomic.LoadUint32(addr) | ||
if v == 0 { | ||
return false | ||
} | ||
if atomic.CompareAndSwapUint32(addr, v, v-1) { | ||
return true | ||
} | ||
} | ||
} | ||
|
||
//go:linkname semrelease internal/poll.runtime_Semrelease | ||
func semrelease(sema *uint32) { | ||
panic("todo: semrelease") | ||
root := semtable.rootFor(sema) | ||
atomic.AddUint32(sema, 1) | ||
if root.nwait.Load() == 0 { | ||
return | ||
} | ||
Comment on lines
+68
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are not awaking the waiting goroutine here. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//go:build tinygo && linux && !wasip1 && !wasip2 && tinygo.wasm && !wasm_unknown && !darwin && !baremetal && !nintendoswitch | ||
|
||
package syscall | ||
|
||
import ( | ||
"sync" | ||
) | ||
|
||
var ForkLock sync.RWMutex | ||
|
||
func CloseOnExec(fd int) { | ||
system.CloseOnExec(fd) | ||
} | ||
|
||
func SetNonblock(fd int, nonblocking bool) (err error) { | ||
return system.SetNonblock(fd, nonblocking) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't make unrelated changes in the PR. While this is probably a good idea, it would be better to make a separate cleanup PR instead of putting everything in one huge PR.