Source file
src/runtime/list.go
1
2
3
4
5 package runtime
6
7 import (
8 "unsafe"
9 )
10
11
12
13
14
15
16 type listHead struct {
17 obj unsafe.Pointer
18
19 initialized bool
20 nodeOffset uintptr
21 }
22
23
24
25 func (head *listHead) init(off uintptr) {
26 head.initialized = true
27 head.nodeOffset = off
28 }
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 type listNode struct {
46 prev unsafe.Pointer
47 next unsafe.Pointer
48 }
49
50 func (head *listHead) getNode(p unsafe.Pointer) *listNode {
51 if !head.initialized {
52 throw("runtime: uninitialized listHead")
53 }
54
55 if p == nil {
56 return nil
57 }
58 return (*listNode)(unsafe.Add(p, head.nodeOffset))
59 }
60
61
62 func (head *listHead) empty() bool {
63 return head.obj == nil
64 }
65
66
67 func (head *listHead) head() unsafe.Pointer {
68 return head.obj
69 }
70
71
72 func (head *listHead) push(p unsafe.Pointer) {
73
74
75
76 pNode := head.getNode(p)
77 pNode.next = head.obj
78
79
80 if head.obj != nil {
81 headNode := head.getNode(head.obj)
82 headNode.prev = p
83 }
84
85 head.obj = p
86 }
87
88
89 func (head *listHead) pop() unsafe.Pointer {
90 if head.obj == nil {
91 return nil
92 }
93
94
95 p := head.obj
96
97
98 pNode := head.getNode(p)
99 head.obj = pNode.next
100
101
102 pNode.next = nil
103
104
105 if head.obj != nil {
106 headNode := head.getNode(head.obj)
107 headNode.prev = nil
108 }
109
110 return p
111 }
112
113
114 func (head *listHead) remove(p unsafe.Pointer) {
115 if head.obj == p {
116
117 head.pop()
118 return
119 }
120
121 pNode := head.getNode(p)
122 prevNode := head.getNode(pNode.prev)
123 nextNode := head.getNode(pNode.next)
124
125
126 if prevNode != nil {
127 prevNode.next = pNode.next
128 }
129
130 if nextNode != nil {
131 nextNode.prev = pNode.prev
132 }
133
134 pNode.prev = nil
135 pNode.next = nil
136 }
137
View as plain text