LEFT | RIGHT |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "arch_GOARCH.h" | 6 #include "arch_GOARCH.h" |
7 #include "defs_GOOS_GOARCH.h" | 7 #include "defs_GOOS_GOARCH.h" |
8 #include "malloc.h" | 8 #include "malloc.h" |
9 | 9 |
10 #define LOG if(1) {} else runtime·printf | 10 #define LOG if(1) {} else runtime·printf |
(...skipping 14 matching lines...) Expand all Loading... |
25 int64 wd; | 25 int64 wd; |
26 }; | 26 }; |
27 | 27 |
28 static struct | 28 static struct |
29 { | 29 { |
30 Lock; | 30 Lock; |
31 int32 fd; | 31 int32 fd; |
32 PollFD* cache; | 32 PollFD* cache; |
33 } s; | 33 } s; |
34 | 34 |
35 static void epollblock(PollFD *fd, G**); | 35 static void» epollblock(PollFD *fd, G**); |
36 static G* epollunblock(PollFD *fd, G**); | 36 static G*» epollunblock(PollFD *fd, G**); |
37 static void deadline(int64, Eface); | 37 static void» deadline(int64, Eface); |
38 static void readDeadline(int64, Eface); | 38 static void» readDeadline(int64, Eface); |
39 static void writeDeadline(int64, Eface); | 39 static void» writeDeadline(int64, Eface); |
40 static PollFD* allocFD(void); | 40 static PollFD*» allocFD(void); |
| 41 static void» pollloop(void); |
41 | 42 |
42 #define READY ((G*)1) | 43 #define READY ((G*)1) |
43 | 44 |
44 void | 45 void |
45 net·runtime_initPollServer(void) | 46 net·runtime_initPollServer(void) |
46 { | 47 { |
47 int32 errno; | 48 int32 errno; |
48 | 49 |
49 LOG("init epoll dispatcher\n"); | 50 LOG("init epoll dispatcher\n"); |
| 51 runtime·newproc1((byte*)pollloop, nil, 0, 0, net·runtime_initPollServer)
; |
50 errno = runtime·epollcreate1(EPOLL_CLOEXEC, &s.fd); | 52 errno = runtime·epollcreate1(EPOLL_CLOEXEC, &s.fd); |
51 LOG("epollcreate1: errno=%d fd=%d\n", errno, s.fd); | 53 LOG("epollcreate1: errno=%d fd=%d\n", errno, s.fd); |
52 if(errno == 0) | 54 if(errno == 0) |
53 return; | 55 return; |
54 errno = runtime·epollcreate(1024, &s.fd); | 56 errno = runtime·epollcreate(1024, &s.fd); |
55 LOG("epollcreate: errno=%d fd=%d\n", errno, s.fd); | 57 LOG("epollcreate: errno=%d fd=%d\n", errno, s.fd); |
56 if(errno == 0) | 58 if(errno == 0) |
57 // TODO(dvyukov): set CLOEXEC | 59 // TODO(dvyukov): set CLOEXEC |
58 return; | 60 return; |
59 runtime·printf("epoll: failed to create descriptor (%d)\n", errno); | 61 runtime·printf("epoll: failed to create descriptor (%d)\n", errno); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 runtime·deltimer(&fd->wt); | 214 runtime·deltimer(&fd->wt); |
213 fd->wt.f = nil; | 215 fd->wt.f = nil; |
214 } | 216 } |
215 runtime·unlock(fd); | 217 runtime·unlock(fd); |
216 if(rg) | 218 if(rg) |
217 runtime·ready(rg); | 219 runtime·ready(rg); |
218 if(wg) | 220 if(wg) |
219 runtime·ready(wg); | 221 runtime·ready(wg); |
220 } | 222 } |
221 | 223 |
222 G* | 224 static G* |
223 runtime·netwait(uint32 ms) | 225 netwait(uint32 ms, uint32 cnt) |
224 { | 226 { |
225 EpollEvent ev, events[128]; | 227 EpollEvent ev, events[128]; |
226 PollFD *fd; | 228 PollFD *fd; |
227 G *gp, *rg, *wg; | 229 G *gp, *rg, *wg; |
228 int32 n, i; | 230 int32 n, i; |
229 | 231 |
230 LOG("epoll wait\n"); | 232 LOG("epoll wait\n"); |
| 233 /* |
231 if(s.fd == 0) { | 234 if(s.fd == 0) { |
232 runtime·usleep(ms*1000); | 235 runtime·usleep(ms*1000); |
233 return nil; | 236 return nil; |
234 } | 237 } |
235 » n = runtime·epollwait(s.fd, events, nelem(events), ms); | 238 » */ |
| 239 » if(cnt > nelem(events)) |
| 240 » » cnt = nelem(events); |
| 241 » runtime·entersyscall(); |
| 242 » n = runtime·epollwait(s.fd, events, cnt, ms); |
| 243 » runtime·exitsyscall(); |
236 //TODO(dvyukov): handle errors other than EAGAIN and EINTR | 244 //TODO(dvyukov): handle errors other than EAGAIN and EINTR |
237 LOG("epoll wait got %d\n", n); | 245 LOG("epoll wait got %d\n", n); |
238 if(n <= 0) | 246 if(n <= 0) |
239 return nil; | 247 return nil; |
240 gp = nil; | 248 gp = nil; |
241 for(i = 0; i < n; i++) { | 249 for(i = 0; i < n; i++) { |
242 ev = events[i]; | 250 ev = events[i]; |
243 if(ev.events == 0) | 251 if(ev.events == 0) |
244 continue; | 252 continue; |
245 fd = (PollFD*)ev.ctx; | 253 fd = (PollFD*)ev.ctx; |
(...skipping 11 matching lines...) Expand all Loading... |
257 } | 265 } |
258 if(wg) { | 266 if(wg) { |
259 wg->schedlink = gp; | 267 wg->schedlink = gp; |
260 gp = wg; | 268 gp = wg; |
261 } | 269 } |
262 } | 270 } |
263 return gp; | 271 return gp; |
264 } | 272 } |
265 | 273 |
266 static void | 274 static void |
| 275 pollloop(void) |
| 276 { |
| 277 G *gp, *gp1; |
| 278 |
| 279 for(;;) { |
| 280 gp = netwait(10, 10); |
| 281 while(gp) { |
| 282 gp1 = gp; |
| 283 gp = gp->schedlink; |
| 284 runtime·ready(gp1); |
| 285 } |
| 286 } |
| 287 } |
| 288 |
| 289 static void |
267 epollblock(PollFD *fd, G **gp) | 290 epollblock(PollFD *fd, G **gp) |
268 { | 291 { |
269 LOG("epoll block %p on %p\n", g, gp); | 292 LOG("epoll block %p on %p\n", g, gp); |
270 if(*gp == READY) { | 293 if(*gp == READY) { |
271 *gp = nil; | 294 *gp = nil; |
272 return; | 295 return; |
273 } | 296 } |
274 if(*gp != nil) | 297 if(*gp != nil) |
275 runtime·throw("epoll: double wait"); | 298 runtime·throw("epoll: double wait"); |
276 *gp = g; | 299 *gp = g; |
277 » runtime·park(&fd->Lock, (void(*)(void*))runtime·unlock, "IO wait"); | 300 » runtime·park(runtime·unlock, &fd->Lock, "IO wait"); |
278 runtime·lock(fd); | 301 runtime·lock(fd); |
279 } | 302 } |
280 | 303 |
281 static G* | 304 static G* |
282 epollunblock(PollFD *fd, G **gp) | 305 epollunblock(PollFD *fd, G **gp) |
283 { | 306 { |
284 G *old; | 307 G *old; |
285 | 308 |
286 USED(fd); | 309 USED(fd); |
287 LOG("epoll unblock on %p\n", gp); | 310 LOG("epoll unblock on %p\n", gp); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 for(i=0; i<n; i++) { | 390 for(i=0; i<n; i++) { |
368 fd[i].link = s.cache; | 391 fd[i].link = s.cache; |
369 s.cache = &fd[i]; | 392 s.cache = &fd[i]; |
370 }· | 393 }· |
371 } | 394 } |
372 fd = s.cache; | 395 fd = s.cache; |
373 s.cache = fd->link; | 396 s.cache = fd->link; |
374 runtime·unlock(&s); | 397 runtime·unlock(&s); |
375 return fd; | 398 return fd; |
376 } | 399 } |
LEFT | RIGHT |