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