Hex Artifact Content
Not logged in

Artifact fec6cc2884777c832acacfd6bf2f5966f8f138cf:


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 23 69 6e  "taskimpl.h".#in
0050: 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a  clude <fcntl.h>.
0060: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
0070: 54 61 73 6b 6c 69 73 74 20 54 61 73 6b 6c 69 73  Tasklist Tasklis
0080: 74 3b 0a 73 74 72 75 63 74 20 54 61 73 6b 6c 69  t;.struct Taskli
0090: 73 74 0a 7b 0a 09 54 61 73 6b 20 2a 68 65 61 64  st.{..Task *head
00a0: 3b 0a 09 54 61 73 6b 20 2a 74 61 69 6c 3b 0a 7d  ;..Task *tail;.}
00b0: 3b 0a 0a 69 6e 74 09 74 61 73 6b 64 65 62 75 67  ;..int.taskdebug
00c0: 6c 65 76 65 6c 3b 0a 69 6e 74 09 74 61 73 6b 63  level;.int.taskc
00d0: 6f 75 6e 74 3b 0a 69 6e 74 09 74 61 73 6b 6e 73  ount;.int.taskns
00e0: 77 69 74 63 68 3b 0a 69 6e 74 09 74 61 73 6b 65  witch;.int.taske
00f0: 78 69 74 76 61 6c 3b 0a 54 61 73 6b 09 2a 74 61  xitval;.Task.*ta
0100: 73 6b 72 75 6e 6e 69 6e 67 3b 0a 0a 43 6f 6e 74  skrunning;..Cont
0110: 65 78 74 09 74 61 73 6b 73 63 68 65 64 63 6f 6e  ext.taskschedcon
0120: 74 65 78 74 3b 0a 54 61 73 6b 6c 69 73 74 09 74  text;.Tasklist.t
0130: 61 73 6b 72 75 6e 71 75 65 75 65 3b 0a 0a 73 74  askrunqueue;..st
0140: 61 74 69 63 20 63 68 61 72 20 2a 61 72 67 76 30  atic char *argv0
0150: 3b 0a 73 74 61 74 69 63 09 76 6f 69 64 09 09 61  ;.static.void..a
0160: 64 64 74 61 73 6b 28 54 61 73 6b 6c 69 73 74 2a  ddtask(Tasklist*
0170: 2c 20 54 61 73 6b 2a 29 3b 0a 73 74 61 74 69 63  , Task*);.static
0180: 09 76 6f 69 64 09 09 64 65 6c 74 61 73 6b 28 54  .void..deltask(T
0190: 61 73 6b 6c 69 73 74 2a 2c 20 54 61 73 6b 2a 29  asklist*, Task*)
01a0: 3b 0a 73 74 61 74 69 63 09 76 6f 69 64 09 09 63  ;.static.void..c
01b0: 6f 6e 74 65 78 74 73 77 69 74 63 68 28 43 6f 6e  ontextswitch(Con
01c0: 74 65 78 74 20 2a 66 72 6f 6d 2c 20 43 6f 6e 74  text *from, Cont
01d0: 65 78 74 20 2a 74 6f 29 3b 0a 0a 73 74 61 74 69  ext *to);..stati
01e0: 63 20 76 6f 69 64 0a 74 61 73 6b 64 65 62 75 67  c void.taskdebug
01f0: 28 63 68 61 72 20 2a 66 6d 74 2c 20 2e 2e 2e 29  (char *fmt, ...)
0200: 0a 7b 0a 09 76 61 5f 6c 69 73 74 20 61 72 67 3b  .{..va_list arg;
0210: 0a 09 63 68 61 72 20 62 75 66 5b 31 32 38 5d 3b  ..char buf[128];
0220: 0a 09 54 61 73 6b 20 2a 74 3b 0a 09 63 68 61 72  ..Task *t;..char
0230: 20 2a 70 3b 0a 09 73 74 61 74 69 63 20 69 6e 74   *p;..static int
0240: 20 66 64 20 3d 20 2d 31 3b 0a 0a 72 65 74 75 72   fd = -1;..retur
0250: 6e 3b 0a 09 76 61 5f 73 74 61 72 74 28 61 72 67  n;..va_start(arg
0260: 2c 20 66 6d 74 29 3b 0a 09 76 66 70 72 69 6e 74  , fmt);..vfprint
0270: 28 31 2c 20 66 6d 74 2c 20 61 72 67 29 3b 0a 09  (1, fmt, arg);..
0280: 76 61 5f 65 6e 64 28 61 72 67 29 3b 0a 72 65 74  va_end(arg);.ret
0290: 75 72 6e 3b 0a 0a 09 69 66 28 66 64 20 3c 20 30  urn;...if(fd < 0
02a0: 29 7b 0a 09 09 70 20 3d 20 73 74 72 72 63 68 72  ){...p = strrchr
02b0: 28 61 72 67 76 30 2c 20 27 2f 27 29 3b 0a 09 09  (argv0, '/');...
02c0: 69 66 28 70 29 0a 09 09 09 70 2b 2b 3b 0a 09 09  if(p)....p++;...
02d0: 65 6c 73 65 0a 09 09 09 70 20 3d 20 61 72 67 76  else....p = argv
02e0: 30 3b 0a 09 09 73 6e 70 72 69 6e 74 28 62 75 66  0;...snprint(buf
02f0: 2c 20 73 69 7a 65 6f 66 20 62 75 66 2c 20 22 2f  , sizeof buf, "/
0300: 74 6d 70 2f 25 73 2e 74 6c 6f 67 22 2c 20 70 29  tmp/%s.tlog", p)
0310: 3b 0a 09 09 69 66 28 28 66 64 20 3d 20 6f 70 65  ;...if((fd = ope
0320: 6e 28 62 75 66 2c 20 4f 5f 43 52 45 41 54 7c 4f  n(buf, O_CREAT|O
0330: 5f 57 52 4f 4e 4c 59 2c 20 30 36 36 36 29 29 20  _WRONLY, 0666)) 
0340: 3c 20 30 29 0a 09 09 09 66 64 20 3d 20 6f 70 65  < 0)....fd = ope
0350: 6e 28 22 2f 64 65 76 2f 6e 75 6c 6c 22 2c 20 4f  n("/dev/null", O
0360: 5f 57 52 4f 4e 4c 59 29 3b 0a 09 7d 0a 0a 09 76  _WRONLY);..}...v
0370: 61 5f 73 74 61 72 74 28 61 72 67 2c 20 66 6d 74  a_start(arg, fmt
0380: 29 3b 0a 09 76 73 6e 70 72 69 6e 74 28 62 75 66  );..vsnprint(buf
0390: 2c 20 73 69 7a 65 6f 66 20 62 75 66 2c 20 66 6d  , sizeof buf, fm
03a0: 74 2c 20 61 72 67 29 3b 0a 09 76 61 5f 65 6e 64  t, arg);..va_end
03b0: 28 61 72 67 29 3b 0a 09 74 20 3d 20 74 61 73 6b  (arg);..t = task
03c0: 72 75 6e 6e 69 6e 67 3b 0a 09 69 66 28 74 29 0a  running;..if(t).
03d0: 09 09 66 70 72 69 6e 74 28 66 64 2c 20 22 25 64  ..fprint(fd, "%d
03e0: 2e 25 64 3a 20 25 73 5c 6e 22 2c 20 67 65 74 70  .%d: %s\n", getp
03f0: 69 64 28 29 2c 20 74 2d 3e 69 64 2c 20 62 75 66  id(), t->id, buf
0400: 29 3b 0a 09 65 6c 73 65 0a 09 09 66 70 72 69 6e  );..else...fprin
0410: 74 28 66 64 2c 20 22 25 64 2e 5f 3a 20 25 73 5c  t(fd, "%d._: %s\
0420: 6e 22 2c 20 67 65 74 70 69 64 28 29 2c 20 62 75  n", getpid(), bu
0430: 66 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  f);.}..static vo
0440: 69 64 0a 74 61 73 6b 73 74 61 72 74 28 75 69 6e  id.taskstart(uin
0450: 74 20 79 2c 20 75 69 6e 74 20 78 29 0a 7b 0a 09  t y, uint x).{..
0460: 54 61 73 6b 20 2a 74 3b 0a 09 75 6c 6f 6e 67 20  Task *t;..ulong 
0470: 7a 3b 0a 0a 09 7a 20 3d 20 78 3c 3c 31 36 3b 09  z;...z = x<<16;.
0480: 2f 2a 20 68 69 64 65 20 75 6e 64 65 66 69 6e 65  /* hide undefine
0490: 64 20 33 32 2d 62 69 74 20 73 68 69 66 74 20 66  d 32-bit shift f
04a0: 72 6f 6d 20 33 32 2d 62 69 74 20 63 6f 6d 70 69  rom 32-bit compi
04b0: 6c 65 72 73 20 2a 2f 0a 09 7a 20 3c 3c 3d 20 31  lers */..z <<= 1
04c0: 36 3b 0a 09 7a 20 7c 3d 20 79 3b 0a 09 74 20 3d  6;..z |= y;..t =
04d0: 20 28 54 61 73 6b 2a 29 7a 3b 0a 0a 2f 2f 70 72   (Task*)z;..//pr
04e0: 69 6e 74 28 22 74 61 73 6b 73 74 61 72 74 20 25  int("taskstart %
04f0: 70 5c 6e 22 2c 20 76 29 3b 0a 09 74 2d 3e 73 74  p\n", v);..t->st
0500: 61 72 74 66 6e 28 74 2d 3e 73 74 61 72 74 61 72  artfn(t->startar
0510: 67 29 3b 0a 2f 2f 70 72 69 6e 74 28 22 74 61 73  g);.//print("tas
0520: 6b 65 78 69 74 73 20 25 70 5c 6e 22 2c 20 76 29  kexits %p\n", v)
0530: 3b 0a 09 74 61 73 6b 65 78 69 74 28 30 29 3b 0a  ;..taskexit(0);.
0540: 2f 2f 70 72 69 6e 74 28 22 6e 6f 74 20 72 65 61  //print("not rea
0550: 63 65 68 64 5c 6e 22 29 3b 0a 7d 0a 0a 73 74 61  cehd\n");.}..sta
0560: 74 69 63 20 69 6e 74 20 74 61 73 6b 69 64 67 65  tic int taskidge
0570: 6e 3b 0a 0a 73 74 61 74 69 63 20 54 61 73 6b 2a  n;..static Task*
0580: 0a 74 61 73 6b 61 6c 6c 6f 63 28 76 6f 69 64 20  .taskalloc(void 
0590: 28 2a 66 6e 29 28 76 6f 69 64 2a 29 2c 20 76 6f  (*fn)(void*), vo
05a0: 69 64 20 2a 61 72 67 2c 20 75 69 6e 74 20 73 74  id *arg, uint st
05b0: 61 63 6b 29 0a 7b 0a 09 54 61 73 6b 20 2a 74 3b  ack).{..Task *t;
05c0: 0a 09 73 69 67 73 65 74 5f 74 20 7a 65 72 6f 3b  ..sigset_t zero;
05d0: 0a 09 75 69 6e 74 20 78 2c 20 79 3b 0a 09 75 6c  ..uint x, y;..ul
05e0: 6f 6e 67 20 7a 3b 0a 0a 09 2f 2a 20 61 6c 6c 6f  ong z;.../* allo
05f0: 63 61 74 65 20 74 68 65 20 74 61 73 6b 20 61 6e  cate the task an
0600: 64 20 73 74 61 63 6b 20 74 6f 67 65 74 68 65 72  d stack together
0610: 20 2a 2f 0a 09 74 20 3d 20 6d 61 6c 6c 6f 63 28   */..t = malloc(
0620: 73 69 7a 65 6f 66 20 2a 74 2b 73 74 61 63 6b 29  sizeof *t+stack)
0630: 3b 0a 09 69 66 28 74 20 3d 3d 20 6e 69 6c 29 7b  ;..if(t == nil){
0640: 0a 09 09 66 70 72 69 6e 74 28 32 2c 20 22 74 61  ...fprint(2, "ta
0650: 73 6b 61 6c 6c 6f 63 20 6d 61 6c 6c 6f 63 3a 20  skalloc malloc: 
0660: 25 72 5c 6e 22 29 3b 0a 09 09 61 62 6f 72 74 28  %r\n");...abort(
0670: 29 3b 0a 09 7d 0a 09 6d 65 6d 73 65 74 28 74 2c  );..}..memset(t,
0680: 20 30 2c 20 73 69 7a 65 6f 66 20 2a 74 29 3b 0a   0, sizeof *t);.
0690: 09 74 2d 3e 73 74 6b 20 3d 20 28 75 63 68 61 72  .t->stk = (uchar
06a0: 2a 29 28 74 2b 31 29 3b 0a 09 74 2d 3e 73 74 6b  *)(t+1);..t->stk
06b0: 73 69 7a 65 20 3d 20 73 74 61 63 6b 3b 0a 09 74  size = stack;..t
06c0: 2d 3e 69 64 20 3d 20 2b 2b 74 61 73 6b 69 64 67  ->id = ++taskidg
06d0: 65 6e 3b 0a 09 74 2d 3e 73 74 61 72 74 66 6e 20  en;..t->startfn 
06e0: 3d 20 66 6e 3b 0a 09 74 2d 3e 73 74 61 72 74 61  = fn;..t->starta
06f0: 72 67 20 3d 20 61 72 67 3b 0a 0a 09 2f 2a 20 64  rg = arg;.../* d
0700: 6f 20 61 20 72 65 61 73 6f 6e 61 62 6c 65 20 69  o a reasonable i
0710: 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 2a 2f  nitialization */
0720: 0a 09 6d 65 6d 73 65 74 28 26 74 2d 3e 63 6f 6e  ..memset(&t->con
0730: 74 65 78 74 2e 75 63 2c 20 30 2c 20 73 69 7a 65  text.uc, 0, size
0740: 6f 66 20 74 2d 3e 63 6f 6e 74 65 78 74 2e 75 63  of t->context.uc
0750: 29 3b 0a 09 73 69 67 65 6d 70 74 79 73 65 74 28  );..sigemptyset(
0760: 26 7a 65 72 6f 29 3b 0a 09 73 69 67 70 72 6f 63  &zero);..sigproc
0770: 6d 61 73 6b 28 53 49 47 5f 42 4c 4f 43 4b 2c 20  mask(SIG_BLOCK, 
0780: 26 7a 65 72 6f 2c 20 26 74 2d 3e 63 6f 6e 74 65  &zero, &t->conte
0790: 78 74 2e 75 63 2e 75 63 5f 73 69 67 6d 61 73 6b  xt.uc.uc_sigmask
07a0: 29 3b 0a 0a 09 2f 2a 20 6d 75 73 74 20 69 6e 69  );.../* must ini
07b0: 74 69 61 6c 69 7a 65 20 77 69 74 68 20 63 75 72  tialize with cur
07c0: 72 65 6e 74 20 63 6f 6e 74 65 78 74 20 2a 2f 0a  rent context */.
07d0: 09 69 66 28 67 65 74 63 6f 6e 74 65 78 74 28 26  .if(getcontext(&
07e0: 74 2d 3e 63 6f 6e 74 65 78 74 2e 75 63 29 20 3c  t->context.uc) <
07f0: 20 30 29 7b 0a 09 09 66 70 72 69 6e 74 28 32 2c   0){...fprint(2,
0800: 20 22 67 65 74 63 6f 6e 74 65 78 74 3a 20 25 72   "getcontext: %r
0810: 5c 6e 22 29 3b 0a 09 09 61 62 6f 72 74 28 29 3b  \n");...abort();
0820: 0a 09 7d 0a 0a 09 2f 2a 20 63 61 6c 6c 20 6d 61  ..}.../* call ma
0830: 6b 65 63 6f 6e 74 65 78 74 20 74 6f 20 64 6f 20  kecontext to do 
0840: 74 68 65 20 72 65 61 6c 20 77 6f 72 6b 2e 20 2a  the real work. *
0850: 2f 0a 09 2f 2a 20 6c 65 61 76 65 20 61 20 66 65  /../* leave a fe
0860: 77 20 77 6f 72 64 73 20 6f 70 65 6e 20 6f 6e 20  w words open on 
0870: 62 6f 74 68 20 65 6e 64 73 20 2a 2f 0a 09 74 2d  both ends */..t-
0880: 3e 63 6f 6e 74 65 78 74 2e 75 63 2e 75 63 5f 73  >context.uc.uc_s
0890: 74 61 63 6b 2e 73 73 5f 73 70 20 3d 20 74 2d 3e  tack.ss_sp = t->
08a0: 73 74 6b 2b 38 3b 0a 09 74 2d 3e 63 6f 6e 74 65  stk+8;..t->conte
08b0: 78 74 2e 75 63 2e 75 63 5f 73 74 61 63 6b 2e 73  xt.uc.uc_stack.s
08c0: 73 5f 73 69 7a 65 20 3d 20 74 2d 3e 73 74 6b 73  s_size = t->stks
08d0: 69 7a 65 2d 36 34 3b 0a 23 69 66 64 65 66 20 5f  ize-64;.#ifdef _
08e0: 5f 73 75 6e 5f 5f 09 09 2f 2a 20 73 69 67 68 20  _sun__../* sigh 
08f0: 2a 2f 0a 09 2f 2a 20 63 61 6e 20 61 76 6f 69 64  */../* can avoid
0900: 20 74 68 69 73 20 77 69 74 68 20 5f 5f 4d 41 4b   this with __MAK
0910: 45 43 4f 4e 54 45 58 54 5f 56 32 5f 53 4f 55 52  ECONTEXT_V2_SOUR
0920: 43 45 20 62 75 74 20 6f 6e 6c 79 20 6f 6e 20 53  CE but only on S
0930: 75 6e 4f 53 20 35 2e 39 20 2a 2f 0a 09 74 2d 3e  unOS 5.9 */..t->
0940: 63 6f 6e 74 65 78 74 2e 75 63 2e 75 63 5f 73 74  context.uc.uc_st
0950: 61 63 6b 2e 73 73 5f 73 70 20 3d 20 0a 09 09 28  ack.ss_sp = ...(
0960: 63 68 61 72 2a 29 74 2d 3e 63 6f 6e 74 65 78 74  char*)t->context
0970: 2e 75 63 2e 75 63 5f 73 74 61 63 6b 2e 73 73 5f  .uc.uc_stack.ss_
0980: 73 70 0a 09 09 2b 74 2d 3e 63 6f 6e 74 65 78 74  sp...+t->context
0990: 2e 75 63 2e 75 63 5f 73 74 61 63 6b 2e 73 73 5f  .uc.uc_stack.ss_
09a0: 73 69 7a 65 3b 0a 23 65 6e 64 69 66 0a 09 2f 2a  size;.#endif../*
09b0: 0a 09 20 2a 20 41 6c 6c 20 74 68 69 73 20 6d 61  .. * All this ma
09c0: 67 69 63 20 69 73 20 62 65 63 61 75 73 65 20 79  gic is because y
09d0: 6f 75 20 68 61 76 65 20 74 6f 20 70 61 73 73 20  ou have to pass 
09e0: 6d 61 6b 65 63 6f 6e 74 65 78 74 20 61 0a 09 20  makecontext a.. 
09f0: 2a 20 66 75 6e 63 74 69 6f 6e 20 74 68 61 74 20  * function that 
0a00: 74 61 6b 65 73 20 73 6f 6d 65 20 6e 75 6d 62 65  takes some numbe
0a10: 72 20 6f 66 20 77 6f 72 64 2d 73 69 7a 65 64 20  r of word-sized 
0a20: 76 61 72 69 61 62 6c 65 73 2c 0a 09 20 2a 20 61  variables,.. * a
0a30: 6e 64 20 6f 6e 20 36 34 2d 62 69 74 20 6d 61 63  nd on 64-bit mac
0a40: 68 69 6e 65 73 20 70 6f 69 6e 74 65 72 73 20 61  hines pointers a
0a50: 72 65 20 62 69 67 67 65 72 20 74 68 61 6e 20 77  re bigger than w
0a60: 6f 72 64 73 2e 0a 09 20 2a 2f 0a 09 7a 20 3d 20  ords... */..z = 
0a70: 28 75 6c 6f 6e 67 29 74 3b 0a 09 79 20 3d 20 7a  (ulong)t;..y = z
0a80: 3b 0a 09 7a 20 3e 3e 3d 20 31 36 3b 09 2f 2a 20  ;..z >>= 16;./* 
0a90: 68 69 64 65 20 75 6e 64 65 66 69 6e 65 64 20 33  hide undefined 3
0aa0: 32 2d 62 69 74 20 73 68 69 66 74 20 66 72 6f 6d  2-bit shift from
0ab0: 20 33 32 2d 62 69 74 20 63 6f 6d 70 69 6c 65 72   32-bit compiler
0ac0: 73 20 2a 2f 0a 09 78 20 3d 20 7a 3e 3e 31 36 3b  s */..x = z>>16;
0ad0: 0a 09 6d 61 6b 65 63 6f 6e 74 65 78 74 28 26 74  ..makecontext(&t
0ae0: 2d 3e 63 6f 6e 74 65 78 74 2e 75 63 2c 20 28 76  ->context.uc, (v
0af0: 6f 69 64 28 2a 29 28 29 29 74 61 73 6b 73 74 61  oid(*)())tasksta
0b00: 72 74 2c 20 32 2c 20 79 2c 20 78 29 3b 0a 0a 09  rt, 2, y, x);...
0b10: 72 65 74 75 72 6e 20 74 3b 0a 7d 0a 0a 69 6e 74  return t;.}..int
0b20: 0a 74 61 73 6b 63 72 65 61 74 65 28 76 6f 69 64  .taskcreate(void
0b30: 20 28 2a 66 6e 29 28 76 6f 69 64 2a 29 2c 20 76   (*fn)(void*), v
0b40: 6f 69 64 20 2a 61 72 67 2c 20 75 69 6e 74 20 73  oid *arg, uint s
0b50: 74 61 63 6b 29 0a 7b 0a 09 69 6e 74 20 69 64 3b  tack).{..int id;
0b60: 0a 09 54 61 73 6b 20 2a 74 3b 0a 0a 09 74 20 3d  ..Task *t;...t =
0b70: 20 74 61 73 6b 61 6c 6c 6f 63 28 66 6e 2c 20 61   taskalloc(fn, a
0b80: 72 67 2c 20 73 74 61 63 6b 29 3b 0a 09 74 61 73  rg, stack);..tas
0b90: 6b 63 6f 75 6e 74 2b 2b 3b 0a 09 69 64 20 3d 20  kcount++;..id = 
0ba0: 74 2d 3e 69 64 3b 0a 09 74 61 73 6b 72 65 61 64  t->id;..taskread
0bb0: 79 28 74 29 3b 0a 09 72 65 74 75 72 6e 20 69 64  y(t);..return id
0bc0: 3b 0a 7d 0a 0a 76 6f 69 64 0a 74 61 73 6b 73 77  ;.}..void.tasksw
0bd0: 69 74 63 68 28 76 6f 69 64 29 0a 7b 0a 09 6e 65  itch(void).{..ne
0be0: 65 64 73 74 61 63 6b 28 30 29 3b 0a 09 63 6f 6e  edstack(0);..con
0bf0: 74 65 78 74 73 77 69 74 63 68 28 26 74 61 73 6b  textswitch(&task
0c00: 72 75 6e 6e 69 6e 67 2d 3e 63 6f 6e 74 65 78 74  running->context
0c10: 2c 20 26 74 61 73 6b 73 63 68 65 64 63 6f 6e 74  , &taskschedcont
0c20: 65 78 74 29 3b 0a 7d 0a 0a 76 6f 69 64 0a 74 61  ext);.}..void.ta
0c30: 73 6b 72 65 61 64 79 28 54 61 73 6b 20 2a 74 29  skready(Task *t)
0c40: 0a 7b 0a 09 61 64 64 74 61 73 6b 28 26 74 61 73  .{..addtask(&tas
0c50: 6b 72 75 6e 71 75 65 75 65 2c 20 74 29 3b 0a 7d  krunqueue, t);.}
0c60: 0a 0a 69 6e 74 0a 74 61 73 6b 79 69 65 6c 64 28  ..int.taskyield(
0c70: 76 6f 69 64 29 0a 7b 0a 09 69 6e 74 20 6e 3b 0a  void).{..int n;.
0c80: 09 0a 09 6e 20 3d 20 74 61 73 6b 6e 73 77 69 74  ...n = tasknswit
0c90: 63 68 3b 0a 09 74 61 73 6b 72 65 61 64 79 28 74  ch;..taskready(t
0ca0: 61 73 6b 72 75 6e 6e 69 6e 67 29 3b 0a 09 74 61  askrunning);..ta
0cb0: 73 6b 73 77 69 74 63 68 28 29 3b 0a 09 72 65 74  skswitch();..ret
0cc0: 75 72 6e 20 74 61 73 6b 6e 73 77 69 74 63 68 20  urn tasknswitch 
0cd0: 2d 20 6e 3b 0a 7d 0a 0a 69 6e 74 0a 61 6e 79 72  - n;.}..int.anyr
0ce0: 65 61 64 79 28 76 6f 69 64 29 0a 7b 0a 09 72 65  eady(void).{..re
0cf0: 74 75 72 6e 20 74 61 73 6b 72 75 6e 71 75 65 75  turn taskrunqueu
0d00: 65 2e 68 65 61 64 20 21 3d 20 6e 69 6c 3b 0a 7d  e.head != nil;.}
0d10: 0a 0a 76 6f 69 64 0a 74 61 73 6b 65 78 69 74 61  ..void.taskexita
0d20: 6c 6c 28 69 6e 74 20 76 61 6c 29 0a 7b 0a 09 65  ll(int val).{..e
0d30: 78 69 74 28 76 61 6c 29 3b 0a 7d 0a 0a 76 6f 69  xit(val);.}..voi
0d40: 64 0a 74 61 73 6b 65 78 69 74 28 69 6e 74 20 76  d.taskexit(int v
0d50: 61 6c 29 0a 7b 0a 09 74 61 73 6b 65 78 69 74 76  al).{..taskexitv
0d60: 61 6c 20 3d 20 76 61 6c 3b 0a 09 74 61 73 6b 72  al = val;..taskr
0d70: 75 6e 6e 69 6e 67 2d 3e 65 78 69 74 69 6e 67 20  unning->exiting 
0d80: 3d 20 31 3b 0a 09 74 61 73 6b 73 77 69 74 63 68  = 1;..taskswitch
0d90: 28 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  ();.}..static vo
0da0: 69 64 0a 63 6f 6e 74 65 78 74 73 77 69 74 63 68  id.contextswitch
0db0: 28 43 6f 6e 74 65 78 74 20 2a 66 72 6f 6d 2c 20  (Context *from, 
0dc0: 43 6f 6e 74 65 78 74 20 2a 74 6f 29 0a 7b 0a 09  Context *to).{..
0dd0: 69 66 28 73 77 61 70 63 6f 6e 74 65 78 74 28 26  if(swapcontext(&
0de0: 66 72 6f 6d 2d 3e 75 63 2c 20 26 74 6f 2d 3e 75  from->uc, &to->u
0df0: 63 29 20 3c 20 30 29 7b 0a 09 09 66 70 72 69 6e  c) < 0){...fprin
0e00: 74 28 32 2c 20 22 73 77 61 70 63 6f 6e 74 65 78  t(2, "swapcontex
0e10: 74 20 66 61 69 6c 65 64 3a 20 25 72 5c 6e 22 29  t failed: %r\n")
0e20: 3b 0a 09 09 61 73 73 65 72 74 28 30 29 3b 0a 09  ;...assert(0);..
0e30: 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  }.}..static void
0e40: 0a 74 61 73 6b 73 63 68 65 64 75 6c 65 72 28 76  .taskscheduler(v
0e50: 6f 69 64 29 0a 7b 0a 09 54 61 73 6b 20 2a 74 3b  oid).{..Task *t;
0e60: 0a 0a 09 74 61 73 6b 64 65 62 75 67 28 22 73 63  ...taskdebug("sc
0e70: 68 65 64 75 6c 65 72 20 65 6e 74 65 72 22 29 3b  heduler enter");
0e80: 0a 09 66 6f 72 28 3b 3b 29 7b 0a 09 09 74 20 3d  ..for(;;){...t =
0e90: 20 74 61 73 6b 72 75 6e 71 75 65 75 65 2e 68 65   taskrunqueue.he
0ea0: 61 64 3b 0a 09 09 69 66 28 74 20 3d 3d 20 6e 69  ad;...if(t == ni
0eb0: 6c 29 7b 0a 09 09 09 69 66 28 74 61 73 6b 63 6f  l){....if(taskco
0ec0: 75 6e 74 20 3d 3d 20 30 29 0a 09 09 09 09 65 78  unt == 0).....ex
0ed0: 69 74 28 74 61 73 6b 65 78 69 74 76 61 6c 29 3b  it(taskexitval);
0ee0: 0a 09 09 09 66 70 72 69 6e 74 28 32 2c 20 22 6e  ....fprint(2, "n
0ef0: 6f 20 72 75 6e 6e 61 62 6c 65 20 74 61 73 6b 73  o runnable tasks
0f00: 21 20 25 64 20 74 61 73 6b 73 20 73 74 61 6c 6c  ! %d tasks stall
0f10: 65 64 5c 6e 22 2c 20 74 61 73 6b 63 6f 75 6e 74  ed\n", taskcount
0f20: 29 3b 0a 09 09 09 65 78 69 74 28 31 29 3b 0a 09  );....exit(1);..
0f30: 09 7d 0a 09 09 64 65 6c 74 61 73 6b 28 26 74 61  .}...deltask(&ta
0f40: 73 6b 72 75 6e 71 75 65 75 65 2c 20 74 29 3b 0a  skrunqueue, t);.
0f50: 09 09 74 61 73 6b 72 75 6e 6e 69 6e 67 20 3d 20  ..taskrunning = 
0f60: 74 3b 0a 09 09 74 61 73 6b 6e 73 77 69 74 63 68  t;...tasknswitch
0f70: 2b 2b 3b 0a 09 09 74 61 73 6b 64 65 62 75 67 28  ++;...taskdebug(
0f80: 22 72 75 6e 20 25 64 20 28 25 73 29 22 2c 20 74  "run %d (%s)", t
0f90: 2d 3e 69 64 2c 20 74 2d 3e 6e 61 6d 65 29 3b 0a  ->id, t->name);.
0fa0: 09 09 63 6f 6e 74 65 78 74 73 77 69 74 63 68 28  ..contextswitch(
0fb0: 26 74 61 73 6b 73 63 68 65 64 63 6f 6e 74 65 78  &taskschedcontex
0fc0: 74 2c 20 26 74 2d 3e 63 6f 6e 74 65 78 74 29 3b  t, &t->context);
0fd0: 0a 2f 2f 70 72 69 6e 74 28 22 62 61 63 6b 20 69  .//print("back i
0fe0: 6e 20 73 63 68 65 64 75 6c 65 72 5c 6e 22 29 3b  n scheduler\n");
0ff0: 0a 09 09 74 61 73 6b 72 75 6e 6e 69 6e 67 20 3d  ...taskrunning =
1000: 20 6e 69 6c 3b 0a 09 09 69 66 28 74 2d 3e 65 78   nil;...if(t->ex
1010: 69 74 69 6e 67 29 7b 0a 09 09 09 74 61 73 6b 63  iting){....taskc
1020: 6f 75 6e 74 2d 2d 3b 0a 09 09 09 66 72 65 65 28  ount--;....free(
1030: 74 29 3b 0a 09 09 7d 0a 09 7d 0a 7d 0a 0a 76 6f  t);...}..}.}..vo
1040: 69 64 2a 2a 0a 74 61 73 6b 64 61 74 61 28 76 6f  id**.taskdata(vo
1050: 69 64 29 0a 7b 0a 09 72 65 74 75 72 6e 20 26 74  id).{..return &t
1060: 61 73 6b 72 75 6e 6e 69 6e 67 2d 3e 75 64 61 74  askrunning->udat
1070: 61 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 64 65 62 75  a;.}../*. * debu
1080: 67 67 69 6e 67 0a 20 2a 2f 0a 76 6f 69 64 0a 74  gging. */.void.t
1090: 61 73 6b 73 65 74 6e 61 6d 65 28 63 68 61 72 20  asksetname(char 
10a0: 2a 66 6d 74 2c 20 2e 2e 2e 29 0a 7b 0a 09 76 61  *fmt, ...).{..va
10b0: 5f 6c 69 73 74 20 61 72 67 3b 0a 09 54 61 73 6b  _list arg;..Task
10c0: 20 2a 74 3b 0a 0a 09 74 20 3d 20 74 61 73 6b 72   *t;...t = taskr
10d0: 75 6e 6e 69 6e 67 3b 0a 09 76 61 5f 73 74 61 72  unning;..va_star
10e0: 74 28 61 72 67 2c 20 66 6d 74 29 3b 0a 09 76 73  t(arg, fmt);..vs
10f0: 6e 70 72 69 6e 74 28 74 2d 3e 6e 61 6d 65 2c 20  nprint(t->name, 
1100: 73 69 7a 65 6f 66 20 74 2d 3e 6e 61 6d 65 2c 20  sizeof t->name, 
1110: 66 6d 74 2c 20 61 72 67 29 3b 0a 09 76 61 5f 65  fmt, arg);..va_e
1120: 6e 64 28 61 72 67 29 3b 0a 7d 0a 0a 63 68 61 72  nd(arg);.}..char
1130: 2a 0a 74 61 73 6b 67 65 74 6e 61 6d 65 28 76 6f  *.taskgetname(vo
1140: 69 64 29 0a 7b 0a 09 72 65 74 75 72 6e 20 74 61  id).{..return ta
1150: 73 6b 72 75 6e 6e 69 6e 67 2d 3e 6e 61 6d 65 3b  skrunning->name;
1160: 0a 7d 0a 0a 76 6f 69 64 0a 74 61 73 6b 73 65 74  .}..void.taskset
1170: 73 74 61 74 65 28 63 68 61 72 20 2a 66 6d 74 2c  state(char *fmt,
1180: 20 2e 2e 2e 29 0a 7b 0a 09 76 61 5f 6c 69 73 74   ...).{..va_list
1190: 20 61 72 67 3b 0a 09 54 61 73 6b 20 2a 74 3b 0a   arg;..Task *t;.
11a0: 0a 09 74 20 3d 20 74 61 73 6b 72 75 6e 6e 69 6e  ..t = taskrunnin
11b0: 67 3b 0a 09 76 61 5f 73 74 61 72 74 28 61 72 67  g;..va_start(arg
11c0: 2c 20 66 6d 74 29 3b 0a 09 76 73 6e 70 72 69 6e  , fmt);..vsnprin
11d0: 74 28 74 2d 3e 73 74 61 74 65 2c 20 73 69 7a 65  t(t->state, size
11e0: 6f 66 20 74 2d 3e 6e 61 6d 65 2c 20 66 6d 74 2c  of t->name, fmt,
11f0: 20 61 72 67 29 3b 0a 09 76 61 5f 65 6e 64 28 61   arg);..va_end(a
1200: 72 67 29 3b 0a 7d 0a 0a 76 6f 69 64 0a 6e 65 65  rg);.}..void.nee
1210: 64 73 74 61 63 6b 28 69 6e 74 20 6e 29 0a 7b 0a  dstack(int n).{.
1220: 09 54 61 73 6b 20 2a 74 3b 0a 0a 09 74 20 3d 20  .Task *t;...t = 
1230: 74 61 73 6b 72 75 6e 6e 69 6e 67 3b 0a 0a 09 69  taskrunning;...i
1240: 66 28 28 63 68 61 72 2a 29 26 74 20 3c 3d 20 28  f((char*)&t <= (
1250: 63 68 61 72 2a 29 74 2d 3e 73 74 6b 0a 09 7c 7c  char*)t->stk..||
1260: 20 28 63 68 61 72 2a 29 26 74 20 2d 20 28 63 68   (char*)&t - (ch
1270: 61 72 2a 29 74 2d 3e 73 74 6b 20 3c 20 32 35 36  ar*)t->stk < 256
1280: 2b 6e 29 7b 0a 09 09 66 70 72 69 6e 74 28 32 2c  +n){...fprint(2,
1290: 20 22 74 61 73 6b 20 73 74 61 63 6b 20 6f 76 65   "task stack ove
12a0: 72 66 6c 6f 77 3a 20 26 74 3d 25 70 20 74 73 74  rflow: &t=%p tst
12b0: 6b 3d 25 70 20 6e 3d 25 64 5c 6e 22 2c 20 26 74  k=%p n=%d\n", &t
12c0: 2c 20 74 2d 3e 73 74 6b 2c 20 32 35 36 2b 6e 29  , t->stk, 256+n)
12d0: 3b 0a 09 09 61 62 6f 72 74 28 29 3b 0a 09 7d 0a  ;...abort();..}.
12e0: 7d 0a 0a 2f 2a 0a 20 2a 20 73 74 61 72 74 75 70  }../*. * startup
12f0: 0a 20 2a 2f 0a 0a 73 74 61 74 69 63 20 69 6e 74  . */..static int
1300: 20 74 61 73 6b 61 72 67 63 3b 0a 73 74 61 74 69   taskargc;.stati
1310: 63 20 63 68 61 72 20 2a 2a 74 61 73 6b 61 72 67  c char **taskarg
1320: 76 3b 0a 69 6e 74 20 6d 61 69 6e 73 74 61 63 6b  v;.int mainstack
1330: 73 69 7a 65 3b 0a 0a 73 74 61 74 69 63 20 76 6f  size;..static vo
1340: 69 64 0a 74 61 73 6b 6d 61 69 6e 73 74 61 72 74  id.taskmainstart
1350: 28 76 6f 69 64 20 2a 76 29 0a 7b 0a 09 74 61 73  (void *v).{..tas
1360: 6b 6d 61 69 6e 28 74 61 73 6b 61 72 67 63 2c 20  kmain(taskargc, 
1370: 74 61 73 6b 61 72 67 76 29 3b 0a 7d 0a 0a 69 6e  taskargv);.}..in
1380: 74 0a 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c  t.main(int argc,
1390: 20 63 68 61 72 20 2a 2a 61 72 67 76 29 0a 7b 0a   char **argv).{.
13a0: 09 61 72 67 76 30 20 3d 20 61 72 67 76 5b 30 5d  .argv0 = argv[0]
13b0: 3b 0a 09 74 61 73 6b 61 72 67 63 20 3d 20 61 72  ;..taskargc = ar
13c0: 67 63 3b 0a 09 74 61 73 6b 61 72 67 76 20 3d 20  gc;..taskargv = 
13d0: 61 72 67 76 3b 0a 0a 09 69 66 28 6d 61 69 6e 73  argv;...if(mains
13e0: 74 61 63 6b 73 69 7a 65 20 3d 3d 20 30 29 0a 09  tacksize == 0)..
13f0: 09 6d 61 69 6e 73 74 61 63 6b 73 69 7a 65 20 3d  .mainstacksize =
1400: 20 32 35 36 2a 31 30 32 34 3b 0a 09 74 61 73 6b   256*1024;..task
1410: 63 72 65 61 74 65 28 74 61 73 6b 6d 61 69 6e 73  create(taskmains
1420: 74 61 72 74 2c 20 6e 69 6c 2c 20 6d 61 69 6e 73  tart, nil, mains
1430: 74 61 63 6b 73 69 7a 65 29 3b 0a 09 74 61 73 6b  tacksize);..task
1440: 73 63 68 65 64 75 6c 65 72 28 29 3b 0a 09 66 70  scheduler();..fp
1450: 72 69 6e 74 28 32 2c 20 22 74 61 73 6b 73 63 68  rint(2, "tasksch
1460: 65 64 75 6c 65 72 20 72 65 74 75 72 6e 65 64 20  eduler returned 
1470: 69 6e 20 6d 61 69 6e 21 5c 6e 22 29 3b 0a 09 61  in main!\n");..a
1480: 62 6f 72 74 28 29 3b 0a 09 72 65 74 75 72 6e 20  bort();..return 
1490: 30 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 68 6f 6f 72  0;.}../*. * hoor
14a0: 61 79 20 66 6f 72 20 6c 69 6e 6b 65 64 20 6c 69  ay for linked li
14b0: 73 74 73 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76  sts. */.static v
14c0: 6f 69 64 0a 61 64 64 74 61 73 6b 28 54 61 73 6b  oid.addtask(Task
14d0: 6c 69 73 74 20 2a 6c 2c 20 54 61 73 6b 20 2a 74  list *l, Task *t
14e0: 29 0a 7b 0a 09 69 66 28 6c 2d 3e 74 61 69 6c 29  ).{..if(l->tail)
14f0: 7b 0a 09 09 6c 2d 3e 74 61 69 6c 2d 3e 6e 65 78  {...l->tail->nex
1500: 74 20 3d 20 74 3b 0a 09 09 74 2d 3e 70 72 65 76  t = t;...t->prev
1510: 20 3d 20 6c 2d 3e 74 61 69 6c 3b 0a 09 7d 65 6c   = l->tail;..}el
1520: 73 65 7b 0a 09 09 6c 2d 3e 68 65 61 64 20 3d 20  se{...l->head = 
1530: 74 3b 0a 09 09 74 2d 3e 70 72 65 76 20 3d 20 6e  t;...t->prev = n
1540: 69 6c 3b 0a 09 7d 0a 09 6c 2d 3e 74 61 69 6c 20  il;..}..l->tail 
1550: 3d 20 74 3b 0a 09 74 2d 3e 6e 65 78 74 20 3d 20  = t;..t->next = 
1560: 6e 69 6c 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  nil;.}..static v
1570: 6f 69 64 0a 64 65 6c 74 61 73 6b 28 54 61 73 6b  oid.deltask(Task
1580: 6c 69 73 74 20 2a 6c 2c 20 54 61 73 6b 20 2a 74  list *l, Task *t
1590: 29 0a 7b 0a 09 69 66 28 74 2d 3e 70 72 65 76 29  ).{..if(t->prev)
15a0: 0a 09 09 74 2d 3e 70 72 65 76 2d 3e 6e 65 78 74  ...t->prev->next
15b0: 20 3d 20 74 2d 3e 6e 65 78 74 3b 0a 09 65 6c 73   = t->next;..els
15c0: 65 0a 09 09 6c 2d 3e 68 65 61 64 20 3d 20 74 2d  e...l->head = t-
15d0: 3e 6e 65 78 74 3b 0a 09 69 66 28 74 2d 3e 6e 65  >next;..if(t->ne
15e0: 78 74 29 0a 09 09 74 2d 3e 6e 65 78 74 2d 3e 70  xt)...t->next->p
15f0: 72 65 76 20 3d 20 74 2d 3e 70 72 65 76 3b 0a 09  rev = t->prev;..
1600: 65 6c 73 65 0a 09 09 6c 2d 3e 74 61 69 6c 20 3d  else...l->tail =
1610: 20 74 2d 3e 70 72 65 76 3b 0a 7d 0a 0a 75 6e 73   t->prev;.}..uns
1620: 69 67 6e 65 64 20 69 6e 74 0a 74 61 73 6b 69 64  igned int.taskid
1630: 28 76 6f 69 64 29 0a 7b 0a 09 72 65 74 75 72 6e  (void).{..return
1640: 20 74 61 73 6b 72 75 6e 6e 69 6e 67 2d 3e 69 64   taskrunning->id
1650: 3b 0a 7d 0a 0a                                   ;.}..