annotate libgo/go/runtime/netpoll_aix.go @ 136:4627f235cf2a

fix c-next example
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 08 Nov 2018 14:11:56 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // Copyright 2017 The Go Authors. All rights reserved.
kono
parents:
diff changeset
2 // Use of this source code is governed by a BSD-style
kono
parents:
diff changeset
3 // license that can be found in the LICENSE file.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 package runtime
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 import "unsafe"
kono
parents:
diff changeset
8
kono
parents:
diff changeset
9 // This is based on the former libgo/runtime/netpoll_select.c implementation
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
10 // except that it uses poll instead of select and is written in Go.
111
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 type pollfd struct {
kono
parents:
diff changeset
13 fd int32
kono
parents:
diff changeset
14 events int16
kono
parents:
diff changeset
15 revents int16
kono
parents:
diff changeset
16 }
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 const _POLLIN = 0x0001
kono
parents:
diff changeset
19 const _POLLOUT = 0x0002
kono
parents:
diff changeset
20 const _POLLHUP = 0x2000
kono
parents:
diff changeset
21 const _POLLERR = 0x4000
kono
parents:
diff changeset
22
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
23 //go:noescape
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
24 //extern poll
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
25 func libc_poll(pfds *pollfd, npfds uintptr, timeout uintptr) int32
111
kono
parents:
diff changeset
26
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
27 //go:noescape
111
kono
parents:
diff changeset
28 //extern pipe
kono
parents:
diff changeset
29 func libc_pipe(fd *int32) int32
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 //extern __go_fcntl_uintptr
kono
parents:
diff changeset
32 func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr)
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 func fcntl(fd, cmd int32, arg uintptr) uintptr {
kono
parents:
diff changeset
35 r, _ := fcntlUintptr(uintptr(fd), uintptr(cmd), arg)
kono
parents:
diff changeset
36 return r
kono
parents:
diff changeset
37 }
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 var (
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
40 pfds []pollfd
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
41 pds []*pollDesc
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
42 mtxpoll mutex
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
43 mtxset mutex
111
kono
parents:
diff changeset
44 rdwake int32
kono
parents:
diff changeset
45 wrwake int32
kono
parents:
diff changeset
46 needsUpdate bool
kono
parents:
diff changeset
47 )
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 func netpollinit() {
kono
parents:
diff changeset
50 var p [2]int32
kono
parents:
diff changeset
51
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
52 // Create the pipe we use to wakeup poll.
111
kono
parents:
diff changeset
53 if err := libc_pipe(&p[0]); err < 0 {
kono
parents:
diff changeset
54 throw("runtime: netpollinit failed to create pipe")
kono
parents:
diff changeset
55 }
kono
parents:
diff changeset
56 rdwake = p[0]
kono
parents:
diff changeset
57 wrwake = p[1]
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 fl := fcntl(rdwake, _F_GETFL, 0)
kono
parents:
diff changeset
60 fcntl(rdwake, _F_SETFL, fl|_O_NONBLOCK)
kono
parents:
diff changeset
61 fcntl(rdwake, _F_SETFD, _FD_CLOEXEC)
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 fl = fcntl(wrwake, _F_GETFL, 0)
kono
parents:
diff changeset
64 fcntl(wrwake, _F_SETFD, _FD_CLOEXEC)
kono
parents:
diff changeset
65
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66 // Pre-allocate array of pollfd structures for poll.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 pfds = make([]pollfd, 1, 128)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
68 // Poll the read side of the pipe.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69 pfds[0].fd = rdwake
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70 pfds[0].events = _POLLIN
111
kono
parents:
diff changeset
71
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72 // Allocate index to pd array
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 pds = make([]*pollDesc, 1, 128)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 pds[0] = nil
111
kono
parents:
diff changeset
75 }
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 func netpolldescriptor() uintptr {
kono
parents:
diff changeset
78 return ^uintptr(0)
kono
parents:
diff changeset
79 }
kono
parents:
diff changeset
80
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 func netpollwakeup() {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 if !needsUpdate {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 needsUpdate = true
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84 b := [1]byte{0}
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85 write(uintptr(wrwake), unsafe.Pointer(&b[0]), 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
86 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88
111
kono
parents:
diff changeset
89 func netpollopen(fd uintptr, pd *pollDesc) int32 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
90 lock(&mtxpoll)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
91 netpollwakeup()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 lock(&mtxset)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
94 unlock(&mtxpoll)
111
kono
parents:
diff changeset
95
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 pd.user = uint32(len(pfds))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 var pfd pollfd
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 pfd.fd = int32(fd)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 pfds = append(pfds, pfd)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 pds = append(pds, pd)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101 unlock(&mtxset)
111
kono
parents:
diff changeset
102 return 0
kono
parents:
diff changeset
103 }
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 func netpollclose(fd uintptr) int32 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 lock(&mtxpoll)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 netpollwakeup()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 lock(&mtxset)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 unlock(&mtxpoll)
111
kono
parents:
diff changeset
111
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112 for i := 0; i < len(pfds); i++ {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 if pfds[i].fd == int32(fd) {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 pfds[i] = pfds[len(pfds)-1]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115 pfds = pfds[:len(pfds)-1]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 pds[i] = pds[len(pds)-1]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118 pds[i].user = uint32(i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 pds = pds[:len(pds)-1]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 break
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121 }
111
kono
parents:
diff changeset
122 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 unlock(&mtxset)
111
kono
parents:
diff changeset
124 return 0
kono
parents:
diff changeset
125 }
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 func netpollarm(pd *pollDesc, mode int) {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
128 lock(&mtxpoll)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
129 netpollwakeup()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 lock(&mtxset)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 unlock(&mtxpoll)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134 switch mode {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135 case 'r':
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 pfds[pd.user].events |= _POLLIN
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 case 'w':
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 pfds[pd.user].events |= _POLLOUT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
139 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
140 unlock(&mtxset)
111
kono
parents:
diff changeset
141 }
kono
parents:
diff changeset
142
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
143 //go:nowritebarrierrec
111
kono
parents:
diff changeset
144 func netpoll(block bool) *g {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
145 timeout := ^uintptr(0)
111
kono
parents:
diff changeset
146 if !block {
kono
parents:
diff changeset
147 timeout = 0
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
148 return nil
111
kono
parents:
diff changeset
149 }
kono
parents:
diff changeset
150 retry:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
151 lock(&mtxpoll)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
152 lock(&mtxset)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
153 needsUpdate = false
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
154 unlock(&mtxpoll)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156 n := libc_poll(&pfds[0], uintptr(len(pfds)), timeout)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 if n < 0 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
158 e := errno()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159 if e != _EINTR {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160 throw("runtime: poll failed")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 unlock(&mtxset)
111
kono
parents:
diff changeset
163 goto retry
kono
parents:
diff changeset
164 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 // Check if some descriptors need to be changed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 if n != 0 && pfds[0].revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
167 var b [1]byte
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
168 for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 {
111
kono
parents:
diff changeset
169 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 // Do not look at the other fds in this case as the mode may have changed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 // XXX only additions of flags are made, so maybe it is ok
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 unlock(&mtxset)
111
kono
parents:
diff changeset
173 goto retry
kono
parents:
diff changeset
174 }
kono
parents:
diff changeset
175 var gp guintptr
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 for i := 0; i < len(pfds) && n > 0; i++ {
111
kono
parents:
diff changeset
177 pfd := &pfds[i]
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 var mode int32
kono
parents:
diff changeset
180 if pfd.revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 {
kono
parents:
diff changeset
181 mode += 'r'
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 pfd.events &= ^_POLLIN
111
kono
parents:
diff changeset
183 }
kono
parents:
diff changeset
184 if pfd.revents&(_POLLOUT|_POLLHUP|_POLLERR) != 0 {
kono
parents:
diff changeset
185 mode += 'w'
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186 pfd.events &= ^_POLLOUT
111
kono
parents:
diff changeset
187 }
kono
parents:
diff changeset
188 if mode != 0 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
189 netpollready(&gp, pds[i], mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
190 n--
111
kono
parents:
diff changeset
191 }
kono
parents:
diff changeset
192 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
193 unlock(&mtxset)
111
kono
parents:
diff changeset
194 if block && gp == 0 {
kono
parents:
diff changeset
195 goto retry
kono
parents:
diff changeset
196 }
kono
parents:
diff changeset
197 return gp.ptr()
kono
parents:
diff changeset
198 }