Hex Artifact Content
Not logged in

Artifact 1e44b9aba2216df3ccbed0b92a5876870279fb27:


0000: 2f 2a 20 43 6f 70 79 72 69 67 68 74 20 28 63 29  /* Copyright (c)
0010: 20 32 30 30 35 20 52 75 73 73 20 43 6f 78 2c 20   2005 Russ Cox, 
0020: 4d 49 54 3b 20 73 65 65 20 43 4f 50 59 52 49 47  MIT; see COPYRIG
0030: 48 54 20 2a 2f 0a 0a 23 69 6e 63 6c 75 64 65 20  HT */..#include 
0040: 22 74 61 73 6b 69 6d 70 6c 2e 68 22 0a 0a 43 68  "taskimpl.h"..Ch
0050: 61 6e 6e 65 6c 2a 0a 63 68 61 6e 63 72 65 61 74  annel*.chancreat
0060: 65 28 69 6e 74 20 65 6c 65 6d 73 69 7a 65 2c 20  e(int elemsize, 
0070: 69 6e 74 20 62 75 66 73 69 7a 65 29 0a 7b 0a 09  int bufsize).{..
0080: 43 68 61 6e 6e 65 6c 20 2a 63 3b 0a 0a 09 63 20  Channel *c;...c 
0090: 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 20  = malloc(sizeof 
00a0: 2a 63 2b 62 75 66 73 69 7a 65 2a 65 6c 65 6d 73  *c+bufsize*elems
00b0: 69 7a 65 29 3b 0a 09 69 66 28 63 20 3d 3d 20 6e  ize);..if(c == n
00c0: 69 6c 29 7b 0a 09 09 66 70 72 69 6e 74 28 32 2c  il){...fprint(2,
00d0: 20 22 63 68 61 6e 63 72 65 61 74 65 20 6d 61 6c   "chancreate mal
00e0: 6c 6f 63 3a 20 25 72 22 29 3b 0a 09 09 65 78 69  loc: %r");...exi
00f0: 74 28 31 29 3b 0a 09 7d 0a 09 6d 65 6d 73 65 74  t(1);..}..memset
0100: 28 63 2c 20 30 2c 20 73 69 7a 65 6f 66 20 2a 63  (c, 0, sizeof *c
0110: 29 3b 0a 09 63 2d 3e 65 6c 65 6d 73 69 7a 65 20  );..c->elemsize 
0120: 3d 20 65 6c 65 6d 73 69 7a 65 3b 0a 09 63 2d 3e  = elemsize;..c->
0130: 62 75 66 73 69 7a 65 20 3d 20 62 75 66 73 69 7a  bufsize = bufsiz
0140: 65 3b 0a 09 63 2d 3e 6e 62 75 66 20 3d 20 30 3b  e;..c->nbuf = 0;
0150: 0a 09 63 2d 3e 62 75 66 20 3d 20 28 75 63 68 61  ..c->buf = (ucha
0160: 72 2a 29 28 63 2b 31 29 3b 0a 09 72 65 74 75 72  r*)(c+1);..retur
0170: 6e 20 63 3b 0a 7d 0a 0a 2f 2a 20 62 75 67 20 2d  n c;.}../* bug -
0180: 20 77 6f 72 6b 20 6f 75 74 20 72 61 63 65 73 20   work out races 
0190: 2a 2f 0a 76 6f 69 64 0a 63 68 61 6e 66 72 65 65  */.void.chanfree
01a0: 28 43 68 61 6e 6e 65 6c 20 2a 63 29 0a 7b 0a 09  (Channel *c).{..
01b0: 69 66 28 63 20 3d 3d 20 6e 69 6c 29 0a 09 09 72  if(c == nil)...r
01c0: 65 74 75 72 6e 3b 0a 09 66 72 65 65 28 63 2d 3e  eturn;..free(c->
01d0: 6e 61 6d 65 29 3b 0a 09 66 72 65 65 28 63 2d 3e  name);..free(c->
01e0: 61 72 65 63 76 2e 61 29 3b 0a 09 66 72 65 65 28  arecv.a);..free(
01f0: 63 2d 3e 61 73 65 6e 64 2e 61 29 3b 0a 09 66 72  c->asend.a);..fr
0200: 65 65 28 63 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  ee(c);.}..static
0210: 20 76 6f 69 64 0a 61 64 64 61 72 72 61 79 28 41   void.addarray(A
0220: 6c 74 61 72 72 61 79 20 2a 61 2c 20 41 6c 74 20  ltarray *a, Alt 
0230: 2a 61 6c 74 29 0a 7b 0a 09 69 66 28 61 2d 3e 6e  *alt).{..if(a->n
0240: 20 3d 3d 20 61 2d 3e 6d 29 7b 0a 09 09 61 2d 3e   == a->m){...a->
0250: 6d 20 2b 3d 20 31 36 3b 0a 09 09 61 2d 3e 61 20  m += 16;...a->a 
0260: 3d 20 72 65 61 6c 6c 6f 63 28 61 2d 3e 61 2c 20  = realloc(a->a, 
0270: 61 2d 3e 6d 2a 73 69 7a 65 6f 66 20 61 2d 3e 61  a->m*sizeof a->a
0280: 5b 30 5d 29 3b 0a 09 7d 0a 09 61 2d 3e 61 5b 61  [0]);..}..a->a[a
0290: 2d 3e 6e 2b 2b 5d 20 3d 20 61 6c 74 3b 0a 7d 0a  ->n++] = alt;.}.
02a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 0a 64 65 6c  .static void.del
02b0: 61 72 72 61 79 28 41 6c 74 61 72 72 61 79 20 2a  array(Altarray *
02c0: 61 2c 20 69 6e 74 20 69 29 0a 7b 0a 09 2d 2d 61  a, int i).{..--a
02d0: 2d 3e 6e 3b 0a 09 61 2d 3e 61 5b 69 5d 20 3d 20  ->n;..a->a[i] = 
02e0: 61 2d 3e 61 5b 61 2d 3e 6e 5d 3b 0a 7d 0a 0a 2f  a->a[a->n];.}../
02f0: 2a 0a 20 2a 20 64 6f 65 73 6e 27 74 20 72 65 61  *. * doesn't rea
0300: 6c 6c 79 20 77 6f 72 6b 20 66 6f 72 20 74 68 69  lly work for thi
0310: 6e 67 73 20 6f 74 68 65 72 20 74 68 61 6e 20 43  ngs other than C
0320: 48 41 4e 53 4e 44 20 61 6e 64 20 43 48 41 4e 52  HANSND and CHANR
0330: 43 56 0a 20 2a 20 62 75 74 20 69 73 20 6f 6e 6c  CV. * but is onl
0340: 79 20 75 73 65 64 20 61 73 20 61 72 67 20 74 6f  y used as arg to
0350: 20 63 68 61 6e 61 72 72 61 79 2c 20 77 68 69 63   chanarray, whic
0360: 68 20 63 61 6e 20 68 61 6e 64 6c 65 20 69 74 0a  h can handle it.
0370: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 6f 74 68 65   */.#define othe
0380: 72 6f 70 28 6f 70 29 09 28 43 48 41 4e 53 4e 44  rop(op).(CHANSND
0390: 2b 43 48 41 4e 52 43 56 2d 28 6f 70 29 29 0a 0a  +CHANRCV-(op))..
03a0: 73 74 61 74 69 63 20 41 6c 74 61 72 72 61 79 2a  static Altarray*
03b0: 0a 63 68 61 6e 61 72 72 61 79 28 43 68 61 6e 6e  .chanarray(Chann
03c0: 65 6c 20 2a 63 2c 20 75 69 6e 74 20 6f 70 29 0a  el *c, uint op).
03d0: 7b 0a 09 73 77 69 74 63 68 28 6f 70 29 7b 0a 09  {..switch(op){..
03e0: 64 65 66 61 75 6c 74 3a 0a 09 09 72 65 74 75 72  default:...retur
03f0: 6e 20 6e 69 6c 3b 0a 09 63 61 73 65 20 43 48 41  n nil;..case CHA
0400: 4e 53 4e 44 3a 0a 09 09 72 65 74 75 72 6e 20 26  NSND:...return &
0410: 63 2d 3e 61 73 65 6e 64 3b 0a 09 63 61 73 65 20  c->asend;..case 
0420: 43 48 41 4e 52 43 56 3a 0a 09 09 72 65 74 75 72  CHANRCV:...retur
0430: 6e 20 26 63 2d 3e 61 72 65 63 76 3b 0a 09 7d 0a  n &c->arecv;..}.
0440: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 0a 61 6c  }..static int.al
0450: 74 63 61 6e 65 78 65 63 28 41 6c 74 20 2a 61 29  tcanexec(Alt *a)
0460: 0a 7b 0a 09 41 6c 74 61 72 72 61 79 20 2a 61 72  .{..Altarray *ar
0470: 3b 0a 09 43 68 61 6e 6e 65 6c 20 2a 63 3b 0a 0a  ;..Channel *c;..
0480: 09 69 66 28 61 2d 3e 6f 70 20 3d 3d 20 43 48 41  .if(a->op == CHA
0490: 4e 4e 4f 50 29 0a 09 09 72 65 74 75 72 6e 20 30  NNOP)...return 0
04a0: 3b 0a 09 63 20 3d 20 61 2d 3e 63 3b 0a 09 69 66  ;..c = a->c;..if
04b0: 28 63 2d 3e 62 75 66 73 69 7a 65 20 3d 3d 20 30  (c->bufsize == 0
04c0: 29 7b 0a 09 09 61 72 20 3d 20 63 68 61 6e 61 72  ){...ar = chanar
04d0: 72 61 79 28 63 2c 20 6f 74 68 65 72 6f 70 28 61  ray(c, otherop(a
04e0: 2d 3e 6f 70 29 29 3b 0a 09 09 72 65 74 75 72 6e  ->op));...return
04f0: 20 61 72 20 26 26 20 61 72 2d 3e 6e 3b 0a 09 7d   ar && ar->n;..}
0500: 65 6c 73 65 7b 0a 09 09 73 77 69 74 63 68 28 61  else{...switch(a
0510: 2d 3e 6f 70 29 7b 0a 09 09 64 65 66 61 75 6c 74  ->op){...default
0520: 3a 0a 09 09 09 72 65 74 75 72 6e 20 30 3b 0a 09  :....return 0;..
0530: 09 63 61 73 65 20 43 48 41 4e 53 4e 44 3a 0a 09  .case CHANSND:..
0540: 09 09 72 65 74 75 72 6e 20 63 2d 3e 6e 62 75 66  ..return c->nbuf
0550: 20 3c 20 63 2d 3e 62 75 66 73 69 7a 65 3b 0a 09   < c->bufsize;..
0560: 09 63 61 73 65 20 43 48 41 4e 52 43 56 3a 0a 09  .case CHANRCV:..
0570: 09 09 72 65 74 75 72 6e 20 63 2d 3e 6e 62 75 66  ..return c->nbuf
0580: 20 3e 20 30 3b 0a 09 09 7d 0a 09 7d 0a 7d 0a 0a   > 0;...}..}.}..
0590: 73 74 61 74 69 63 20 76 6f 69 64 0a 61 6c 74 71  static void.altq
05a0: 75 65 75 65 28 41 6c 74 20 2a 61 29 0a 7b 0a 09  ueue(Alt *a).{..
05b0: 41 6c 74 61 72 72 61 79 20 2a 61 72 3b 0a 0a 09  Altarray *ar;...
05c0: 61 72 20 3d 20 63 68 61 6e 61 72 72 61 79 28 61  ar = chanarray(a
05d0: 2d 3e 63 2c 20 61 2d 3e 6f 70 29 3b 0a 09 61 64  ->c, a->op);..ad
05e0: 64 61 72 72 61 79 28 61 72 2c 20 61 29 3b 0a 7d  darray(ar, a);.}
05f0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 0a 61 6c  ..static void.al
0600: 74 64 65 71 75 65 75 65 28 41 6c 74 20 2a 61 29  tdequeue(Alt *a)
0610: 0a 7b 0a 09 69 6e 74 20 69 3b 0a 09 41 6c 74 61  .{..int i;..Alta
0620: 72 72 61 79 20 2a 61 72 3b 0a 0a 09 61 72 20 3d  rray *ar;...ar =
0630: 20 63 68 61 6e 61 72 72 61 79 28 61 2d 3e 63 2c   chanarray(a->c,
0640: 20 61 2d 3e 6f 70 29 3b 0a 09 69 66 28 61 72 20   a->op);..if(ar 
0650: 3d 3d 20 6e 69 6c 29 7b 0a 09 09 66 70 72 69 6e  == nil){...fprin
0660: 74 28 32 2c 20 22 62 61 64 20 75 73 65 20 6f 66  t(2, "bad use of
0670: 20 61 6c 74 64 65 71 75 65 75 65 20 6f 70 3d 25   altdequeue op=%
0680: 64 5c 6e 22 2c 20 61 2d 3e 6f 70 29 3b 0a 09 09  d\n", a->op);...
0690: 61 62 6f 72 74 28 29 3b 0a 09 7d 0a 0a 09 66 6f  abort();..}...fo
06a0: 72 28 69 3d 30 3b 20 69 3c 61 72 2d 3e 6e 3b 20  r(i=0; i<ar->n; 
06b0: 69 2b 2b 29 0a 09 09 69 66 28 61 72 2d 3e 61 5b  i++)...if(ar->a[
06c0: 69 5d 20 3d 3d 20 61 29 7b 0a 09 09 09 64 65 6c  i] == a){....del
06d0: 61 72 72 61 79 28 61 72 2c 20 69 29 3b 0a 09 09  array(ar, i);...
06e0: 09 72 65 74 75 72 6e 3b 0a 09 09 7d 0a 09 66 70  .return;...}..fp
06f0: 72 69 6e 74 28 32 2c 20 22 63 61 6e 6e 6f 74 20  rint(2, "cannot 
0700: 66 69 6e 64 20 73 65 6c 66 20 69 6e 20 61 6c 74  find self in alt
0710: 64 71 5c 6e 22 29 3b 0a 09 61 62 6f 72 74 28 29  dq\n");..abort()
0720: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
0730: 0a 61 6c 74 61 6c 6c 64 65 71 75 65 75 65 28 41  .altalldequeue(A
0740: 6c 74 20 2a 61 29 0a 7b 0a 09 69 6e 74 20 69 3b  lt *a).{..int i;
0750: 0a 0a 09 66 6f 72 28 69 3d 30 3b 20 61 5b 69 5d  ...for(i=0; a[i]
0760: 2e 6f 70 21 3d 43 48 41 4e 45 4e 44 20 26 26 20  .op!=CHANEND && 
0770: 61 5b 69 5d 2e 6f 70 21 3d 43 48 41 4e 4e 4f 42  a[i].op!=CHANNOB
0780: 4c 4b 3b 20 69 2b 2b 29 0a 09 09 69 66 28 61 5b  LK; i++)...if(a[
0790: 69 5d 2e 6f 70 20 21 3d 20 43 48 41 4e 4e 4f 50  i].op != CHANNOP
07a0: 29 0a 09 09 09 61 6c 74 64 65 71 75 65 75 65 28  )....altdequeue(
07b0: 26 61 5b 69 5d 29 3b 0a 7d 0a 0a 73 74 61 74 69  &a[i]);.}..stati
07c0: 63 20 76 6f 69 64 0a 61 6d 6f 76 65 28 76 6f 69  c void.amove(voi
07d0: 64 20 2a 64 73 74 2c 20 76 6f 69 64 20 2a 73 72  d *dst, void *sr
07e0: 63 2c 20 75 69 6e 74 20 6e 29 0a 7b 0a 09 69 66  c, uint n).{..if
07f0: 28 64 73 74 29 7b 0a 09 09 69 66 28 73 72 63 20  (dst){...if(src 
0800: 3d 3d 20 6e 69 6c 29 0a 09 09 09 6d 65 6d 73 65  == nil)....memse
0810: 74 28 64 73 74 2c 20 30 2c 20 6e 29 3b 0a 09 09  t(dst, 0, n);...
0820: 65 6c 73 65 0a 09 09 09 6d 65 6d 6d 6f 76 65 28  else....memmove(
0830: 64 73 74 2c 20 73 72 63 2c 20 6e 29 3b 0a 09 7d  dst, src, n);..}
0840: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 63 74 75 61 6c  .}../*. * Actual
0850: 6c 79 20 6d 6f 76 65 20 74 68 65 20 64 61 74 61  ly move the data
0860: 20 61 72 6f 75 6e 64 2e 20 20 54 68 65 72 65 20   around.  There 
0870: 61 72 65 20 75 70 20 74 6f 20 74 68 72 65 65 0a  are up to three.
0880: 20 2a 20 70 6c 61 79 65 72 73 3a 20 74 68 65 20   * players: the 
0890: 73 65 6e 64 65 72 2c 20 74 68 65 20 72 65 63 65  sender, the rece
08a0: 69 76 65 72 2c 20 61 6e 64 20 74 68 65 20 63 68  iver, and the ch
08b0: 61 6e 6e 65 6c 20 69 74 73 65 6c 66 2e 0a 20 2a  annel itself.. *
08c0: 20 49 66 20 74 68 65 20 63 68 61 6e 6e 65 6c 20   If the channel 
08d0: 69 73 20 75 6e 62 75 66 66 65 72 65 64 20 6f 72  is unbuffered or
08e0: 20 74 68 65 20 62 75 66 66 65 72 20 69 73 20 65   the buffer is e
08f0: 6d 70 74 79 2c 0a 20 2a 20 64 61 74 61 20 67 6f  mpty,. * data go
0900: 65 73 20 66 72 6f 6d 20 73 65 6e 64 65 72 20 74  es from sender t
0910: 6f 20 72 65 63 65 69 76 65 72 2e 20 20 49 66 20  o receiver.  If 
0920: 74 68 65 20 63 68 61 6e 6e 65 6c 20 69 73 20 66  the channel is f
0930: 75 6c 6c 2c 0a 20 2a 20 74 68 65 20 72 65 63 65  ull,. * the rece
0940: 69 76 65 72 20 72 65 6d 6f 76 65 73 20 73 6f 6d  iver removes som
0950: 65 20 66 72 6f 6d 20 74 68 65 20 63 68 61 6e 6e  e from the chann
0960: 65 6c 20 61 6e 64 20 74 68 65 20 73 65 6e 64 65  el and the sende
0970: 72 0a 20 2a 20 67 65 74 73 20 74 6f 20 70 75 74  r. * gets to put
0980: 20 73 6f 6d 65 20 69 6e 2e 0a 20 2a 2f 0a 73 74   some in.. */.st
0990: 61 74 69 63 20 76 6f 69 64 0a 61 6c 74 63 6f 70  atic void.altcop
09a0: 79 28 41 6c 74 20 2a 73 2c 20 41 6c 74 20 2a 72  y(Alt *s, Alt *r
09b0: 29 0a 7b 0a 09 41 6c 74 20 2a 74 3b 0a 09 43 68  ).{..Alt *t;..Ch
09c0: 61 6e 6e 65 6c 20 2a 63 3b 0a 09 75 63 68 61 72  annel *c;..uchar
09d0: 20 2a 63 70 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 57   *cp;.../*.. * W
09e0: 6f 72 6b 20 6f 75 74 20 77 68 6f 20 69 73 20 73  ork out who is s
09f0: 65 6e 64 65 72 20 61 6e 64 20 77 68 6f 20 69 73  ender and who is
0a00: 20 72 65 63 65 69 76 65 72 0a 09 20 2a 2f 0a 09   receiver.. */..
0a10: 69 66 28 73 20 3d 3d 20 6e 69 6c 20 26 26 20 72  if(s == nil && r
0a20: 20 3d 3d 20 6e 69 6c 29 0a 09 09 72 65 74 75 72   == nil)...retur
0a30: 6e 3b 0a 09 61 73 73 65 72 74 28 73 20 21 3d 20  n;..assert(s != 
0a40: 6e 69 6c 29 3b 0a 09 63 20 3d 20 73 2d 3e 63 3b  nil);..c = s->c;
0a50: 0a 09 69 66 28 73 2d 3e 6f 70 20 3d 3d 20 43 48  ..if(s->op == CH
0a60: 41 4e 52 43 56 29 7b 0a 09 09 74 20 3d 20 73 3b  ANRCV){...t = s;
0a70: 0a 09 09 73 20 3d 20 72 3b 0a 09 09 72 20 3d 20  ...s = r;...r = 
0a80: 74 3b 0a 09 7d 0a 09 61 73 73 65 72 74 28 73 3d  t;..}..assert(s=
0a90: 3d 6e 69 6c 20 7c 7c 20 73 2d 3e 6f 70 20 3d 3d  =nil || s->op ==
0aa0: 20 43 48 41 4e 53 4e 44 29 3b 0a 09 61 73 73 65   CHANSND);..asse
0ab0: 72 74 28 72 3d 3d 6e 69 6c 20 7c 7c 20 72 2d 3e  rt(r==nil || r->
0ac0: 6f 70 20 3d 3d 20 43 48 41 4e 52 43 56 29 3b 0a  op == CHANRCV);.
0ad0: 0a 09 2f 2a 0a 09 20 2a 20 43 68 61 6e 6e 65 6c  ../*.. * Channel
0ae0: 20 69 73 20 65 6d 70 74 79 20 28 6f 72 20 75 6e   is empty (or un
0af0: 62 75 66 66 65 72 65 64 29 20 2d 20 63 6f 70 79  buffered) - copy
0b00: 20 64 69 72 65 63 74 6c 79 2e 0a 09 20 2a 2f 0a   directly... */.
0b10: 09 69 66 28 73 20 26 26 20 72 20 26 26 20 63 2d  .if(s && r && c-
0b20: 3e 6e 62 75 66 20 3d 3d 20 30 29 7b 0a 09 09 61  >nbuf == 0){...a
0b30: 6d 6f 76 65 28 72 2d 3e 76 2c 20 73 2d 3e 76 2c  move(r->v, s->v,
0b40: 20 63 2d 3e 65 6c 65 6d 73 69 7a 65 29 3b 0a 09   c->elemsize);..
0b50: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 2f 2a  .return;..}.../*
0b60: 0a 09 20 2a 20 4f 74 68 65 72 77 69 73 65 20 69  .. * Otherwise i
0b70: 74 27 73 20 61 6c 77 61 79 73 20 6f 6b 61 79 20  t's always okay 
0b80: 74 6f 20 72 65 63 65 69 76 65 20 61 6e 64 20 74  to receive and t
0b90: 68 65 6e 20 73 65 6e 64 2e 0a 09 20 2a 2f 0a 09  hen send... */..
0ba0: 69 66 28 72 29 7b 0a 09 09 63 70 20 3d 20 63 2d  if(r){...cp = c-
0bb0: 3e 62 75 66 20 2b 20 63 2d 3e 6f 66 66 2a 63 2d  >buf + c->off*c-
0bc0: 3e 65 6c 65 6d 73 69 7a 65 3b 0a 09 09 61 6d 6f  >elemsize;...amo
0bd0: 76 65 28 72 2d 3e 76 2c 20 63 70 2c 20 63 2d 3e  ve(r->v, cp, c->
0be0: 65 6c 65 6d 73 69 7a 65 29 3b 0a 09 09 2d 2d 63  elemsize);...--c
0bf0: 2d 3e 6e 62 75 66 3b 0a 09 09 69 66 28 2b 2b 63  ->nbuf;...if(++c
0c00: 2d 3e 6f 66 66 20 3d 3d 20 63 2d 3e 62 75 66 73  ->off == c->bufs
0c10: 69 7a 65 29 0a 09 09 09 63 2d 3e 6f 66 66 20 3d  ize)....c->off =
0c20: 20 30 3b 0a 09 7d 0a 09 69 66 28 73 29 7b 0a 09   0;..}..if(s){..
0c30: 09 63 70 20 3d 20 63 2d 3e 62 75 66 20 2b 20 28  .cp = c->buf + (
0c40: 63 2d 3e 6f 66 66 2b 63 2d 3e 6e 62 75 66 29 25  c->off+c->nbuf)%
0c50: 63 2d 3e 62 75 66 73 69 7a 65 2a 63 2d 3e 65 6c  c->bufsize*c->el
0c60: 65 6d 73 69 7a 65 3b 0a 09 09 61 6d 6f 76 65 28  emsize;...amove(
0c70: 63 70 2c 20 73 2d 3e 76 2c 20 63 2d 3e 65 6c 65  cp, s->v, c->ele
0c80: 6d 73 69 7a 65 29 3b 0a 09 09 2b 2b 63 2d 3e 6e  msize);...++c->n
0c90: 62 75 66 3b 0a 09 7d 0a 7d 0a 0a 73 74 61 74 69  buf;..}.}..stati
0ca0: 63 20 76 6f 69 64 0a 61 6c 74 65 78 65 63 28 41  c void.altexec(A
0cb0: 6c 74 20 2a 61 29 0a 7b 0a 09 69 6e 74 20 69 3b  lt *a).{..int i;
0cc0: 0a 09 41 6c 74 61 72 72 61 79 20 2a 61 72 3b 0a  ..Altarray *ar;.
0cd0: 09 41 6c 74 20 2a 6f 74 68 65 72 3b 0a 09 43 68  .Alt *other;..Ch
0ce0: 61 6e 6e 65 6c 20 2a 63 3b 0a 0a 09 63 20 3d 20  annel *c;...c = 
0cf0: 61 2d 3e 63 3b 0a 09 61 72 20 3d 20 63 68 61 6e  a->c;..ar = chan
0d00: 61 72 72 61 79 28 63 2c 20 6f 74 68 65 72 6f 70  array(c, otherop
0d10: 28 61 2d 3e 6f 70 29 29 3b 0a 09 69 66 28 61 72  (a->op));..if(ar
0d20: 20 26 26 20 61 72 2d 3e 6e 29 7b 0a 09 09 69 20   && ar->n){...i 
0d30: 3d 20 72 61 6e 64 28 29 25 61 72 2d 3e 6e 3b 0a  = rand()%ar->n;.
0d40: 09 09 6f 74 68 65 72 20 3d 20 61 72 2d 3e 61 5b  ..other = ar->a[
0d50: 69 5d 3b 0a 09 09 61 6c 74 63 6f 70 79 28 61 2c  i];...altcopy(a,
0d60: 20 6f 74 68 65 72 29 3b 0a 09 09 61 6c 74 61 6c   other);...altal
0d70: 6c 64 65 71 75 65 75 65 28 6f 74 68 65 72 2d 3e  ldequeue(other->
0d80: 78 61 6c 74 29 3b 0a 09 09 6f 74 68 65 72 2d 3e  xalt);...other->
0d90: 78 61 6c 74 5b 30 5d 2e 78 61 6c 74 20 3d 20 6f  xalt[0].xalt = o
0da0: 74 68 65 72 3b 0a 09 09 74 61 73 6b 72 65 61 64  ther;...taskread
0db0: 79 28 6f 74 68 65 72 2d 3e 74 61 73 6b 29 3b 0a  y(other->task);.
0dc0: 09 7d 65 6c 73 65 0a 09 09 61 6c 74 63 6f 70 79  .}else...altcopy
0dd0: 28 61 2c 20 6e 69 6c 29 3b 0a 7d 0a 0a 23 64 65  (a, nil);.}..#de
0de0: 66 69 6e 65 20 64 62 67 61 6c 74 20 30 0a 69 6e  fine dbgalt 0.in
0df0: 74 0a 63 68 61 6e 61 6c 74 28 41 6c 74 20 2a 61  t.chanalt(Alt *a
0e00: 29 0a 7b 0a 09 69 6e 74 20 69 2c 20 6a 2c 20 6e  ).{..int i, j, n
0e10: 63 61 6e 2c 20 6e 2c 20 63 61 6e 62 6c 6f 63 6b  can, n, canblock
0e20: 3b 0a 09 43 68 61 6e 6e 65 6c 20 2a 63 3b 0a 09  ;..Channel *c;..
0e30: 54 61 73 6b 20 2a 74 3b 0a 0a 09 6e 65 65 64 73  Task *t;...needs
0e40: 74 61 63 6b 28 35 31 32 29 3b 0a 09 66 6f 72 28  tack(512);..for(
0e50: 69 3d 30 3b 20 61 5b 69 5d 2e 6f 70 20 21 3d 20  i=0; a[i].op != 
0e60: 43 48 41 4e 45 4e 44 20 26 26 20 61 5b 69 5d 2e  CHANEND && a[i].
0e70: 6f 70 20 21 3d 20 43 48 41 4e 4e 4f 42 4c 4b 3b  op != CHANNOBLK;
0e80: 20 69 2b 2b 29 0a 09 09 3b 0a 09 6e 20 3d 20 69   i++)...;..n = i
0e90: 3b 0a 09 63 61 6e 62 6c 6f 63 6b 20 3d 20 61 5b  ;..canblock = a[
0ea0: 69 5d 2e 6f 70 20 3d 3d 20 43 48 41 4e 45 4e 44  i].op == CHANEND
0eb0: 3b 0a 0a 09 74 20 3d 20 74 61 73 6b 72 75 6e 6e  ;...t = taskrunn
0ec0: 69 6e 67 3b 0a 09 66 6f 72 28 69 3d 30 3b 20 69  ing;..for(i=0; i
0ed0: 3c 6e 3b 20 69 2b 2b 29 7b 0a 09 09 61 5b 69 5d  <n; i++){...a[i]
0ee0: 2e 74 61 73 6b 20 3d 20 74 3b 0a 09 09 61 5b 69  .task = t;...a[i
0ef0: 5d 2e 78 61 6c 74 20 3d 20 61 3b 0a 09 7d 0a 69  ].xalt = a;..}.i
0f00: 66 28 64 62 67 61 6c 74 29 20 70 72 69 6e 74 28  f(dbgalt) print(
0f10: 22 61 6c 74 20 22 29 3b 0a 09 6e 63 61 6e 20 3d  "alt ");..ncan =
0f20: 20 30 3b 0a 09 66 6f 72 28 69 3d 30 3b 20 69 3c   0;..for(i=0; i<
0f30: 6e 3b 20 69 2b 2b 29 7b 0a 09 09 63 20 3d 20 61  n; i++){...c = a
0f40: 5b 69 5d 2e 63 3b 0a 69 66 28 64 62 67 61 6c 74  [i].c;.if(dbgalt
0f50: 29 20 70 72 69 6e 74 28 22 20 25 63 3a 22 2c 20  ) print(" %c:", 
0f60: 22 65 73 72 6e 62 22 5b 61 5b 69 5d 2e 6f 70 5d  "esrnb"[a[i].op]
0f70: 29 3b 0a 69 66 28 64 62 67 61 6c 74 29 20 7b 20  );.if(dbgalt) { 
0f80: 69 66 28 63 2d 3e 6e 61 6d 65 29 20 70 72 69 6e  if(c->name) prin
0f90: 74 28 22 25 73 22 2c 20 63 2d 3e 6e 61 6d 65 29  t("%s", c->name)
0fa0: 3b 20 65 6c 73 65 20 70 72 69 6e 74 28 22 25 70  ; else print("%p
0fb0: 22 2c 20 63 29 3b 20 7d 0a 09 09 69 66 28 61 6c  ", c); }...if(al
0fc0: 74 63 61 6e 65 78 65 63 28 26 61 5b 69 5d 29 29  tcanexec(&a[i]))
0fd0: 7b 0a 69 66 28 64 62 67 61 6c 74 29 20 70 72 69  {.if(dbgalt) pri
0fe0: 6e 74 28 22 2a 22 29 3b 0a 09 09 09 6e 63 61 6e  nt("*");....ncan
0ff0: 2b 2b 3b 0a 09 09 7d 0a 09 7d 0a 09 69 66 28 6e  ++;...}..}..if(n
1000: 63 61 6e 29 7b 0a 09 09 6a 20 3d 20 72 61 6e 64  can){...j = rand
1010: 28 29 25 6e 63 61 6e 3b 0a 09 09 66 6f 72 28 69  ()%ncan;...for(i
1020: 3d 30 3b 20 69 3c 6e 3b 20 69 2b 2b 29 7b 0a 09  =0; i<n; i++){..
1030: 09 09 69 66 28 61 6c 74 63 61 6e 65 78 65 63 28  ..if(altcanexec(
1040: 26 61 5b 69 5d 29 29 7b 0a 09 09 09 09 69 66 28  &a[i])){.....if(
1050: 6a 2d 2d 20 3d 3d 20 30 29 7b 0a 69 66 28 64 62  j-- == 0){.if(db
1060: 67 61 6c 74 29 7b 0a 63 20 3d 20 61 5b 69 5d 2e  galt){.c = a[i].
1070: 63 3b 0a 70 72 69 6e 74 28 22 20 3d 3e 20 25 63  c;.print(" => %c
1080: 3a 22 2c 20 22 65 73 72 6e 62 22 5b 61 5b 69 5d  :", "esrnb"[a[i]
1090: 2e 6f 70 5d 29 3b 0a 69 66 28 63 2d 3e 6e 61 6d  .op]);.if(c->nam
10a0: 65 29 20 70 72 69 6e 74 28 22 25 73 22 2c 20 63  e) print("%s", c
10b0: 2d 3e 6e 61 6d 65 29 3b 20 65 6c 73 65 20 70 72  ->name); else pr
10c0: 69 6e 74 28 22 25 70 22 2c 20 63 29 3b 0a 70 72  int("%p", c);.pr
10d0: 69 6e 74 28 22 5c 6e 22 29 3b 0a 7d 0a 09 09 09  int("\n");.}....
10e0: 09 09 61 6c 74 65 78 65 63 28 26 61 5b 69 5d 29  ..altexec(&a[i])
10f0: 3b 0a 09 09 09 09 09 72 65 74 75 72 6e 20 69 3b  ;......return i;
1100: 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 09 09 7d 0a  .....}....}...}.
1110: 09 7d 0a 69 66 28 64 62 67 61 6c 74 29 70 72 69  .}.if(dbgalt)pri
1120: 6e 74 28 22 5c 6e 22 29 3b 0a 0a 09 69 66 28 21  nt("\n");...if(!
1130: 63 61 6e 62 6c 6f 63 6b 29 0a 09 09 72 65 74 75  canblock)...retu
1140: 72 6e 20 2d 31 3b 0a 0a 09 66 6f 72 28 69 3d 30  rn -1;...for(i=0
1150: 3b 20 69 3c 6e 3b 20 69 2b 2b 29 7b 0a 09 09 69  ; i<n; i++){...i
1160: 66 28 61 5b 69 5d 2e 6f 70 20 21 3d 20 43 48 41  f(a[i].op != CHA
1170: 4e 4e 4f 50 29 0a 09 09 09 61 6c 74 71 75 65 75  NNOP)....altqueu
1180: 65 28 26 61 5b 69 5d 29 3b 0a 09 7d 0a 0a 09 74  e(&a[i]);..}...t
1190: 61 73 6b 73 77 69 74 63 68 28 29 3b 0a 0a 09 2f  askswitch();.../
11a0: 2a 0a 09 20 2a 20 74 68 65 20 67 75 79 20 77 68  *.. * the guy wh
11b0: 6f 20 72 61 6e 20 74 68 65 20 6f 70 20 74 6f 6f  o ran the op too
11c0: 6b 20 63 61 72 65 20 6f 66 20 64 65 71 75 65 75  k care of dequeu
11d0: 65 69 6e 67 20 75 73 0a 09 20 2a 20 61 6e 64 20  eing us.. * and 
11e0: 74 68 65 6e 20 73 65 74 20 61 5b 30 5d 2e 61 6c  then set a[0].al
11f0: 74 20 74 6f 20 74 68 65 20 6f 6e 65 20 74 68 61  t to the one tha
1200: 74 20 77 61 73 20 65 78 65 63 75 74 65 64 2e 0a  t was executed..
1210: 09 20 2a 2f 0a 09 72 65 74 75 72 6e 20 61 5b 30  . */..return a[0
1220: 5d 2e 78 61 6c 74 20 2d 20 61 3b 0a 7d 0a 0a 73  ].xalt - a;.}..s
1230: 74 61 74 69 63 20 69 6e 74 0a 5f 63 68 61 6e 6f  tatic int._chano
1240: 70 28 43 68 61 6e 6e 65 6c 20 2a 63 2c 20 69 6e  p(Channel *c, in
1250: 74 20 6f 70 2c 20 76 6f 69 64 20 2a 70 2c 20 69  t op, void *p, i
1260: 6e 74 20 63 61 6e 62 6c 6f 63 6b 29 0a 7b 0a 09  nt canblock).{..
1270: 41 6c 74 20 61 5b 32 5d 3b 0a 0a 09 61 5b 30 5d  Alt a[2];...a[0]
1280: 2e 63 20 3d 20 63 3b 0a 09 61 5b 30 5d 2e 6f 70  .c = c;..a[0].op
1290: 20 3d 20 6f 70 3b 0a 09 61 5b 30 5d 2e 76 20 3d   = op;..a[0].v =
12a0: 20 70 3b 0a 09 61 5b 31 5d 2e 6f 70 20 3d 20 63   p;..a[1].op = c
12b0: 61 6e 62 6c 6f 63 6b 20 3f 20 43 48 41 4e 45 4e  anblock ? CHANEN
12c0: 44 20 3a 20 43 48 41 4e 4e 4f 42 4c 4b 3b 0a 09  D : CHANNOBLK;..
12d0: 69 66 28 63 68 61 6e 61 6c 74 28 61 29 20 3c 20  if(chanalt(a) < 
12e0: 30 29 0a 09 09 72 65 74 75 72 6e 20 2d 31 3b 0a  0)...return -1;.
12f0: 09 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 69 6e  .return 1;.}..in
1300: 74 0a 63 68 61 6e 73 65 6e 64 28 43 68 61 6e 6e  t.chansend(Chann
1310: 65 6c 20 2a 63 2c 20 76 6f 69 64 20 2a 76 29 0a  el *c, void *v).
1320: 7b 0a 09 72 65 74 75 72 6e 20 5f 63 68 61 6e 6f  {..return _chano
1330: 70 28 63 2c 20 43 48 41 4e 53 4e 44 2c 20 76 2c  p(c, CHANSND, v,
1340: 20 31 29 3b 0a 7d 0a 0a 69 6e 74 0a 63 68 61 6e   1);.}..int.chan
1350: 6e 62 73 65 6e 64 28 43 68 61 6e 6e 65 6c 20 2a  nbsend(Channel *
1360: 63 2c 20 76 6f 69 64 20 2a 76 29 0a 7b 0a 09 72  c, void *v).{..r
1370: 65 74 75 72 6e 20 5f 63 68 61 6e 6f 70 28 63 2c  eturn _chanop(c,
1380: 20 43 48 41 4e 53 4e 44 2c 20 76 2c 20 30 29 3b   CHANSND, v, 0);
1390: 0a 7d 0a 0a 69 6e 74 0a 63 68 61 6e 72 65 63 76  .}..int.chanrecv
13a0: 28 43 68 61 6e 6e 65 6c 20 2a 63 2c 20 76 6f 69  (Channel *c, voi
13b0: 64 20 2a 76 29 0a 7b 0a 09 72 65 74 75 72 6e 20  d *v).{..return 
13c0: 5f 63 68 61 6e 6f 70 28 63 2c 20 43 48 41 4e 52  _chanop(c, CHANR
13d0: 43 56 2c 20 76 2c 20 31 29 3b 0a 7d 0a 0a 69 6e  CV, v, 1);.}..in
13e0: 74 0a 63 68 61 6e 6e 62 72 65 63 76 28 43 68 61  t.channbrecv(Cha
13f0: 6e 6e 65 6c 20 2a 63 2c 20 76 6f 69 64 20 2a 76  nnel *c, void *v
1400: 29 0a 7b 0a 09 72 65 74 75 72 6e 20 5f 63 68 61  ).{..return _cha
1410: 6e 6f 70 28 63 2c 20 43 48 41 4e 52 43 56 2c 20  nop(c, CHANRCV, 
1420: 76 2c 20 30 29 3b 0a 7d 0a 0a 69 6e 74 0a 63 68  v, 0);.}..int.ch
1430: 61 6e 73 65 6e 64 70 28 43 68 61 6e 6e 65 6c 20  ansendp(Channel 
1440: 2a 63 2c 20 76 6f 69 64 20 2a 76 29 0a 7b 0a 09  *c, void *v).{..
1450: 72 65 74 75 72 6e 20 5f 63 68 61 6e 6f 70 28 63  return _chanop(c
1460: 2c 20 43 48 41 4e 53 4e 44 2c 20 28 76 6f 69 64  , CHANSND, (void
1470: 2a 29 26 76 2c 20 31 29 3b 0a 7d 0a 0a 76 6f 69  *)&v, 1);.}..voi
1480: 64 2a 0a 63 68 61 6e 72 65 63 76 70 28 43 68 61  d*.chanrecvp(Cha
1490: 6e 6e 65 6c 20 2a 63 29 0a 7b 0a 09 76 6f 69 64  nnel *c).{..void
14a0: 20 2a 76 3b 0a 0a 09 5f 63 68 61 6e 6f 70 28 63   *v;..._chanop(c
14b0: 2c 20 43 48 41 4e 52 43 56 2c 20 28 76 6f 69 64  , CHANRCV, (void
14c0: 2a 29 26 76 2c 20 31 29 3b 0a 09 72 65 74 75 72  *)&v, 1);..retur
14d0: 6e 20 76 3b 0a 7d 0a 0a 69 6e 74 0a 63 68 61 6e  n v;.}..int.chan
14e0: 6e 62 73 65 6e 64 70 28 43 68 61 6e 6e 65 6c 20  nbsendp(Channel 
14f0: 2a 63 2c 20 76 6f 69 64 20 2a 76 29 0a 7b 0a 09  *c, void *v).{..
1500: 72 65 74 75 72 6e 20 5f 63 68 61 6e 6f 70 28 63  return _chanop(c
1510: 2c 20 43 48 41 4e 53 4e 44 2c 20 28 76 6f 69 64  , CHANSND, (void
1520: 2a 29 26 76 2c 20 30 29 3b 0a 7d 0a 0a 76 6f 69  *)&v, 0);.}..voi
1530: 64 2a 0a 63 68 61 6e 6e 62 72 65 63 76 70 28 43  d*.channbrecvp(C
1540: 68 61 6e 6e 65 6c 20 2a 63 29 0a 7b 0a 09 76 6f  hannel *c).{..vo
1550: 69 64 20 2a 76 3b 0a 0a 09 5f 63 68 61 6e 6f 70  id *v;..._chanop
1560: 28 63 2c 20 43 48 41 4e 52 43 56 2c 20 28 76 6f  (c, CHANRCV, (vo
1570: 69 64 2a 29 26 76 2c 20 30 29 3b 0a 09 72 65 74  id*)&v, 0);..ret
1580: 75 72 6e 20 76 3b 0a 7d 0a 0a 69 6e 74 0a 63 68  urn v;.}..int.ch
1590: 61 6e 73 65 6e 64 75 6c 28 43 68 61 6e 6e 65 6c  ansendul(Channel
15a0: 20 2a 63 2c 20 75 6c 6f 6e 67 20 76 61 6c 29 0a   *c, ulong val).
15b0: 7b 0a 09 72 65 74 75 72 6e 20 5f 63 68 61 6e 6f  {..return _chano
15c0: 70 28 63 2c 20 43 48 41 4e 53 4e 44 2c 20 26 76  p(c, CHANSND, &v
15d0: 61 6c 2c 20 31 29 3b 0a 7d 0a 0a 75 6c 6f 6e 67  al, 1);.}..ulong
15e0: 0a 63 68 61 6e 72 65 63 76 75 6c 28 43 68 61 6e  .chanrecvul(Chan
15f0: 6e 65 6c 20 2a 63 29 0a 7b 0a 09 75 6c 6f 6e 67  nel *c).{..ulong
1600: 20 76 61 6c 3b 0a 0a 09 5f 63 68 61 6e 6f 70 28   val;..._chanop(
1610: 63 2c 20 43 48 41 4e 52 43 56 2c 20 26 76 61 6c  c, CHANRCV, &val
1620: 2c 20 31 29 3b 0a 09 72 65 74 75 72 6e 20 76 61  , 1);..return va
1630: 6c 3b 0a 7d 0a 0a 69 6e 74 0a 63 68 61 6e 6e 62  l;.}..int.channb
1640: 73 65 6e 64 75 6c 28 43 68 61 6e 6e 65 6c 20 2a  sendul(Channel *
1650: 63 2c 20 75 6c 6f 6e 67 20 76 61 6c 29 0a 7b 0a  c, ulong val).{.
1660: 09 72 65 74 75 72 6e 20 5f 63 68 61 6e 6f 70 28  .return _chanop(
1670: 63 2c 20 43 48 41 4e 53 4e 44 2c 20 26 76 61 6c  c, CHANSND, &val
1680: 2c 20 30 29 3b 0a 7d 0a 0a 75 6c 6f 6e 67 0a 63  , 0);.}..ulong.c
1690: 68 61 6e 6e 62 72 65 63 76 75 6c 28 43 68 61 6e  hannbrecvul(Chan
16a0: 6e 65 6c 20 2a 63 29 0a 7b 0a 09 75 6c 6f 6e 67  nel *c).{..ulong
16b0: 20 76 61 6c 3b 0a 0a 09 5f 63 68 61 6e 6f 70 28   val;..._chanop(
16c0: 63 2c 20 43 48 41 4e 52 43 56 2c 20 26 76 61 6c  c, CHANRCV, &val
16d0: 2c 20 30 29 3b 0a 09 72 65 74 75 72 6e 20 76 61  , 0);..return va
16e0: 6c 3b 0a 7d 0a 0a                                l;.}..