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 33*59cc4ca5SDavid 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 42*59cc4ca5SDavid 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 467dd7cddfSDavid du Colombier }; 477dd7cddfSDavid du Colombier 487dd7cddfSDavid du Colombier struct Proc { 497dd7cddfSDavid du Colombier Lock lock; 507dd7cddfSDavid du Colombier int pid; 517dd7cddfSDavid du Colombier 527dd7cddfSDavid du Colombier jmp_buf oldenv; // jump buf for returning to original stack 537dd7cddfSDavid du Colombier 547dd7cddfSDavid du Colombier int nthreads; 557dd7cddfSDavid du Colombier Tqueue threads; // All threads of this proc 567dd7cddfSDavid du Colombier Tqueue runnable; // Runnable threads 577dd7cddfSDavid du Colombier Thread *curthread; // Running thread 587dd7cddfSDavid du Colombier 597dd7cddfSDavid du Colombier int blocked; // In a rendezvous 607dd7cddfSDavid du Colombier uint nextID; // ID of most recently created thread 617dd7cddfSDavid du Colombier Proc *next; // linked list of Procs 627dd7cddfSDavid du Colombier 637dd7cddfSDavid du Colombier void *arg; // passed between shared and unshared stk 64*59cc4ca5SDavid du Colombier char str[ERRLEN]; // used by threadexits to avoid malloc 657dd7cddfSDavid du Colombier 667dd7cddfSDavid du Colombier ulong udata; // User per-proc data pointer 677dd7cddfSDavid du Colombier }; 687dd7cddfSDavid du Colombier 697dd7cddfSDavid du Colombier typedef struct Newproc { 707dd7cddfSDavid du Colombier uchar *stack; 717dd7cddfSDavid du Colombier uint stacksize; 727dd7cddfSDavid du Colombier ulong *stackptr; 737dd7cddfSDavid du Colombier ulong launcher; 747dd7cddfSDavid du Colombier int grp; 757dd7cddfSDavid du Colombier } Newproc; 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier typedef struct Execproc { 78*59cc4ca5SDavid du Colombier Proc *procp; 797dd7cddfSDavid du Colombier char *file; 80*59cc4ca5SDavid du Colombier char **arg; 81*59cc4ca5SDavid du Colombier char data[4096]; 827dd7cddfSDavid du Colombier } Execproc; 837dd7cddfSDavid du Colombier 847dd7cddfSDavid du Colombier struct Pqueue { // Proc queue 857dd7cddfSDavid du Colombier Lock lock; 867dd7cddfSDavid du Colombier Proc *head; 877dd7cddfSDavid du Colombier Proc *tail; 887dd7cddfSDavid du Colombier }; 897dd7cddfSDavid du Colombier 907dd7cddfSDavid du Colombier extern struct Pqueue pq; // Linked list of procs 917dd7cddfSDavid du Colombier extern Proc **procp; // Pointer to pointer to proc's Proc structure 927dd7cddfSDavid du Colombier 937dd7cddfSDavid du Colombier int tas(int*); 947dd7cddfSDavid du Colombier int inc(int*, int); 957dd7cddfSDavid du Colombier int cas(Lock *lock, Lock old, Lock new); 96*59cc4ca5SDavid du Colombier ulong _threadrendezvous(ulong, ulong); 977dd7cddfSDavid du Colombier void *_threadmalloc(long size); 987dd7cddfSDavid du Colombier void _xinc(long*); 997dd7cddfSDavid du Colombier long _xdec(long*); 100