1 package task
2 3 import (
4 "unsafe"
5 )
6 7 // Task is a state of goroutine for scheduling purposes.
8 type Task struct {
9 // Next is a field which can be used to make a linked list of tasks.
10 Next *Task
11 12 // Ptr is a field which can be used for storing a pointer.
13 Ptr unsafe.Pointer
14 15 // Data is a field which can be used for storing state information.
16 Data uint64
17 18 // gcData holds data for the GC.
19 gcData gcData
20 21 // state is the underlying running state of the task.
22 state state
23 24 // This is needed for some crypto packages.
25 FipsIndicator uint8
26 27 // State of the goroutine: running, paused, or must-resume-next-pause.
28 // This extra field doesn't increase memory usage on 32-bit CPUs and above,
29 // since it falls into the padding of the FipsIndicator bit above.
30 RunState uint8
31 32 // DeferFrame stores a pointer to the (stack allocated) defer frame of the
33 // goroutine that is used for the recover builtin.
34 DeferFrame unsafe.Pointer
35 }
36 37 const (
38 // Initial state: the goroutine state is saved on the stack.
39 RunStatePaused = iota
40 41 // The goroutine is running right now.
42 RunStateRunning
43 44 // The goroutine is running, but already marked as "can resume".
45 // The next call to Pause() won't actually pause the goroutine.
46 RunStateResuming
47 )
48 49 // DataUint32 returns the Data field as a uint32. The value is only valid after
50 // setting it through SetDataUint32 or by storing to it using DataAtomicUint32.
51 func (t *Task) DataUint32() uint32 {
52 return *(*uint32)(unsafe.Pointer(&t.Data))
53 }
54 55 // SetDataUint32 updates the uint32 portion of the Data field (which could be
56 // the first 4 or last 4 bytes depending on the architecture endianness).
57 func (t *Task) SetDataUint32(val uint32) {
58 *(*uint32)(unsafe.Pointer(&t.Data)) = val
59 }
60 61 // DataAtomicUint32 returns the Data field as an atomic-if-needed Uint32 value.
62 func (t *Task) DataAtomicUint32() *Uint32 {
63 return (*Uint32)(unsafe.Pointer(&t.Data))
64 }
65 66 // getGoroutineStackSize is a compiler intrinsic that returns the stack size for
67 // the given function and falls back to the default stack size. It is replaced
68 // with a load from a special section just before codegen.
69 func getGoroutineStackSize(fn uintptr) uintptr
70 71 //go:linkname runtime_alloc runtime.alloc
72 func runtime_alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
73 74 //go:linkname scheduleTask runtime.scheduleTask
75 func scheduleTask(*Task)
76