Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(121)

Side by Side Diff: src/runtime/select.go

Issue 152570049: [dev.power64] code review 152570049: all: merge default into dev.power64 (Closed)
Patch Set: diff -r 36f7fc9495481ed67a159eea0eb2fac35b7c46a5 https://code.google.com/p/go Created 10 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime/runtime_test.go ('k') | src/runtime/sema.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 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 package runtime 5 package runtime
6 6
7 // This file contains the implementation of Go select statements. 7 // This file contains the implementation of Go select statements.
8 8
9 import "unsafe" 9 import "unsafe"
10 10
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 } 361 }
362 } 362 }
363 363
364 // wait for someone to wake us up 364 // wait for someone to wake us up
365 gp.param = nil 365 gp.param = nil
366 gopark(unsafe.Pointer(funcPC(selparkcommit)), unsafe.Pointer(sel), "sele ct") 366 gopark(unsafe.Pointer(funcPC(selparkcommit)), unsafe.Pointer(sel), "sele ct")
367 367
368 // someone woke us up 368 // someone woke us up
369 sellock(sel) 369 sellock(sel)
370 sg = (*sudog)(gp.param) 370 sg = (*sudog)(gp.param)
371 gp.param = nil
371 372
372 // pass 3 - dequeue from unsuccessful chans 373 // pass 3 - dequeue from unsuccessful chans
373 // otherwise they stack up on quiet channels 374 // otherwise they stack up on quiet channels
374 // record the successful case, if any. 375 // record the successful case, if any.
375 // We singly-linked up the SudoGs in case order, so when 376 // We singly-linked up the SudoGs in case order, so when
376 // iterating through the linked list they are in reverse order. 377 // iterating through the linked list they are in reverse order.
377 cas = nil 378 cas = nil
378 sglist = gp.waiting 379 sglist = gp.waiting
380 // Clear all selectdone and elem before unlinking from gp.waiting.
381 // They must be cleared before being put back into the sudog cache.
382 // Clear before unlinking, because if a stack copy happens after the unl ink,
383 // they will not be updated, they will be left pointing to the old stack ,
384 // which creates dangling pointers, which may be detected by the
385 // garbage collector.
386 for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
387 sg1.selectdone = nil
388 sg1.elem = nil
389 }
379 gp.waiting = nil 390 gp.waiting = nil
380 for i := int(sel.ncase) - 1; i >= 0; i-- { 391 for i := int(sel.ncase) - 1; i >= 0; i-- {
381 k = &scases[pollorder[i]] 392 k = &scases[pollorder[i]]
382 if sglist.releasetime > 0 { 393 if sglist.releasetime > 0 {
383 k.releasetime = sglist.releasetime 394 k.releasetime = sglist.releasetime
384 } 395 }
385 if sg == sglist { 396 if sg == sglist {
386 cas = k 397 cas = k
387 } else { 398 } else {
388 c = k._chan 399 c = k._chan
389 if k.kind == _CaseSend { 400 if k.kind == _CaseSend {
390 » » » » c.sendq.dequeueg(gp) 401 » » » » c.sendq.dequeueSudoG(sglist)
391 } else { 402 } else {
392 » » » » c.recvq.dequeueg(gp) 403 » » » » c.recvq.dequeueSudoG(sglist)
393 } 404 }
394 } 405 }
395 sgnext = sglist.waitlink 406 sgnext = sglist.waitlink
396 releaseSudog(sglist) 407 releaseSudog(sglist)
397 sglist = sgnext 408 sglist = sgnext
398 } 409 }
399 410
400 if cas == nil { 411 if cas == nil {
401 goto loop 412 goto loop
402 } 413 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 selunlock(sel) 510 selunlock(sel)
500 if debugSelect { 511 if debugSelect {
501 print("syncrecv: sel=", sel, " c=", c, "\n") 512 print("syncrecv: sel=", sel, " c=", c, "\n")
502 } 513 }
503 if cas.receivedp != nil { 514 if cas.receivedp != nil {
504 *cas.receivedp = true 515 *cas.receivedp = true
505 } 516 }
506 if cas.elem != nil { 517 if cas.elem != nil {
507 memmove(cas.elem, sg.elem, uintptr(c.elemsize)) 518 memmove(cas.elem, sg.elem, uintptr(c.elemsize))
508 } 519 }
520 sg.elem = nil
509 gp = sg.g 521 gp = sg.g
510 gp.param = unsafe.Pointer(sg) 522 gp.param = unsafe.Pointer(sg)
511 if sg.releasetime != 0 { 523 if sg.releasetime != 0 {
512 sg.releasetime = cputicks() 524 sg.releasetime = cputicks()
513 } 525 }
514 goready(gp) 526 goready(gp)
515 goto retc 527 goto retc
516 528
517 rclose: 529 rclose:
518 // read at end of closed channel 530 // read at end of closed channel
(...skipping 15 matching lines...) Expand all
534 raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc) 546 raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
535 racesync(c, sg) 547 racesync(c, sg)
536 } 548 }
537 selunlock(sel) 549 selunlock(sel)
538 if debugSelect { 550 if debugSelect {
539 print("syncsend: sel=", sel, " c=", c, "\n") 551 print("syncsend: sel=", sel, " c=", c, "\n")
540 } 552 }
541 if sg.elem != nil { 553 if sg.elem != nil {
542 memmove(sg.elem, cas.elem, uintptr(c.elemsize)) 554 memmove(sg.elem, cas.elem, uintptr(c.elemsize))
543 } 555 }
556 sg.elem = nil
544 gp = sg.g 557 gp = sg.g
545 gp.param = unsafe.Pointer(sg) 558 gp.param = unsafe.Pointer(sg)
546 if sg.releasetime != 0 { 559 if sg.releasetime != 0 {
547 sg.releasetime = cputicks() 560 sg.releasetime = cputicks()
548 } 561 }
549 goready(gp) 562 goready(gp)
550 563
551 retc: 564 retc:
552 if cas.releasetime > 0 { 565 if cas.releasetime > 0 {
553 blockevent(cas.releasetime-t0, 2) 566 blockevent(cas.releasetime-t0, 2)
(...skipping 27 matching lines...) Expand all
581 const ( 594 const (
582 _ selectDir = iota 595 _ selectDir = iota
583 selectSend // case Chan <- Send 596 selectSend // case Chan <- Send
584 selectRecv // case <-Chan: 597 selectRecv // case <-Chan:
585 selectDefault // default 598 selectDefault // default
586 ) 599 )
587 600
588 func reflect_rselect(cases []runtimeSelect) (chosen int, recvOK bool) { 601 func reflect_rselect(cases []runtimeSelect) (chosen int, recvOK bool) {
589 // flagNoScan is safe here, because all objects are also referenced from cases. 602 // flagNoScan is safe here, because all objects are also referenced from cases.
590 size := selectsize(uintptr(len(cases))) 603 size := selectsize(uintptr(len(cases)))
591 » sel := (*_select)(gomallocgc(size, nil, flagNoScan)) 604 » sel := (*_select)(mallocgc(size, nil, flagNoScan))
592 newselect(sel, int64(size), int32(len(cases))) 605 newselect(sel, int64(size), int32(len(cases)))
593 r := new(bool) 606 r := new(bool)
594 for i := range cases { 607 for i := range cases {
595 rc := &cases[i] 608 rc := &cases[i]
596 switch rc.dir { 609 switch rc.dir {
597 case selectDefault: 610 case selectDefault:
598 selectdefaultImpl(sel, uintptr(i), 0) 611 selectdefaultImpl(sel, uintptr(i), 0)
599 case selectSend: 612 case selectSend:
600 if rc.ch == nil { 613 if rc.ch == nil {
601 break 614 break
602 } 615 }
603 selectsendImpl(sel, rc.ch, uintptr(i), rc.val, 0) 616 selectsendImpl(sel, rc.ch, uintptr(i), rc.val, 0)
604 case selectRecv: 617 case selectRecv:
605 if rc.ch == nil { 618 if rc.ch == nil {
606 break 619 break
607 } 620 }
608 selectrecvImpl(sel, rc.ch, uintptr(i), rc.val, r, 0) 621 selectrecvImpl(sel, rc.ch, uintptr(i), rc.val, r, 0)
609 } 622 }
610 } 623 }
611 624
612 pc, _ := selectgoImpl(sel) 625 pc, _ := selectgoImpl(sel)
613 chosen = int(pc) 626 chosen = int(pc)
614 recvOK = *r 627 recvOK = *r
615 return 628 return
616 } 629 }
617 630
618 func (q *waitq) dequeueg(gp *g) { 631 func (q *waitq) dequeueSudoG(s *sudog) {
619 var prevsgp *sudog 632 var prevsgp *sudog
620 l := &q.first 633 l := &q.first
621 for { 634 for {
622 sgp := *l 635 sgp := *l
623 if sgp == nil { 636 if sgp == nil {
624 return 637 return
625 } 638 }
626 » » if sgp.g == gp { 639 » » if sgp == s {
627 *l = sgp.next 640 *l = sgp.next
628 if q.last == sgp { 641 if q.last == sgp {
629 q.last = prevsgp 642 q.last = prevsgp
630 } 643 }
631 return 644 return
632 } 645 }
633 l = &sgp.next 646 l = &sgp.next
634 prevsgp = sgp 647 prevsgp = sgp
635 } 648 }
636 } 649 }
OLDNEW
« no previous file with comments | « src/runtime/runtime_test.go ('k') | src/runtime/sema.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b