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 1041dd6b47SDavid du Colombier /* 1141dd6b47SDavid du Colombier * Channel structure. S is the size of the buffer. For unbuffered channels 1259cc4ca5SDavid du Colombier * s is zero. v is an array of s values. If s is zero, v is unused. 1359cc4ca5SDavid du Colombier * f and n represent the state of the queue pointed to by v. 1459cc4ca5SDavid du Colombier */ 1559cc4ca5SDavid du Colombier 169a747e4fSDavid du Colombier enum { 179a747e4fSDavid du Colombier Nqwds = 2, 1841dd6b47SDavid du Colombier Nqshift = 5, /* log₂ # of bits in long */ 199a747e4fSDavid du Colombier Nqmask = -1, 209a747e4fSDavid du Colombier Nqbits = (1 << Nqshift) * 2, 219a747e4fSDavid du Colombier }; 229a747e4fSDavid du Colombier 2359cc4ca5SDavid du Colombier struct Channel { 2441dd6b47SDavid du Colombier int s; /* Size of the channel (may be zero) */ 2541dd6b47SDavid du Colombier uint f; /* Extraction point (insertion pt: (f+n) % s) */ 2641dd6b47SDavid du Colombier uint n; /* Number of values in the channel */ 2741dd6b47SDavid du Colombier int e; /* Element size */ 2841dd6b47SDavid du Colombier int freed; /* Set when channel is being deleted */ 2941dd6b47SDavid du Colombier volatile Alt **qentry; /* Receivers/senders waiting (malloc) */ 3041dd6b47SDavid du Colombier volatile int nentry; /* # of entries malloc-ed */ 316a5ecc41SDavid du Colombier volatile int closed; /* channel is closed */ 3241dd6b47SDavid du Colombier uchar v[1]; /* Array of s values in the channel */ 3359cc4ca5SDavid du Colombier }; 3459cc4ca5SDavid du Colombier 3559cc4ca5SDavid du Colombier 367dd7cddfSDavid du Colombier /* Channel operations for alt: */ 379a747e4fSDavid du Colombier typedef enum { 389a747e4fSDavid du Colombier CHANEND, 399a747e4fSDavid du Colombier CHANSND, 409a747e4fSDavid du Colombier CHANRCV, 419a747e4fSDavid du Colombier CHANNOP, 429a747e4fSDavid du Colombier CHANNOBLK, 439a747e4fSDavid du Colombier } ChanOp; 447dd7cddfSDavid du Colombier 457dd7cddfSDavid du Colombier struct Alt { 467dd7cddfSDavid du Colombier Channel *c; /* channel */ 477dd7cddfSDavid du Colombier void *v; /* pointer to value */ 489a747e4fSDavid du Colombier ChanOp op; /* operation */ 496a5ecc41SDavid du Colombier char *err; /* did the op fail? */ 5041dd6b47SDavid du Colombier /* 5141dd6b47SDavid du Colombier * the next variables are used internally to alt 527dd7cddfSDavid du Colombier * they need not be initialized 537dd7cddfSDavid du Colombier */ 547dd7cddfSDavid du Colombier Channel **tag; /* pointer to rendez-vous tag */ 559a747e4fSDavid du Colombier int entryno; /* entry number */ 567dd7cddfSDavid du Colombier }; 577dd7cddfSDavid du Colombier 587dd7cddfSDavid du Colombier struct Ref { 597dd7cddfSDavid du Colombier long ref; 607dd7cddfSDavid du Colombier }; 617dd7cddfSDavid du Colombier 627dd7cddfSDavid du Colombier int alt(Alt alts[]); 636a5ecc41SDavid du Colombier int chanclose(Channel*); 64*b39189fdSDavid du Colombier int chanclosing(Channel *c); 657dd7cddfSDavid du Colombier Channel*chancreate(int elemsize, int bufsize); 6659cc4ca5SDavid du Colombier int chaninit(Channel *c, int elemsize, int elemcnt); 677dd7cddfSDavid du Colombier void chanfree(Channel *c); 689a747e4fSDavid du Colombier int chanprint(Channel *, char *, ...); 697dd7cddfSDavid du Colombier long decref(Ref *r); /* returns 0 iff value is now zero */ 707dd7cddfSDavid du Colombier void incref(Ref *r); 717dd7cddfSDavid du Colombier int nbrecv(Channel *c, void *v); 727dd7cddfSDavid du Colombier void* nbrecvp(Channel *c); 737dd7cddfSDavid du Colombier ulong nbrecvul(Channel *c); 747dd7cddfSDavid du Colombier int nbsend(Channel *c, void *v); 757dd7cddfSDavid du Colombier int nbsendp(Channel *c, void *v); 767dd7cddfSDavid du Colombier int nbsendul(Channel *c, ulong v); 772cca75a1SDavid du Colombier void needstack(int); 787dd7cddfSDavid du Colombier int proccreate(void (*f)(void *arg), void *arg, uint stacksize); 7980ee5cbfSDavid du Colombier int procrfork(void (*f)(void *arg), void *arg, uint stacksize, int flag); 809a747e4fSDavid du Colombier void** procdata(void); 817dd7cddfSDavid du Colombier void procexec(Channel *, char *, char *[]); 827dd7cddfSDavid du Colombier void procexecl(Channel *, char *, ...); 837dd7cddfSDavid du Colombier int recv(Channel *c, void *v); 847dd7cddfSDavid du Colombier void* recvp(Channel *c); 857dd7cddfSDavid du Colombier ulong recvul(Channel *c); 867dd7cddfSDavid du Colombier int send(Channel *c, void *v); 877dd7cddfSDavid du Colombier int sendp(Channel *c, void *v); 887dd7cddfSDavid du Colombier int sendul(Channel *c, ulong v); 897dd7cddfSDavid du Colombier int threadcreate(void (*f)(void *arg), void *arg, uint stacksize); 909a747e4fSDavid du Colombier void** threaddata(void); 917dd7cddfSDavid du Colombier void threadexits(char *); 927dd7cddfSDavid du Colombier void threadexitsall(char *); 937dd7cddfSDavid du Colombier int threadgetgrp(void); /* return thread group of current thread */ 947dd7cddfSDavid du Colombier char* threadgetname(void); 959a747e4fSDavid du Colombier void threadint(int); /* interrupt thread */ 969a747e4fSDavid du Colombier void threadintgrp(int); /* interrupt threads in grp */ 9759cc4ca5SDavid du Colombier void threadkill(int); /* kill thread */ 987dd7cddfSDavid du Colombier void threadkillgrp(int); /* kill threads in group */ 997dd7cddfSDavid du Colombier void threadmain(int argc, char *argv[]); 10080ee5cbfSDavid du Colombier void threadnonotes(void); 1019a747e4fSDavid du Colombier int threadnotify(int (*f)(void*, char*), int in); 1029a747e4fSDavid du Colombier int threadid(void); 10380ee5cbfSDavid du Colombier int threadpid(int); 1047dd7cddfSDavid du Colombier int threadsetgrp(int); /* set thread group, return old */ 105c193876bSDavid du Colombier void threadsetname(char *fmt, ...); 1067dd7cddfSDavid du Colombier Channel*threadwaitchan(void); 1076b6b9ac8SDavid du Colombier int tprivalloc(void); 1086b6b9ac8SDavid du Colombier void tprivfree(int); 1096b6b9ac8SDavid du Colombier void **tprivaddr(int); 1107dd7cddfSDavid du Colombier void yield(void); 1119a747e4fSDavid du Colombier 1129a747e4fSDavid du Colombier extern int mainstacksize; 1133ff48bf5SDavid du Colombier 1143ff48bf5SDavid du Colombier /* slave I/O processes */ 1153ff48bf5SDavid du Colombier typedef struct Ioproc Ioproc; 1163ff48bf5SDavid du Colombier 11712fd1c83SDavid du Colombier #pragma incomplete Ioproc 11812fd1c83SDavid du Colombier 11912fd1c83SDavid du Colombier 1203ff48bf5SDavid du Colombier Ioproc* ioproc(void); 1213ff48bf5SDavid du Colombier void closeioproc(Ioproc*); 1223ff48bf5SDavid du Colombier void iointerrupt(Ioproc*); 1233ff48bf5SDavid du Colombier 1243ff48bf5SDavid du Colombier int ioclose(Ioproc*, int); 1253ff48bf5SDavid du Colombier int iodial(Ioproc*, char*, char*, char*, int*); 1263ff48bf5SDavid du Colombier int ioopen(Ioproc*, char*, int); 1273ff48bf5SDavid du Colombier long ioread(Ioproc*, int, void*, long); 1283ff48bf5SDavid du Colombier long ioreadn(Ioproc*, int, void*, long); 1293ff48bf5SDavid du Colombier long iowrite(Ioproc*, int, void*, long); 1307fd46167SDavid du Colombier int iosleep(Ioproc*, long); 1313ff48bf5SDavid du Colombier 1323ff48bf5SDavid du Colombier long iocall(Ioproc*, long (*)(va_list*), ...); 1333ff48bf5SDavid du Colombier void ioret(Ioproc*, int); 134