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 volatile int closed; /* channel is closed */ 32 uchar v[1]; /* Array of s values in the channel */ 33 }; 34 35 36 /* Channel operations for alt: */ 37 typedef enum { 38 CHANEND, 39 CHANSND, 40 CHANRCV, 41 CHANNOP, 42 CHANNOBLK, 43 } ChanOp; 44 45 struct Alt { 46 Channel *c; /* channel */ 47 void *v; /* pointer to value */ 48 ChanOp op; /* operation */ 49 char *err; /* did the op fail? */ 50 /* 51 * the next variables are used internally to alt 52 * they need not be initialized 53 */ 54 Channel **tag; /* pointer to rendez-vous tag */ 55 int entryno; /* entry number */ 56 }; 57 58 struct Ref { 59 long ref; 60 }; 61 62 int alt(Alt alts[]); 63 int chanclose(Channel*); 64 int chanclosing(Channel *c); 65 Channel*chancreate(int elemsize, int bufsize); 66 int chaninit(Channel *c, int elemsize, int elemcnt); 67 void chanfree(Channel *c); 68 int chanprint(Channel *, char *, ...); 69 long decref(Ref *r); /* returns 0 iff value is now zero */ 70 void incref(Ref *r); 71 int nbrecv(Channel *c, void *v); 72 void* nbrecvp(Channel *c); 73 ulong nbrecvul(Channel *c); 74 int nbsend(Channel *c, void *v); 75 int nbsendp(Channel *c, void *v); 76 int nbsendul(Channel *c, ulong v); 77 void needstack(int); 78 int proccreate(void (*f)(void *arg), void *arg, uint stacksize); 79 int procrfork(void (*f)(void *arg), void *arg, uint stacksize, int flag); 80 void** procdata(void); 81 void procexec(Channel *, char *, char *[]); 82 void procexecl(Channel *, char *, ...); 83 int recv(Channel *c, void *v); 84 void* recvp(Channel *c); 85 ulong recvul(Channel *c); 86 int send(Channel *c, void *v); 87 int sendp(Channel *c, void *v); 88 int sendul(Channel *c, ulong v); 89 int threadcreate(void (*f)(void *arg), void *arg, uint stacksize); 90 void** threaddata(void); 91 void threadexits(char *); 92 void threadexitsall(char *); 93 int threadgetgrp(void); /* return thread group of current thread */ 94 char* threadgetname(void); 95 void threadint(int); /* interrupt thread */ 96 void threadintgrp(int); /* interrupt threads in grp */ 97 void threadkill(int); /* kill thread */ 98 void threadkillgrp(int); /* kill threads in group */ 99 void threadmain(int argc, char *argv[]); 100 void threadnonotes(void); 101 int threadnotify(int (*f)(void*, char*), int in); 102 int threadid(void); 103 int threadpid(int); 104 int threadsetgrp(int); /* set thread group, return old */ 105 void threadsetname(char *fmt, ...); 106 Channel*threadwaitchan(void); 107 int tprivalloc(void); 108 void tprivfree(int); 109 void **tprivaddr(int); 110 void yield(void); 111 112 extern int mainstacksize; 113 114 /* slave I/O processes */ 115 typedef struct Ioproc Ioproc; 116 117 #pragma incomplete Ioproc 118 119 120 Ioproc* ioproc(void); 121 void closeioproc(Ioproc*); 122 void iointerrupt(Ioproc*); 123 124 int ioclose(Ioproc*, int); 125 int iodial(Ioproc*, char*, char*, char*, int*); 126 int ioopen(Ioproc*, char*, int); 127 long ioread(Ioproc*, int, void*, long); 128 long ioreadn(Ioproc*, int, void*, long); 129 long iowrite(Ioproc*, int, void*, long); 130 int iosleep(Ioproc*, long); 131 132 long iocall(Ioproc*, long (*)(va_list*), ...); 133 void ioret(Ioproc*, int); 134