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