8000 net: enable native golang linux networking by leongross · Pull Request #4498 · tinygo-org/tinygo · GitHub
[go: up one dir, main page]

Skip to content

net: enable native golang linux networking #4498

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

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
Open
Prev Previous commit
implement semrealse and semacquire using futex
Signed-off-by: leongross <leon.gross@9elements.com>
  • Loading branch information
leongross committed Nov 29, 2024
commit c16ff80f46f24e7545ecb8eb7a0a0c98670ed9ab
81 changes: 16 additions & 65 deletions src/runtime/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
package runtime

import (
"internal/task"
"sync"
"sync/atomic"
"internal/futex"
)

// This file contains stub implementations for internal/poll.
Expand All @@ -25,77 +23,30 @@ import (
// This means we assu 8000 me the following constant settings from the golang standard
// library: lifo=false,profile=semaBlock,skipframe=0,reason=waitReasonSemaquire

// The global state of the semaphore table.
// Semaphores are identified by their address.
// The table maps the address to the task that is currently holding the semaphore.
// The table is protected by a mutex.
// When a task acquires a semaphore, the mapping is added to the map.
// When a task releases a semaphore, the mapping is removed from the map.
//
// The table is used to implement the cansemacquire function.
// The cansemacquire function is called by the semacquire function.
// The cansemacquire function checks if the semaphore is available.
// If the semaphore is available, the function returns true.
// If the semaphore is not available, the function returns false.
type semTable struct {
table map[*uint32]*task.Task
lock sync.Mutex
}

var semtable semTable

func init() {
semtable.table = make(map[*uint32]*task.Task)
}

func (s *semTable) Lock() {
s.lock.Lock()
}

func (s *semTable) Unlock() {
s.lock.Unlock()
}

//go:linkname semacquire internal/poll.runtime_Semacquire
func semacquire(sema *uint32) {
if cansemacquire(sema) {
return
}
}

// Copied from src/runtime/sema.go
func cansemacquire(addr *uint32) bool {
// Busy Looping until a lookup to the global semaphore table can be made
semtable.Lock()
var semaBlock futex.Futex
semaBlock.Store(*sema)

if _, ok := semtable.table[addr]; !ok {
semtable.table[addr] = task.Current()
semtable.Unlock()
return true
}
// check if we can acquire the semaphore
semaBlock.Wait(1)

v := atomic.LoadUint32(addr)
if v == 0 {
semtable.Unlock()
return false
}
if atomic.CompareAndSwapUint32(addr, v, v-1) {
semtable.Unlock()
return true
// the semaphore is free to use so we can acquire it
if semaBlock.Swap(0) != 1 {
panic("semaphore is already acquired, racy")
}
return true
}

//go:linkname semrelease internal/poll.runtime_Semrelease
func semrelease(sema *uint32) {
// Check if the semaphore is in the table
semtable.Lock()
if _, ok := semtable.table[sema]; !ok {
panic("invalid semaphore")
}
var semaBlock futex.Futex
semaBlock.Store(*sema)

atomic.AddUint32(sema, 1)
semtable.Unlock()
// check if we can release the semaphore
if semaBlock.Swap(1) != 0 {
panic("semaphore is not acquired, racy")
}

Gosched()
// wake up the next waiter
semaBlock.Wake()
}
Loading
< BB3 template id="snippet-clipboard-copy-button">
0