Commit cb9b1038 authored by Ken Thompson's avatar Ken Thompson

select

R=r
APPROVED=r
DELTA=638  (433 added, 21 deleted, 184 changed)
OCL=13426
CL=13438
parent 485d1bb3
......@@ -255,6 +255,17 @@ loop:
breakpc = sbreak;
break;
case OSELECT:
gen(n->ninit);
sbreak = breakpc;
p1 = gbranch(AJMP, T); // goto test
breakpc = gbranch(AJMP, T); // break: goto done
patch(p1, pc); // test:
gen(n->nbody); // select() body
patch(breakpc, pc); // done:
breakpc = sbreak;
break;
case OASOP:
cgen_asop(n);
break;
......
......@@ -107,6 +107,7 @@ void compile(Node*);
void proglist(void);
void gen(Node*);
void swgen(Node*);
void selgen(Node*);
Node* lookdot(Node*, Node*, int);
void inarggen(void);
void agen_inter(Node*, Node*);
......
......@@ -219,8 +219,8 @@ enum
OLIST, OCMP,
OPTR, OARRAY,
ORETURN, OFOR, OIF, OSWITCH, OI2S, OS2I, OI2I,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL, OSELECT,
OGOTO, OPROC, ONEW, OPANIC, OPRINT, OEMPTY,
OAS, OASOP, OCASE, OXCASE, OSCASE, OFALL, OXFALL,
OGOTO, OPROC, ONEW, OPANIC, OPRINT, OEMPTY, OSELECT,
OOROR,
OANDAND,
......@@ -575,6 +575,7 @@ void walktype(Node*, int);
void walkbool(Node*);
Type* walkswitch(Node*, Type*(*)(Node*, Type*));
int casebody(Node*);
void walkselect(Node*);
int whatis(Node*);
void walkdot(Node*, int);
Node* ascompatee(int, Node**, Node**);
......@@ -585,7 +586,9 @@ Node* prcompat(Node*);
Node* nodpanic(long);
Node* newcompat(Node*);
Node* stringop(Node*, int);
Type* fixmap(Type*);
Node* mapop(Node*, int);
Type* fixchan(Type*);
Node* chanop(Node*, int);
Node* convas(Node*);
void arrayconv(Type*, Node*);
......
......@@ -338,8 +338,6 @@ complex_stmt:
| LSWITCH if_stmt
{
popdcl();
if(!casebody($2->nbody))
yyerror("switch statement must have case labels");
$$ = $2;
$$->op = OSWITCH;
//if($$->ninit != N && $$->ntest == N)
......
......@@ -7,6 +7,7 @@
6g sys.go
echo '1,/((/d
/))/+1,$d
g/init_.*_function/d
1,$s/foop/sys/g
1,$s/^[ ]*/ "/g
1,$s/$/\\n"/g
......
......@@ -603,6 +603,7 @@ opnames[] =
[OCALLINTER] = "CALLINTER",
[OCASE] = "CASE",
[OXCASE] = "XCASE",
[OSCASE] = "SCASE",
[OCMP] = "CMP",
[OFALL] = "FALL",
[OCONV] = "CONV",
......
......@@ -51,6 +51,11 @@ func chanrecv3(hchan *chan any) (elem any, pres bool);
func chansend1(hchan *chan any, elem any);
func chansend2(hchan *chan any, elem any) (pres bool);
func newselect(size uint32) (sel *byte);
func selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
func selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
func selectgo(sel *byte);
func gosched();
func goexit();
......@@ -112,6 +117,12 @@ export
chansend1
chansend2
// select
newselect
selectsend
selectrecv
selectgo
// go routines
gosched
goexit
......
......@@ -3,10 +3,10 @@ char* sysimport =
"type sys._esys_002 {}\n"
"type sys.any 24\n"
"type sys._esys_003 *sys.any\n"
"type sys._osys_332 {_esys_330 sys._esys_003}\n"
"type sys._osys_361 {_esys_359 sys._esys_003}\n"
"type sys.uint32 6\n"
"type sys._isys_334 {_esys_331 sys.uint32}\n"
"type sys._esys_001 (sys._esys_002 sys._osys_332 sys._isys_334)\n"
"type sys._isys_363 {_esys_360 sys.uint32}\n"
"type sys._esys_001 (sys._esys_002 sys._osys_361 sys._isys_363)\n"
"var !sys.mal sys._esys_001\n"
"type sys._esys_005 {}\n"
"type sys._esys_006 {}\n"
......@@ -16,249 +16,282 @@ char* sysimport =
"type sys._esys_009 {}\n"
"type sys._esys_010 {}\n"
"type sys.int32 5\n"
"type sys._isys_340 {_esys_339 sys.int32}\n"
"type sys._esys_008 (sys._esys_009 sys._esys_010 sys._isys_340)\n"
"type sys._isys_369 {_esys_368 sys.int32}\n"
"type sys._esys_008 (sys._esys_009 sys._esys_010 sys._isys_369)\n"
"var !sys.panicl sys._esys_008\n"
"type sys._esys_012 {}\n"
"type sys._esys_013 {}\n"
"type sys.bool 12\n"
"type sys._isys_345 {_esys_344 sys.bool}\n"
"type sys._esys_011 (sys._esys_012 sys._esys_013 sys._isys_345)\n"
"type sys._isys_374 {_esys_373 sys.bool}\n"
"type sys._esys_011 (sys._esys_012 sys._esys_013 sys._isys_374)\n"
"var !sys.printbool sys._esys_011\n"
"type sys._esys_015 {}\n"
"type sys._esys_016 {}\n"
"type sys.float64 10\n"
"type sys._isys_350 {_esys_349 sys.float64}\n"
"type sys._esys_014 (sys._esys_015 sys._esys_016 sys._isys_350)\n"
"type sys._isys_379 {_esys_378 sys.float64}\n"
"type sys._esys_014 (sys._esys_015 sys._esys_016 sys._isys_379)\n"
"var !sys.printfloat sys._esys_014\n"
"type sys._esys_018 {}\n"
"type sys._esys_019 {}\n"
"type sys.int64 7\n"
"type sys._isys_355 {_esys_354 sys.int64}\n"
"type sys._esys_017 (sys._esys_018 sys._esys_019 sys._isys_355)\n"
"type sys._isys_384 {_esys_383 sys.int64}\n"
"type sys._esys_017 (sys._esys_018 sys._esys_019 sys._isys_384)\n"
"var !sys.printint sys._esys_017\n"
"type sys._esys_021 {}\n"
"type sys._esys_022 {}\n"
"type sys._esys_023 25\n"
"type sys.string *sys._esys_023\n"
"type sys._isys_360 {_esys_359 sys.string}\n"
"type sys._esys_020 (sys._esys_021 sys._esys_022 sys._isys_360)\n"
"type sys._isys_389 {_esys_388 sys.string}\n"
"type sys._esys_020 (sys._esys_021 sys._esys_022 sys._isys_389)\n"
"var !sys.printstring sys._esys_020\n"
"type sys._esys_025 {}\n"
"type sys._esys_026 {}\n"
"type sys._esys_027 *sys.any\n"
"type sys._isys_365 {_esys_364 sys._esys_027}\n"
"type sys._esys_024 (sys._esys_025 sys._esys_026 sys._isys_365)\n"
"type sys._isys_394 {_esys_393 sys._esys_027}\n"
"type sys._esys_024 (sys._esys_025 sys._esys_026 sys._isys_394)\n"
"var !sys.printpointer sys._esys_024\n"
"type sys._esys_029 {}\n"
"type sys._osys_372 {_esys_369 sys.string}\n"
"type sys._isys_374 {_esys_370 sys.string _esys_371 sys.string}\n"
"type sys._esys_028 (sys._esys_029 sys._osys_372 sys._isys_374)\n"
"type sys._osys_401 {_esys_398 sys.string}\n"
"type sys._isys_403 {_esys_399 sys.string _esys_400 sys.string}\n"
"type sys._esys_028 (sys._esys_029 sys._osys_401 sys._isys_403)\n"
"var !sys.catstring sys._esys_028\n"
"type sys._esys_031 {}\n"
"type sys._osys_382 {_esys_379 sys.int32}\n"
"type sys._isys_384 {_esys_380 sys.string _esys_381 sys.string}\n"
"type sys._esys_030 (sys._esys_031 sys._osys_382 sys._isys_384)\n"
"type sys._osys_411 {_esys_408 sys.int32}\n"
"type sys._isys_413 {_esys_409 sys.string _esys_410 sys.string}\n"
"type sys._esys_030 (sys._esys_031 sys._osys_411 sys._isys_413)\n"
"var !sys.cmpstring sys._esys_030\n"
"type sys._esys_033 {}\n"
"type sys._osys_393 {_esys_389 sys.string}\n"
"type sys._isys_395 {_esys_390 sys.string _esys_391 sys.int32 _esys_392 sys.int32}\n"
"type sys._esys_032 (sys._esys_033 sys._osys_393 sys._isys_395)\n"
"type sys._osys_422 {_esys_418 sys.string}\n"
"type sys._isys_424 {_esys_419 sys.string _esys_420 sys.int32 _esys_421 sys.int32}\n"
"type sys._esys_032 (sys._esys_033 sys._osys_422 sys._isys_424)\n"
"var !sys.slicestring sys._esys_032\n"
"type sys._esys_035 {}\n"
"type sys.uint8 2\n"
"type sys._osys_404 {_esys_401 sys.uint8}\n"
"type sys._isys_406 {_esys_402 sys.string _esys_403 sys.int32}\n"
"type sys._esys_034 (sys._esys_035 sys._osys_404 sys._isys_406)\n"
"type sys._osys_433 {_esys_430 sys.uint8}\n"
"type sys._isys_435 {_esys_431 sys.string _esys_432 sys.int32}\n"
"type sys._esys_034 (sys._esys_035 sys._osys_433 sys._isys_435)\n"
"var !sys.indexstring sys._esys_034\n"
"type sys._esys_037 {}\n"
"type sys._osys_413 {_esys_411 sys.string}\n"
"type sys._isys_415 {_esys_412 sys.int64}\n"
"type sys._esys_036 (sys._esys_037 sys._osys_413 sys._isys_415)\n"
"type sys._osys_442 {_esys_440 sys.string}\n"
"type sys._isys_444 {_esys_441 sys.int64}\n"
"type sys._esys_036 (sys._esys_037 sys._osys_442 sys._isys_444)\n"
"var !sys.intstring sys._esys_036\n"
"type sys._esys_039 {}\n"
"type sys._osys_422 {_esys_419 sys.string}\n"
"type sys._osys_451 {_esys_448 sys.string}\n"
"type sys._esys_040 *sys.uint8\n"
"type sys._isys_424 {_esys_420 sys._esys_040 _esys_421 sys.int32}\n"
"type sys._esys_038 (sys._esys_039 sys._osys_422 sys._isys_424)\n"
"type sys._isys_453 {_esys_449 sys._esys_040 _esys_450 sys.int32}\n"
"type sys._esys_038 (sys._esys_039 sys._osys_451 sys._isys_453)\n"
"var !sys.byteastring sys._esys_038\n"
"type sys._esys_042 {}\n"
"type sys._esys_043 <>\n"
"type sys._osys_433 {_esys_429 sys._esys_043}\n"
"type sys._osys_462 {_esys_458 sys._esys_043}\n"
"type sys._esys_044 *sys.uint8\n"
"type sys._esys_045 *sys.uint8\n"
"type sys._ssys_440 {}\n"
"type sys._esys_046 *sys._ssys_440\n"
"type sys._isys_435 {_esys_430 sys._esys_044 _esys_431 sys._esys_045 _esys_432 sys._esys_046}\n"
"type sys._esys_041 (sys._esys_042 sys._osys_433 sys._isys_435)\n"
"type sys._ssys_469 {}\n"
"type sys._esys_046 *sys._ssys_469\n"
"type sys._isys_464 {_esys_459 sys._esys_044 _esys_460 sys._esys_045 _esys_461 sys._esys_046}\n"
"type sys._esys_041 (sys._esys_042 sys._osys_462 sys._isys_464)\n"
"var !sys.mkiface sys._esys_041\n"
"type sys._esys_048 {}\n"
"type sys._osys_444 {_esys_443 sys.int32}\n"
"type sys._osys_473 {_esys_472 sys.int32}\n"
"type sys._esys_049 {}\n"
"type sys._esys_047 (sys._esys_048 sys._osys_444 sys._esys_049)\n"
"type sys._esys_047 (sys._esys_048 sys._osys_473 sys._esys_049)\n"
"var !sys.argc sys._esys_047\n"
"type sys._esys_051 {}\n"
"type sys._osys_448 {_esys_447 sys.int32}\n"
"type sys._osys_477 {_esys_476 sys.int32}\n"
"type sys._esys_052 {}\n"
"type sys._esys_050 (sys._esys_051 sys._osys_448 sys._esys_052)\n"
"type sys._esys_050 (sys._esys_051 sys._osys_477 sys._esys_052)\n"
"var !sys.envc sys._esys_050\n"
"type sys._esys_054 {}\n"
"type sys._osys_453 {_esys_451 sys.string}\n"
"type sys._isys_455 {_esys_452 sys.int32}\n"
"type sys._esys_053 (sys._esys_054 sys._osys_453 sys._isys_455)\n"
"type sys._osys_482 {_esys_480 sys.string}\n"
"type sys._isys_484 {_esys_481 sys.int32}\n"
"type sys._esys_053 (sys._esys_054 sys._osys_482 sys._isys_484)\n"
"var !sys.argv sys._esys_053\n"
"type sys._esys_056 {}\n"
"type sys._osys_461 {_esys_459 sys.string}\n"
"type sys._isys_463 {_esys_460 sys.int32}\n"
"type sys._esys_055 (sys._esys_056 sys._osys_461 sys._isys_463)\n"
"type sys._osys_490 {_esys_488 sys.string}\n"
"type sys._isys_492 {_esys_489 sys.int32}\n"
"type sys._esys_055 (sys._esys_056 sys._osys_490 sys._isys_492)\n"
"var !sys.envv sys._esys_055\n"
"type sys._esys_058 {}\n"
"type sys._osys_470 {_esys_467 sys.float64 _esys_468 sys.int32}\n"
"type sys._isys_472 {_esys_469 sys.float64}\n"
"type sys._esys_057 (sys._esys_058 sys._osys_470 sys._isys_472)\n"
"type sys._osys_499 {_esys_496 sys.float64 _esys_497 sys.int32}\n"
"type sys._isys_501 {_esys_498 sys.float64}\n"
"type sys._esys_057 (sys._esys_058 sys._osys_499 sys._isys_501)\n"
"var !sys.frexp sys._esys_057\n"
"type sys._esys_060 {}\n"
"type sys._osys_479 {_esys_476 sys.float64}\n"
"type sys._isys_481 {_esys_477 sys.float64 _esys_478 sys.int32}\n"
"type sys._esys_059 (sys._esys_060 sys._osys_479 sys._isys_481)\n"
"type sys._osys_508 {_esys_505 sys.float64}\n"
"type sys._isys_510 {_esys_506 sys.float64 _esys_507 sys.int32}\n"
"type sys._esys_059 (sys._esys_060 sys._osys_508 sys._isys_510)\n"
"var !sys.ldexp sys._esys_059\n"
"type sys._esys_062 {}\n"
"type sys._osys_489 {_esys_486 sys.float64 _esys_487 sys.float64}\n"
"type sys._isys_491 {_esys_488 sys.float64}\n"
"type sys._esys_061 (sys._esys_062 sys._osys_489 sys._isys_491)\n"
"type sys._osys_518 {_esys_515 sys.float64 _esys_516 sys.float64}\n"
"type sys._isys_520 {_esys_517 sys.float64}\n"
"type sys._esys_061 (sys._esys_062 sys._osys_518 sys._isys_520)\n"
"var !sys.modf sys._esys_061\n"
"type sys._esys_064 {}\n"
"type sys._osys_498 {_esys_495 sys.bool}\n"
"type sys._isys_500 {_esys_496 sys.float64 _esys_497 sys.int32}\n"
"type sys._esys_063 (sys._esys_064 sys._osys_498 sys._isys_500)\n"
"type sys._osys_527 {_esys_524 sys.bool}\n"
"type sys._isys_529 {_esys_525 sys.float64 _esys_526 sys.int32}\n"
"type sys._esys_063 (sys._esys_064 sys._osys_527 sys._isys_529)\n"
"var !sys.isInf sys._esys_063\n"
"type sys._esys_066 {}\n"
"type sys._osys_507 {_esys_505 sys.bool}\n"
"type sys._isys_509 {_esys_506 sys.float64}\n"
"type sys._esys_065 (sys._esys_066 sys._osys_507 sys._isys_509)\n"
"type sys._osys_536 {_esys_534 sys.bool}\n"
"type sys._isys_538 {_esys_535 sys.float64}\n"
"type sys._esys_065 (sys._esys_066 sys._osys_536 sys._isys_538)\n"
"var !sys.isNaN sys._esys_065\n"
"type sys._esys_068 {}\n"
"type sys._osys_515 {_esys_513 sys.float64}\n"
"type sys._isys_517 {_esys_514 sys.int32}\n"
"type sys._esys_067 (sys._esys_068 sys._osys_515 sys._isys_517)\n"
"type sys._osys_544 {_esys_542 sys.float64}\n"
"type sys._isys_546 {_esys_543 sys.int32}\n"
"type sys._esys_067 (sys._esys_068 sys._osys_544 sys._isys_546)\n"
"var !sys.Inf sys._esys_067\n"
"type sys._esys_070 {}\n"
"type sys._osys_522 {_esys_521 sys.float64}\n"
"type sys._osys_551 {_esys_550 sys.float64}\n"
"type sys._esys_071 {}\n"
"type sys._esys_069 (sys._esys_070 sys._osys_522 sys._esys_071)\n"
"type sys._esys_069 (sys._esys_070 sys._osys_551 sys._esys_071)\n"
"var !sys.NaN sys._esys_069\n"
"type sys._esys_073 {}\n"
"type sys._esys_075 [sys.any] sys.any\n"
"type sys._esys_074 *sys._esys_075\n"
"type sys._osys_525 {hmap sys._esys_074}\n"
"type sys._isys_527 {keysize sys.uint32 valsize sys.uint32 keyalg sys.uint32 valalg sys.uint32 hint sys.uint32}\n"
"type sys._esys_072 (sys._esys_073 sys._osys_525 sys._isys_527)\n"
"type sys._osys_554 {hmap sys._esys_074}\n"
"type sys._isys_556 {keysize sys.uint32 valsize sys.uint32 keyalg sys.uint32 valalg sys.uint32 hint sys.uint32}\n"
"type sys._esys_072 (sys._esys_073 sys._osys_554 sys._isys_556)\n"
"var !sys.newmap sys._esys_072\n"
"type sys._esys_077 {}\n"
"type sys._osys_536 {val sys.any}\n"
"type sys._osys_565 {val sys.any}\n"
"type sys._esys_079 [sys.any] sys.any\n"
"type sys._esys_078 *sys._esys_079\n"
"type sys._isys_538 {hmap sys._esys_078 key sys.any}\n"
"type sys._esys_076 (sys._esys_077 sys._osys_536 sys._isys_538)\n"
"type sys._isys_567 {hmap sys._esys_078 key sys.any}\n"
"type sys._esys_076 (sys._esys_077 sys._osys_565 sys._isys_567)\n"
"var !sys.mapaccess1 sys._esys_076\n"
"type sys._esys_081 {}\n"
"type sys._osys_544 {val sys.any pres sys.bool}\n"
"type sys._osys_573 {val sys.any pres sys.bool}\n"
"type sys._esys_083 [sys.any] sys.any\n"
"type sys._esys_082 *sys._esys_083\n"
"type sys._isys_546 {hmap sys._esys_082 key sys.any}\n"
"type sys._esys_080 (sys._esys_081 sys._osys_544 sys._isys_546)\n"
"type sys._isys_575 {hmap sys._esys_082 key sys.any}\n"
"type sys._esys_080 (sys._esys_081 sys._osys_573 sys._isys_575)\n"
"var !sys.mapaccess2 sys._esys_080\n"
"type sys._esys_085 {}\n"
"type sys._esys_086 {}\n"
"type sys._esys_088 [sys.any] sys.any\n"
"type sys._esys_087 *sys._esys_088\n"
"type sys._isys_553 {hmap sys._esys_087 key sys.any val sys.any}\n"
"type sys._esys_084 (sys._esys_085 sys._esys_086 sys._isys_553)\n"
"type sys._isys_582 {hmap sys._esys_087 key sys.any val sys.any}\n"
"type sys._esys_084 (sys._esys_085 sys._esys_086 sys._isys_582)\n"
"var !sys.mapassign1 sys._esys_084\n"
"type sys._esys_090 {}\n"
"type sys._esys_091 {}\n"
"type sys._esys_093 [sys.any] sys.any\n"
"type sys._esys_092 *sys._esys_093\n"
"type sys._isys_559 {hmap sys._esys_092 key sys.any val sys.any pres sys.bool}\n"
"type sys._esys_089 (sys._esys_090 sys._esys_091 sys._isys_559)\n"
"type sys._isys_588 {hmap sys._esys_092 key sys.any val sys.any pres sys.bool}\n"
"type sys._esys_089 (sys._esys_090 sys._esys_091 sys._isys_588)\n"
"var !sys.mapassign2 sys._esys_089\n"
"type sys._esys_095 {}\n"
"type sys._esys_097 1 sys.any\n"
"type sys._esys_096 *sys._esys_097\n"
"type sys._osys_566 {hchan sys._esys_096}\n"
"type sys._isys_568 {elemsize sys.uint32 elemalg sys.uint32 hint sys.uint32}\n"
"type sys._esys_094 (sys._esys_095 sys._osys_566 sys._isys_568)\n"
"type sys._osys_595 {hchan sys._esys_096}\n"
"type sys._isys_597 {elemsize sys.uint32 elemalg sys.uint32 hint sys.uint32}\n"
"type sys._esys_094 (sys._esys_095 sys._osys_595 sys._isys_597)\n"
"var !sys.newchan sys._esys_094\n"
"type sys._esys_099 {}\n"
"type sys._osys_575 {elem sys.any}\n"
"type sys._osys_604 {elem sys.any}\n"
"type sys._esys_101 1 sys.any\n"
"type sys._esys_100 *sys._esys_101\n"
"type sys._isys_577 {hchan sys._esys_100}\n"
"type sys._esys_098 (sys._esys_099 sys._osys_575 sys._isys_577)\n"
"type sys._isys_606 {hchan sys._esys_100}\n"
"type sys._esys_098 (sys._esys_099 sys._osys_604 sys._isys_606)\n"
"var !sys.chanrecv1 sys._esys_098\n"
"type sys._esys_103 {}\n"
"type sys._osys_582 {elem sys.any pres sys.bool}\n"
"type sys._osys_611 {elem sys.any pres sys.bool}\n"
"type sys._esys_105 1 sys.any\n"
"type sys._esys_104 *sys._esys_105\n"
"type sys._isys_584 {hchan sys._esys_104}\n"
"type sys._esys_102 (sys._esys_103 sys._osys_582 sys._isys_584)\n"
"type sys._isys_613 {hchan sys._esys_104}\n"
"type sys._esys_102 (sys._esys_103 sys._osys_611 sys._isys_613)\n"
"var !sys.chanrecv2 sys._esys_102\n"
"type sys._esys_107 {}\n"
"type sys._osys_590 {elem sys.any pres sys.bool}\n"
"type sys._osys_619 {elem sys.any pres sys.bool}\n"
"type sys._esys_109 1 sys.any\n"
"type sys._esys_108 *sys._esys_109\n"
"type sys._isys_592 {hchan sys._esys_108}\n"
"type sys._esys_106 (sys._esys_107 sys._osys_590 sys._isys_592)\n"
"type sys._isys_621 {hchan sys._esys_108}\n"
"type sys._esys_106 (sys._esys_107 sys._osys_619 sys._isys_621)\n"
"var !sys.chanrecv3 sys._esys_106\n"
"type sys._esys_111 {}\n"
"type sys._esys_112 {}\n"
"type sys._esys_114 1 sys.any\n"
"type sys._esys_113 *sys._esys_114\n"
"type sys._isys_598 {hchan sys._esys_113 elem sys.any}\n"
"type sys._esys_110 (sys._esys_111 sys._esys_112 sys._isys_598)\n"
"type sys._isys_627 {hchan sys._esys_113 elem sys.any}\n"
"type sys._esys_110 (sys._esys_111 sys._esys_112 sys._isys_627)\n"
"var !sys.chansend1 sys._esys_110\n"
"type sys._esys_116 {}\n"
"type sys._osys_603 {pres sys.bool}\n"
"type sys._osys_632 {pres sys.bool}\n"
"type sys._esys_118 1 sys.any\n"
"type sys._esys_117 *sys._esys_118\n"
"type sys._isys_605 {hchan sys._esys_117 elem sys.any}\n"
"type sys._esys_115 (sys._esys_116 sys._osys_603 sys._isys_605)\n"
"type sys._isys_634 {hchan sys._esys_117 elem sys.any}\n"
"type sys._esys_115 (sys._esys_116 sys._osys_632 sys._isys_634)\n"
"var !sys.chansend2 sys._esys_115\n"
"type sys._esys_120 {}\n"
"type sys._esys_121 {}\n"
"type sys._esys_122 {}\n"
"type sys._esys_119 (sys._esys_120 sys._esys_121 sys._esys_122)\n"
"var !sys.gosched sys._esys_119\n"
"type sys._esys_124 {}\n"
"type sys._esys_125 {}\n"
"type sys._esys_126 {}\n"
"type sys._esys_123 (sys._esys_124 sys._esys_125 sys._esys_126)\n"
"var !sys.goexit sys._esys_123\n"
"type sys._esys_121 *sys.uint8\n"
"type sys._osys_640 {sel sys._esys_121}\n"
"type sys._isys_642 {size sys.uint32}\n"
"type sys._esys_119 (sys._esys_120 sys._osys_640 sys._isys_642)\n"
"var !sys.newselect sys._esys_119\n"
"type sys._esys_123 {}\n"
"type sys._osys_647 {selected sys.bool}\n"
"type sys._esys_124 *sys.uint8\n"
"type sys._esys_126 1 sys.any\n"
"type sys._esys_125 *sys._esys_126\n"
"type sys._isys_649 {sel sys._esys_124 hchan sys._esys_125 elem sys.any}\n"
"type sys._esys_122 (sys._esys_123 sys._osys_647 sys._isys_649)\n"
"var !sys.selectsend sys._esys_122\n"
"type sys._esys_128 {}\n"
"type sys._osys_616 {_esys_613 sys.string _esys_614 sys.bool}\n"
"type sys._isys_618 {_esys_615 sys.string}\n"
"type sys._esys_127 (sys._esys_128 sys._osys_616 sys._isys_618)\n"
"var !sys.readfile sys._esys_127\n"
"type sys._esys_130 {}\n"
"type sys._osys_625 {_esys_622 sys.bool}\n"
"type sys._isys_627 {_esys_623 sys.string _esys_624 sys.string}\n"
"type sys._esys_129 (sys._esys_130 sys._osys_625 sys._isys_627)\n"
"var !sys.writefile sys._esys_129\n"
"type sys._esys_132 {}\n"
"type sys._osys_637 {_esys_632 sys.int32 _esys_633 sys.int32}\n"
"type sys._esys_133 *sys.uint8\n"
"type sys._isys_639 {_esys_634 sys._esys_133 _esys_635 sys.int32 _esys_636 sys.int32}\n"
"type sys._esys_131 (sys._esys_132 sys._osys_637 sys._isys_639)\n"
"var !sys.bytestorune sys._esys_131\n"
"type sys._osys_656 {selected sys.bool}\n"
"type sys._esys_129 *sys.uint8\n"
"type sys._esys_131 1 sys.any\n"
"type sys._esys_130 *sys._esys_131\n"
"type sys._esys_132 *sys.any\n"
"type sys._isys_658 {sel sys._esys_129 hchan sys._esys_130 elem sys._esys_132}\n"
"type sys._esys_127 (sys._esys_128 sys._osys_656 sys._isys_658)\n"
"var !sys.selectrecv sys._esys_127\n"
"type sys._esys_134 {}\n"
"type sys._esys_135 {}\n"
"type sys._osys_650 {_esys_645 sys.int32 _esys_646 sys.int32}\n"
"type sys._isys_652 {_esys_647 sys.string _esys_648 sys.int32 _esys_649 sys.int32}\n"
"type sys._esys_134 (sys._esys_135 sys._osys_650 sys._isys_652)\n"
"var !sys.stringtorune sys._esys_134\n"
"type sys._esys_137 {}\n"
"type sys._esys_136 *sys.uint8\n"
"type sys._isys_665 {sel sys._esys_136}\n"
"type sys._esys_133 (sys._esys_134 sys._esys_135 sys._isys_665)\n"
"var !sys.selectgo sys._esys_133\n"
"type sys._esys_138 {}\n"
"type sys._isys_659 {_esys_658 sys.int32}\n"
"type sys._esys_136 (sys._esys_137 sys._esys_138 sys._isys_659)\n"
"var !sys.exit sys._esys_136\n"
"type sys._esys_139 {}\n"
"type sys._esys_140 {}\n"
"type sys._esys_137 (sys._esys_138 sys._esys_139 sys._esys_140)\n"
"var !sys.gosched sys._esys_137\n"
"type sys._esys_142 {}\n"
"type sys._esys_143 {}\n"
"type sys._esys_144 {}\n"
"type sys._esys_141 (sys._esys_142 sys._esys_143 sys._esys_144)\n"
"var !sys.goexit sys._esys_141\n"
"type sys._esys_146 {}\n"
"type sys._osys_674 {_esys_671 sys.string _esys_672 sys.bool}\n"
"type sys._isys_676 {_esys_673 sys.string}\n"
"type sys._esys_145 (sys._esys_146 sys._osys_674 sys._isys_676)\n"
"var !sys.readfile sys._esys_145\n"
"type sys._esys_148 {}\n"
"type sys._osys_683 {_esys_680 sys.bool}\n"
"type sys._isys_685 {_esys_681 sys.string _esys_682 sys.string}\n"
"type sys._esys_147 (sys._esys_148 sys._osys_683 sys._isys_685)\n"
"var !sys.writefile sys._esys_147\n"
"type sys._esys_150 {}\n"
"type sys._osys_695 {_esys_690 sys.int32 _esys_691 sys.int32}\n"
"type sys._esys_151 *sys.uint8\n"
"type sys._isys_697 {_esys_692 sys._esys_151 _esys_693 sys.int32 _esys_694 sys.int32}\n"
"type sys._esys_149 (sys._esys_150 sys._osys_695 sys._isys_697)\n"
"var !sys.bytestorune sys._esys_149\n"
"type sys._esys_153 {}\n"
"type sys._osys_708 {_esys_703 sys.int32 _esys_704 sys.int32}\n"
"type sys._isys_710 {_esys_705 sys.string _esys_706 sys.int32 _esys_707 sys.int32}\n"
"type sys._esys_152 (sys._esys_153 sys._osys_708 sys._isys_710)\n"
"var !sys.stringtorune sys._esys_152\n"
"type sys._esys_155 {}\n"
"type sys._esys_156 {}\n"
"type sys._isys_717 {_esys_716 sys.int32}\n"
"type sys._esys_154 (sys._esys_155 sys._esys_156 sys._isys_717)\n"
"var !sys.exit sys._esys_154\n"
"type sys._esys_158 {}\n"
"type sys._esys_159 {}\n"
"type sys._esys_160 {}\n"
"type sys._esys_157 (sys._esys_158 sys._esys_159 sys._esys_160)\n"
"))\n"
;
......@@ -70,7 +70,7 @@ loop:
if(top != Etop)
goto nottop;
walktype(n->left, Erv);
*n = *nod(OLIST, prcompat(n->left), nodpanic(n->lineno));
*n = *list(prcompat(n->left), nodpanic(n->lineno));
goto ret;
case OLITERAL:
......@@ -121,6 +121,9 @@ loop:
if(top != Etop)
goto nottop;
if(!casebody(n->nbody))
yyerror("switch statement must have case labels");
if(n->ntest == N)
n->ntest = booltrue;
walktype(n->ninit, Etop);
......@@ -142,6 +145,20 @@ loop:
walktype(n->nincr, Erv);
goto ret;
case OSELECT:
if(top != Etop)
goto nottop;
walkselect(n);
goto ret;
case OSCASE:
if(top != Etop)
goto nottop;
// walktype(n->left, Erv); SPECIAL
n = n->right;
goto loop;
case OEMPTY:
if(top != Etop)
goto nottop;
......@@ -216,7 +233,7 @@ loop:
l = ascompatte(n->op, getinarg(t), &n->right, 0);
r = ascompatte(n->op, getthis(t), &n->left->left, 0);
if(l != N)
r = nod(OLIST, r, l);
r = list(r, l);
n->left->left = N;
ullmancalc(n->left);
n->right = reorder1(r);
......@@ -255,7 +272,7 @@ loop:
walktype(r, Erv);
l = ascompatet(n->op, &n->left, &r->type, 0);
if(l != N) {
*n = *nod(OLIST, r, reorder2(l));
*n = *list(r, reorder2(l));
}
goto ret;
}
......@@ -591,8 +608,8 @@ loop:
case OSEND:
if(top == Elv)
goto nottop;
walktype(n->left, Erv);
walktype(n->right, Erv);
walktype(n->left, Erv); // chan
walktype(n->right, Erv); // e
*n = *chanop(n, top);
goto ret;
......@@ -805,7 +822,7 @@ sw2(Node *c, Type *place)
}
/*
* check that selected type
* check that switch type
* is compat with all the cases
*/
Type*
......@@ -897,6 +914,125 @@ loop:
goto loop;
}
Node*
selcase(Node *c, Node *var)
{
Node *a, *r, *on;
Type *t;
walktype(c->left, Erv); // chan
walktype(c->right, Erv); // elem
t = fixchan(c->left->type);
if(t == T)
return;
convlit(c->right, t->type);
if(!ascompat(t->type, c->right->type)) {
badtype(c->op, t->type, c->right->type);
return;
}
// selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
on = syslook("selectsend", 1);
argtype(on, t->type);
argtype(on, t->type);
a = c->right; // elem
r = a;
a = c->left; // chan
r = list(a, r);
a = var; // sel-var
r = list(a, r);
a = nod(OCALL, on, r);
r = nod(OIF, N, N);
r->ntest = a;
return r;
}
void
walkselect(Node *sel)
{
Iter iter;
Node *n, *oc, *on, *r;
Node *var, *bod, *res;
int count;
long lno;
lno = setlineno(sel);
// generate sel-struct
var = nod(OXXX, N, N);
tempname(var, ptrto(types[TUINT8]));
n = listfirst(&iter, &sel->left);
if(n == N || n->op != OXCASE)
yyerror("first select statement must be a case");
count = 0; // number of cases
res = N; // entire select body
bod = N; // body of each case
oc = N; // last case
for(count=0; n!=N; n=listnext(&iter)) {
setlineno(n);
switch(n->op) {
default:
bod = list(bod, n);
break;
case OXCASE:
switch(n->left->op) {
default:
yyerror("select cases must be send or recv");
break;
case OSEND:
if(oc != N) {
bod = list(bod, nod(OBREAK, N, N));
oc->nbody = rev(bod);
}
oc = selcase(n->left, var);
res = list(res, oc);
break;
}
bod = N;
count++;
break;
}
}
if(oc != N) {
bod = list(bod, nod(OBREAK, N, N));
oc->nbody = rev(bod);
}
setlineno(sel);
// selectgo(sel *byte);
on = syslook("selectgo", 0);
r = nod(OCALL, on, var); // sel-var
res = list(res, r);
// newselect(size uint32) (sel *byte);
on = syslook("newselect", 0);
r = nod(OXXX, N, N);
nodconst(r, types[TINT32], count); // count
r = nod(OCALL, on, r);
r = nod(OAS, var, r);
sel->ninit = r;
sel->nbody = rev(res);
sel->left = N;
walktype(sel->ninit, Etop);
walktype(sel->nbody, Etop);
lineno = lno;
}
/*
* allowable type combinations for
* normal binary operations.
......@@ -1053,7 +1189,7 @@ loop:
if(nn == N)
nn = a;
else
nn = nod(OLIST, a, nn);
nn = list(a, nn);
l = listnext(&savel);
r = listnext(&saver);
......@@ -1093,7 +1229,7 @@ loop:
if(nn == N)
nn = a;
else
nn = nod(OLIST, a, nn);
nn = list(a, nn);
l = listnext(&savel);
r = structnext(&saver);
......@@ -1134,7 +1270,7 @@ loop:
if(nn == N)
nn = a;
else
nn = nod(OLIST, a, nn);
nn = list(a, nn);
l = structnext(&savel);
r = listnext(&saver);
......@@ -1230,7 +1366,7 @@ loop:
if(r == N)
r = nod(OCALL, on, l);
else
r = nod(OLIST, r, nod(OCALL, on, l));
r = list(r, nod(OCALL, on, l));
l = listnext(&save);
goto loop;
......@@ -1305,7 +1441,7 @@ stringop(Node *n, int top)
case OLT:
// sys_cmpstring(s1, s2) :: 0
on = syslook("cmpstring", 0);
r = nod(OLIST, n->left, n->right);
r = list(n->left, n->right);
r = nod(OCALL, on, r);
c = nodintconst(0);
r = nod(n->op, r, c);
......@@ -1314,7 +1450,7 @@ stringop(Node *n, int top)
case OADD:
// sys_catstring(s1, s2)
on = syslook("catstring", 0);
r = nod(OLIST, n->left, n->right);
r = list(n->left, n->right);
r = nod(OCALL, on, r);
break;
......@@ -1328,7 +1464,7 @@ stringop(Node *n, int top)
// s1 = sys_catstring(s1, s2)
if(n->etype != OADD)
fatal("stringop: not cat");
r = nod(OLIST, n->left, n->right);
r = list(n->left, n->right);
on = syslook("catstring", 0);
r = nod(OCALL, on, r);
r = nod(OAS, n->left, r);
......@@ -1344,8 +1480,8 @@ stringop(Node *n, int top)
c = nod(OCONV, n->right->right, N);
c->type = types[TINT32];
r = nod(OLIST, r, c);
r = nod(OLIST, n->left, r);
r = list(r, c);
r = list(n->left, r);
on = syslook("slicestring", 0);
r = nod(OCALL, on, r);
break;
......@@ -1360,7 +1496,7 @@ stringop(Node *n, int top)
}
r = nod(OCONV, n->right, N);
r->type = types[TINT32];
r = nod(OLIST, c, r);
r = list(c, r);
on = syslook("indexstring", 0);
r = nod(OCALL, on, r);
break;
......@@ -1382,7 +1518,7 @@ stringop(Node *n, int top)
l = isbytearray(n->left->type);
c = nodintconst(l-1);
r = nod(OLIST, r, c);
r = list(r, c);
on = syslook("byteastring", 0);
r = nod(OCALL, on, r);
break;
......@@ -1499,13 +1635,13 @@ mapop(Node *n, int top)
a = nodintconst(0);
r = a;
a = nodintconst(algtype(t->type)); // val algorithm
r = nod(OLIST, a, r);
r = list(a, r);
a = nodintconst(algtype(t->down)); // key algorithm
r = nod(OLIST, a, r);
r = list(a, r);
a = nodintconst(t->type->width); // val width
r = nod(OLIST, a, r);
r = list(a, r);
a = nodintconst(t->down->width); // key width
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("newmap", 1);
......@@ -1541,7 +1677,7 @@ mapop(Node *n, int top)
r = a;
a = n->left; // map
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("mapaccess1", 1);
......@@ -1579,9 +1715,9 @@ mapop(Node *n, int top)
a = n->right; // val
r = a;
a = n->left->right; // key
r = nod(OLIST, a, r);
r = list(a, r);
a = n->left->left; // map
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("mapassign1", 1);
......@@ -1608,11 +1744,11 @@ mapop(Node *n, int top)
a = n->right->right; // pres
r = a;
a = n->right->left; // val
r =nod(OLIST, a, r);
r =list(a, r);
a = n->left->right; // key
r = nod(OLIST, a, r);
r = list(a, r);
a = n->left->left; // map
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("mapassign2", 1);
......@@ -1639,7 +1775,7 @@ mapop(Node *n, int top)
a = n->right->right; // key
r = a;
a = n->right->left; // map
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("mapaccess2", 1);
......@@ -1695,9 +1831,9 @@ chanop(Node *n, int top)
a = nodintconst(0);
r = a;
a = nodintconst(algtype(t->type)); // elem algorithm
r = nod(OLIST, a, r);
r = list(a, r);
a = nodintconst(t->type->width); // elem width
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("newchan", 1);
argtype(on, t->type); // any-1
......@@ -1789,7 +1925,7 @@ fatal("recv2 not yet");
a = n->right; // e
r = a;
a = n->left; // chan
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("chansend1", 1);
argtype(on, t->type); // any-1
......@@ -1807,7 +1943,7 @@ fatal("recv2 not yet");
a = n->right; // e
r = a;
a = n->left; // chan
r = nod(OLIST, a, r);
r = list(a, r);
on = syslook("chansend2", 1);
argtype(on, t->type); // any-1
......@@ -1981,7 +2117,7 @@ colas(Node *nl, Node *nr)
if(n == N)
n = a;
else
n = nod(OLIST, n, a);
n = list(n, a);
l = listnext(&savel);
r = listnext(&saver);
......@@ -2017,7 +2153,7 @@ multi:
if(n == N)
n = a;
else
n = nod(OLIST, n, a);
n = list(n, a);
l = listnext(&savel);
t = structnext(&saver);
}
......@@ -2039,7 +2175,7 @@ multi:
a = old2new(nl->left, t->type);
n = a;
a = old2new(nl->right, types[TBOOL]);
n = nod(OLIST, n, a);
n = list(n, a);
break;
case ORECV:
......@@ -2052,7 +2188,7 @@ multi:
a = old2new(nl->left, t->type->type);
n = a;
a = old2new(nl->right, types[TBOOL]);
n = nod(OLIST, n, a);
n = list(n, a);
}
n = rev(n);
return n;
......@@ -2107,15 +2243,15 @@ loop2:
r = rev(r);
g = rev(g);
if(g != N)
f = nod(OLIST, g, f);
r = nod(OLIST, f, r);
f = list(g, f);
r = list(f, r);
return r;
}
if(l->ullman < UINF) {
if(r == N)
r = l;
else
r = nod(OLIST, l, r);
r = list(l, r);
goto more;
}
if(f == N) {
......@@ -2131,7 +2267,7 @@ loop2:
if(g == N)
g = a;
else
g = nod(OLIST, a, g);
g = list(a, g);
// put normal arg assignment on list
// with fncall replaced by tempname
......@@ -2139,7 +2275,7 @@ loop2:
if(r == N)
r = l;
else
r = nod(OLIST, l, r);
r = list(l, r);
more:
l = listnext(&save);
......@@ -2256,7 +2392,7 @@ reorder3(Node *n)
if(r == N)
r = q;
else
r = nod(OLIST, r, q);
r = list(r, q);
break;
}
}
......@@ -2275,7 +2411,7 @@ reorder3(Node *n)
if(q == N)
q = l1;
else
q = nod(OLIST, q, l1);
q = list(q, l1);
l1 = listnext(&save1);
}
......@@ -2285,7 +2421,7 @@ reorder3(Node *n)
if(q == N)
q = l1;
else
q = nod(OLIST, q, l1);
q = list(q, l1);
l1 = listnext(&save1);
}
......
......@@ -10,10 +10,13 @@ typedef struct Hchan Hchan;
typedef struct Link Link;
typedef struct WaitQ WaitQ;
typedef struct SudoG SudoG;
typedef struct Select Select;
typedef struct Scase Scase;
struct SudoG
{
G* g; // g and selgen constitute
byte elem[8]; // synch data element
int64 selgen; // a weak pointer to g
SudoG* link;
};
......@@ -29,8 +32,8 @@ struct Hchan
uint32 elemsize;
uint32 dataqsiz; // size of the circular q
uint32 qcount; // total data in the q
uint32 eo; // vararg of element
uint32 po; // vararg of present bool
uint16 eo; // vararg of element
uint16 po; // vararg of present bool
Alg* elemalg; // interface for element type
Link* senddataq; // pointer for sender
Link* recvdataq; // pointer for receiver
......@@ -41,14 +44,33 @@ struct Hchan
struct Link
{
Link* link;
byte elem[8];
Link* link; // asynch queue circular linked list
byte elem[8]; // asynch queue data element
};
struct Scase
{
Hchan* chan; // chan
byte* pc; // return pc
uint16 send; // 0-recv 1-send
uint16 so; // vararg of selected bool
byte elem[8]; // element
};
struct Select
{
uint16 tcase; // total count of scase[]
uint16 ncase; // currently filled scase[]
Scase scase[1]; // one per case
};
static SudoG* dequeue(WaitQ*, Hchan*);
static void enqueue(WaitQ*, SudoG*);
static SudoG* allocsg(Hchan*);
static void freesg(Hchan*, SudoG*);
static uint32 gcd(uint32, uint32);
static uint32 fastrand1(void);
static uint32 fastrand2(void);
// newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any);
void
......@@ -134,16 +156,15 @@ sys·chansend1(Hchan* c, ...)
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, sgr->elem, ae);
c->elemalg->copy(c->elemsize, gr->elem, ae);
gr = sgr->g;
gr->status = Grunnable;
return;
}
c->elemalg->copy(c->elemsize, g->elem, ae);
sgr = allocsg(c);
c->elemalg->copy(c->elemsize, sgr->elem, ae);
g->status = Gwaiting;
enqueue(&c->sendq, sgr);
sys·gosched();
......@@ -191,9 +212,8 @@ sys·chansend2(Hchan* c, ...)
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, sgr->elem, ae);
c->elemalg->copy(c->elemsize, gr->elem, ae);
gr->status = Grunnable;
*ap = true;
return;
......@@ -237,18 +257,20 @@ sys·chanrecv1(Hchan* c, ...)
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, sgs->elem);
c->elemalg->copy(c->elemsize, ae, gs->elem);
gs = sgs->g;
gs->status = Grunnable;
freesg(c, sgs);
return;
}
sgs = allocsg(c);
g->status = Gwaiting;
enqueue(&c->recvq, sgs);
sys·gosched();
c->elemalg->copy(c->elemsize, ae, g->elem);
c->elemalg->copy(c->elemsize, ae, sgs->elem);
freesg(c, sgs);
return;
asynch:
......@@ -291,11 +313,12 @@ sys·chanrecv2(Hchan* c, ...)
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, sgs->elem);
c->elemalg->copy(c->elemsize, ae, gs->elem);
gs = sgs->g;
gs->status = Grunnable;
freesg(c, sgs);
*ap = true;
return;
}
......@@ -320,6 +343,150 @@ asynch:
*ap = true;
}
// newselect(size uint32) (sel *byte);
void
sys·newselect(int32 size, Select *sel)
{
int32 n;
n = 0;
if(size > 1)
n = size-1;
sel = mal(sizeof(*sel) + n*sizeof(sel->scase[0]));
sel->tcase = size;
sel->ncase = 0;
FLUSH(&sel);
if(debug) {
prints("newselect s=");
sys·printpointer(sel);
prints("\n");
}
}
// selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
void
sys·selectsend(Select *sel, Hchan *c, ...)
{
int32 i, eo;
Scase *cas;
byte *as, *ae;
// return val, selected, is preset to false
if(c == nil)
return;
i = sel->ncase;
if(i >= sel->tcase)
throw("selectsend: too many cases");
sel->ncase = i+1;
cas = &sel->scase[i];
cas->pc = sys·getcallerpc(&sel);
cas->chan = c;
eo = rnd(sizeof(sel), sizeof(c));
eo = rnd(eo+sizeof(c), c->elemsize);
cas->so = rnd(eo+c->elemsize, 1);
cas->send = 1;
ae = (byte*)&sel + eo;
c->elemalg->copy(c->elemsize, cas->elem, ae);
as = (byte*)&sel + cas->so;
*as = false;
if(debug) {
prints("newselect s=");
sys·printpointer(sel);
prints(" pc=");
sys·printpointer(cas->pc);
prints(" chan=");
sys·printpointer(cas->chan);
prints(" po=");
sys·printint(cas->so);
prints(" send=");
sys·printint(cas->send);
prints("\n");
}
}
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
void
sys·selectrecv(Select *sel, Hchan *c, ...)
{
throw("selectrecv");
}
// selectgo(sel *byte);
void
sys·selectgo(Select *sel)
{
uint32 p, o, i;
Scase *cas;
Hchan *c;
byte *ae, *as;
SudoG *sgr;
G *gr;
if(sel->ncase < 1) {
throw("selectgo: no cases");
}
// select a (relative) prime
for(i=0;; i++) {
p = fastrand1();
if(gcd(p, sel->ncase) == 1)
break;
if(i > 1000) {
throw("selectgo: failed to select prime");
}
}
o = fastrand2();
p %= sel->ncase;
o %= sel->ncase;
// pass 1 - look for something that can go
for(i=0; i<sel->ncase; i++) {
cas = &sel->scase[o];
c = cas->chan;
if(cas->send) {
if(c->dataqsiz > 0) {
throw("selectgo: asynch");
}
sgr = dequeue(&c->recvq, c);
if(sgr == nil)
continue;
c->elemalg->copy(c->elemsize, sgr->elem, cas->elem);
gr = sgr->g;
gr->status = Grunnable;
goto retc;
}
o += p;
if(o >= sel->ncase)
o -= sel->ncase;
}
if(debug) {
prints("selectgo s=");
sys·printpointer(sel);
prints(" p=");
sys·printpointer((void*)p);
prints("\n");
}
throw("selectgo");
retc:
sys·setcallerpc(&sel, cas->pc);
as = (byte*)&sel + cas->so;
*as = true;
}
static SudoG*
dequeue(WaitQ *q, Hchan *c)
{
......@@ -377,3 +544,41 @@ freesg(Hchan *c, SudoG *sg)
sg->link = c->free;
c->free = sg;
}
static uint32
gcd(uint32 u, uint32 v)
{
for(;;) {
if(u > v) {
if(v == 0)
return u;
u = u%v;
continue;
}
if(u == 0)
return v;
v = v%u;
}
}
static uint32
fastrand1(void)
{
static uint32 x = 0x49f6428aUL;
x += x;
if(x & 0x80000000L)
x ^= 0x88888eefUL;
return x;
}
static uint32
fastrand2(void)
{
static uint32 x = 0x49f6428aUL;
x += x;
if(x & 0x80000000L)
x ^= 0xfafd871bUL;
return x;
}
......@@ -110,7 +110,6 @@ struct G
int32 status;
int32 goid;
int64 selgen; // valid sudog pointer
byte elem[8]; // transfer element for chan
};
struct M
{
......@@ -205,6 +204,7 @@ void sys·write(int32, void*, int32);
void sys·breakpoint(void);
uint8* sys·mmap(byte*, uint32, int32, int32, int32, uint32);
void sys·memclr(byte*, uint32);
void sys·setcallerpc(void*, void*);
void* sys·getcallerpc(void*);
void sys·sigaction(int64, void*, void*);
void sys·rt_sigaction(int64, void*, void*, uint64);
......
......@@ -110,6 +110,12 @@ TEXT sys·memclr(SB),1,$-8
RET
TEXT sys·getcallerpc+0(SB),1,$0
MOVQ x+0(FP),AX
MOVQ -8(AX),AX
MOVQ x+0(FP),AX // addr of first arg
MOVQ -8(AX),AX // get calling pc
RET
TEXT sys·setcallerpc+0(SB),1,$0
MOVQ x+0(FP),AX // addr of first arg
MOVQ x+8(FP), BX
MOVQ BX, -8(AX) // set calling pc
RET
......@@ -114,6 +114,12 @@ TEXT sys·memclr(SB),1,$0-16
RET
TEXT sys·getcallerpc+0(SB),1,$0
MOVQ x+0(FP),AX
MOVQ -8(AX),AX
MOVQ x+0(FP),AX // addr of first arg
MOVQ -8(AX),AX // get calling pc
RET
TEXT sys·setcallerpc+0(SB),1,$0
MOVQ x+0(FP),AX // addr of first arg
MOVQ x+8(FP), BX
MOVQ BX, -8(AX) // set calling pc
RET
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment