1 #pragma src "/sys/src/libthread" 2 #pragma lib "libthread.a" 3 4 #pragma varargck argpos chanprint 2 5 6 typedef struct Alt Alt; 7 typedef struct Channel Channel; 8 typedef struct Ref Ref; 9 10 /* 11 * Channel structure. S is the size of the buffer. For unbuffered channels 12 * s is zero. v is an array of s values. If s is zero, v is unused. 13 * f and n represent the state of the queue pointed to by v. 14 */ 15 16 enum { 17 Nqwds = 2, 18 Nqshift = 5, /* log₂ # of bits in long */ 19 Nqmask = -1, 20 Nqbits = (1 << Nqshift) * 2, 21 }; 22 23 struct Channel { 24 int s; /* Size of the channel (may be zero) */ 25 uint f; /* Extraction point (insertion pt: (f+n) % s) */ 26 uint n; /* Number of values in the channel */ 27 int e; /* Element size */ 28 int freed; /* Set when channel is being deleted */ 29 volatile Alt **qentry; /* Receivers/senders waiting (malloc) */ 30 volatile int nentry; /* # of entries malloc-ed */ 31 uchar v[1]; /* Array of s values in the channel */ 32 }; 33 34 35 /* Channel operations for alt: */ 36 typedef enum { 37 CHANEND, 38 CHANSND, 39 CHANRCV, 40 CHANNOP, 41 CHANNOBLK, 42 } ChanOp; 43 44 struct Alt { 45 Channel *c; /* channel */ 46 void *v; /* pointer to value */ 47 ChanOp op; /* operation */ 48 /* 49 * the next variables are used internally to alt 50 * they need not be initialized 51 */ 52 Channel **tag; /* pointer to rendez-vous tag */ 53 int entryno; /* entry number */ 54 }; 55 56 struct Ref { 57 long ref; 58 }; 59 60 int alt(Alt alts[]); 61 Channel*chancreate(int elemsize, int bufsize); 62 int chaninit(Channel *c, int elemsize, int elemcnt); 63 void chanfree(Channel *c); 64 int chanprint(Channel *, char *, ...); 65 long decref(Ref *r); /* returns 0 iff value is now zero */ 66 void incref(Ref *r); 67 int nbrecv(Channel *c, void *v); 68 void* nbrecvp(Channel *c); 69 ulong nbrecvul(Channel *c); 70 int nbsend(Channel *c, void *v); 71 int nbsendp(Channel *c, void *v); 72 int nbsendul(Channel *c, ulong v); 73 void needstack(int); 74 int proccreate(void (*f)(void *arg), void *arg, uint stacksize); 75 int procrfork(void (*f)(void *arg), void *arg, uint stacksize, int flag); 76 void** procdata(void); 77 void procexec(Channel *, char *, char *[]); 78 void procexecl(Channel *, char *, ...); 79 int recv(Channel *c, void *v); 80 void* recvp(Channel *c); 81 ulong recvul(Channel *c); 82 int send(Channel *c, void *v); 83 int sendp(Channel *c, void *v); 84 int sendul(Channel *c, ulong v); 85 int threadcreate(void (*f)(void *arg), void *arg, uint stacksize); 86 void** threaddata(void); 87 void threadexits(char *); 88 void threadexitsall(char *); 89 int threadgetgrp(void); /* return thread group of current thread */ 90 char* threadgetname(void); 91 void threadint(int); /* interrupt thread */ 92 void threadintgrp(int); /* interrupt threads in grp */ 93 void threadkill(int); /* kill thread */ 94 void threadkillgrp(int); /* kill threads in group */ 95 void threadmain(int argc, char *argv[]); 96 void threadnonotes(void); 97 int threadnotify(int (*f)(void*, char*), int in); 98 int threadid(void); 99 int threadpid(int); 100 int threadsetgrp(int); /* set thread group, return old */ 101 void threadsetname(char *fmt, ...); 102 Channel*threadwaitchan(void); 103 int tprivalloc(void); 104 void tprivfree(int); 105 void **tprivaddr(int); 106 void yield(void); 107 108 extern int mainstacksize; 109 110 /* slave I/O processes */ 111 typedef struct Ioproc Ioproc; 112 113 #pragma incomplete Ioproc 114 115 116 Ioproc* ioproc(void); 117 void closeioproc(Ioproc*); 118 void iointerrupt(Ioproc*); 119 120 int ioclose(Ioproc*, int); 121 int iodial(Ioproc*, char*, char*, char*, int*); 122 int ioopen(Ioproc*, char*, int); 123 long ioread(Ioproc*, int, void*, long); 124 long ioreadn(Ioproc*, int, void*, long); 125 long iowrite(Ioproc*, int, void*, long); 126 int iosleep(Ioproc*, long); 127 128 long iocall(Ioproc*, long (*)(va_list*), ...); 129 void ioret(Ioproc*, int); 130