1 // AUTO-GENERATED by autogen.sh; DO NOT EDIT
10 #line 13 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
11 uint32 runtime_Hchansize
= sizeof ( Hchan
) ;
12 #line 15 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
13 static void dequeueg ( WaitQ
* ) ;
14 static SudoG
* dequeue ( WaitQ
* ) ;
15 static void enqueue ( WaitQ
* , SudoG
* ) ;
16 static void racesync ( Hchan
* , SudoG
* ) ;
17 #line 20 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
19 makechan ( ChanType
*t
, int64 hint
)
24 #line 27 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
25 elem
= t
->__element_type
;
26 #line 30 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
27 if ( elem
->__size
>= ( 1<<16 ) )
28 runtime_throw ( "makechan: invalid channel element type" ) ;
29 #line 33 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
30 if ( hint
< 0 || ( intgo
) hint
!= hint
|| ( elem
->__size
> 0 && ( uintptr
) hint
> ( MaxMem
- sizeof ( *c
) ) / elem
->__size
) )
31 runtime_panicstring ( "makechan: size out of range" ) ;
32 #line 36 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
34 n
= ROUND ( n
, elem
->__align
) ;
35 #line 40 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
36 c
= ( Hchan
* ) runtime_mallocgc ( sizeof ( *c
) + hint
*elem
->__size
, ( uintptr
) t
| TypeInfo_Chan
, 0 ) ;
37 c
->elemsize
= elem
->__size
;
40 #line 45 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
42 runtime_printf ( "makechan: chan=%p; elemsize=%D; dataqsiz=%D\n" ,
43 c
, ( int64
) elem
->__size
, ( int64
) c
->dataqsiz
) ;
44 #line 49 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
47 Hchan
* reflect_makechan(ChanType
* t
, uint64 size
) __asm__ (GOSYM_PREFIX
"reflect.makechan");
48 Hchan
* reflect_makechan(ChanType
* t
, uint64 size
)
51 #line 52 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
53 c
= makechan(t
, size
);
57 #line 56 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
59 __go_new_channel ( ChanType
*t
, uintptr hint
)
61 return makechan ( t
, hint
) ;
63 #line 62 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
65 __go_new_channel_big ( ChanType
*t
, uint64 hint
)
67 return makechan ( t
, hint
) ;
69 #line 82 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
71 chansend ( ChanType
*t
, Hchan
*c
, byte
*ep
, bool block
, void *pc
)
78 #line 91 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
80 #line 93 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
82 runtime_racereadobjectpc ( ep
, t
->__element_type
, runtime_getcallerpc ( &t
) , chansend
) ;
83 #line 96 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
88 runtime_park ( nil
, nil
, "chan send (nil chan)" ) ;
91 #line 104 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
92 if ( runtime_gcwaiting ( ) )
94 #line 107 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
96 runtime_printf ( "chansend: chan=%p\n" , c
) ;
98 #line 111 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
100 mysg
.releasetime
= 0;
101 if ( runtime_blockprofilerate
> 0 ) {
102 t0
= runtime_cputicks ( ) ;
103 mysg
.releasetime
= -1;
105 #line 118 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
108 runtime_racereadpc ( c
, pc
, chansend
) ;
111 #line 124 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
112 if ( c
->dataqsiz
> 0 )
114 #line 127 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
115 sg
= dequeue ( &c
->recvq
) ;
118 racesync ( c
, sg
) ;
119 runtime_unlock ( c
) ;
120 #line 133 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
123 if ( sg
->elem
!= nil
)
124 runtime_memmove ( sg
->elem
, ep
, c
->elemsize
) ;
125 if ( sg
->releasetime
)
126 sg
->releasetime
= runtime_cputicks ( ) ;
127 runtime_ready ( gp
) ;
130 #line 143 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
132 runtime_unlock ( c
) ;
135 #line 148 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
138 mysg
.selectdone
= nil
;
140 enqueue ( &c
->sendq
, &mysg
) ;
141 runtime_parkunlock ( c
, "chan send" ) ;
142 #line 155 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
143 if ( g
->param
== nil
) {
146 runtime_throw ( "chansend: spurious wakeup" ) ;
149 #line 162 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
150 if ( mysg
.releasetime
> 0 )
151 runtime_blockevent ( mysg
.releasetime
- t0
, 2 ) ;
152 #line 165 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
154 #line 167 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
158 #line 171 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
159 if ( c
->qcount
>= c
->dataqsiz
) {
161 runtime_unlock ( c
) ;
166 mysg
.selectdone
= nil
;
167 enqueue ( &c
->sendq
, &mysg
) ;
168 runtime_parkunlock ( c
, "chan send" ) ;
169 #line 182 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
173 #line 186 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
175 runtime_racerelease ( chanbuf ( c
, c
->sendx
) ) ;
176 #line 189 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
177 runtime_memmove ( chanbuf ( c
, c
->sendx
) , ep
, c
->elemsize
) ;
178 if ( ++c
->sendx
== c
->dataqsiz
)
181 #line 194 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
182 sg
= dequeue ( &c
->recvq
) ;
185 runtime_unlock ( c
) ;
186 if ( sg
->releasetime
)
187 sg
->releasetime
= runtime_cputicks ( ) ;
188 runtime_ready ( gp
) ;
190 runtime_unlock ( c
) ;
191 if ( mysg
.releasetime
> 0 )
192 runtime_blockevent ( mysg
.releasetime
- t0
, 2 ) ;
194 #line 207 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
196 runtime_unlock ( c
) ;
197 runtime_panicstring ( "send on closed channel" ) ;
200 #line 214 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
202 chanrecv ( ChanType
*t
, Hchan
* c
, byte
*ep
, bool block
, bool *received
)
209 #line 223 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
210 if ( runtime_gcwaiting ( ) )
211 runtime_gosched ( ) ;
212 #line 228 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
214 runtime_printf ( "chanrecv: chan=%p\n" , c
) ;
215 #line 231 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
217 #line 233 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
222 runtime_park ( nil
, nil
, "chan receive (nil chan)" ) ;
225 #line 241 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
227 mysg
.releasetime
= 0;
228 if ( runtime_blockprofilerate
> 0 ) {
229 t0
= runtime_cputicks ( ) ;
230 mysg
.releasetime
= -1;
232 #line 248 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
234 if ( c
->dataqsiz
> 0 )
236 #line 252 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
239 #line 255 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
240 sg
= dequeue ( &c
->sendq
) ;
243 racesync ( c
, sg
) ;
244 runtime_unlock ( c
) ;
245 #line 261 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
247 runtime_memmove ( ep
, sg
->elem
, c
->elemsize
) ;
250 if ( sg
->releasetime
)
251 sg
->releasetime
= runtime_cputicks ( ) ;
252 runtime_ready ( gp
) ;
253 #line 269 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
254 if ( received
!= nil
)
258 #line 274 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
260 runtime_unlock ( c
) ;
263 #line 279 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
266 mysg
.selectdone
= nil
;
268 enqueue ( &c
->recvq
, &mysg
) ;
269 runtime_parkunlock ( c
, "chan receive" ) ;
270 #line 286 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
271 if ( g
->param
== nil
) {
274 runtime_throw ( "chanrecv: spurious wakeup" ) ;
277 #line 293 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
278 if ( received
!= nil
)
280 if ( mysg
.releasetime
> 0 )
281 runtime_blockevent ( mysg
.releasetime
- t0
, 2 ) ;
283 #line 299 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
285 if ( c
->qcount
<= 0 ) {
288 #line 304 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
290 runtime_unlock ( c
) ;
291 if ( received
!= nil
)
297 mysg
.selectdone
= nil
;
298 enqueue ( &c
->recvq
, &mysg
) ;
299 runtime_parkunlock ( c
, "chan receive" ) ;
300 #line 316 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
304 #line 320 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
306 runtime_raceacquire ( chanbuf ( c
, c
->recvx
) ) ;
307 #line 323 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
309 runtime_memmove ( ep
, chanbuf ( c
, c
->recvx
) , c
->elemsize
) ;
310 runtime_memclr ( chanbuf ( c
, c
->recvx
) , c
->elemsize
) ;
311 if ( ++c
->recvx
== c
->dataqsiz
)
314 #line 330 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
315 sg
= dequeue ( &c
->sendq
) ;
318 runtime_unlock ( c
) ;
319 if ( sg
->releasetime
)
320 sg
->releasetime
= runtime_cputicks ( ) ;
321 runtime_ready ( gp
) ;
323 runtime_unlock ( c
) ;
324 #line 340 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
325 if ( received
!= nil
)
327 if ( mysg
.releasetime
> 0 )
328 runtime_blockevent ( mysg
.releasetime
- t0
, 2 ) ;
330 #line 346 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
333 runtime_memclr ( ep
, c
->elemsize
) ;
334 if ( received
!= nil
)
337 runtime_raceacquire ( c
) ;
338 runtime_unlock ( c
) ;
339 if ( mysg
.releasetime
> 0 )
340 runtime_blockevent ( mysg
.releasetime
- t0
, 2 ) ;
343 #line 361 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
345 __go_send_small ( ChanType
*t
, Hchan
* c
, uint64 val
)
349 byte b
[sizeof ( uint64
) ];
353 #line 371 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
355 #ifndef WORDS_BIGENDIAN
358 v
= u
.b
+ sizeof ( uint64
) - t
->__element_type
->__size
;
360 chansend ( t
, c
, v
, true , runtime_getcallerpc ( &t
) ) ;
362 #line 382 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
364 __go_send_big ( ChanType
*t
, Hchan
* c
, byte
* v
)
366 chansend ( t
, c
, v
, true , runtime_getcallerpc ( &t
) ) ;
368 #line 390 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
370 __go_receive ( ChanType
*t
, Hchan
* c
, byte
* v
)
372 chanrecv ( t
, c
, v
, true , nil
) ;
374 #line 396 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
375 _Bool
runtime_chanrecv2 ( ChanType
*t
, Hchan
* c
, byte
* v
)
376 __asm__ ( GOSYM_PREFIX
"runtime.chanrecv2" ) ;
377 #line 399 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
379 runtime_chanrecv2 ( ChanType
*t
, Hchan
* c
, byte
* v
)
381 bool received
= false;
382 #line 404 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
383 chanrecv ( t
, c
, v
, true , &received
) ;
386 bool runtime_selectnbsend(ChanType
* t
, Hchan
* c
, byte
* elem
) __asm__ (GOSYM_PREFIX
"runtime.selectnbsend");
387 bool runtime_selectnbsend(ChanType
* t
, Hchan
* c
, byte
* elem
)
390 #line 425 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
392 selected
= chansend(t
, c
, elem
, false, runtime_getcallerpc(&t
));
395 bool runtime_selectnbrecv(ChanType
* t
, byte
* elem
, Hchan
* c
) __asm__ (GOSYM_PREFIX
"runtime.selectnbrecv");
396 bool runtime_selectnbrecv(ChanType
* t
, byte
* elem
, Hchan
* c
)
399 #line 446 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
401 selected
= chanrecv(t
, c
, elem
, false, nil
);
404 bool runtime_selectnbrecv2(ChanType
* t
, byte
* elem
, bool* received
, Hchan
* c
) __asm__ (GOSYM_PREFIX
"runtime.selectnbrecv2");
405 bool runtime_selectnbrecv2(ChanType
* t
, byte
* elem
, bool* received
, Hchan
* c
)
408 #line 467 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
412 selected
= chanrecv(t
, c
, elem
, false, received
== nil
? nil
: &r
);
417 bool reflect_chansend(ChanType
* t
, Hchan
* c
, byte
* elem
, bool nb
) __asm__ (GOSYM_PREFIX
"reflect.chansend");
418 bool reflect_chansend(ChanType
* t
, Hchan
* c
, byte
* elem
, bool nb
)
421 #line 475 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
423 selected
= chansend(t
, c
, elem
, !nb
, runtime_getcallerpc(&t
));
426 struct reflect_chanrecv_ret
{
430 struct reflect_chanrecv_ret
reflect_chanrecv(ChanType
* t
, Hchan
* c
, bool nb
, byte
* elem
) __asm__ (GOSYM_PREFIX
"reflect.chanrecv");
431 struct reflect_chanrecv_ret
reflect_chanrecv(ChanType
* t
, Hchan
* c
, bool nb
, byte
* elem
)
435 #line 479 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
438 selected
= chanrecv(t
, c
, elem
, !nb
, &received
);
440 struct reflect_chanrecv_ret __ret
;
441 __ret
.selected
= selected
;
442 __ret
.received
= received
;
447 #line 484 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
448 static Select
* newselect ( int32
) ;
449 byte
* runtime_newselect(int32 size
) __asm__ (GOSYM_PREFIX
"runtime.newselect");
450 byte
* runtime_newselect(int32 size
)
453 #line 486 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
455 sel
= (byte
*)newselect(size
);
459 #line 490 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
461 newselect ( int32 size
)
465 #line 496 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
469 #line 504 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
470 sel
= runtime_mal ( sizeof ( *sel
) +
471 n
*sizeof ( sel
->scase
[0] ) +
472 size
*sizeof ( sel
->lockorder
[0] ) +
473 size
*sizeof ( sel
->pollorder
[0] ) ) ;
474 #line 509 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
477 sel
->lockorder
= ( void* ) ( sel
->scase
+ size
) ;
478 sel
->pollorder
= ( void* ) ( sel
->lockorder
+ size
) ;
479 #line 514 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
481 runtime_printf ( "newselect s=%p size=%d\n" , sel
, size
) ;
484 #line 520 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
485 static void selectsend ( Select
*sel
, Hchan
*c
, int index
, void *elem
) ;
486 void runtime_selectsend(Select
* sel
, Hchan
* c
, byte
* elem
, int32 index
) __asm__ (GOSYM_PREFIX
"runtime.selectsend");
487 void runtime_selectsend(Select
* sel
, Hchan
* c
, byte
* elem
, int32 index
)
489 #line 522 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
491 // nil cases do not compete
493 selectsend(sel
, c
, index
, elem
);
496 #line 528 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
498 selectsend ( Select
*sel
, Hchan
*c
, int index
, void *elem
)
502 #line 534 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
504 if ( i
>= sel
->tcase
)
505 runtime_throw ( "selectsend: too many cases" ) ;
507 cas
= &sel
->scase
[i
];
508 #line 540 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
511 cas
->kind
= CaseSend
;
513 #line 545 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
515 runtime_printf ( "selectsend s=%p index=%d chan=%p\n" ,
516 sel
, cas
->index
, cas
->chan
) ;
518 #line 551 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
519 static void selectrecv ( Select
*sel
, Hchan
*c
, int index
, void *elem
, bool* ) ;
520 void runtime_selectrecv(Select
* sel
, Hchan
* c
, byte
* elem
, int32 index
) __asm__ (GOSYM_PREFIX
"runtime.selectrecv");
521 void runtime_selectrecv(Select
* sel
, Hchan
* c
, byte
* elem
, int32 index
)
523 #line 553 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
525 // nil cases do not compete
527 selectrecv(sel
, c
, index
, elem
, nil
);
529 void runtime_selectrecv2(Select
* sel
, Hchan
* c
, byte
* elem
, bool* received
, int32 index
) __asm__ (GOSYM_PREFIX
"runtime.selectrecv2");
530 void runtime_selectrecv2(Select
* sel
, Hchan
* c
, byte
* elem
, bool* received
, int32 index
)
532 #line 559 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
534 // nil cases do not compete
536 selectrecv(sel
, c
, index
, elem
, received
);
539 #line 565 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
541 selectrecv ( Select
*sel
, Hchan
*c
, int index
, void *elem
, bool *received
)
545 #line 571 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
547 if ( i
>= sel
->tcase
)
548 runtime_throw ( "selectrecv: too many cases" ) ;
550 cas
= &sel
->scase
[i
];
553 #line 579 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
554 cas
->kind
= CaseRecv
;
556 cas
->receivedp
= received
;
557 #line 583 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
559 runtime_printf ( "selectrecv s=%p index=%d chan=%p\n" ,
560 sel
, cas
->index
, cas
->chan
) ;
562 #line 589 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
563 static void selectdefault ( Select
* , int ) ;
564 void runtime_selectdefault(Select
* sel
, int32 index
) __asm__ (GOSYM_PREFIX
"runtime.selectdefault");
565 void runtime_selectdefault(Select
* sel
, int32 index
)
567 #line 591 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
569 selectdefault(sel
, index
);
572 #line 595 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
574 selectdefault ( Select
*sel
, int32 index
)
578 #line 601 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
580 if ( i
>= sel
->tcase
)
581 runtime_throw ( "selectdefault: too many cases" ) ;
583 cas
= &sel
->scase
[i
];
586 #line 609 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
587 cas
->kind
= CaseDefault
;
588 #line 611 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
590 runtime_printf ( "selectdefault s=%p index=%d\n" ,
593 #line 616 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
595 sellock ( Select
*sel
)
599 #line 622 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
601 for ( i
=0; i
<sel
->ncase
; i
++ ) {
602 c0
= sel
->lockorder
[i
];
603 if ( c0
&& c0
!= c
) {
604 c
= sel
->lockorder
[i
];
609 #line 632 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
611 selunlock ( Select
*sel
)
615 #line 646 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
616 n
= ( int32
) sel
->ncase
;
618 #line 649 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
619 if ( n
>0 && sel
->lockorder
[0] == nil
)
621 for ( i
= n
-1; i
>= r
; i
-- ) {
622 c
= sel
->lockorder
[i
];
623 if ( i
>0 && sel
->lockorder
[i
-1] == c
)
625 runtime_unlock ( c
) ;
628 #line 659 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
630 selparkcommit ( G
*gp
, void *sel
)
636 void runtime_block() __asm__ (GOSYM_PREFIX
"runtime.block");
639 #line 667 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
641 runtime_park(nil
, nil
, "select (no cases)"); // forever
644 #line 671 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
645 static int selectgo ( Select
** ) ;
646 int32
runtime_selectgo(Select
* sel
) __asm__ (GOSYM_PREFIX
"runtime.selectgo");
647 int32
runtime_selectgo(Select
* sel
)
650 #line 675 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
652 return selectgo(&sel
);
656 #line 679 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
658 selectgo ( Select
**selp
)
661 uint32 o
, i
, j
, k
, done
;
669 #line 692 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
671 if ( runtime_gcwaiting ( ) )
672 runtime_gosched ( ) ;
673 #line 696 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
675 runtime_printf ( "select: sel=%p\n" , sel
) ;
676 #line 699 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
678 #line 701 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
680 if ( runtime_blockprofilerate
> 0 ) {
681 t0
= runtime_cputicks ( ) ;
682 for ( i
=0; i
<sel
->ncase
; i
++ )
683 sel
->scase
[i
].sg
.releasetime
= -1;
685 #line 717 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
686 for ( i
=0; i
<sel
->ncase
; i
++ )
687 sel
->pollorder
[i
] = i
;
688 for ( i
=1; i
<sel
->ncase
; i
++ ) {
689 o
= sel
->pollorder
[i
];
690 j
= runtime_fastrand1 ( ) % ( i
+1 ) ;
691 sel
->pollorder
[i
] = sel
->pollorder
[j
];
692 sel
->pollorder
[j
] = o
;
694 #line 728 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
695 for ( i
=0; i
<sel
->ncase
; i
++ ) {
697 c
= sel
->scase
[j
].chan
;
698 while ( j
> 0 && sel
->lockorder
[k
= ( j
-1 ) /2] < c
) {
699 sel
->lockorder
[j
] = sel
->lockorder
[k
];
702 sel
->lockorder
[j
] = c
;
704 for ( i
=sel
->ncase
; i
-->0; ) {
705 c
= sel
->lockorder
[i
];
706 sel
->lockorder
[i
] = sel
->lockorder
[0];
712 if ( k
+1 < i
&& sel
->lockorder
[k
] < sel
->lockorder
[k
+1] )
714 if ( c
< sel
->lockorder
[k
] ) {
715 sel
->lockorder
[j
] = sel
->lockorder
[k
];
721 sel
->lockorder
[j
] = c
;
723 #line 763 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
725 #line 765 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
727 #line 767 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
729 for ( i
=0; i
<sel
->ncase
; i
++ ) {
730 o
= sel
->pollorder
[i
];
731 cas
= &sel
->scase
[o
];
733 #line 773 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
734 switch ( cas
->kind
) {
736 if ( c
->dataqsiz
> 0 ) {
740 sg
= dequeue ( &c
->sendq
) ;
747 #line 787 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
750 runtime_racereadpc ( c
, runtime_selectgo
, chansend
) ;
753 if ( c
->dataqsiz
> 0 ) {
754 if ( c
->qcount
< c
->dataqsiz
)
757 sg
= dequeue ( &c
->recvq
) ;
762 #line 802 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
768 #line 808 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
774 #line 816 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
776 for ( i
=0; i
<sel
->ncase
; i
++ ) {
777 o
= sel
->pollorder
[i
];
778 cas
= &sel
->scase
[o
];
782 sg
->selectdone
= &done
;
783 #line 825 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
784 switch ( cas
->kind
) {
786 enqueue ( &c
->recvq
, sg
) ;
788 #line 830 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
790 enqueue ( &c
->sendq
, sg
) ;
794 #line 836 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
796 runtime_park ( selparkcommit
, sel
, "select" ) ;
797 #line 839 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
800 #line 844 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
801 for ( i
=0; i
<sel
->ncase
; i
++ ) {
802 cas
= &sel
->scase
[i
];
803 if ( cas
!= ( Scase
* ) sg
) {
805 if ( cas
->kind
== CaseSend
)
806 dequeueg ( &c
->sendq
) ;
808 dequeueg ( &c
->recvq
) ;
811 #line 855 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
814 #line 858 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
817 #line 861 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
818 if ( c
->dataqsiz
> 0 )
819 runtime_throw ( "selectgo: shouldn't happen" ) ;
820 #line 864 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
822 runtime_printf ( "wait-return: sel=%p c=%p cas=%p kind=%d\n" ,
823 sel
, c
, cas
, cas
->kind
) ;
824 #line 868 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
825 if ( cas
->kind
== CaseRecv
) {
826 if ( cas
->receivedp
!= nil
)
827 *cas
->receivedp
= true;
829 #line 873 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
831 if ( cas
->kind
== CaseRecv
&& cas
->sg
.elem
!= nil
)
832 runtime_racewriteobjectpc ( cas
->sg
.elem
, c
->elemtype
, selectgo
, chanrecv
) ;
833 else if ( cas
->kind
== CaseSend
)
834 runtime_racereadobjectpc ( cas
->sg
.elem
, c
->elemtype
, selectgo
, chansend
) ;
836 #line 880 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
839 #line 883 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
841 #line 885 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
843 if ( cas
->sg
.elem
!= nil
)
844 runtime_racewriteobjectpc ( cas
->sg
.elem
, c
->elemtype
, selectgo
, chanrecv
) ;
845 runtime_raceacquire ( chanbuf ( c
, c
->recvx
) ) ;
847 if ( cas
->receivedp
!= nil
)
848 *cas
->receivedp
= true;
849 if ( cas
->sg
.elem
!= nil
)
850 runtime_memmove ( cas
->sg
.elem
, chanbuf ( c
, c
->recvx
) , c
->elemsize
) ;
851 runtime_memclr ( chanbuf ( c
, c
->recvx
) , c
->elemsize
) ;
852 if ( ++c
->recvx
== c
->dataqsiz
)
855 sg
= dequeue ( &c
->sendq
) ;
859 if ( sg
->releasetime
)
860 sg
->releasetime
= runtime_cputicks ( ) ;
861 runtime_ready ( gp
) ;
866 #line 910 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
868 #line 912 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
870 runtime_racerelease ( chanbuf ( c
, c
->sendx
) ) ;
871 runtime_racereadobjectpc ( cas
->sg
.elem
, c
->elemtype
, selectgo
, chansend
) ;
873 runtime_memmove ( chanbuf ( c
, c
->sendx
) , cas
->sg
.elem
, c
->elemsize
) ;
874 if ( ++c
->sendx
== c
->dataqsiz
)
877 sg
= dequeue ( &c
->recvq
) ;
881 if ( sg
->releasetime
)
882 sg
->releasetime
= runtime_cputicks ( ) ;
883 runtime_ready ( gp
) ;
888 #line 932 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
890 #line 934 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
892 if ( cas
->sg
.elem
!= nil
)
893 runtime_racewriteobjectpc ( cas
->sg
.elem
, c
->elemtype
, selectgo
, chanrecv
) ;
894 racesync ( c
, sg
) ;
898 runtime_printf ( "syncrecv: sel=%p c=%p o=%d\n" , sel
, c
, o
) ;
899 if ( cas
->receivedp
!= nil
)
900 *cas
->receivedp
= true;
901 if ( cas
->sg
.elem
!= nil
)
902 runtime_memmove ( cas
->sg
.elem
, sg
->elem
, c
->elemsize
) ;
905 if ( sg
->releasetime
)
906 sg
->releasetime
= runtime_cputicks ( ) ;
907 runtime_ready ( gp
) ;
909 #line 953 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
911 #line 955 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
913 if ( cas
->receivedp
!= nil
)
914 *cas
->receivedp
= false;
915 if ( cas
->sg
.elem
!= nil
)
916 runtime_memclr ( cas
->sg
.elem
, c
->elemsize
) ;
918 runtime_raceacquire ( c
) ;
920 #line 964 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
922 #line 966 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
924 runtime_racereadobjectpc ( cas
->sg
.elem
, c
->elemtype
, selectgo
, chansend
) ;
925 racesync ( c
, sg
) ;
929 runtime_printf ( "syncsend: sel=%p c=%p o=%d\n" , sel
, c
, o
) ;
930 if ( sg
->elem
!= nil
)
931 runtime_memmove ( sg
->elem
, cas
->sg
.elem
, c
->elemsize
) ;
934 if ( sg
->releasetime
)
935 sg
->releasetime
= runtime_cputicks ( ) ;
936 runtime_ready ( gp
) ;
937 #line 981 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
939 #line 983 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
941 if ( cas
->sg
.releasetime
> 0 )
942 runtime_blockevent ( cas
->sg
.releasetime
- t0
, 2 ) ;
943 runtime_free ( sel
) ;
945 #line 989 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
947 #line 991 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
949 runtime_panicstring ( "send on closed channel" ) ;
952 #line 997 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
953 typedef struct runtimeSelect runtimeSelect
;
961 #line 1007 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
967 struct reflect_rselect_ret
{
971 struct reflect_rselect_ret
reflect_rselect(Slice cases
) __asm__ (GOSYM_PREFIX
"reflect.rselect");
972 struct reflect_rselect_ret
reflect_rselect(Slice cases
)
976 #line 1013 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
980 runtimeSelect
* rcase
, *rc
;
985 rcase
= (runtimeSelect
*)cases
.__values
;
987 sel
= newselect(cases
.__count
);
988 for(i
=0; i
<cases
.__count
; i
++) {
992 selectdefault(sel
, i
);
997 selectsend(sel
, rc
->ch
, i
, rc
->val
);
1002 selectrecv(sel
, rc
->ch
, i
, rc
->val
, &recvOK
);
1007 chosen
= (intgo
)(uintptr
)selectgo(&sel
);
1009 struct reflect_rselect_ret __ret
;
1010 __ret
.chosen
= chosen
;
1011 __ret
.recvOK
= recvOK
;
1016 #line 1046 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1017 static void closechan ( Hchan
*c
, void *pc
) ;
1018 void runtime_closechan(Hchan
* c
) __asm__ (GOSYM_PREFIX
"runtime.closechan");
1019 void runtime_closechan(Hchan
* c
)
1021 #line 1048 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1023 closechan(c
, runtime_getcallerpc(&c
));
1025 void reflect_chanclose(Hchan
* c
) __asm__ (GOSYM_PREFIX
"reflect.chanclose");
1026 void reflect_chanclose(Hchan
* c
)
1028 #line 1052 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1030 closechan(c
, runtime_getcallerpc(&c
));
1033 #line 1056 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1035 closechan ( Hchan
*c
, void *pc
)
1039 #line 1062 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1041 runtime_panicstring ( "close of nil channel" ) ;
1042 #line 1065 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1043 if ( runtime_gcwaiting ( ) )
1044 runtime_gosched ( ) ;
1045 #line 1068 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1046 runtime_lock ( c
) ;
1048 runtime_unlock ( c
) ;
1049 runtime_panicstring ( "close of closed channel" ) ;
1051 #line 1074 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1052 if ( raceenabled
) {
1053 runtime_racewritepc ( c
, pc
, runtime_closechan
) ;
1054 runtime_racerelease ( c
) ;
1056 #line 1079 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1058 #line 1082 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1060 sg
= dequeue ( &c
->recvq
) ;
1065 if ( sg
->releasetime
)
1066 sg
->releasetime
= runtime_cputicks ( ) ;
1067 runtime_ready ( gp
) ;
1069 #line 1094 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1071 sg
= dequeue ( &c
->sendq
) ;
1076 if ( sg
->releasetime
)
1077 sg
->releasetime
= runtime_cputicks ( ) ;
1078 runtime_ready ( gp
) ;
1080 #line 1105 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1081 runtime_unlock ( c
) ;
1083 #line 1108 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1085 __go_builtin_close ( Hchan
*c
)
1087 runtime_closechan ( c
) ;
1089 intgo
reflect_chanlen(Hchan
* c
) __asm__ (GOSYM_PREFIX
"reflect.chanlen");
1090 intgo
reflect_chanlen(Hchan
* c
)
1093 #line 1114 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1102 #line 1121 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1104 __go_chan_len ( Hchan
*c
)
1106 return reflect_chanlen ( c
) ;
1108 intgo
reflect_chancap(Hchan
* c
) __asm__ (GOSYM_PREFIX
"reflect.chancap");
1109 intgo
reflect_chancap(Hchan
* c
)
1112 #line 1127 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1121 #line 1134 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1123 __go_chan_cap ( Hchan
*c
)
1125 return reflect_chancap ( c
) ;
1127 #line 1140 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1129 dequeue ( WaitQ
*q
)
1132 #line 1145 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1137 q
->first
= sgp
->link
;
1138 #line 1152 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1139 if ( sgp
->selectdone
!= nil
) {
1140 #line 1154 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1141 if ( *sgp
->selectdone
!= 0 || !runtime_cas ( sgp
->selectdone
, 0 , 1 ) )
1144 #line 1158 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1147 #line 1161 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1149 dequeueg ( WaitQ
*q
)
1151 SudoG
**l
, *sgp
, *prevsgp
;
1153 #line 1167 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1156 for ( l
=&q
->first
; ( sgp
=*l
) != nil
; l
=&sgp
->link
, prevsgp
=sgp
) {
1157 if ( sgp
->g
== g
) {
1159 if ( q
->last
== sgp
)
1165 #line 1179 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1167 enqueue ( WaitQ
*q
, SudoG
*sgp
)
1170 if ( q
->first
== nil
) {
1175 q
->last
->link
= sgp
;
1178 #line 1192 "../../../trunk/libgo/runtime/../../../trunk/libgo/runtime/chan.goc"
1180 racesync ( Hchan
*c
, SudoG
*sg
)
1182 runtime_racerelease ( chanbuf ( c
, 0 ) ) ;
1183 runtime_raceacquireg ( sg
->g
, chanbuf ( c
, 0 ) ) ;
1184 runtime_racereleaseg ( sg
->g
, chanbuf ( c
, 0 ) ) ;
1185 runtime_raceacquire ( chanbuf ( c
, 0 ) ) ;