Source File
sema.go
Belonging Package
runtime
package runtime
import (
)
const semTabSize = 251
var semtable [semTabSize]struct {
root semaRoot
pad [cpu.CacheLinePadSize - unsafe.Sizeof(semaRoot{})]byte
}
func ( *uint32) {
semacquire1(, false, semaBlockProfile, 0)
}
func ( *uint32) {
semacquire1(, false, semaBlockProfile, 0)
}
func ( *uint32, bool, int) {
semrelease1(, , )
}
func ( *uint32, bool, int) {
semacquire1(, , semaBlockProfile|semaMutexProfile, )
}
func ( *uint32) {
semrelease()
}
func ( *sudog, int) {
if .releasetime != 0 {
.releasetime = cputicks()
}
goready(.g, )
}
type semaProfileFlags int
const (
semaBlockProfile semaProfileFlags = 1 << iota
semaMutexProfile
)
if cansemacquire() {
return
}
:= acquireSudog()
:= semroot()
:= int64(0)
.releasetime = 0
.acquiretime = 0
.ticket = 0
if &semaBlockProfile != 0 && blockprofilerate > 0 {
= cputicks()
.releasetime = -1
}
if &semaMutexProfile != 0 && mutexprofilerate > 0 {
if == 0 {
= cputicks()
}
.acquiretime =
}
for {
.queue(, , )
goparkunlock(&.lock, waitReasonSemacquire, traceEvGoBlockSync, 4+)
if .ticket != 0 || cansemacquire() {
break
}
}
if .releasetime > 0 {
blockevent(.releasetime-, 3+)
}
releaseSudog()
}
func ( *uint32) {
semrelease1(, false, 0)
}
func ( *uint32, bool, int) {
:= semroot()
atomic.Xadd(, 1)
unlock(&.lock)
return
}
, := .dequeue()
if != nil {
atomic.Xadd(&.nwait, -1)
}
unlock(&.lock)
if != nil { // May be slow or even yield, so unlock first
:= .acquiretime
if != 0 {
mutexevent(-, 3+)
}
if .ticket != 0 {
throw("corrupted semaphore ticket")
}
if && cansemacquire() {
.ticket = 1
}
readyWithTime(, 5+)
func ( *notifyList, uint32) {
lockWithRank(&.lock, lockRankNotifyList)
:= acquireSudog()
.g = getg()
.ticket =
.releasetime = 0
:= int64(0)
if blockprofilerate > 0 {
= cputicks()
.releasetime = -1
}
if .tail == nil {
.head =
} else {
.tail.next =
}
.tail =
goparkunlock(&.lock, waitReasonSyncCondWait, traceEvGoBlockCond, 3)
if != 0 {
blockevent(.releasetime-, 2)
}
releaseSudog()
}
lockWithRank(&.lock, lockRankNotifyList)
:= .head
.head = nil
.tail = nil
for != nil {
:= .next
.next = nil
readyWithTime(, 4)
=
}
}
if atomic.Load(&.wait) == atomic.Load(&.notify) {
return
}
lockWithRank(&.lock, lockRankNotifyList)
func ( uintptr) {
if != unsafe.Sizeof(notifyList{}) {
print("runtime: bad notifyList size - sync=", , " runtime=", unsafe.Sizeof(notifyList{}), "\n")
throw("bad notifyList size")
}
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin 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 @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |