Documentation
¶
Index ¶
- func Block()
- func CloseChan(c *hchan)
- func MakeChan(chanType *abi.ChanType, sz int) *hchan
- func Recover(argp uintptr) any
- func Recv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool)
- func Sched(guarded bool)
- func Select(cas0 *SelectCase, order0 *uint16, pc0 *uintptr, nsends, nrecvs int, block bool) (int, bool)
- func Send(c *hchan, elem unsafe.Pointer, block bool, callerpc uintptr) bool
- type Chan
- type Defer
- type G
- type GHead
- type Gobuf
- type Guintptr
- type Mutex
- type Panic
- type SelectCase
- type Stack
- type Status
- type Sudog
- type WaitReason
- type Waitq
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Recv ¶
Recv receives on channel c and writes the received data to ep.
ep may be nil, in which case received data is ignored.
If block == false and no elements are available, returns (false, false). Otherwise, if c is closed, zeros *ep and returns (true, false). Otherwise, fills in *ep with an element and returns (true, true). A non-nil ep must point to the heap or the caller's stack.
func Sched ¶
func Sched(guarded bool)
Gosched yields the processor, allowing other goroutines to run. It does not suspend the current goroutine, so execution resumes automatically.
If guarded is true, also checks for forbidden states and opts out of the yield in those cases.
func Select ¶
func Select(cas0 *SelectCase, order0 *uint16, pc0 *uintptr, nsends, nrecvs int, block bool) (int, bool)
Select implements the select statement.
cas0 points to an array of type [ncases]scase, and order0 points to an array of type [2*ncases]uint16 where ncases must be <= 65536. Both reside on the goroutine's stack (regardless of any escaping in Select).
For race detector builds, pc0 points to an array of type [ncases]uintptr (also on the stack); for other builds, it's set to nil.
Select returns the index of the chosen scase, which matches the ordinal position of its respective select{recv,send,default} call. Also, if the chosen scase was a receive operation, it reports whether a value was received.
func Send ¶
generic single channel send
If block is not nil, then the protocol will not sleep but return if it could not complete.
sleep can wake up with g.param == nil when a channel involved in the sleep has been closed. it is easiest to loop and re-run the operation; we'll see that it's now closed.
Types ¶
type Chan ¶
type Chan struct {
Qcount uint // total data in the queue
DataqSize uint // size of the circular queue
Buf unsafe.Pointer // points to an array of dataqsiz elements
ElemSize uint16
Closed uint32
ElemType *abi.Type // element type
Sendx uint // send index
Recvx uint // receive index
// Lock protects all fields in hchan, as well as several
// fields in sudogs blocked on this channel.
//
// Do not change another G's status while holding this Lock
// (in particular, do not ready a G), as this can deadlock
// with stack shrinking.
Lock Mutex
// contains filtered or unexported fields
}
type Defer ¶
type Defer struct {
Started bool
Heap bool
// OpenDefer indicates that this _defer is for a frame with open-coded
// defers. We have only one defer record for the entire frame (which may
// currently have 0, 1, or more defers active).
OpenDefer bool
SP uintptr // sp at time of defer
PC uintptr // pc at time of defer
Fn func() // can be nil for open-coded defers
Panic *Panic // panic that is running defer
Link *Defer // next defer on G; can point to either heap or stack!
// If openDefer is true, the fields below record values about the stack
// frame and associated function that has the open-coded defer(s). sp
// above will be the sp for the frame, and pc will be address of the
// deferreturn call in the function.
FuncData unsafe.Pointer // funcdata for the function associated with the frame
Varp uintptr // value of varp for the stack frame
// FramePC is the current pc associated with the stack frame. Together,
// with sp above (which is the sp associated with the stack frame),
// FramePC/sp can be used as pc/sp pair to continue a stack trace via
// gentraceback().
FramePC uintptr
}
A Defer holds an entry on the list of deferred calls. If you add a field here, add code to clear it in deferProcStack. This struct must match the code in cmd/compile/internal/ssagen/ssa.go:deferstruct and cmd/compile/internal/ssagen/ssa.go:(*state).call. Some defers will be allocated on the stack and some on the heap. All defers are logically part of the stack, so write barriers to initialize them are not required. All defers must be manually scanned, and for heap defers, marked.
See $GOROOT/src/runtime/runtime2.go#type:_defer
type G ¶
type G interface {
ID() uint64
Rand32() uint32
Rand64() uint64
// Status returns the status of this goroutine.
Status() Status
// DefaultAlloc returns the default allocator in this goroutine.
DefaultAlloc() alloc.M
// PersistantAlloc returns the persistant allocator in this goroutine.
PersistantAlloc() alloc.P
}
G defines required methods for a goroutine implementation.
type GHead ¶
type GHead struct {
// Stack parameters.
//
// Stack describes the actual Stack memory: [Stack.lo, Stack.hi).
// stackguard0 is the Stack pointer compared in the Go Stack growth prologue.
// It is Stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
// stackguard1 is the Stack pointer compared in the C Stack growth prologue.
// It is Stack.lo+StackGuard on g0 and gsignal stacks.
// It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
Stack Stack // offset known to runtime/cgo
Stackguard0 uintptr // offset known to liblink
Stackguard1 uintptr // offset known to liblink
Panic *Panic // innermost panic - offset known to liblink
Defer *Defer // innermost defer
M unsafe.Pointer // current m; offset known to arm liblink
Sched Gobuf
SyscallSP uintptr // if status==Gsyscall, syscallsp = Sched.sp to use during gc
SyscallPC uintptr // if status==Gsyscall, syscallpc = Sched.pc to use during gc
StacktopSP uintptr // expected sp at top of stack, to check in traceback
ID_ uint64
// Itab for the G interface value.
Itab *abi.Itab
}
GHead contains required per-G data.
See ${GOROOT}/src/runtime/runtime2.go#type:g
NOTE:
- unsafe.Offsetof(T.GHead.Stack) MUST be 0.
- (dev) MUST be kept as non-generic struct type.
type Gobuf ¶
type Gobuf struct {
// The offsets of SP, PC, and G are known to (hard-coded in) libmach.
//
// Ctxt is unusual with respect to GC: it may be a
// heap-allocated funcval, so GC needs to track it, but it
// needs to be set and cleared from assembly, where it's
// difficult to have write barriers. However, ctxt is really a
// saved, live register, and we only ever exchange it between
// the real register and the gobuf. Hence, we treat it as a
// root during stack scanning, which means assembly that saves
// and restores it doesn't need write barriers. It's still
// typed as a pointer so that any other writes from Go get
// write barriers.
SP uintptr
PC uintptr
G Guintptr
Ctxt unsafe.Pointer
Ret uintptr
LR uintptr
BP uintptr // for framepointer-enabled architectures
}
See ${GOROOT}/src/runtime/runtime2.go#type:gobuf
type Guintptr ¶
type Guintptr uintptr
A Guintptr holds a goroutine pointer, but typed as a uintptr to bypass write barriers. It is used in the Gobuf goroutine state and in scheduling lists that are manipulated without a P.
The Gobuf.G goroutine pointer is almost always updated by assembly code. In one of the few places it is updated by Go code - func save - it must be treated as a uintptr to avoid a write barrier being emitted at a bad time. Instead of figuring out how to emit the write barriers missing in the assembly manipulation, we change the type of the field to uintptr, so that it does not require write barriers at all.
Goroutine structs are published in the allg list and never freed. That will keep the goroutine structs from being collected. There is never a time that Gobuf.g's contain the only references to a goroutine: the publishing of the goroutine in allg comes first. Goroutine pointers are also kept in non-GC-visible places like TLS, so I can't see them ever moving. If we did want to start moving data in the GC, we'd need to allocate the goroutine structs from an alternate arena. Using Guintptr doesn't make that problem any worse. Note that pollDesc.rg, pollDesc.wg also store g in uintptr form, so they would need to be updated too if g's start moving.
type Mutex ¶
type Mutex struct {
// contains filtered or unexported fields
}
Mutual exclusion locks. In the uncontended case, as fast as spin locks (just a few user-level instructions), but on the contention path they sleep in the kernel. A zeroed Mutex is unlocked (no need to initialize each lock). Initialization is helpful for static lock ranking, but not required.
type Panic ¶
type Panic struct {
Argp unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
Arg any // argument to panic
Link *Panic // link to earlier panic
PC uintptr // where to return to in runtime if this panic is bypassed
SP unsafe.Pointer // where to return to in runtime if this panic is bypassed
Recovered bool // whether this panic is over
Aborted bool // the panic was aborted
Goexit bool
}
A Panic holds information about an active panic.
A Panic value must only ever live on the stack.
The argp and link fields are stack pointers, but don't need special handling during stack growth: because they are pointer-typed and Panic values only live on the stack, regular stack pointer adjustment takes care of them.
see $GOROOT/src/runtime/runtime2.go#type:_panic
type SelectCase ¶
Select case descriptor. Known to compiler. Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype.
type Stack ¶
Stack describes a Go execution Stack. The bounds of the Stack are exactly [lo, hi), with no implicit data structures on either side.
func (Stack) PointerOnStack ¶ added in v0.2.0
type Status ¶
type Status = uint32
G status
Beyond indicating the general state of a G, the G status acts like a lock on the goroutine's stack (and hence its ability to execute user code).
If you add to this list, add to the list of "okay during garbage collection" status in mgcmark.go too.
TODO(austin): The StatusGscan bit could be much lighter-weight. For example, we could choose not to run StatusGscanrunnable goroutines found in the run queue, rather than CAS-looping until they become StatusGrunnable. And transitions like StatusGscanwaiting -> StatusGscanrunnable are actually okay because they don't affect stack ownership.
const ( // StatusGidle means this goroutine was just allocated and has not // yet been initialized. StatusGidle Status = iota // 0 // StatusGrunnable means this goroutine is on a run queue. It is // not currently executing user code. The stack is not owned. StatusGrunnable // 1 // StatusGrunning means this goroutine may execute user code. The // stack is owned by this goroutine. It is not on a run queue. // It is assigned an M and a P (g.m and g.m.p are valid). StatusGrunning // 2 // StatusGsyscall means this goroutine is executing a system call. // It is not executing user code. The stack is owned by this // goroutine. It is not on a run queue. It is assigned an M. StatusGsyscall // 3 // StatusGwaiting means this goroutine is blocked in the runtime. // It is not executing user code. It is not on a run queue, // but should be recorded somewhere (e.g., a channel wait // queue) so it can be ready()d when necessary. The stack is // not owned *except* that a channel operation may read or // write parts of the stack under the appropriate channel // lock. Otherwise, it is not safe to access the stack after a // goroutine enters StatusGwaiting (e.g., it may get moved). StatusGwaiting // 4 // StatusGmoribund_unused is currently unused, but hardcoded in gdb // scripts. StatusGmoribund_unused // 5 // StatusGdead means this goroutine is currently unused. It may be // just exited, on a free list, or just being initialized. It // is not executing user code. It may or may not have a stack // allocated. The G and its stack (if any) are owned by the M // that is exiting the G or that obtained the G from the free // list. StatusGdead // 6 // StatusGenqueue_unused is currently unused. StatusGenqueue_unused // 7 // StatusGcopystack means this goroutine's stack is being moved. It // is not executing user code and is not on a run queue. The // stack is owned by the goroutine that put it in StatusGcopystack. StatusGcopystack // 8 // StatusGpreempted means this goroutine stopped itself for a // suspendG preemption. It is like StatusGwaiting, but nothing is // yet responsible for ready()ing it. Some suspendG must CAS // the status to StatusGwaiting to take responsibility for // ready()ing this G. StatusGpreempted // 9 // StatusGscan combined with one of the above states other than // StatusGrunning indicates that GC is scanning the stack. The // goroutine is not executing user code and the stack is owned // by the goroutine that set the StatusGscan bit. // // StatusGscanrunning is different: it is used to briefly block // state transitions while GC signals the G to scan its own // stack. This is otherwise like StatusGrunning. // // atomicstatus&~Gscan gives the state the goroutine will // return to when the scan completes. StatusGscan Status = 0x1000 StatusGscanrunnable Status = StatusGscan + StatusGrunnable // 0x1001 StatusGscanrunning Status = StatusGscan + StatusGrunning // 0x1002 StatusGscansyscall Status = StatusGscan + StatusGsyscall // 0x1003 StatusGscanwaiting Status = StatusGscan + StatusGwaiting // 0x1004 StatusGscanpreempted Status = StatusGscan + StatusGpreempted // 0x1009 )
type Sudog ¶
type Sudog struct {
// contains filtered or unexported fields
}
Sudog represents a g in a wait list, such as for sending/receiving on a channel.
Sudog is necessary because the g ↔ synchronization object relation is many-to-many. A g can be on many wait lists, so there may be many sudogs for one g; and many gs may be waiting on the same synchronization object, so there may be many sudogs for one object.
sudogs are allocated from a special pool. Use acquireSudog and releaseSudog to allocate and free them.
See ${GOROOT}/src/runtime/runtime2.go#type:sudog
type WaitReason ¶
type WaitReason uint8
A WaitReason explains why a goroutine has been stopped. See gopark. Do not re-use waitReasons, add new ones.
const ( WaitReasonZero WaitReason = iota // "" WaitReasonGCAssistMarking // "GC assist marking" WaitReasonIOWait // "IO wait" WaitReasonChanReceiveNilChan // "chan receive (nil chan)" WaitReasonChanSendNilChan // "chan send (nil chan)" WaitReasonDumpingHeap // "dumping heap" WaitReasonGarbageCollection // "garbage collection" WaitReasonGarbageCollectionScan // "garbage collection scan" WaitReasonPanicWait // "panicwait" WaitReasonSelect // "select" WaitReasonSelectNoCases // "select (no cases)" WaitReasonGCAssistWait // "GC assist wait" WaitReasonGCSweepWait // "GC sweep wait" WaitReasonGCScavengeWait // "GC scavenge wait" WaitReasonChanReceive // "chan receive" WaitReasonChanSend // "chan send" WaitReasonFinalizerWait // "finalizer wait" WaitReasonForceGCIdle // "force gc (idle)" WaitReasonSemacquire // "semacquire" WaitReasonSleep // "sleep" WaitReasonSyncCondWait // "sync.Cond.Wait" WaitReasonSyncMutexLock // "sync.Mutex.Lock" WaitReasonSyncRWMutexRLock // "sync.RWMutex.RLock" WaitReasonSyncRWMutexLock // "sync.RWMutex.Lock" WaitReasonTraceReaderBlocked // "trace reader (blocked)" WaitReasonWaitForGCCycle // "wait for GC cycle" WaitReasonGCWorkerIdle // "GC worker (idle)" WaitReasonGCWorkerActive // "GC worker (active)" WaitReasonPreempted // "preempted" WaitReasonDebugCall // "debug call" WaitReasonGCMarkTermination // "GC mark termination" WaitReasonStoppingTheWorld // "stopping the world" )
func (WaitReason) IsMutexWait ¶
func (w WaitReason) IsMutexWait() bool