package runtime
import (
"internal/runtime/atomic"
"unsafe"
)
func key32(p *uintptr ) *uint32 {
return (*uint32 )(unsafe .Pointer (p ))
}
func noteclear(n *note ) {
n .key = 0
}
func notewakeup(n *note ) {
old := atomic .Xchg (key32 (&n .key ), 1 )
if old != 0 {
print ("notewakeup - double wakeup (" , old , ")\n" )
throw ("notewakeup - double wakeup" )
}
futexwakeup (key32 (&n .key ), 1 )
}
func notesleep(n *note ) {
gp := getg ()
if gp != gp .m .g0 {
throw ("notesleep not on g0" )
}
ns := int64 (-1 )
if *cgo_yield != nil {
ns = 10e6
}
for atomic .Load (key32 (&n .key )) == 0 {
gp .m .blocked = true
futexsleep (key32 (&n .key ), 0 , ns )
if *cgo_yield != nil {
asmcgocall (*cgo_yield , nil )
}
gp .m .blocked = false
}
}
func notetsleep_internal(n *note , ns int64 ) bool {
gp := getg ()
if ns < 0 {
if *cgo_yield != nil {
ns = 10e6
}
for atomic .Load (key32 (&n .key )) == 0 {
gp .m .blocked = true
futexsleep (key32 (&n .key ), 0 , ns )
if *cgo_yield != nil {
asmcgocall (*cgo_yield , nil )
}
gp .m .blocked = false
}
return true
}
if atomic .Load (key32 (&n .key )) != 0 {
return true
}
deadline := nanotime () + ns
for {
if *cgo_yield != nil && ns > 10e6 {
ns = 10e6
}
gp .m .blocked = true
futexsleep (key32 (&n .key ), 0 , ns )
if *cgo_yield != nil {
asmcgocall (*cgo_yield , nil )
}
gp .m .blocked = false
if atomic .Load (key32 (&n .key )) != 0 {
break
}
now := nanotime ()
if now >= deadline {
break
}
ns = deadline - now
}
return atomic .Load (key32 (&n .key )) != 0
}
func notetsleep(n *note , ns int64 ) bool {
gp := getg ()
if gp != gp .m .g0 && gp .m .preemptoff != "" {
throw ("notetsleep not on g0" )
}
return notetsleep_internal (n , ns )
}
func notetsleepg(n *note , ns int64 ) bool {
gp := getg ()
if gp == gp .m .g0 {
throw ("notetsleepg on g0" )
}
entersyscallblock ()
ok := notetsleep_internal (n , ns )
exitsyscall ()
return ok
}
func beforeIdle(int64 , int64 ) (*g , bool ) {
return nil , false
}
func checkTimeouts() {}
func semacreate(mp *m ) {}
func semasleep(ns int64 ) int32 {
mp := getg ().m
for v := atomic .Xadd (&mp .waitsema , -1 ); ; v = atomic .Load (&mp .waitsema ) {
if int32 (v ) >= 0 {
return 0
}
futexsleep (&mp .waitsema , v , ns )
if ns >= 0 {
if int32 (v ) >= 0 {
return 0
} else {
return -1
}
}
}
}
func semawakeup(mp *m ) {
v := atomic .Xadd (&mp .waitsema , 1 )
if v == 0 {
futexwakeup (&mp .waitsema , 1 )
}
}
The pages are generated with Golds v0.7.3-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .