17dd7cddfSDavid du Colombier #pragma src "/sys/src/libthread" 27dd7cddfSDavid du Colombier #pragma lib "libthread.a" 37dd7cddfSDavid du Colombier 49a747e4fSDavid du Colombier #pragma varargck argpos chanprint 2 57dd7cddfSDavid du Colombier 67dd7cddfSDavid du Colombier typedef struct Alt Alt; 77dd7cddfSDavid du Colombier typedef struct Channel Channel; 87dd7cddfSDavid du Colombier typedef struct Ref Ref; 97dd7cddfSDavid du Colombier 1059cc4ca5SDavid du Colombier /* Channel structure. S is the size of the buffer. For unbuffered channels 1159cc4ca5SDavid du Colombier * s is zero. v is an array of s values. If s is zero, v is unused. 1259cc4ca5SDavid du Colombier * f and n represent the state of the queue pointed to by v. 1359cc4ca5SDavid du Colombier */ 1459cc4ca5SDavid du Colombier 159a747e4fSDavid du Colombier enum { 169a747e4fSDavid du Colombier Nqwds = 2, 179a747e4fSDavid du Colombier Nqshift = 5, // 2log #of bits in long 189a747e4fSDavid du Colombier Nqmask = - 1, 199a747e4fSDavid du Colombier Nqbits = (1 << Nqshift) * 2, 209a747e4fSDavid du Colombier }; 219a747e4fSDavid du Colombier 2259cc4ca5SDavid du Colombier struct Channel { 2359cc4ca5SDavid du Colombier int s; // Size of the channel (may be zero) 2459cc4ca5SDavid du Colombier uint f; // Extraction point (insertion pt: (f + n) % s) 2559cc4ca5SDavid du Colombier uint n; // Number of values in the channel 2659cc4ca5SDavid du Colombier int e; // Element size 2759cc4ca5SDavid du Colombier int freed; // Set when channel is being deleted 289a747e4fSDavid du Colombier volatile Alt **qentry; // Receivers/senders waiting (malloc) 299a747e4fSDavid du Colombier volatile int nentry; // # of entries malloc-ed 309a747e4fSDavid du Colombier uchar v[1]; // Array of s values in the channel 3159cc4ca5SDavid du Colombier }; 3259cc4ca5SDavid du Colombier 3359cc4ca5SDavid du Colombier 347dd7cddfSDavid du Colombier /* Channel operations for alt: */ 359a747e4fSDavid du Colombier typedef enum { 369a747e4fSDavid du Colombier CHANEND, 379a747e4fSDavid du Colombier CHANSND, 389a747e4fSDavid du Colombier CHANRCV, 399a747e4fSDavid du Colombier CHANNOP, 409a747e4fSDavid du Colombier CHANNOBLK, 419a747e4fSDavid du Colombier } ChanOp; 427dd7cddfSDavid du Colombier 437dd7cddfSDavid du Colombier struct Alt { 447dd7cddfSDavid du Colombier Channel *c; /* channel */ 457dd7cddfSDavid du Colombier void *v; /* pointer to value */ 469a747e4fSDavid du Colombier ChanOp op; /* operation */ 477dd7cddfSDavid du Colombier 487dd7cddfSDavid du Colombier /* the next variables are used internally to alt 497dd7cddfSDavid du Colombier * they need not be initialized 507dd7cddfSDavid du Colombier */ 517dd7cddfSDavid du Colombier Channel **tag; /* pointer to rendez-vous tag */ 529a747e4fSDavid du Colombier int entryno; /* entry number */ 537dd7cddfSDavid du Colombier }; 547dd7cddfSDavid du Colombier 557dd7cddfSDavid du Colombier struct Ref { 567dd7cddfSDavid du Colombier long ref; 577dd7cddfSDavid du Colombier }; 587dd7cddfSDavid du Colombier 597dd7cddfSDavid du Colombier int alt(Alt alts[]); 607dd7cddfSDavid du Colombier Channel* chancreate(int elemsize, int bufsize); 6159cc4ca5SDavid du Colombier int chaninit(Channel *c, int elemsize, int elemcnt); 627dd7cddfSDavid du Colombier void chanfree(Channel *c); 639a747e4fSDavid du Colombier int chanprint(Channel *, char *, ...); 647dd7cddfSDavid du Colombier long decref(Ref *r); /* returns 0 iff value is now zero */ 657dd7cddfSDavid du Colombier void incref(Ref *r); 667dd7cddfSDavid du Colombier int nbrecv(Channel *c, void *v); 677dd7cddfSDavid du Colombier void* nbrecvp(Channel *c); 687dd7cddfSDavid du Colombier ulong nbrecvul(Channel *c); 697dd7cddfSDavid du Colombier int nbsend(Channel *c, void *v); 707dd7cddfSDavid du Colombier int nbsendp(Channel *c, void *v); 717dd7cddfSDavid du Colombier int nbsendul(Channel *c, ulong v); 727dd7cddfSDavid du Colombier int proccreate(void (*f)(void *arg), void *arg, uint stacksize); 7380ee5cbfSDavid du Colombier int procrfork(void (*f)(void *arg), void *arg, uint stacksize, int flag); 749a747e4fSDavid du Colombier void** procdata(void); 757dd7cddfSDavid du Colombier void procexec(Channel *, char *, char *[]); 767dd7cddfSDavid du Colombier void procexecl(Channel *, char *, ...); 777dd7cddfSDavid du Colombier int recv(Channel *c, void *v); 787dd7cddfSDavid du Colombier void* recvp(Channel *c); 797dd7cddfSDavid du Colombier ulong recvul(Channel *c); 807dd7cddfSDavid du Colombier int send(Channel *c, void *v); 817dd7cddfSDavid du Colombier int sendp(Channel *c, void *v); 827dd7cddfSDavid du Colombier int sendul(Channel *c, ulong v); 837dd7cddfSDavid du Colombier int threadcreate(void (*f)(void *arg), void *arg, uint stacksize); 849a747e4fSDavid du Colombier void** threaddata(void); 857dd7cddfSDavid du Colombier void threadexits(char *); 867dd7cddfSDavid du Colombier void threadexitsall(char *); 877dd7cddfSDavid du Colombier int threadgetgrp(void); /* return thread group of current thread */ 887dd7cddfSDavid du Colombier char* threadgetname(void); 899a747e4fSDavid du Colombier void threadint(int); /* interrupt thread */ 909a747e4fSDavid du Colombier void threadintgrp(int); /* interrupt threads in grp */ 9159cc4ca5SDavid du Colombier void threadkill(int); /* kill thread */ 927dd7cddfSDavid du Colombier void threadkillgrp(int); /* kill threads in group */ 937dd7cddfSDavid du Colombier void threadmain(int argc, char *argv[]); 9480ee5cbfSDavid du Colombier void threadnonotes(void); 959a747e4fSDavid du Colombier int threadnotify(int (*f)(void*, char*), int in); 969a747e4fSDavid du Colombier int threadid(void); 9780ee5cbfSDavid du Colombier int threadpid(int); 987dd7cddfSDavid du Colombier int threadsetgrp(int); /* set thread group, return old */ 99c193876bSDavid du Colombier void threadsetname(char *fmt, ...); 1007dd7cddfSDavid du Colombier Channel* threadwaitchan(void); 1016b6b9ac8SDavid du Colombier int tprivalloc(void); 1026b6b9ac8SDavid du Colombier void tprivfree(int); 1036b6b9ac8SDavid du Colombier void **tprivaddr(int); 1047dd7cddfSDavid du Colombier void yield(void); 1059a747e4fSDavid du Colombier 1069a747e4fSDavid du Colombier extern int mainstacksize; 1073ff48bf5SDavid du Colombier 1083ff48bf5SDavid du Colombier /* slave I/O processes */ 1093ff48bf5SDavid du Colombier typedef struct Ioproc Ioproc; 1103ff48bf5SDavid du Colombier 111*12fd1c83SDavid du Colombier #pragma incomplete Ioproc 112*12fd1c83SDavid du Colombier 113*12fd1c83SDavid du Colombier 1143ff48bf5SDavid du Colombier Ioproc* ioproc(void); 1153ff48bf5SDavid du Colombier void closeioproc(Ioproc*); 1163ff48bf5SDavid du Colombier void iointerrupt(Ioproc*); 1173ff48bf5SDavid du Colombier 1183ff48bf5SDavid du Colombier int ioclose(Ioproc*, int); 1193ff48bf5SDavid du Colombier int iodial(Ioproc*, char*, char*, char*, int*); 1203ff48bf5SDavid du Colombier int ioopen(Ioproc*, char*, int); 1213ff48bf5SDavid du Colombier long ioread(Ioproc*, int, void*, long); 1223ff48bf5SDavid du Colombier long ioreadn(Ioproc*, int, void*, long); 1233ff48bf5SDavid du Colombier long iowrite(Ioproc*, int, void*, long); 1247fd46167SDavid du Colombier int iosleep(Ioproc*, long); 1253ff48bf5SDavid du Colombier 1263ff48bf5SDavid du Colombier long iocall(Ioproc*, long (*)(va_list*), ...); 1273ff48bf5SDavid du Colombier void ioret(Ioproc*, int); 128