17dd7cddfSDavid du Colombier #include "thread.h" 27dd7cddfSDavid du Colombier 37dd7cddfSDavid du Colombier typedef enum { 47dd7cddfSDavid du Colombier Running, 57dd7cddfSDavid du Colombier Runnable, 67dd7cddfSDavid du Colombier Rendezvous, 77dd7cddfSDavid du Colombier } State; 87dd7cddfSDavid du Colombier 97dd7cddfSDavid du Colombier typedef enum { 107dd7cddfSDavid du Colombier Callnil, 117dd7cddfSDavid du Colombier Callalt, 127dd7cddfSDavid du Colombier Callsnd, 137dd7cddfSDavid du Colombier Callrcv, 147dd7cddfSDavid du Colombier } Callstate; 157dd7cddfSDavid du Colombier 167dd7cddfSDavid du Colombier enum { 177dd7cddfSDavid du Colombier DOEXEC = 1, 187dd7cddfSDavid du Colombier DOEXIT = 2, 197dd7cddfSDavid du Colombier DOPROC = 3, 207dd7cddfSDavid du Colombier }; 217dd7cddfSDavid du Colombier 227dd7cddfSDavid du Colombier struct Tqueue { // Thread queue 237dd7cddfSDavid du Colombier Lock lock; 247dd7cddfSDavid du Colombier Thread *head; 257dd7cddfSDavid du Colombier Thread *tail; 267dd7cddfSDavid du Colombier }; 277dd7cddfSDavid du Colombier 287dd7cddfSDavid du Colombier struct Thread { 297dd7cddfSDavid du Colombier Lock lock; // protects thread data structure 307dd7cddfSDavid du Colombier int id; // thread id 317dd7cddfSDavid du Colombier int grp; // thread group 327dd7cddfSDavid du Colombier State state; // state of thread 3359cc4ca5SDavid du Colombier int exiting; // should it die? 347dd7cddfSDavid du Colombier Callstate call; // which `system call' is current 357dd7cddfSDavid du Colombier char *cmdname; // ptr to name of thread 367dd7cddfSDavid du Colombier Thread *next; // next on queue (run, rendezvous) 377dd7cddfSDavid du Colombier Thread *nextt; // next on list of all theads 387dd7cddfSDavid du Colombier Proc *proc; // proc of this thread 397dd7cddfSDavid du Colombier ulong tag; // rendez-vous tag 407dd7cddfSDavid du Colombier Alt *alt; // pointer to alt structure 417dd7cddfSDavid du Colombier ulong value; // rendez-vous value 4259cc4ca5SDavid du Colombier Thread *garbage; // ptr to thread to clean up 437dd7cddfSDavid du Colombier jmp_buf env; // jump buf for launching or switching threads 447dd7cddfSDavid du Colombier uchar *stk; // top of stack (lowest address of stack) 457dd7cddfSDavid du Colombier uint stksize; // stack size 46*80ee5cbfSDavid du Colombier 47*80ee5cbfSDavid du Colombier ulong udata; // User per-thread data pointer 487dd7cddfSDavid du Colombier }; 497dd7cddfSDavid du Colombier 507dd7cddfSDavid du Colombier struct Proc { 517dd7cddfSDavid du Colombier Lock lock; 527dd7cddfSDavid du Colombier int pid; 537dd7cddfSDavid du Colombier 547dd7cddfSDavid du Colombier jmp_buf oldenv; // jump buf for returning to original stack 557dd7cddfSDavid du Colombier 567dd7cddfSDavid du Colombier int nthreads; 577dd7cddfSDavid du Colombier Tqueue threads; // All threads of this proc 587dd7cddfSDavid du Colombier Tqueue runnable; // Runnable threads 597dd7cddfSDavid du Colombier Thread *curthread; // Running thread 607dd7cddfSDavid du Colombier 617dd7cddfSDavid du Colombier int blocked; // In a rendezvous 627dd7cddfSDavid du Colombier uint nextID; // ID of most recently created thread 637dd7cddfSDavid du Colombier Proc *next; // linked list of Procs 647dd7cddfSDavid du Colombier 657dd7cddfSDavid du Colombier void *arg; // passed between shared and unshared stk 6659cc4ca5SDavid du Colombier char str[ERRLEN]; // used by threadexits to avoid malloc 677dd7cddfSDavid du Colombier 687dd7cddfSDavid du Colombier ulong udata; // User per-proc data pointer 697dd7cddfSDavid du Colombier }; 707dd7cddfSDavid du Colombier 717dd7cddfSDavid du Colombier typedef struct Newproc { 727dd7cddfSDavid du Colombier uchar *stack; 737dd7cddfSDavid du Colombier uint stacksize; 747dd7cddfSDavid du Colombier ulong *stackptr; 757dd7cddfSDavid du Colombier ulong launcher; 767dd7cddfSDavid du Colombier int grp; 77*80ee5cbfSDavid du Colombier int rforkflag; 787dd7cddfSDavid du Colombier } Newproc; 797dd7cddfSDavid du Colombier 807dd7cddfSDavid du Colombier typedef struct Execproc { 8159cc4ca5SDavid du Colombier Proc *procp; 827dd7cddfSDavid du Colombier char *file; 8359cc4ca5SDavid du Colombier char **arg; 8459cc4ca5SDavid du Colombier char data[4096]; 857dd7cddfSDavid du Colombier } Execproc; 867dd7cddfSDavid du Colombier 877dd7cddfSDavid du Colombier struct Pqueue { // Proc queue 887dd7cddfSDavid du Colombier Lock lock; 897dd7cddfSDavid du Colombier Proc *head; 907dd7cddfSDavid du Colombier Proc *tail; 917dd7cddfSDavid du Colombier }; 927dd7cddfSDavid du Colombier 937dd7cddfSDavid du Colombier extern struct Pqueue pq; // Linked list of procs 947dd7cddfSDavid du Colombier extern Proc **procp; // Pointer to pointer to proc's Proc structure 957dd7cddfSDavid du Colombier 967dd7cddfSDavid du Colombier int tas(int*); 977dd7cddfSDavid du Colombier int inc(int*, int); 987dd7cddfSDavid du Colombier int cas(Lock *lock, Lock old, Lock new); 9959cc4ca5SDavid du Colombier ulong _threadrendezvous(ulong, ulong); 1007dd7cddfSDavid du Colombier void *_threadmalloc(long size); 1017dd7cddfSDavid du Colombier void _xinc(long*); 1027dd7cddfSDavid du Colombier long _xdec(long*); 103